2011-11-02 67 views
4

我已经在导轨3.1中设置了独角兽,http流式传输直到启用Rack :: Deflater。 我已经尝试使用和不使用Rack :: Chunked。在curl中,我可以在chrome中看到我的回应,但出现以下错误:ERR_INVALID_CHUNKED_ENCODING在使用Rack :: Deflater时导轨中的HTTP流式传输不起作用

其他浏览器(firefox,safari)和开发(osx)与生产(heroku)之间的结果相同。

config.ru:

require ::File.expand_path('../config/environment', __FILE__) 
use Rack::Chunked 
use Rack::Deflater 
run Site::Application 

unicorn.rb:

listen 3001, :tcp_nopush => false 
worker_processes 1 # amount of unicorn workers to spin up 
timeout 30   # restarts workers that hang for 30 seconds 

控制器:

render "someview", :stream => true 

感谢您的帮助。

回答

3

问题是Rails的ActionController :: Streaming直接渲染到一个Chunked :: Body中。这意味着内容首先被分块,然后由Rack :: Deflater中间件进行gzip压缩,而不是gzip压缩,然后分块。

根据HTTP/1.1 RFC 6.2.1,分块必须是最后一个应用编码的转移。

由于“分块”是唯一传输编码需要由HTTP/1.1收件人应理解 ,它在一个持续连接上界定消息 至关重要的作用。无论何时在请求中将传输编码应用于有效载荷主体时,应用的最终传输编码必须为 “块”。

我固定它为我们的猴子打补丁的ActionController ::流_process_options和_render_template方法的初始化,因此不会在分块::身体包裹身体,并让机架::分块中间件做到这一点,而不是。

module GzipStreaming 
    def _process_options(options) 
    stream = options[:stream] 
    # delete the option to stop original implementation 
    options.delete(:stream) 
    super 
    if stream && env["HTTP_VERSION"] != "HTTP/1.0" 
     # Same as org implmenation except don't set the transfer-encoding header 
     # The Rack::Chunked middleware will handle it 
     headers["Cache-Control"] ||= "no-cache" 
     headers.delete('Content-Length') 
     options[:stream] = stream 
    end 
    end 

    def _render_template(options) 
    if options.delete(:stream) 
     # Just render, don't wrap in a Chunked::Body, let 
     # Rack::Chunked middleware handle it 
     view_renderer.render_body(view_context, options) 
    else 
     super 
    end 
    end 
end 

module ActionController 
    class Base 
    include GzipStreaming 
    end 
end 

,并留下您config.ru作为

require ::File.expand_path('../config/environment', __FILE__) 
use Rack::Chunked 
use Rack::Deflater 
run Roam7::Application 

不是一个很好的解决方案,它可能会打破这一检查/修改身体其他一些中间件。如果有人有更好的解决方案,我很乐意听到它。

如果您使用的是新文物,其中间件也必须为disabled when streaming

相关问题