From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on dcvr.yhbt.net X-Spam-Flag: YES X-Spam-Level: *********** X-Spam-ASN: AS200651 185.100.84.0/23 X-Spam-Status: Yes, score=11.1 required=3.0 tests=AWL,BAYES_50, RCVD_IN_BL_SPAMCOP_NET,RCVD_IN_BRBL_LASTEXT,RCVD_IN_MSPIKE_BL, RCVD_IN_MSPIKE_L5,RCVD_IN_PSBL,RCVD_IN_RP_RNBL,RCVD_IN_SBL_CSS,RCVD_IN_XBL, RDNS_NONE,SPF_FAIL,SPF_HELO_FAIL shortcircuit=no autolearn=no autolearn_force=no version=3.4.0 X-Spam-Report: * 3.3 RCVD_IN_SBL_CSS RBL: Received via a relay in Spamhaus SBL-CSS * [185.100.84.108 listed in zen.spamhaus.org] * 0.4 RCVD_IN_XBL RBL: Received via a relay in Spamhaus XBL * 1.4 RCVD_IN_BRBL_LASTEXT RBL: No description available. * [185.100.84.108 listed in bb.barracudacentral.org] * 0.0 RCVD_IN_MSPIKE_L5 RBL: Very bad reputation (-5) * [185.100.84.108 listed in bl.mailspike.net] * 2.7 RCVD_IN_PSBL RBL: Received via a relay in PSBL * [185.100.84.108 listed in psbl.surriel.com] * 1.3 RCVD_IN_BL_SPAMCOP_NET RBL: Received via a relay in bl.spamcop.net * [Blocked - see ] * 1.3 RCVD_IN_RP_RNBL RBL: Relay in RNBL, * https://senderscore.org/blacklistlookup/ * [185.100.84.108 listed in bl.score.senderscore.com] * 0.0 SPF_HELO_FAIL SPF: HELO does not match SPF record (fail) * [SPF failed: Please see http://www.openspf.org/Why?s=helo;id=80x24.org;ip=185.100.84.108;r=dcvr.yhbt.net] * 0.0 SPF_FAIL SPF: sender does not match SPF record (fail) * [SPF failed: Please see http://www.openspf.org/Why?s=mfrom;id=e%4080x24.org;ip=185.100.84.108;r=dcvr.yhbt.net] * 0.8 BAYES_50 BODY: Bayes spam probability is 40 to 60% * [score: 0.4917] * 0.0 RCVD_IN_MSPIKE_BL Mailspike blacklisted * 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS * -1.0 AWL AWL: Adjusted score from AWL reputation of From: address Received: from 80x24.org (unknown [185.100.84.108]) by dcvr.yhbt.net (Postfix) with ESMTP id DE8311FA7C for ; Mon, 16 May 2016 01:44:02 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 7/7] proxy_pass: fix resumes after complete buffering is unblocked Date: Mon, 16 May 2016 01:43:40 +0000 Message-Id: <20160516014340.8258-8-e@80x24.org> In-Reply-To: <20160516014340.8258-1-e@80x24.org> References: <20160516014340.8258-1-e@80x24.org> List-Id: This fixes a bug where a cleared wbuf would kill the process after the response got flushed out to the client as `wbuf.busy' becomes `false'. This fixes a regression introduced in "proxy_pass: trim down proxy_response_finish, too" which was never in a stable release --- lib/yahns/proxy_http_response.rb | 51 ++++++++++++++++++++-------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb index 65fd03b..284a3c6 100644 --- a/lib/yahns/proxy_http_response.rb +++ b/lib/yahns/proxy_http_response.rb @@ -160,7 +160,7 @@ def proxy_read_body(tip, kcar, req_res, alive, wbuf) req_res.proxy_trailers = [ rbuf.dup, tip ] return proxy_read_trailers(kcar, req_res, alive, wbuf) end - wbuf ? proxy_busy_mod_blocked(wbuf, wbuf.busy) : proxy_busy_mod_done(alive) + proxy_busy_mod(wbuf, alive) end def proxy_read_trailers(kcar, req_res, alive, wbuf) @@ -178,7 +178,7 @@ def proxy_read_trailers(kcar, req_res, alive, wbuf) end # no loop here end wbuf = proxy_write(wbuf, trailer_out(tlr), alive) - wbuf ? proxy_busy_mod_blocked(wbuf, wbuf.busy) : proxy_busy_mod_done(alive) + proxy_busy_mod(wbuf, alive) end # start streaming the response once upstream is done sending headers to us. @@ -196,7 +196,7 @@ def proxy_response_start(res, tip, kcar, req_res) # 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) + proxy_busy_mod(wbuf, alive) rescue => e proxy_err_response(502, req_res, e, wbuf) end @@ -218,7 +218,7 @@ def proxy_wait_next(qflags) # | epoll_wait readiness # | ReqRes#yahns_step # | proxy dispatch ... - # | proxy_busy_mod_done + # | proxy_busy_mod # ************************** DANGER BELOW ******************************** # | HttpClient#yahns_step # | # clears env @@ -238,29 +238,28 @@ def proxy_wait_next(qflags) Thread.current[:yahns_queue].queue_mod(self, qflags) end - def proxy_busy_mod_done(alive) - case http_response_done(alive) - when :wait_readable then proxy_wait_next(Yahns::Queue::QEV_RD) - when :wait_writable then proxy_wait_next(Yahns::Queue::QEV_WR) - when :close then close + def proxy_busy_mod(wbuf, alive) + busy = wbuf.busy if wbuf + if busy + # 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 + proxy_wait_next(case busy + when :wait_readable then Yahns::Queue::QEV_RD + when :wait_writable then Yahns::Queue::QEV_WR + else + raise "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 + else + case http_response_done(alive) + when :wait_readable then proxy_wait_next(Yahns::Queue::QEV_RD) + when :wait_writable then proxy_wait_next(Yahns::Queue::QEV_WR) + when :close then close + end end - - nil # signal close for ReqRes#yahns_step - end - - def proxy_busy_mod_blocked(wbuf, busy) - # 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 - 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