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 D26FE1F8B6 for ; Sat, 4 Apr 2015 01:08:20 +0000 (UTC) From: Eric Wong To: yahns-public@yhbt.net Subject: [PATCH 2/4] proxy_pass: test for truncated response behavior Date: Sat, 4 Apr 2015 01:08:14 +0000 Message-Id: <1428109696-14564-3-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: Even if a response is screwed, we need to ensure breakage is predictable. --- test/test_proxy_pass.rb | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/test/test_proxy_pass.rb b/test/test_proxy_pass.rb index 53542ac..cebd004 100644 --- a/test/test_proxy_pass.rb +++ b/test/test_proxy_pass.rb @@ -7,6 +7,11 @@ class TestProxyPass < Testcase ENV["N"].to_i > 1 and parallelize_me! include ServerHelper OMFG = 'a' * (1024 * 1024 * 32) + TRUNCATE_BODY = "HTTP/1.1 200 OK\r\n" \ + "Content-Length: 7\r\n" \ + "Content-Type: text/PAIN\r\n\r\nshort".freeze + TRUNCATE_HEAD = "HTTP/1.1 200 OK\r\n" \ + "Content-Length: 666\r\n".freeze class ProxiedApp def call(env) @@ -30,6 +35,16 @@ def call(env) sleep delay end io.close + when '/truncate-body' + io = env['rack.hijack'].call + io.write(TRUNCATE_BODY) + io.close + when '/truncate-head' + io = env['rack.hijack'].call + io.write(TRUNCATE_HEAD) + io.close + when '/immediate-EOF' + env['rack.hijack'].call.close when %r{\A/chunky-slow-(\d+(?:\.\d+)?)\z} delay = $1.to_f chunky = Object.new @@ -248,6 +263,7 @@ def test_proxy_pass h10.close end end + check_truncated_upstream(host, port) ensure gplv3.close if gplv3 quit_wait pid @@ -298,4 +314,43 @@ def check_pipelining(host, port) ensure pl.close end + + def check_truncated_upstream(host, port) + # we want to make sure we show the truncated response without extra headers + s = TCPSocket.new(host, port) + check_err + res = Timeout.timeout(60) do + s.write "GET /truncate-body HTTP/1.1\r\nHost: example.com\r\n\r\n" + s.read + end + s.close + + exp = "HTTP/1.1 200 OK\r\n" \ + "Content-Length: 7\r\n" \ + "Content-Type: text/PAIN\r\n" \ + "Connection: keep-alive\r\n" \ + "\r\nshort" + assert_equal exp, res + errs = File.readlines(@err.path).grep(/\bERROR\b/) + assert_equal 1, errs.size + assert_match(/premature upstream EOF/, errs[0]) + @err.truncate(0) + + # truncated headers or no response at all... + # Send a 502 error + %w(immediate-EOF truncate-head).each do |path| + s = TCPSocket.new(host, port) + check_err + res = Timeout.timeout(60) do + s.write "GET /#{path} HTTP/1.1\r\nHost: example.com\r\n\r\n" + s.read(1024) + end + assert_match %r{\AHTTP/1.1 502\s+}, res + s.close + errs = File.readlines(@err.path).grep(/\bERROR\b/) + assert_equal 1, errs.size + assert_match(/premature upstream EOF/, errs[0]) + @err.truncate(0) + end + end end -- EW