TL;DR - To use X-Accel-Redirect to serve static files from e.g /mnt/filestorage using send_file, put this in your nginx server configuration.
1 2 3 4 5 6
The need for X-Accel-Redirect (and it’s sibling X-Sendfile) comes from two distinct requirements
- The need to deliver large files.
- The need for those files to not be available to the public.
Here we are going to see how to set up X-Accel-Redirect and Rails. This is a bit complex so I’m going to run through a specific example of downloading a file. Along the way we’ll see the configuration, code and HTTP headers that are used. This assumes you already have Rails and Nginx installed and working.
1. Browser makes a request for a file
2. Nginx receives this request. It adds on a header with configuration data that will be required by rails.
1 2 3 4 5 6
3. Nginx passes the request onto Rails and it invokes the relevant controller.
4. The controller makes its authorization checks and calls send_file. Use the absolute path to the file.
5. Rails (Rack to be precise) then decides what to with the file. We need to tell rails to use X-Accel-Redirect in its configuration as shown below. Instead of using the file as the body of the request, it will add a header to the response. It uses the X-Accel-Mapping that nginx added earlier to change the file path.
1 2 3 4 5 6 7 8 9 10
6. Nginx receives this header from rails and interprets it. It finds the location directive and reverses the changes to the path that rails made in step 5.
1 2 3 4 5 6 7 8 9 10 11 12
7. Browser receives the file as if it was a normal download.
Also, if you have compiled passenger into nginx, remember to use passenger_set_cgi_param instead of proxy_set_header
Software Versions used
- Rails 3.0.7
- Passenger 3.0.5
- Nginx 0.8.54
- on Ubuntu 10.04.2 LTS