From df92940cc9afdd8a95301734c2c79471ed861c9a Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 8 Apr 2015 06:09:40 +0000 Subject: proxy_pass: support backends which rely on EOF to terminate Not all backends are capable of generating chunked responses (especially not to HTTP/1.0 clients) nor can they generate the Content-Length (especially when gzipping), so they'll close the socket to signal EOF instead. --- lib/yahns/proxy_http_response.rb | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb index cbfc17e..af8d8cc 100644 --- a/lib/yahns/proxy_http_response.rb +++ b/lib/yahns/proxy_http_response.rb @@ -106,7 +106,7 @@ module Yahns::HttpResponse # :nodoc: return :wait_readable # self remains in :ignore, wait on upstream end until len == 0 - else # nasty chunked body + elsif kcar.chunked? # nasty chunked body req_res.proxy_trailers = nil # define to avoid warnings for now buf = '' case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf) @@ -137,6 +137,21 @@ module Yahns::HttpResponse # :nodoc: end # no loop here end wbuf = proxy_write(wbuf, trailer_out(tlr), alive) + + else # no Content-Length or Transfer-Encoding: chunked, wait on EOF! + + case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf) + when String + wbuf = proxy_write(wbuf, tmp, alive) + when nil + req_res.shutdown + break + when :wait_readable + # for ensure: + wbuf ||= Yahns::Wbuf.new(nil, alive, k.output_buffer_tmpdir, false) + return :wait_readable # self remains in :ignore, wait on upstream + end while true + end end @@ -163,7 +178,7 @@ module Yahns::HttpResponse # :nodoc: return :wait_readable # self remains in :ignore, wait on upstream end while len != 0 - else # nasty chunked body + elsif kcar.chunked? # nasty chunked body buf = '' unless req_res.proxy_trailers @@ -193,10 +208,23 @@ module Yahns::HttpResponse # :nodoc: end # no loop here end wbuf.wbuf_write(self, trailer_out(tlr)) + + else # no Content-Length or Transfer-Encoding: chunked, wait on EOF! + + case tmp = req_res.kgio_tryread(0x2000, rbuf) + when String + wbuf.wbuf_write(self, tmp) + when nil + req_res.shutdown + break + when :wait_readable + return :wait_readable # self remains in :ignore, wait on upstream + end while true + end busy = wbuf.busy and return proxy_busy_mod_blocked(wbuf, busy) - proxy_busy_mod_done(wbuf.wbuf_persist) + proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil end def proxy_busy_mod_done(alive) -- cgit v1.2.3-24-ge0c7