Rails XSendfile via Nginx

Francis Daly francis at daoine.org
Fri May 11 00:36:27 UTC 2012

On Thu, May 10, 2012 at 10:46:41PM +0200, Ari King wrote:
> > or do you want your rails backend server to do some processing and
> > decide whether or not they should be sent the contents of that file,

> I want rails to authenticate/authorize access to the content in question
> and then have nginx serve that file. The following articles
> explain/demonstrate what I'm trying to do:
> http://rack.rubyforge.org/doc/Rack/Sendfile.html
> http://thedataasylum.com/articles/how-rails-nginx-x-accel-redirect-work-together.html

That seems pretty clear, and seems to match what was mentioned earlier
in the thread.

You must configure the nginx location that corresponds to "/public/url",
to send the request to rails.

You must configure the rails side to send back a response with
"X-Accel-Redirect: /private/url".

You must configure the nginx location that corresponds to "/private/url"
to serve the correct file.

It is probably simplest (and matches the examples on those two pages
most closely) if the /private/url that rails returns maps directly to
a file on the filesystem.

On the nginx side, you want two location{}s -- one which matches
/public/url and one which matches /private/url.

On the rails side, do whatever it takes to get it to turn /public/url
into /private/url. That will probably involve the alias mapping thing
you mentioned earlier -- but that's a rails thing, so you'll get better
help on a rails list for that.

Your thedataasylum.com link does seem to give a strong hint what it is
about, though -- in rails code you call send_file() with the actual
filename you wish to have sent, and then the X-Accel-Mapping value
replaces the first bit of that filename with the private url prefix.

It appears that what you have right now is the location that matches
/public/url not sending the request to rails. And you don't appear to
have any specific location matching the private url, which seems to be
of the form "/video/1/original/example_one.ogg".

So, probably, get rid of your "location /recipes/" thing, and add a
"location /video/" with a suitable alias or root directive.

If you're still having difficulties, I suggest you show your nginx config,
and show the curl request and response when you make the request of the
rails server directly, including "-i" for the headers, and five "-H"
arguments, one for each "proxy_set_header" value that you have in your
nginx config.

(And if that doesn't make it clear where the problem is, probably also
show the line in your rails code which does "send_file()". But that bit
will probably be more interesting to a rails list.)

Good luck with it,

Francis Daly        francis at daoine.org

More information about the nginx mailing list