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=10.1 required=3.0 tests=AWL,BAYES_00, 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] * -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% * [score: 0.0000] * 0.0 RCVD_IN_MSPIKE_BL Mailspike blacklisted * 0.8 RDNS_NONE Delivered to internal network by a host with no rDNS * 0.6 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 72D541FA7B for ; Mon, 16 May 2016 01:43:53 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 3/7] proxy_pass: simplify proxy_http_response Date: Mon, 16 May 2016 01:43:36 +0000 Message-Id: <20160516014340.8258-4-e@80x24.org> In-Reply-To: <20160516014340.8258-1-e@80x24.org> References: <20160516014340.8258-1-e@80x24.org> List-Id: Again, the cost of having extra branches within a loop is probably neglible compared to having bigger bytecode resulting in worse CPU cache performance and increased maintenance overhead for extra code. --- lib/yahns/proxy_http_response.rb | 76 ++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 42 deletions(-) diff --git a/lib/yahns/proxy_http_response.rb b/lib/yahns/proxy_http_response.rb index 693528f..00915df 100644 --- a/lib/yahns/proxy_http_response.rb +++ b/lib/yahns/proxy_http_response.rb @@ -134,38 +134,45 @@ def proxy_response_start(res, tip, kcar, req_res) tip = tip.empty? ? [] : [ tip ] if have_body - if len = kcar.body_bytes_left + req_res.proxy_trailers = nil # define to avoid uninitialized warnings + chunk = ''.dup if kcar.chunked? + tlr = nil + len = kcar.body_bytes_left - case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf) - when String - len = kcar.body_bytes_left -= tmp.size - wbuf = proxy_write(wbuf, tmp, alive) - when nil # premature EOF - return proxy_err_response(nil, req_res, nil, wbuf) - when :wait_readable - return wait_on_upstream(req_res, alive, wbuf) - end until len == 0 - - elsif kcar.chunked? # nasty chunked body - req_res.proxy_trailers = nil # define to avoid warnings for now - buf = ''.dup - case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf) - when String - kcar.filter_body(buf, tmp) - wbuf = proxy_write(wbuf, chunk_out(buf), alive) unless buf.empty? - when nil # premature EOF - return proxy_err_response(nil, req_res, nil, wbuf) - when :wait_readable - return wait_on_upstream(req_res, alive, wbuf) - end until kcar.body_eof? + case tmp = tip.shift || req_res.kgio_tryread(0x2000, rbuf) + when String + if len + kcar.body_bytes_left -= tmp.size # progress for body_eof? => true + elsif chunk + kcar.filter_body(chunk, rbuf = tmp) # progress for body_eof? => true + next if chunk.empty? # read req_res.kgio_tryread for more + tmp = chunk_out(chunk) + elsif alive # HTTP/1.0 upstream, HTTP/1.1 client + tmp = chunk_out(tmp) + # else # HTTP/1.0 upstream, HTTP/1.0 client, do nothing + end + wbuf = proxy_write(wbuf, tmp, alive) + chunk.clear if chunk + when nil # EOF + # HTTP/1.1 upstream, unexpected premature EOF: + return proxy_err_response(nil, req_res, nil, wbuf) if len || chunk + + # HTTP/1.0 upstream: + wbuf = proxy_write(wbuf, "0\r\n\r\n".freeze, true) if alive + req_res.shutdown + break + when :wait_readable + return wait_on_upstream(req_res, alive, wbuf) + end until kcar.body_eof? - buf = tmp - req_res.proxy_trailers = [ buf, tlr = [] ] + if chunk + chunk = rbuf + req_res.proxy_trailers = [ chunk, tlr = [] ] rbuf = Thread.current[:yahns_rbuf] = ''.dup - until kcar.trailers(tlr, buf) + until kcar.trailers(tlr, chunk) case rv = req_res.kgio_tryread(0x2000, rbuf) when String - buf << rv + chunk << rv when :wait_readable return wait_on_upstream(req_res, alive, wbuf) when nil # premature EOF @@ -173,21 +180,6 @@ def proxy_response_start(res, tip, kcar, req_res) 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 - tmp = chunk_out(tmp) if alive - wbuf = proxy_write(wbuf, tmp, alive) - when nil - wbuf = proxy_write(wbuf, "0\r\n\r\n".freeze, true) if alive - req_res.shutdown - break - when :wait_readable - return wait_on_upstream(req_res, alive, wbuf) - end while true - end end