class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) def test_500_01(self): url = TestEnv.mkurl("https", "cgi", "/proxy/hello.py") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/1.1" == r["response"]["json"]["protocol"] assert "" == r["response"]["json"]["https"] assert "" == r["response"]["json"]["ssl_protocol"] assert "" == r["response"]["json"]["h2"] assert "" == r["response"]["json"]["h2push"] # upload and GET again using curl, compare to original content def curl_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/proxy/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.curl_upload(url, fpath, options=options) assert r["rv"] == 0 assert 200 <= r["response"]["status"] < 300 # why is the scheme wrong? r2 = TestEnv.curl_get( re.sub(r'http:', 'https:', r["response"]["header"]["location"])) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] def test_500_10(self): self.curl_upload_and_verify("data-1k", ["--http2"]) self.curl_upload_and_verify("data-10k", ["--http2"]) self.curl_upload_and_verify("data-100k", ["--http2"]) self.curl_upload_and_verify("data-1m", ["--http2"]) # POST some data using nghttp and see it echo'ed properly back def nghttp_post_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/proxy/echo.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload(url, fpath, options=options) assert r["rv"] == 0 assert 200 <= r["response"]["status"] < 300 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() #assert len(src) == len(r["response"]["body"]) assert src == r["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_500_20(self): self.nghttp_post_and_verify("data-1k", []) self.nghttp_post_and_verify("data-10k", []) self.nghttp_post_and_verify("data-100k", []) self.nghttp_post_and_verify("data-1m", []) @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_500_21(self): self.nghttp_post_and_verify("data-1k", ["--no-content-length"]) self.nghttp_post_and_verify("data-10k", ["--no-content-length"]) self.nghttp_post_and_verify("data-100k", ["--no-content-length"]) self.nghttp_post_and_verify("data-1m", ["--no-content-length"]) # upload and GET again using nghttp, compare to original content def nghttp_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/proxy/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload_file(url, fpath, options=options) assert r["rv"] == 0 assert 200 <= r["response"]["status"] < 300 assert r["response"]["header"]["location"] # why is the scheme wrong? r2 = TestEnv.nghttp().get( re.sub(r'http:', 'https:', r["response"]["header"]["location"])) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_500_22(self): self.nghttp_upload_and_verify("data-1k", []) self.nghttp_upload_and_verify("data-10k", []) self.nghttp_upload_and_verify("data-100k", []) self.nghttp_upload_and_verify("data-1m", []) @pytest.mark.skipif( not TestEnv.has_nghttp() or True, reason="no nghttp command available and python3 chokes in chunks") def test_500_23(self): self.nghttp_upload_and_verify("data-1k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-10k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-100k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-1m", ["--no-content-length"]) # upload using nghttp and check returned status def nghttp_upload_stat(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/proxy/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload_file(url, fpath, options=options) assert r["rv"] == 0 assert 200 <= r["response"]["status"] < 300 assert r["response"]["header"]["location"] @pytest.mark.skipif( not TestEnv.has_nghttp() or True, reason="no nghttp command available and python3 chokes on chunks") def test_500_24(self): for i in range(100): self.nghttp_upload_stat("data-1k", ["--no-content-length"])
HttpdConf().add_vhost_cgi(h2proxy_self=True).install() assert TestEnv.apache_restart() == 0 def teardown_module(module): print("teardown_module: %s" % module.__name__) assert TestEnv.apache_stop() == 0 def setup_data(): s100="012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n" with open(os.path.join(TestEnv.GEN_DIR, "data-1k"), 'w') as f: for i in range(10): f.write(s100) # The trailer tests depend on "nghttp" as no other client seems to be able to send those # rare things. @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # check if the server survives a trailer or two def test_202_01(self): url = TestEnv.mkurl("https", "cgi", "/echo.py") fpath = os.path.join(TestEnv.GEN_DIR, "data-1k") r = TestEnv.nghttp().upload(url, fpath, options=[ "--trailer", "test: 1" ]) assert 300 > r["response"]["status"] assert 1000 == len(r["response"]["body"])
class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # upload and GET again using curl, compare to original content def curl_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.curl_upload(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 r2 = TestEnv.curl_get(r["response"]["header"]["location"]) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] def test_004_01(self): self.curl_upload_and_verify("data-1k", ["--http1.1"]) self.curl_upload_and_verify("data-1k", ["--http2"]) def test_004_02(self): self.curl_upload_and_verify("data-10k", ["--http1.1"]) self.curl_upload_and_verify("data-10k", ["--http2"]) def test_004_03(self): self.curl_upload_and_verify("data-100k", ["--http1.1"]) self.curl_upload_and_verify("data-100k", ["--http2"]) def test_004_04(self): self.curl_upload_and_verify("data-1m", ["--http1.1"]) self.curl_upload_and_verify("data-1m", ["--http2"]) def test_004_05(self): self.curl_upload_and_verify( "data-1k", ["-v", "--http1.1", "-H", "Expect: 100-continue"]) self.curl_upload_and_verify( "data-1k", ["-v", "--http2", "-H", "Expect: 100-continue"]) @pytest.mark.skipif(True, reason="python3 regresses in chunked inputs to cgi") def test_004_06(self): self.curl_upload_and_verify("data-1k", ["--http1.1", "-H", "Content-Length: "]) self.curl_upload_and_verify("data-1k", ["--http2", "-H", "Content-Length: "]) # verify that we parse nghttp output correctly def check_nghttp_body(self, ref_input, nghttp_output): with open(TestEnv.e2e_src(os.path.join(TestEnv.GEN_DIR, ref_input)), mode='rb') as f: refbody = f.read() with open(TestEnv.e2e_src(nghttp_output), mode='rb') as f: text = f.read() o = TestEnv.nghttp().parse_output(text) assert "response" in o assert "body" in o["response"] if refbody != o["response"]["body"]: with open(TestEnv.e2e_src( os.path.join(TestEnv.GEN_DIR, '%s.parsed' % ref_input)), mode='bw') as f: f.write(o["response"]["body"]) assert len(refbody) == len(o["response"]["body"]) assert refbody == o["response"]["body"] def test_004_20(self): self.check_nghttp_body('data-1k', 'data/nghttp-output-1k-1.txt') self.check_nghttp_body('data-10k', 'data/nghttp-output-10k-1.txt') self.check_nghttp_body('data-100k', 'data/nghttp-output-100k-1.txt') # POST some data using nghttp and see it echo'ed properly back def nghttp_post_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/echo.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_21(self): self.nghttp_post_and_verify("data-1k", []) self.nghttp_post_and_verify("data-10k", []) self.nghttp_post_and_verify("data-100k", []) self.nghttp_post_and_verify("data-1m", []) @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_22(self): self.nghttp_post_and_verify("data-1k", ["--no-content-length"]) self.nghttp_post_and_verify("data-10k", ["--no-content-length"]) self.nghttp_post_and_verify("data-100k", ["--no-content-length"]) self.nghttp_post_and_verify("data-1m", ["--no-content-length"]) # upload and GET again using nghttp, compare to original content def nghttp_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload_file(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 assert r["response"]["header"]["location"] r2 = TestEnv.nghttp().get(r["response"]["header"]["location"]) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_23(self): self.nghttp_upload_and_verify("data-1k", []) self.nghttp_upload_and_verify("data-10k", []) self.nghttp_upload_and_verify("data-100k", []) self.nghttp_upload_and_verify("data-1m", []) @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_24(self): self.nghttp_upload_and_verify("data-1k", ["--expect-continue"]) self.nghttp_upload_and_verify("data-100k", ["--expect-continue"]) @pytest.mark.skipif(True, reason="python3 regresses in chunked inputs to cgi") def test_004_25(self): self.nghttp_upload_and_verify("data-1k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-10k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-100k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-1m", ["--no-content-length"])
H2PushResource "/006/006.css" critical </Location> <Location /006-push32.html> Header add Link "</006/006.css>;rel=preload" </Location> """).end_vhost().install() assert TestEnv.apache_restart() == 0 def teardown_module(module): print("teardown_module: %s" % module.__name__) assert TestEnv.apache_stop() == 0 # The push tests depend on "nghttp" @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) ############################ # Link: header handling, various combinations # plain resource without configured pushes def test_400_00(self): url = TestEnv.mkurl("https", "push", "/006.html") r = TestEnv.nghttp().get(url)
class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # single page without any assets @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_006_01(self): url = TestEnv.mkurl("https", "test1", "/001.html") r = TestEnv.nghttp().assets(url) assert 0 == r["rv"] assert 1 == len(r["assets"]) assert r["assets"] == [ { "status": 200, "size": "251", "path" : "/001.html" } ] # single image without any assets @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_006_02(self): url = TestEnv.mkurl("https", "test1", "/002.jpg") r = TestEnv.nghttp().assets(url) assert 0 == r["rv"] assert 1 == len(r["assets"]) assert r["assets"] == [ { "status": 200, "size": "88K", "path" : "/002.jpg" } ] # gophertiles, yea! @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_006_03(self): url = TestEnv.mkurl("https", "test1", "/004.html") r = TestEnv.nghttp().assets(url) assert 0 == r["rv"] assert 181 == len(r["assets"]) assert r["assets"] == [ { "status": 200, "size": "10K", "path": "/004.html" }, { "status": 200, "size": "742", "path": "/004/gophertiles.jpg" }, { "status": 200, "size": "945", "path": "/004/gophertiles_002.jpg" }, { "status": 200, "size": "697", "path": "/004/gophertiles_003.jpg" }, { "status": 200, "size": "725", "path": "/004/gophertiles_004.jpg" }, { "status": 200, "size": "837", "path": "/004/gophertiles_005.jpg" }, { "status": 200, "size": "770", "path": "/004/gophertiles_006.jpg" }, { "status": 200, "size": "747", "path": "/004/gophertiles_007.jpg" }, { "status": 200, "size": "694", "path": "/004/gophertiles_008.jpg" }, { "status": 200, "size": "704", "path": "/004/gophertiles_009.jpg" }, { "status": 200, "size": "994", "path": "/004/gophertiles_010.jpg" }, { "status": 200, "size": "979", "path": "/004/gophertiles_011.jpg" }, { "status": 200, "size": "895", "path": "/004/gophertiles_012.jpg" }, { "status": 200, "size": "958", "path": "/004/gophertiles_013.jpg" }, { "status": 200, "size": "894", "path": "/004/gophertiles_014.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_015.jpg" }, { "status": 200, "size": "703", "path": "/004/gophertiles_016.jpg" }, { "status": 200, "size": "707", "path": "/004/gophertiles_017.jpg" }, { "status": 200, "size": "701", "path": "/004/gophertiles_018.jpg" }, { "status": 200, "size": "1013", "path": "/004/gophertiles_019.jpg" }, { "status": 200, "size": "737", "path": "/004/gophertiles_020.jpg" }, { "status": 200, "size": "801", "path": "/004/gophertiles_021.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_022.jpg" }, { "status": 200, "size": "905", "path": "/004/gophertiles_023.jpg" }, { "status": 200, "size": "980", "path": "/004/gophertiles_024.jpg" }, { "status": 200, "size": "708", "path": "/004/gophertiles_025.jpg" }, { "status": 200, "size": "694", "path": "/004/gophertiles_026.jpg" }, { "status": 200, "size": "697", "path": "/004/gophertiles_027.jpg" }, { "status": 200, "size": "795", "path": "/004/gophertiles_028.jpg" }, { "status": 200, "size": "978", "path": "/004/gophertiles_029.jpg" }, { "status": 200, "size": "707", "path": "/004/gophertiles_030.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_031.jpg" }, { "status": 200, "size": "688", "path": "/004/gophertiles_032.jpg" }, { "status": 200, "size": "701", "path": "/004/gophertiles_033.jpg" }, { "status": 200, "size": "898", "path": "/004/gophertiles_034.jpg" }, { "status": 200, "size": "986", "path": "/004/gophertiles_035.jpg" }, { "status": 200, "size": "770", "path": "/004/gophertiles_036.jpg" }, { "status": 200, "size": "959", "path": "/004/gophertiles_037.jpg" }, { "status": 200, "size": "936", "path": "/004/gophertiles_038.jpg" }, { "status": 200, "size": "700", "path": "/004/gophertiles_039.jpg" }, { "status": 200, "size": "784", "path": "/004/gophertiles_040.jpg" }, { "status": 200, "size": "758", "path": "/004/gophertiles_041.jpg" }, { "status": 200, "size": "796", "path": "/004/gophertiles_042.jpg" }, { "status": 200, "size": "813", "path": "/004/gophertiles_043.jpg" }, { "status": 200, "size": "924", "path": "/004/gophertiles_044.jpg" }, { "status": 200, "size": "978", "path": "/004/gophertiles_045.jpg" }, { "status": 200, "size": "752", "path": "/004/gophertiles_046.jpg" }, { "status": 200, "size": "751", "path": "/004/gophertiles_047.jpg" }, { "status": 200, "size": "737", "path": "/004/gophertiles_048.jpg" }, { "status": 200, "size": "992", "path": "/004/gophertiles_049.jpg" }, { "status": 200, "size": "688", "path": "/004/gophertiles_050.jpg" }, { "status": 200, "size": "697", "path": "/004/gophertiles_051.jpg" }, { "status": 200, "size": "699", "path": "/004/gophertiles_052.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_053.jpg" }, { "status": 200, "size": "694", "path": "/004/gophertiles_054.jpg" }, { "status": 200, "size": "767", "path": "/004/gophertiles_055.jpg" }, { "status": 200, "size": "952", "path": "/004/gophertiles_056.jpg" }, { "status": 200, "size": "788", "path": "/004/gophertiles_057.jpg" }, { "status": 200, "size": "759", "path": "/004/gophertiles_058.jpg" }, { "status": 200, "size": "700", "path": "/004/gophertiles_059.jpg" }, { "status": 200, "size": "985", "path": "/004/gophertiles_060.jpg" }, { "status": 200, "size": "915", "path": "/004/gophertiles_061.jpg" }, { "status": 200, "size": "681", "path": "/004/gophertiles_062.jpg" }, { "status": 200, "size": "707", "path": "/004/gophertiles_063.jpg" }, { "status": 200, "size": "693", "path": "/004/gophertiles_064.jpg" }, { "status": 200, "size": "861", "path": "/004/gophertiles_065.jpg" }, { "status": 200, "size": "991", "path": "/004/gophertiles_066.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_067.jpg" }, { "status": 200, "size": "697", "path": "/004/gophertiles_068.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_069.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_070.jpg" }, { "status": 200, "size": "784", "path": "/004/gophertiles_071.jpg" }, { "status": 200, "size": "698", "path": "/004/gophertiles_072.jpg" }, { "status": 200, "size": "1004", "path": "/004/gophertiles_073.jpg" }, { "status": 200, "size": "969", "path": "/004/gophertiles_074.jpg" }, { "status": 200, "size": "915", "path": "/004/gophertiles_075.jpg" }, { "status": 200, "size": "784", "path": "/004/gophertiles_076.jpg" }, { "status": 200, "size": "697", "path": "/004/gophertiles_077.jpg" }, { "status": 200, "size": "692", "path": "/004/gophertiles_078.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_079.jpg" }, { "status": 200, "size": "725", "path": "/004/gophertiles_080.jpg" }, { "status": 200, "size": "877", "path": "/004/gophertiles_081.jpg" }, { "status": 200, "size": "743", "path": "/004/gophertiles_082.jpg" }, { "status": 200, "size": "785", "path": "/004/gophertiles_083.jpg" }, { "status": 200, "size": "690", "path": "/004/gophertiles_084.jpg" }, { "status": 200, "size": "724", "path": "/004/gophertiles_085.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_086.jpg" }, { "status": 200, "size": "883", "path": "/004/gophertiles_087.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_088.jpg" }, { "status": 200, "size": "693", "path": "/004/gophertiles_089.jpg" }, { "status": 200, "size": "947", "path": "/004/gophertiles_090.jpg" }, { "status": 200, "size": "959", "path": "/004/gophertiles_091.jpg" }, { "status": 200, "size": "736", "path": "/004/gophertiles_092.jpg" }, { "status": 200, "size": "806", "path": "/004/gophertiles_093.jpg" }, { "status": 200, "size": "820", "path": "/004/gophertiles_094.jpg" }, { "status": 200, "size": "918", "path": "/004/gophertiles_095.jpg" }, { "status": 200, "size": "689", "path": "/004/gophertiles_096.jpg" }, { "status": 200, "size": "796", "path": "/004/gophertiles_097.jpg" }, { "status": 200, "size": "686", "path": "/004/gophertiles_098.jpg" }, { "status": 200, "size": "698", "path": "/004/gophertiles_099.jpg" }, { "status": 200, "size": "686", "path": "/004/gophertiles_100.jpg" }, { "status": 200, "size": "686", "path": "/004/gophertiles_101.jpg" }, { "status": 200, "size": "682", "path": "/004/gophertiles_102.jpg" }, { "status": 200, "size": "703", "path": "/004/gophertiles_103.jpg" }, { "status": 200, "size": "698", "path": "/004/gophertiles_104.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_105.jpg" }, { "status": 200, "size": "989", "path": "/004/gophertiles_106.jpg" }, { "status": 200, "size": "720", "path": "/004/gophertiles_107.jpg" }, { "status": 200, "size": "834", "path": "/004/gophertiles_108.jpg" }, { "status": 200, "size": "756", "path": "/004/gophertiles_109.jpg" }, { "status": 200, "size": "703", "path": "/004/gophertiles_110.jpg" }, { "status": 200, "size": "815", "path": "/004/gophertiles_111.jpg" }, { "status": 200, "size": "780", "path": "/004/gophertiles_112.jpg" }, { "status": 200, "size": "992", "path": "/004/gophertiles_113.jpg" }, { "status": 200, "size": "862", "path": "/004/gophertiles_114.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_115.jpg" }, { "status": 200, "size": "756", "path": "/004/gophertiles_116.jpg" }, { "status": 200, "size": "1012", "path": "/004/gophertiles_117.jpg" }, { "status": 200, "size": "905", "path": "/004/gophertiles_118.jpg" }, { "status": 200, "size": "808", "path": "/004/gophertiles_119.jpg" }, { "status": 200, "size": "814", "path": "/004/gophertiles_120.jpg" }, { "status": 200, "size": "832", "path": "/004/gophertiles_121.jpg" }, { "status": 200, "size": "704", "path": "/004/gophertiles_122.jpg" }, { "status": 200, "size": "741", "path": "/004/gophertiles_123.jpg" }, { "status": 200, "size": "694", "path": "/004/gophertiles_124.jpg" }, { "status": 200, "size": "950", "path": "/004/gophertiles_125.jpg" }, { "status": 200, "size": "770", "path": "/004/gophertiles_126.jpg" }, { "status": 200, "size": "749", "path": "/004/gophertiles_127.jpg" }, { "status": 200, "size": "942", "path": "/004/gophertiles_128.jpg" }, { "status": 200, "size": "997", "path": "/004/gophertiles_129.jpg" }, { "status": 200, "size": "708", "path": "/004/gophertiles_130.jpg" }, { "status": 200, "size": "821", "path": "/004/gophertiles_131.jpg" }, { "status": 200, "size": "849", "path": "/004/gophertiles_132.jpg" }, { "status": 200, "size": "715", "path": "/004/gophertiles_133.jpg" }, { "status": 200, "size": "794", "path": "/004/gophertiles_134.jpg" }, { "status": 200, "size": "869", "path": "/004/gophertiles_135.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_136.jpg" }, { "status": 200, "size": "757", "path": "/004/gophertiles_137.jpg" }, { "status": 200, "size": "991", "path": "/004/gophertiles_138.jpg" }, { "status": 200, "size": "704", "path": "/004/gophertiles_139.jpg" }, { "status": 200, "size": "707", "path": "/004/gophertiles_140.jpg" }, { "status": 200, "size": "959", "path": "/004/gophertiles_141.jpg" }, { "status": 200, "size": "691", "path": "/004/gophertiles_142.jpg" }, { "status": 200, "size": "921", "path": "/004/gophertiles_143.jpg" }, { "status": 200, "size": "932", "path": "/004/gophertiles_144.jpg" }, { "status": 200, "size": "696", "path": "/004/gophertiles_145.jpg" }, { "status": 200, "size": "711", "path": "/004/gophertiles_146.jpg" }, { "status": 200, "size": "817", "path": "/004/gophertiles_147.jpg" }, { "status": 200, "size": "966", "path": "/004/gophertiles_148.jpg" }, { "status": 200, "size": "1002", "path": "/004/gophertiles_149.jpg" }, { "status": 200, "size": "900", "path": "/004/gophertiles_150.jpg" }, { "status": 200, "size": "724", "path": "/004/gophertiles_151.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_152.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_153.jpg" }, { "status": 200, "size": "971", "path": "/004/gophertiles_154.jpg" }, { "status": 200, "size": "708", "path": "/004/gophertiles_155.jpg" }, { "status": 200, "size": "699", "path": "/004/gophertiles_156.jpg" }, { "status": 200, "size": "834", "path": "/004/gophertiles_157.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_158.jpg" }, { "status": 200, "size": "880", "path": "/004/gophertiles_159.jpg" }, { "status": 200, "size": "701", "path": "/004/gophertiles_160.jpg" }, { "status": 200, "size": "688", "path": "/004/gophertiles_161.jpg" }, { "status": 200, "size": "853", "path": "/004/gophertiles_162.jpg" }, { "status": 200, "size": "690", "path": "/004/gophertiles_163.jpg" }, { "status": 200, "size": "759", "path": "/004/gophertiles_164.jpg" }, { "status": 200, "size": "831", "path": "/004/gophertiles_165.jpg" }, { "status": 200, "size": "732", "path": "/004/gophertiles_166.jpg" }, { "status": 200, "size": "955", "path": "/004/gophertiles_167.jpg" }, { "status": 200, "size": "1K", "path": "/004/gophertiles_168.jpg" }, { "status": 200, "size": "969", "path": "/004/gophertiles_169.jpg" }, { "status": 200, "size": "701", "path": "/004/gophertiles_170.jpg" }, { "status": 200, "size": "755", "path": "/004/gophertiles_171.jpg" }, { "status": 200, "size": "924", "path": "/004/gophertiles_172.jpg" }, { "status": 200, "size": "958", "path": "/004/gophertiles_173.jpg" }, { "status": 200, "size": "998", "path": "/004/gophertiles_174.jpg" }, { "status": 200, "size": "702", "path": "/004/gophertiles_175.jpg" }, { "status": 200, "size": "760", "path": "/004/gophertiles_176.jpg" }, { "status": 200, "size": "732", "path": "/004/gophertiles_177.jpg" }, { "status": 200, "size": "929", "path": "/004/gophertiles_178.jpg" }, { "status": 200, "size": "712", "path": "/004/gophertiles_179.jpg" }, { "status": 200, "size": "1013", "path": "/004/gophertiles_180.jpg" } ] # page with js and css @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_006_04(self): url = TestEnv.mkurl("https", "test1", "/006.html") r = TestEnv.nghttp().assets(url) assert 0 == r["rv"] assert 3 == len(r["assets"]) assert r["assets"] == [ { "status": 200, "size": "543", "path": "/006.html" }, { "status": 200, "size": "216", "path": "/006/006.css" }, { "status": 200, "size": "839", "path": "/006/006.js" } ] # page with image, try different window size @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_006_05(self): url = TestEnv.mkurl("https", "test1", "/003.html") r = TestEnv.nghttp().assets(url, options=[ "--window-bits=24" ]) assert 0 == r["rv"] assert 2 == len(r["assets"]) assert r["assets"] == [ { "status": 200, "size": "316", "path": "/003.html" }, { "status": 200, "size": "88K", "path": "/003/003_img.jpg" } ]
<Location /006-hints.html> H2PushResource "/006/006.css" critical </Location> <Location /006-nohints.html> Header add Link "</006/006.css>;rel=preload" </Location> """).end_vhost( ).install() assert TestEnv.apache_restart() == 0 def teardown_module(module): print("teardown_module: %s" % module.__name__) assert TestEnv.apache_stop() == 0 # The push tests depend on "nghttp" @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # H2EarlyHints enabled in general, check that it works for H2PushResource def test_400_31(self): url = TestEnv.mkurl("https", "hints", "/006-hints.html") r = TestEnv.nghttp().get(url) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 1 == len(promises)
class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # check SSL environment variables from CGI script def test_003_01(self): url = TestEnv.mkurl("https", "cgi", "/hello.py") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2.0" == r["response"]["json"]["protocol"] assert "on" == r["response"]["json"]["https"] assert "TLSv1.2" == r["response"]["json"]["ssl_protocol"] assert "on" == r["response"]["json"]["h2"] assert "off" == r["response"]["json"]["h2push"] r = TestEnv.curl_get(url, 5, [ "--http1.1" ]) assert 200 == r["response"]["status"] assert "HTTP/1.1" == r["response"]["json"]["protocol"] assert "on" == r["response"]["json"]["https"] assert "TLSv1.2" == r["response"]["json"]["ssl_protocol"] assert "" == r["response"]["json"]["h2"] assert "" == r["response"]["json"]["h2push"] # retrieve a html file from the server and compare it to its source def test_003_02(self): with open(TestEnv.e2e_src( "htdocs/test1/index.html"), mode='rb') as file: src = file.read() url = TestEnv.mkurl("https", "test1", "/index.html") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert src == r["response"]["body"] url = TestEnv.mkurl("https", "test1", "/index.html") r = TestEnv.curl_get(url, 5, [ "--http1.1" ]) assert 200 == r["response"]["status"] assert "HTTP/1.1" == r["response"]["protocol"] assert src == r["response"]["body"] # retrieve chunked content from a cgi script def check_necho(self, n, text): url = TestEnv.mkurl("https", "cgi", "/necho.py") r = TestEnv.curl_get(url, 5, [ "-F", ("count=%d" % (n)), "-F", ("text=%s" % (text)) ]) assert 200 == r["response"]["status"] exp = "" for i in range(n): exp += text + "\n" assert exp == r["response"]["body"] def test_003_10(self): self.check_necho(10, "0123456789") def test_003_11(self): self.check_necho(100, "0123456789") def test_003_12(self): self.check_necho(1000, "0123456789") def test_003_13(self): self.check_necho(10000, "0123456789") def test_003_14(self): self.check_necho(100000, "0123456789") # github issue #126 def test_003_20(self): url = TestEnv.mkurl("https", "test1", "/006/") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert '''<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <html> <head> <title>Index of /006</title> </head> <body> <title>My Header Title</title> <ul><li><a href="/"> Parent Directory</a></li> <li><a href="006.css"> 006.css</a></li> <li><a href="006.js"> 006.js</a></li> <li><a href="header.html"> header.html</a></li> </ul> </body></html> ''' == r["response"]["body"] # github issue #133 def clean_header(self, s): s = re.sub(r'\r\n', '\n', s, flags=re.MULTILINE) s = re.sub(r'^date:.*\n', '', s, flags=re.MULTILINE) s = re.sub(r'^server:.*\n', '', s, flags=re.MULTILINE) s = re.sub(r'^last-modified:.*\n', '', s, flags=re.MULTILINE) s = re.sub(r'^etag:.*\n', '', s, flags=re.MULTILINE) s = re.sub(r'^vary:.*\n', '', s, flags=re.MULTILINE) return re.sub(r'^accept-ranges:.*\n', '', s, flags=re.MULTILINE) def test_003_21(self): url = TestEnv.mkurl("https", "test1", "/index.html") r = TestEnv.curl_get(url, 5, [ "-I" ]) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] s = self.clean_header(r["response"]["body"]) assert '''HTTP/2 200 content-length: 2007 content-type: text/html ''' == s r = TestEnv.curl_get(url, 5, [ "-I", url ]) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] s = self.clean_header(r["response"]["body"]) assert '''HTTP/2 200 content-length: 2007 content-type: text/html HTTP/2 200 content-length: 2007 content-type: text/html ''' == s # test conditionals: if-modified-since @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) def test_003_30(self, path): url = TestEnv.mkurl("https", "test1", path) r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] h = r["response"]["header"] assert "last-modified" in h lastmod = h["last-modified"] r = TestEnv.curl_get(url, 5, [ '-H', ("if-modified-since: %s" % lastmod) ]) assert 304 == r["response"]["status"] # test conditionals: if-etag @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) def test_003_31(self, path): url = TestEnv.mkurl("https", "test1", path) r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] h = r["response"]["header"] assert "etag" in h etag = h["etag"] r = TestEnv.curl_get(url, 5, [ '-H', ("if-none-match: %s" % etag) ]) assert 304 == r["response"]["status"] # test various response body lengths to work correctly def test_003_40(self): n = 1001 while n <= 1025024: url = TestEnv.mkurl("https", "cgi", "/mnot164.py?count=%d&text=X" % (n)) r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert n == len(r["response"]["body"]) n *= 2 # test various response body lengths to work correctly @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") @pytest.mark.parametrize("n", [ 0, 1, 1291, 1292, 80000, 80123, 81087, 98452 ]) def test_003_41(self, n): url = TestEnv.mkurl("https", "cgi", "/mnot164.py?count=%d&text=X" % (n)) r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert n == len(r["response"]["body"]) # test ranges @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) def test_003_50(self, path): # check that the resource supports ranges and we see its raw content-length url = TestEnv.mkurl("https", "test1", path) r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] h = r["response"]["header"] assert "accept-ranges" in h assert "bytes" == h["accept-ranges"] assert "content-length" in h clen = h["content-length"] # get the first 1024 bytes of the resource, 206 status, but content-length as original r = TestEnv.curl_get(url, 5, options=[ "-H", "range: bytes=0-1023"]) assert 206 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert 1024 == len(r["response"]["body"]) assert "content-length" in h assert clen == h["content-length"]
class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # accessing http://test1, will not try h2 and advertise h2 in the response def test_103_01(self): url = TestEnv.mkurl("http", "test1", "/index.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert "upgrade" in r["response"]["header"] assert "h2c" == r["response"]["header"]["upgrade"] # accessing http://noh2, will not advertise, because noh2 host does not have it enabled def test_103_02(self): url = TestEnv.mkurl("http", "noh2", "/index.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert not "upgrade" in r["response"]["header"] # accessing http://test2, will not advertise, because h2 has less preference than http/1.1 def test_103_03(self): url = TestEnv.mkurl("http", "test2", "/index.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert not "upgrade" in r["response"]["header"] # accessing https://noh2, will not advertise, because noh2 host does not have it enabled def test_103_04(self): url = TestEnv.mkurl("https", "noh2", "/index.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert not "upgrade" in r["response"]["header"] # accessing https://test2, will not advertise, because h2 has less preference than http/1.1 def test_103_05(self): url = TestEnv.mkurl("https", "test2", "/index.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert not "upgrade" in r["response"]["header"] # accessing https://test1, will advertise h2 in the response def test_103_06(self): url = TestEnv.mkurl("https", "test1", "/index.html") r = TestEnv.curl_get(url, options=[ "--http1.1" ]) assert 0 == r["rv"] assert "response" in r assert "upgrade" in r["response"]["header"] assert "h2" == r["response"]["header"]["upgrade"] # accessing https://test3, will not send Upgrade since it is suppressed def test_103_07(self): url = TestEnv.mkurl("https", "test3", "/index.html") r = TestEnv.curl_get(url, options=[ "--http1.1" ]) assert 0 == r["rv"] assert "response" in r assert not "upgrade" in r["response"]["header"] # upgrade to h2c for a request, where h2c is preferred @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_103_20(self): url = TestEnv.mkurl("http", "test1", "/index.html") r = TestEnv.nghttp().get(url, options=[ "-u" ]) assert 200 == r["response"]["status"] # upgrade to h2c for a request where http/1.1 is preferred, but the clients upgrade # wish is honored nevertheless @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_103_21(self): url = TestEnv.mkurl("http", "test2", "/index.html") r = TestEnv.nghttp().get(url, options=[ "-u" ]) assert 404 == r["response"]["status"] # ugrade to h2c on a host where h2c is not enabled will fail @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_103_22(self): url = TestEnv.mkurl("http", "noh2", "/index.html") r = TestEnv.nghttp().get(url, options=[ "-u" ]) assert not "response" in r # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_103_23(self): url = TestEnv.mkurl("http", "test1b", "/index.html") r = TestEnv.nghttp().get(url, options=[ "-u" ]) assert not "response" in r # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled on the server, # but allowed for a specific location @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_103_23(self): url = TestEnv.mkurl("http", "test1b", "/006.html") r = TestEnv.nghttp().get(url, options=[ "-u" ]) assert 200 == r["response"]["status"]
class TestStore: def setup_method(self, method): print("setup_method: %s" % method.__name__) def teardown_method(self, method): print("teardown_method: %s" % method.__name__) # upload and GET again using curl, compare to original content def curl_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.curl_upload(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 r2 = TestEnv.curl_get(r["response"]["header"]["location"]) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] def test_004_01(self): self.curl_upload_and_verify("data-1k", ["--http1.1"]) self.curl_upload_and_verify("data-1k", ["--http2"]) def test_004_02(self): self.curl_upload_and_verify("data-10k", ["--http1.1"]) self.curl_upload_and_verify("data-10k", ["--http2"]) def test_004_03(self): self.curl_upload_and_verify("data-100k", ["--http1.1"]) self.curl_upload_and_verify("data-100k", ["--http2"]) def test_004_04(self): self.curl_upload_and_verify("data-1m", ["--http1.1"]) self.curl_upload_and_verify("data-1m", ["--http2"]) def test_004_05(self): self.curl_upload_and_verify( "data-1k", ["-v", "--http1.1", "-H", "Expect: 100-continue"]) self.curl_upload_and_verify( "data-1k", ["-v", "--http2", "-H", "Expect: 100-continue"]) @pytest.mark.skipif(True, reason="python3 regresses in chunked inputs to cgi") def test_004_06(self): self.curl_upload_and_verify("data-1k", ["--http1.1", "-H", "Content-Length: "]) self.curl_upload_and_verify("data-1k", ["--http2", "-H", "Content-Length: "]) @pytest.mark.parametrize("name, value", [ ("HTTP2", "on"), ("H2PUSH", "off"), ("H2_PUSHED", ""), ("H2_PUSHED_ON", ""), ("H2_STREAM_ID", "1"), ("H2_STREAM_TAG", r'\d+-1'), ]) def test_004_07(self, name, value): url = TestEnv.mkurl("https", "cgi", "/env.py") r = TestEnv.curl_post_value(url, "name", name) assert r["rv"] == 0 assert r["response"]["status"] == 200 m = re.match("{0}=(.*)".format(name), r["response"]["body"].decode('utf-8')) assert m assert re.match(value, m.group(1)) # verify that we parse nghttp output correctly def check_nghttp_body(self, ref_input, nghttp_output): with open(TestEnv.e2e_src(os.path.join(TestEnv.GEN_DIR, ref_input)), mode='rb') as f: refbody = f.read() with open(TestEnv.e2e_src(nghttp_output), mode='rb') as f: text = f.read() o = TestEnv.nghttp().parse_output(text) assert "response" in o assert "body" in o["response"] if refbody != o["response"]["body"]: with open(TestEnv.e2e_src( os.path.join(TestEnv.GEN_DIR, '%s.parsed' % ref_input)), mode='bw') as f: f.write(o["response"]["body"]) assert len(refbody) == len(o["response"]["body"]) assert refbody == o["response"]["body"] def test_004_20(self): self.check_nghttp_body('data-1k', 'data/nghttp-output-1k-1.txt') self.check_nghttp_body('data-10k', 'data/nghttp-output-10k-1.txt') self.check_nghttp_body('data-100k', 'data/nghttp-output-100k-1.txt') # POST some data using nghttp and see it echo'ed properly back def nghttp_post_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/echo.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_21(self): self.nghttp_post_and_verify("data-1k", []) self.nghttp_post_and_verify("data-10k", []) self.nghttp_post_and_verify("data-100k", []) self.nghttp_post_and_verify("data-1m", []) @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_22(self): self.nghttp_post_and_verify("data-1k", ["--no-content-length"]) self.nghttp_post_and_verify("data-10k", ["--no-content-length"]) self.nghttp_post_and_verify("data-100k", ["--no-content-length"]) self.nghttp_post_and_verify("data-1m", ["--no-content-length"]) # upload and GET again using nghttp, compare to original content def nghttp_upload_and_verify(self, fname, options=None): url = TestEnv.mkurl("https", "cgi", "/upload.py") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.nghttp().upload_file(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"]["status"] < 300 assert r["response"]["header"]["location"] r2 = TestEnv.nghttp().get(r["response"]["header"]["location"]) assert r2["rv"] == 0 assert r2["response"]["status"] == 200 with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == r2["response"]["body"] @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_23(self): self.nghttp_upload_and_verify("data-1k", []) self.nghttp_upload_and_verify("data-10k", []) self.nghttp_upload_and_verify("data-100k", []) self.nghttp_upload_and_verify("data-1m", []) @pytest.mark.skipif(not TestEnv.has_nghttp(), reason="no nghttp command available") def test_004_24(self): self.nghttp_upload_and_verify("data-1k", ["--expect-continue"]) self.nghttp_upload_and_verify("data-100k", ["--expect-continue"]) @pytest.mark.skipif(True, reason="python3 regresses in chunked inputs to cgi") def test_004_25(self): self.nghttp_upload_and_verify("data-1k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-10k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-100k", ["--no-content-length"]) self.nghttp_upload_and_verify("data-1m", ["--no-content-length"]) def test_004_30(self): # issue: #203 resource = "data-1k" full_length = 1000 chunk = 200 self.curl_upload_and_verify(resource, ["-v", "--http2"]) logfile = os.path.join(TestEnv.HTTPD_LOGS_DIR, "test_004_30") if os.path.isfile(logfile): os.remove(logfile) HttpdConf().add_line(""" LogFormat "{ \\"request\\": \\"%r\\", \\"status\\": %>s, \\"bytes_resp_B\\": %B, \\"bytes_tx_O\\": %O, \\"bytes_rx_I\\": %I, \\"bytes_rx_tx_S\\": %S }" issue_203 CustomLog logs/test_004_30 issue_203 """).add_vhost_cgi().install() assert TestEnv.apache_restart() == 0 url = TestEnv.mkurl("https", "cgi", "/files/{0}".format(resource)) r = TestEnv.curl_get(url, 5, ["--http2"]) assert 200 == r["response"]["status"] r = TestEnv.curl_get( url, 5, ["--http1.1", "-H", "Range: bytes=0-{0}".format(chunk - 1)]) assert 206 == r["response"]["status"] assert chunk == len(r["response"]["body"].decode('utf-8')) r = TestEnv.curl_get( url, 5, ["--http2", "-H", "Range: bytes=0-{0}".format(chunk - 1)]) assert 206 == r["response"]["status"] assert chunk == len(r["response"]["body"].decode('utf-8')) # now check what response lengths have actually been reported lines = open(logfile).readlines() log_h2_full = json.loads(lines[-3]) log_h1 = json.loads(lines[-2]) log_h2 = json.loads(lines[-1]) assert log_h2_full['bytes_rx_I'] > 0 assert log_h2_full['bytes_resp_B'] == full_length assert log_h2_full['bytes_tx_O'] > full_length assert log_h1['bytes_rx_I'] > 0 # input bytes recieved assert log_h1['bytes_resp_B'] == chunk # response bytes sent (payload) assert log_h1['bytes_tx_O'] > chunk # output bytes sent assert log_h2['bytes_rx_I'] > 0 assert log_h2['bytes_resp_B'] == chunk assert log_h2['bytes_tx_O'] > chunk def test_004_40(self): # echo content using h2test_module "echo" handler def post_and_verify(fname, options=None): url = TestEnv.mkurl("https", "cgi", "/h2test/echo") fpath = os.path.join(TestEnv.GEN_DIR, fname) r = TestEnv.curl_upload(url, fpath, options=options) assert r["rv"] == 0 assert r["response"]["status"] >= 200 and r["response"][ "status"] < 300 ct = r["response"]["header"]["content-type"] mail_hd = "Content-Type: " + ct + "\r\nMIME-Version: 1.0\r\n\r\n" mime_msg = mail_hd.encode() + r["response"]["body"] # this MIME API is from hell body = email.parser.BytesParser().parsebytes(mime_msg) assert body assert body.is_multipart() filepart = None for part in body.walk(): if fname == part.get_filename(): filepart = part assert filepart with open(TestEnv.e2e_src(fpath), mode='rb') as file: src = file.read() assert src == filepart.get_payload(decode=True) post_and_verify("data-1k", [])