When you use the
send_file
Show archive.org snapshot
method to send a local file to the browser, you can save resources on the application server by setting the :x_sendfile
option to true
. This option is activated by default for Rails 3, so you need to understand this.
What this option does is not to send any data at all, but rather set the local file path as a new response header:
X-Sendfile: /opt/www/awesome-project/shared/downloads/image.png
When the response comes back from Rails to Apache for delivery, Apache will detect that header and replace the empty response body with the local file contents. This trick frees up the expensive Rails/Passenger worker process and lets the lightweight Apache worker do the heavy lifting.
You need to configure Apache to be aware of X-Sendfile
or you will end up with unprocessed, zero-byte file dowloads.
Configuring the Apache module
Install the Apache module by saying
sudo apt-get install libapache2-mod-xsendfile
Check which version you got because that will be relevant later:
dpkg -l | grep libapache2-mod-xsendfile
If you have a module version < 0.10, add this to the virtual host config that needs to send files:
XSendFile On
XSendFileAllowAbove On
This allows any file path (not only those below your VHost root) to be sent through X-Sendfile
, which is sort of bad practice. You can either live with it or
compile a newer version of the module
Show archive.org snapshot
.
If you got a module version >= 0.10 you can whitelist the allowed paths instead:
XSendFile On
XSendFilePath /opt/www/awesome-project
Note that you cannot whitelist a symlink inside a current
release directory, because Apache sees those downloads with their real paths (releases/123456
).
Now restart Apache and you're good to go.