diff options
author | Eric Wong <e@80x24.org> | 2016-04-30 10:02:06 +0000 |
---|---|---|
committer | Eric Wong <e@80x24.org> | 2016-04-30 10:02:06 +0000 |
commit | 01a63717093d3b11a57abc92bc77463545189e4c (patch) | |
tree | e395193845a61c2ff66edcecc1dce043a2b0f185 /lib/yahns/proxy_http_response.rb | |
parent | 498386c33d162cac11506da694f0355add06be06 (diff) | |
parent | 5a74026b580cefeb95d75db40e1a55cd0be52751 (diff) | |
download | yahns-01a63717093d3b11a57abc92bc77463545189e4c.tar.gz |
* proxy_pass-fix: proxy_pass: drop resources immediately on errors proxy_http_response: do not persist upstream on slow clients proxy_http_response: cleanup: avoid redundant setting of "alive" wbuf: drop persistence if writing to client fails test_proxy_pass: test for auto chunking on 1.0 backends
Diffstat (limited to 'lib/yahns/proxy_http_response.rb')
-rw-r--r-- | lib/yahns/proxy_http_response.rb | 37 |
1 files changed, 21 insertions, 16 deletions
diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb index c8a2a42..c5e7be5 100644 --- a/lib/yahns/proxy_http_response.rb +++ b/lib/yahns/proxy_http_response.rb @@ -43,7 +43,12 @@ module Yahns::HttpResponse # :nodoc: Rack::Utils::HTTP_STATUS_CODES[code]}\r\n\r\n") rescue nil shutdown rescue nil - req_res.shutdown rescue nil + @input = @input.close if @input + + # this is safe ONLY because we are in an :ignore state after + # Fdmap#forget when we got hijacked: + close + nil # signal close of req_res from yahns_step in yahns/proxy_pass.rb ensure wbuf.wbuf_abort if wbuf @@ -56,6 +61,7 @@ module Yahns::HttpResponse # :nodoc: :wait_readable # self remains in :ignore, wait on upstream end + # start streaming the response once upstream is done sending headers to us. # returns :wait_readable if we need to read more from req_res # returns :ignore if we yield control to the client(self) # returns nil if completely done @@ -101,7 +107,6 @@ module Yahns::HttpResponse # :nodoc: # but the backend does not terminate properly if alive && ! term && (env['HTTP_VERSION'] == 'HTTP/1.1'.freeze) res << "Transfer-Encoding: chunked\r\n".freeze - alive = true end res << (alive ? "Connection: keep-alive\r\n\r\n".freeze : "Connection: close\r\n\r\n".freeze) @@ -178,9 +183,9 @@ module Yahns::HttpResponse # :nodoc: end end - return proxy_busy_mod_done(alive) unless wbuf - req_res.resbuf = wbuf - proxy_busy_mod_blocked(wbuf, wbuf.busy) + # all done reading response from upstream, req_res will be discarded + # when we return nil: + wbuf ? proxy_busy_mod_blocked(wbuf, wbuf.busy) : proxy_busy_mod_done(alive) rescue => e proxy_err_response(502, req_res, e, wbuf) end @@ -248,7 +253,7 @@ module Yahns::HttpResponse # :nodoc: end busy = wbuf.busy and return proxy_busy_mod_blocked(wbuf, busy) - proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil + proxy_busy_mod_done(wbuf.wbuf_persist) # returns nil to close req_res end def proxy_wait_next(qflags) @@ -289,23 +294,23 @@ module Yahns::HttpResponse # :nodoc: when :close then close end - nil # close the req_res, too + nil # signal close for ReqRes#yahns_step end def proxy_busy_mod_blocked(wbuf, busy) - q = Thread.current[:yahns_queue] # we are completely done reading and buffering the upstream response, # but have not completely written the response to the client, # yield control to the client socket: @state = wbuf - case busy - when :wait_readable then q.queue_mod(self, Yahns::Queue::QEV_RD) - when :wait_writable then q.queue_mod(self, Yahns::Queue::QEV_WR) - else - abort "BUG: invalid wbuf.busy: #{busy.inspect}" - end - # no touching self after queue_mod - :ignore + proxy_wait_next(case busy + when :wait_readable then Yahns::Queue::QEV_RD + when :wait_writable then Yahns::Queue::QEV_WR + else + abort "BUG: invalid wbuf.busy: #{busy.inspect}" + end) + # no touching self after proxy_wait_next, we may be running + # HttpClient#yahns_step in a different thread at this point + nil # signal close for ReqRes#yahns_step end # n.b.: we can use String#size for optimized dispatch under YARV instead |