Linux Rails 使用 send_file 发送 0 字节文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3724853/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Rails sends 0 byte files using send_file
提问by fivetwentysix
I can't get send_file(Model.attachment.path) to work. It doesn't fail, instead, it sends a 0 byte size file to the client, the file names are correct though.
我无法让 send_file(Model.attachment.path) 工作。它不会失败,而是向客户端发送一个 0 字节大小的文件,但文件名是正确的。
This problem started happening after I did a big migration from Rails 2.3.8 to 3.
在我从 Rails 2.3.8 大迁移到 3 之后,这个问题开始发生。
There were a lot of other things that took place in this migration and I will try my best to detail all of them.
在这次迁移中还发生了很多其他的事情,我会尽力详细说明所有这些事情。
- Distrubution change/Server Change. Rackspace RHEL5 to Linode Ubuntu 10.04LTS
- Ruby version change, 1.8.6 -> 1.9.2
- Rails version change, 2.3.8 -> 3.0.0
- httpd platform change, apache2 -> nginx (However I tried on apache2 as well and it did not work).
- 分销变更/服务器变更。Rackspace RHEL5 到 Linode Ubuntu 10.04LTS
- Ruby 版本更改,1.8.6 -> 1.9.2
- Rails 版本更改,2.3.8 -> 3.0.0
- httpd 平台更改,apache2 -> nginx(不过我也尝试过 apache2,但没有奏效)。
I moved the attachments via ftp as they were not part of my git repositories so they were published via cap deploy, instead manual ftp remote(RHEL5) to local(Win7) then local(Win7) to remote(Ubuntu10).
我通过 ftp 移动了附件,因为它们不是我的 git 存储库的一部分,所以它们通过 cap deploy 发布,而不是手动 ftp 远程(RHEL5)到本地(Win7)然后本地(Win7)到远程(Ubuntu10)。
I do know that FTPing does not retain the file permissions through the transfers, so what I've also done is mimicked the chmods that were seen on my previous servers so they are almost identical. (users/groups are different, set to root:root instead of olduser:olduser).
我确实知道 FTPing 不会通过传输保留文件权限,所以我还做了模仿在我以前的服务器上看到的 chmods,因此它们几乎相同。(用户/组不同,设置为 root:root 而不是 olduser:olduser)。
A snippet of the request to download a attachment from my production log.
从我的生产日志下载附件的请求片段。
Started GET "/attachments/replies/1410?1277105698" for 218.102.140.205 at 2010-09-16 09:44:31 +0000
Processing by AttachmentsController#replies as HTML
Parameters: {"1277105698"=>nil, "id"=>"1410"}
Sent file /srv/app/releases/20100916094249/attachments/replies/UE0003-Requisition_For_Compensation_Leave.doc (0.2ms)
Completed 200 OK in 78ms
Everything's okay. Let me also rule out local issues, I've tried downloading via Chrome on both Win7 and Ubuntu (on Vbox).
一切正常。让我也排除本地问题,我尝试在 Win7 和 Ubuntu(在 Vbox 上)上通过 Chrome 下载。
Let me also assure you that the path is indeed correct.
我也向你保证,这条路确实是正确的。
root@li162-41:/srv/app/current# tail /srv/app/releases/20100916094249/attachments/replies/UE0003-Requisition_For_Compensation_Leave.doc
#
#
%17nw
HQ??+1ae????
%33333333333(??QR???HX?"%%??@9
??@?p4??#P@??Unknown????????????G??z ?Times New Roman5??Symbol3&?
?z ?Arial5&?
So to sum up the question, how do I get send_file to actually send files instead of fake 0 byte junk.
所以总结一下这个问题,我如何让 send_file 实际发送文件而不是假的 0 字节垃圾。
采纳答案by gertas
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.
send_file
具有在 Rails 3 中:x_sendfile
默认为的参数true
。此功能通过返回带有路径的 X-Sendfile 标头的空响应,将流式下载卸载到前端服务器 - Apache(使用 mod_xsendfile)或 lighttpd。
Nginx uses X-Accel-Redirect
header for same functionality but you have to
configure Rails properly in proper environment file:
Nginx 使用X-Accel-Redirect
标头实现相同的功能,但您必须在适当的环境文件中正确配置 Rails:
config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'
Rails 3 update: this line already exists in production.rb
, just uncomment it.
Rails 3 更新:此行已存在于 中production.rb
,只需取消注释即可。
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.
添加sendfile on;
到您的 nginx 配置以利用 Rails 发送的标头。请记住,必须使用绝对路径,并且 nginx 必须具有对文件的读取权限。
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:
为了更好的安全性,我在 nginx 中使用别名而不是绝对路径,但是send_file
方法检查是否存在以别名失败的文件。因此我改变了我的行动:
head(
'X-Accel-Redirect'=> file_item.location,
'Content-Type' => file_item.content_type,
'Content-Disposition' => "attachment; filename=\"#{file_item.name}\"");
render :nothing => true;
回答by ashisrai_
In Rails 3, just uncomment the line config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect'in production.rb
inside environments folder.
在Rails 3,只是取消对线config.action_dispatch.x_sendfile_header =“X-阿塞尔-重定向”在production.rb
内部环境中的文件夹。
回答by evaneykelen
I've had similar issues with send_file() in the past, using send_data() instead saved me back then (e.g. send_data File.read(filename), :disposition => 'inline', :type => "some/mimetype")
过去我在 send_file() 上遇到过类似的问题,当时使用 send_data() 代替了我(例如 send_data File.read(filename), :disposition => 'inline', :type => "some/mimetype" )
回答by NoICE
Yes, I had the same problem with X-sendfile being enabled by default in Rails 3 too.
是的,我也遇到了在 Rails 3 中默认启用 X-sendfile 的同样问题。
If you have large volume of "send_file" calls, you can just comment-out following line in config/environments/production.rb:
如果您有大量的“send_file”调用,您可以在 config/environments/production.rb 中注释掉以下行:
#config.action_dispatch.x_sendfile_header = "X-Sendfile"
Then send_file
method started working perfectly.
然后send_file
方法开始完美地工作。
Because I can't install x-sendfile extension to Apache, I just searched a little and found this.
因为我无法将x-sendfile扩展安装到Apache,我只是搜索了一下,发现了这个。
I hope it helps.
我希望它有帮助。
回答by James Tan
on rails 4, i realize my problem is that i deleted the temporary file which ive generated to send to user.
在 Rails 4 上,我意识到我的问题是我删除了我生成的要发送给用户的临时文件。
if i didnt delete the file, send_file works. ive not tested on thin but it works great on passenger 5 as standalone server
如果我没有删除文件, send_file 就可以了。我没有在瘦身上测试过,但它在乘客 5 上作为独立服务器运行良好