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 to
configure 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;
rails send_file and send_data sends out zero byte files
Try sending a simple file to see if it works
send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
Read this thread, I think it has everything you need.
Rails 3, apache & passenger, send_file sends zero byte files
I believe the previous answer isn't the right way to go because, as far as I can tell, Apache isn't handling the downloads at all when this solution is applied, instead the rails process is. That's why the nginx directive, which shouldn't work, appears to. You get the same result by commenting out the config directive.
Another drawback (aside from tying up a rails process for too long) is that when the data streaming is handled by the rails process the response doesn't seem to send the content length header. So a user doesn't know how large the file they're downloading is, nor how long it will take (a usability problem).
I was able to get it to work by ensuring that mod_sendfile was properly included and loaded in my apache config, like so (this will be dependent on your apache install, etc.):
LoadModule xsendfile_module /usr/lib64/httpd/modules/mod_xsendfile.so
...
# enable mod_x_sendfile for offloading zip file downloads from rails
XSendFile on
XSendFilePath /
What happend after send_file in Rails controller?
The send_file
is a render itself. You could use the approach proposed in this question:
Rails: send_file never renders page or DoubleRender error
Basically your download link will send to a "success" view, from which you call the download file method automatically.
send_file just sends an empty file
Problem saved, but I don't know why
File.open(file_path, 'r') do |f|
send_data f.read, :type => "text/xml", :filename => "10.xml"
end
send_data is working... but send_file not!
Ruby on rails : send_file returns a page full of bytes
Well, the answer is simple : juste change get
in post
in routes.rb and add method: 'post'
to the link...
Rails send_file not sending data when called through a web service
It was not a problem with send_file. It was how the .NET web service was programmed. It was expecting content length.
There is a change (between Rails 2 & Rails3) in the default behaviour when sending content. Now it is chunked content - so there can not be a content length.
The .NET guy changed the code and everything is now working fine! Hope this would help somebody.
Send_file download and inline
The main problem is that you would need two separate requests to do this. A possible solution could be that you render the inline PDF in a browser iframe and at the same time start a javascript request to which the server responds with send_file
or send_data
. The user only has to click once, but there are two requests made to the server, one renders the file as a download, the other sends it as an inline file.
The only caveat I can think of here is that a browser that doesn't support inline rendering of PDF files would start downloading the PDF twice. You'd have to find some way to check for this.
Related Topics
Undefined Method Attr_Accessible
Why Isn't Current Directory on My Ruby Path
Convert Array of 2-Element Arrays into a Hash, Where Duplicate Keys Append Additional Values
Parallel Assignment Operator in Ruby
What Is a Regex to Match a String Not At the End of a Line
Rspec: Expect VS Expect With Block - What's the Difference
What Are the Magic $-Prefixed Variables in Ruby
Rails Engines Extending Functionality
How to Remove the Bom from a Utf-8 Encoded File
How to Sort an Array in Ruby to a Particular Order
"Certificate Verify Failed" Openssl Error When Using Ruby 1.9.3
Ruby: How to Copy a Variable Without Pointing to the Same Object
How to Edit or Write on Existing Pdf With Ruby
Matching Balanced Parenthesis in Ruby Using Recursive Regular Expressions Like Perl
How to Format a Date in Ruby to Include "Rd" as in "3Rd"
Xpath Axis, Get All Following Nodes Until