5

我正在制作一个简单的机架应用程序,在身份验证后授予对受保护文件的访问权限。
由于文件中的数据是敏感的,它们位于应用程序的非公共文件夹中。

现在,在检查会话数据后,我只是打开文件进行读取并将内容作为响应的主体发送。
感觉很难看,并且对于较大的文件必须非常消耗资源。

示例响应:

[ "200", {"Content-Type"=> MIME::Types.type_for(file).first.to_s }, File.open( file ).read() ]

我查看了Rack::Sendfile,但据我了解,它是一个中间件,无法从应用程序本身内部发送文件。

从 Rack 应用程序发送非公共二进制文件的最有效方法是什么?

4

2 回答 2

4

机架响应主体必须响应#each{|d|}. 所以你可以像这样流式传输响应:

class FileStreamer
  def initialize(path)
    @file = File.open(path)
  end

  def each(&blk)
    @file.each(&blk)
  ensure
    @file.close
  end
end

用法:

[ "200", {"Content-Type"=> MIME::Types.type_for(file).first.to_s }, FileStreamer.new(file) ]
于 2012-10-31T09:25:10.547 回答
0

作为替代方案,如果您使用Rack::Response 对象,您可以执行以下操作:

response = Rack::Response.new
file = open(path_to_binary_file, "rb")
# other stuff…
mime = Mime.mime_type(::File.extname(file.path), 'text/html')
response.headers.merge!( "Content-Type" => mime ) if mime
response.write file
response.finish
于 2013-03-08T05:26:35.747 回答