2011-11-02 71 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

相關問題