Проблема в том, что Rails ActionController :: Streaming рендерится напрямую в Chunked :: Body.Это означает, что содержимое сначала разбивается на куски, а затем архивируется промежуточным программным обеспечением Rack :: Deflater вместо gzipped, а затем разбивается на куски.
В соответствии с HTTP / 1.1 RFC 6.2.1 , чанкинг долженбыть последним примененным кодированием для передачи.
Поскольку "chunked" является единственным кодированием передачи, которое необходимо понимать получателям HTTP / 1.1, он играет решающую роль в разграничении сообщений на постоянном соединении.Всякий раз, когда кодирование передачи применяется к телу полезной нагрузки в запросе, окончательное примененное кодирование передачи должно быть «разбито на куски».
Я исправил это для нас, установив в ActionController обезьяны: Streaming _process_options иМетоды _render_template в инициализаторе, чтобы он не переносил тело в Chunked :: Body, и позволяет промежуточному программному обеспечению Rack :: Chunked делать это вместо этого.
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
Не очень хорошее решение, оно, вероятно, сломает некоторые другие промежуточные программы, которые проверяют / модифицируют тело.Если у кого-то есть лучшее решение, я бы хотел услышать его.
Если вы используете новую реликвию, ее промежуточное программное обеспечение также должно быть отключено при потоковой передаче .