2011-11-02 4 views
4

Rack :: Deflater를 사용할 때까지 레일 3.1 및 http 스트리밍에서 유니콘을 설정했습니다. 나는 Rack :: Chunked를 사용하거나 사용하지 않고 시도했다. 곱슬 곱슬하게 나는 크롬에서 다음과 같은 오류가 발생하는 동안 내 반응을 볼 수 있습니다. ERR_INVALID_CHUNKED_ENCODINGRack :: 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

레일즈 ActionController :: Streaming은 Chunked :: Body로 직접 렌더링됩니다. 즉, 내용은 먼저 chunked되고 gzip 된 다음 chunked 대신 Rack :: Deflater 미들웨어에 의해 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 

그리고

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

아니 아주 좋은 해결책으로 당신의 config.ru를 떠나, 아마/검사 몸을 수정 다른 미들웨어를 중단합니다. 누군가가 더 좋은 해결책을 가지고 있다면 나는 그것을 듣고 싶어한다.

새 유물을 사용하는 경우 해당 미들웨어도 disabled when streaming이어야합니다.