【问题标题】:Rails send_file not working with files larger than 400mbRails send_file 无法处理大于 400mb 的文件
【发布时间】:2014-04-18 23:09:21
【问题描述】:

我使用 Helicon Zoo 在 Windows Server 2008 机器上设置了一个 rails 应用程序。

我的问题是下载超过 400MB 的文件。

在我的 rails 应用程序中,我使用以下内容将文件发送到客户端:

app/controllers/hosted_files_controller.rb

class HostedFilesController < ApplicationController
  before_filter :authenticate_user!
  around_filter :catch_not_foun

  def download
    @footprint = UserAbility.new(current_user).footprints.find(params[:id])
    send_file path
  end

  private

    def path
      if @footprint.subpath?
        @path = "#{HOSTED_FILES_PATH}\\#{@footprint.subpath}\\#{@footprint.filename}"
      else
        @path = "#{HOSTED_FILES_PATH}\\#{@footprint.filename}"
      end
    end

    def catch_not_found
      yield
    rescue ActiveRecord::RecordNotFound
      recover_and_log "We couldn't find that record.", "No record found using the id (#{params[:id]})"
    rescue ActionController::MissingFile
      recover_and_log "We couldn't find the file on our server.", "The file was not found at the following path: #{@path}"
    end

    def recover_and_log (displayed, logged)
      logger.info "!!! Error: #{logged}"
      redirect_to root_url, alert: displayed
    end
end

由于我没有使用 Apache 或 Nginx,因此我在 production.rb 文件中已将 config.action_dispatch.x_sendfile_header 注释掉。

这适用于服务器上低于 ~400MB 的所有文件。超过它之后,我从 Helicon Zoo 收到 500 内部服务器错误,内容如下:

Helicon Zoo module has caught up an error. Please see the details below.
Worker Status
The process was created
Windows error
The pipe has been ended. (ERROR CODE: 109)
Internal module error
message: ZooApplication backend read Error. 
type: ZooException
file: Jobs\JobBase.cpp
line: 566 
version: 3.1.98.508 
STDERR
Empty stderr

有人知道发生了什么吗?我很茫然。

我试过了:

  • 增加 send_file 上的 buffer_size(无效)
  • 在 IIS 中为应用程序池设置内存(无效)
  • 将 x_sendfile_header 更改为 X-Sendfile 和 X-Accel-Redirect(无效)

我正在考虑尝试在 Windows Server 上安装 Apache 并使用 x_sendfile_header 卸载将文件发送到 Apache,但我担心会弄乱已经(几乎)工作的应用程序。

有没有人知道如何解决这个问题?

【问题讨论】:

  • 这不是 ruby​​ on rails 的问题。这是您的应用程序/网络服务器的问题。因为有数据发送限制。就像在 nginx 中一样,您可以指定客户端最大正文大小。

标签: ruby-on-rails ruby iis download heliconzoo


【解决方案1】:

当前版本的 Helicon Zoo Ruby 应用程序默认安装为 FastCGI Ruby Rack 连接器。由于 FastCGI 协议是一个阻塞协议,它可能对请求超时或请求最大大小有一些限制。如果您需要发送大文件,我建议您改为使用“Ruby 1.9 Rack over HTTP with Thin”路线。我想你一直在遵循Ruby on Rails (2.3.x and 3.x.x) 的指令。现在只需按照Ruby Rack over HTTP with Thin 指令中的其他步骤进行操作,例如运行“gem install thin”命令并编辑 web.config,如下所示:

In the < handlers> section comment out two lines that follows

< !-- Ruby 1.9 over FastCGI -->

Uncomment two lines that follows 
< !-- Ruby 1.9 over HTTP, using Thin as a back-end application server -->
In the <environmentVariables> section uncomment line 
< !-- Use this APP_WORKER with HTTP Ruby engine and Thin. Thin need to be installed.
< add name="APP_WORKER" value="GEM_HOME\bin\thin start" />

由于您已经在使用 Helicon 产品,另一个解决方案是安装 Helicon Ape,它提供对 Apache 中的 X-Sendfile HTTP header (see documentation) 标头的支持,并且对于每台服务器的多个站点是免费的。这个解决方案会更好,因为将使用低级别的 WinHTTP 代码来发送数据,这将减少服务器的负载并提高响应速度。

【讨论】:

  • 感谢您的提示。不幸的是,我必须通勤到另一个城市来尝试这些变化,但希望我能尽快做到这一点。问题:如果我采用 Helicon Ape 路线,这是否将 Apache 与 IIS 结合使用,或者我会为此将应用程序迁移到 Apache 吗?
  • Helicon Ape 根本没有使用 Apache。这是一个从头开始编写的本机 IIS 7 模块,它在 IIS 中实现了所有流行的 Apache 模块。这是唯一使用 Windows 强度的 IIS 解决方案,因为它不需要与 *nix 兼容。
  • 不错。很好的解释。所以我安装了 Helicon Ape,现在我似乎在将参数传递到我的 rails 应用程序时遇到了问题。当我访问 /admin/user_info?id=1 之类的路线时,我的 rails 应用程序的 params[:id] 为 nil。这似乎只有在安装 Helicon Ape 时才会发生。当我卸载它时,同样的路线工作得很好。关于这是什么的任何想法?我猜我需要做的不仅仅是安装 Helicon Ape 并在 .htaccess 文件中添加 XSendFile On。
  • 所以我使用 XSendFile On 对下载进行了一些测试,效果很好!一切都毫无问题地发送。现在我只需要弄清楚这整个缺少参数的问题。
  • 我在 SO 上添加了另一个问题,因为这与这里的问题无关。在我能够使用参数修复错误并验证 Helicon Ape 是正确的解决方案后,我将选择此答案作为解决方案。 stackoverflow.com/questions/23249852/…
猜你喜欢
  • 2012-04-17
  • 2023-03-08
  • 2014-06-29
  • 2014-04-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-24
相关资源
最近更新 更多