From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on dcvr.yhbt.net X-Spam-Level: X-Spam-ASN: X-Spam-Status: No, score=-2.9 required=3.0 tests=ALL_TRUSTED,AWL,BAYES_00 shortcircuit=no autolearn=unavailable version=3.3.2 X-Original-To: yahns-public@yhbt.net Received: from localhost (dcvr.yhbt.net [127.0.0.1]) by dcvr.yhbt.net (Postfix) with ESMTP id B6F0F1F5D6 for ; Sat, 4 Apr 2015 01:08:20 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 1/4] proxy_pass: test and fix larger uploads Date: Sat, 4 Apr 2015 01:08:13 +0000 Message-Id: <1428109696-14564-2-git-send-email-e@80x24.org> In-Reply-To: <1428109696-14564-1-git-send-email-e@80x24.org> References: <1428109696-14564-1-git-send-email-e@80x24.org> List-Id: We were incorrectly stashing the return value of detach_rbuf! into the inter-thread buffer buffer which is bound to the client. --- lib/yahns/proxy_pass.rb | 5 +++-- test/test_proxy_pass.rb | 22 +++++++++++++++++++++- 2 files changed, 24 insertions(+), 3 deletions(-) diff --git a/lib/yahns/proxy_pass.rb b/lib/yahns/proxy_pass.rb index 09fb884..ec1fbcf 100644 --- a/lib/yahns/proxy_pass.rb +++ b/lib/yahns/proxy_pass.rb @@ -108,7 +108,7 @@ def send_req_body(req) when Array vec = rv # partial write, retry in case loop when :wait_writable - buf = detach_rbuf! + detach_rbuf! req[0] = vec return :wait_writable when nil @@ -120,13 +120,14 @@ def send_req_body(req) # note: we do not send any trailer, they are folded into the header # because this relies on full request buffering send_req_buf("0\r\n\r\n".freeze) + # prepare_wait_readable already called by send_req_buf else # identity request, easy: while input.read(0x2000, buf) case rv = kgio_trywrite(buf) when String buf = rv # partial write, retry in case loop when :wait_writable - buf = detach_rbuf! + detach_rbuf! req[0] = buf return :wait_writable when nil diff --git a/test/test_proxy_pass.rb b/test/test_proxy_pass.rb index 5bf8722..53542ac 100644 --- a/test/test_proxy_pass.rb +++ b/test/test_proxy_pass.rb @@ -144,6 +144,7 @@ def test_proxy_pass cfg.instance_eval do app(:rack, Yahns::ProxyPass.new("http://#{host2}:#{port2}")) do listen "#{host}:#{port}" + client_max_body_size nil end stderr_path err.path end @@ -154,6 +155,7 @@ def test_proxy_pass cfg.instance_eval do app(:rack, ProxiedApp.new) do listen "#{host2}:#{port2}" + client_max_body_size nil end stderr_path err.path end @@ -195,7 +197,7 @@ def test_proxy_pass assert_equal 'text/PAIN', res['Content-Type'] assert_equal 'HIHIHI!', res.body - # normal content-length + # normal content-length (PUT) gplv3.rewind req = Net::HTTP::Put.new('/') req.body_stream = gplv3 @@ -210,6 +212,24 @@ def test_proxy_pass res = http.request(Net::HTTP::Get.new('/giant-body')) assert_equal 200, res.code.to_i assert_equal OMFG, res.body + + # giant PUT content-length + req = Net::HTTP::Put.new('/') + req.body_stream = StringIO.new(OMFG) + req.content_type = 'application/octet-stream' + req.content_length = OMFG.size + res = http.request(req) + assert_equal OMFG, res.body + assert_equal 201, res.code.to_i + + # giant PUT chunked encoding + req = Net::HTTP::Put.new('/') + req.body_stream = StringIO.new(OMFG) + req.content_type = 'application/octet-stream' + req['Transfer-Encoding'] = 'chunked' + res = http.request(req) + assert_equal OMFG, res.body + assert_equal 201, res.code.to_i end # ensure we do not chunk responses back to an HTTP/1.0 client even if -- EW