ruby-on-rails - 在给定 URL 的情况下,替代 Apache 中的 X-sendfile 发送文件?

标签 ruby-on-rails apache proxy amazon-s3

我正在编写一个 Rails 应用程序,它将存储在远程服务器上的文件提供给最终用户。

在我的情况下,文件存储在 S3 上,但用户通过 Rails 应用程序请求文件(隐藏实际 URL)。如果文件在我的服务器本地文件系统上,我可以使用 Apache header X-Sendfile 为其他请求释放 Ruby 进程,同时 Apache 接管将文件发送到客户端的任务。但在我的情况下——文件不在本地文件系统上,而是在 S3 上——似乎我被迫在 Rails 中临时下载它,然后再将其发送到客户端。

Apache 是否有办法向实际上不在其自身服务器上的客户端提供“远程”文件。我不介意 Apache 是否必须下载文件才能工作,只要我不必在 Ruby 进程运行时绑定(bind)它。

有什么建议么?

最佳答案

托马斯,我有类似的要求/问题,我想我可以回答你的问题。首先(我不是 100% 确定您是否关心这部分),隐藏 S3 url 非常容易,因为亚马逊允许您将 CNAMES 指向您的存储桶并使用自定义 URL 而不是亚马逊 URL。为此,您需要将您的 DNS 指向正确的亚马逊 URL。当我设置我的时,它与此类似:files.domain.com 指向 files.domain.com.s3.amazonaws.com。然后,您需要使用您的自定义 URL 的名称创建存储桶(在本例中为 files.domain.com)。根据您使用的 gem,如何调用该 URL 会有所不同,但要注意的是,我使用的 attachment_fu 插件错误地将我发送到 files.domain.com/files.domain.com/name_of_file....我找不到修复它的设置,因此插件的 S3 部分的简单 .sub 方法修复了它。

关于您的其他问题,要在下载之前执行一些 rails 代码(例如在 db 中记录命中),您可以简单地执行以下操作:

def download
  file = File.find(...
  # code to record 'hit' to database
  redirect_to 3Object.url_for(file.filename, 
                              bucket,
                              :expires_in => 3.hours)
end

该代码仍将导致文件由 S3 提供服务,但仍使您能够运行一些 ruby​​。 (当然,上面的代码不会按原样工作,您需要将它指向正确的文件和存储桶,并且我的亚马逊 key 保存在配置文件中。上面也使用 AWS::S3 gem 的语法- http://amazon.rubyforge.org/)。

其次,Content-Disposition:附件问题有点棘手。希望您的情况比我的情况简单一些,并且以下解决方案可以工作。假设对象"file"(在本例中)是正确的 S3 对象,您可以通过以下方式将处置设置为附件
file.content_disposition = "attachment"
file.save

上面的代码可以在文件存在 S3 服务器后执行(不像其他一些头和权限),这很好,也可以在上传文件时添加(语法取决于您的插件)。我仍在尝试找到一种方法来告诉 S3 将其作为附件发送,并且仅在请求时(不是每次)发送,如果您找到了,请告诉我您的解决方案。我需要能够有时下载它,有时将嵌入图像(例如)保存到 HTML 中。我没有使用上面提到的重定向,但幸运的是,如果您嵌入(例如 HTML 图像标记)带有 content-disposition/attachment header 的文件,并且浏览器仍然正常显示图像(但我没有在足够多的浏览器上对其进行了彻底的测试,以便在野外发送它)。

希望有帮助!祝你好运。

关于ruby-on-rails - 在给定 URL 的情况下,替代 Apache 中的 X-sendfile 发送文件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4398285/

相关文章:

textmate - Text Mate 中的 Bundler Gemfile 语法高亮显示

ruby-on-rails - 模块/类库

javascript - 使用html表格行作为复选框的方法?

php - XAMPP + PostgreSQL = 错误

scala - 加特林代理配置

java - HTTP代理在浏览器中正常工作,但不允许连接到Java中除443之外的任何端口

ruby-on-rails - 添加唯一:对于Active Record中的add_column和add_index为true

apache - RewriteRule 将 url 部分作为参数传递给 php 脚本

php - Android 的 HTTP header 和 Apache 的 php

c# - HTTPS 代理实现 (SSLStream)