Rails sends 0 byte files using send_file
send_file
has :x_sendfile
param which defaults to true
in Rails 3.This feature offloads streaming download to front server - Apache (with mod_xsendfile) or lighttpd, by returning empty response with X-Sendfile header with path.
Nginx uses X-Accel-Redirect
header for same functionality but you have toconfigure Rails properly in proper environment file:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
Rails 3 update: this line already exists in production.rb
, just uncomment it.
Add sendfile on;
to your nginx config to utilize header sent by Rails.Remember the absolute path must be used and nginx must have read access to file.
Another way for aliased files:
For better security I use aliases in nginx instead of absolute paths,however send_file
method checks existence of file which fails with alias.Thus I changed my action to:
head( 'X-Accel-Redirect'=> file_item.location, 'Content-Type' => file_item.content_type, 'Content-Disposition' => "attachment; filename=\"#{file_item.name}\""); render :nothing => true;
In Rails 3, just uncomment the line config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' in production.rb
inside environments folder.
Yes, I had the same problem with X-sendfile being enabled by default in Rails 3 too.
If you have large volume of "send_file" calls,you can just comment-out following line in config/environments/production.rb:
#config.action_dispatch.x_sendfile_header = "X-Sendfile"
Then send_file
method started working perfectly.
Because I can't install x-sendfile extension to Apache, I just searched a little and found this.
I hope it helps.