def test_400_07(self): url = TestEnv.mkurl("https", "push", "/006-push7.html") r = TestEnv.nghttp().get(url) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 1 == len(promises) assert '/006/006.css' == promises[0]["request"]["header"][":path"]
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"]
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"]
def test_100_03(self): url = TestEnv.mkurl("https", "cgi", "/") hostname = ("test1.%s" % TestEnv.HTTP_TLD) r = TestEnv.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert "text/html" == r["response"]["header"]["content-type"]
def test_100_02(self): url = TestEnv.mkurl("https", "cgi", "/hello.py") hostname = ("cgi-alias.%s" % TestEnv.HTTP_TLD) r = TestEnv.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) assert 200 == r["response"]["status"] assert "HTTP/2" == r["response"]["protocol"] assert hostname == r["response"]["json"]["host"]
def test_002_01(self): url = TestEnv.mkurl("http", "test1", "/alive.json") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert "HTTP/1.1" == r["response"]["protocol"] assert True == r["response"]["json"]["alive"] assert "test1" == r["response"]["json"]["host"]
def test_002_02(self): url = TestEnv.mkurl("https", "test1", "/alive.json") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] assert True == r["response"]["json"]["alive"] assert "test1" == r["response"]["json"]["host"] assert "application/json" == r["response"]["header"]["content-type"]
def test_400_32(self): url = TestEnv.mkurl("https", "hints", "/006-nohints.html") r = TestEnv.nghttp().get(url) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 1 == len(promises) assert not "previous" in r["response"]
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
def test_200_03(self): url = TestEnv.mkurl("https", "cgi", "/hecho.py") for hex in [ "10", "7f" ]: r = TestEnv.curl_post_data(url, "name=x%%%s&value=yz" % hex) assert 0 != r["rv"] r = TestEnv.curl_post_data(url, "name=x&value=y%%%sz" % hex) assert 0 != r["rv"]
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 r["response"]["status"] >= 200 and r["response"]["status"] < 300 assert r["response"]["header"]["location"]
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_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" } ]
def test_005_01(self): url = TestEnv.mkurl("https", "cgi", "/.well-known/h2/state") r = TestEnv.curl_get(url, 5) assert 200 == r["response"]["status"] st = r["response"]["json"] # remove some parts that are very dependant on client/lib versions # or connection time etc. del st["settings"]["SETTINGS_INITIAL_WINDOW_SIZE"] del st["peerSettings"]["SETTINGS_INITIAL_WINDOW_SIZE"] del st["streams"]["1"]["created"] del st["streams"]["1"]["flowOut"] del st["stats"]["in"]["frames"] del st["stats"]["in"]["octets"] del st["stats"]["out"]["frames"] del st["stats"]["out"]["octets"] del st["connFlowOut"] assert st == { "version" : "draft-01", "settings" : { "SETTINGS_MAX_CONCURRENT_STREAMS": 100, "SETTINGS_MAX_FRAME_SIZE": 16384, "SETTINGS_ENABLE_PUSH": 0 }, "peerSettings" : { "SETTINGS_MAX_CONCURRENT_STREAMS": 100, "SETTINGS_MAX_FRAME_SIZE": 16384, "SETTINGS_ENABLE_PUSH": 0, "SETTINGS_HEADER_TABLE_SIZE": 4096, "SETTINGS_MAX_HEADER_LIST_SIZE": -1 }, "connFlowIn": 2147483647, "sentGoAway": 0, "streams": { "1": { "state": "HALF_CLOSED_REMOTE", "flowIn": 65535, "dataIn": 0, "dataOut": 0 } }, "stats": { "in": { "requests": 1, "resets": 0, }, "out": { "responses": 0, }, "push": { "cacheDigest": "AQg", "promises": 0, "submits": 0, "resets": 0 } } }
def test_400_52(self): url = TestEnv.mkurl("https", "push", "/006-push.html") r = TestEnv.nghttp().get(url, options=[ '-H', 'accept-push-policy: head']) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 1 == len(promises) assert '/006/006.css' == promises[0]["request"]["header"][":path"] assert "" == promises[0]["response"]["body"] assert 0 == len(promises[0]["response"]["body"])
def test_600_01(self): url = TestEnv.mkurl("https", "cgi", "/h2proxy/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 "" != r["response"]["json"]["ssl_protocol"] assert "on" == r["response"]["json"]["h2"] assert "off" == r["response"]["json"]["h2push"]
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" } ]
def test_200_02(self): url = TestEnv.mkurl("https", "cgi", "/hecho.py") for x in range(1, 32): if 9 != x: r = TestEnv.curl_post_data(url, "name=x&value=y%%%02x" % x) if x in [ 10, 13 ]: assert 0 == r["rv"], "unexpected exit code for char 0x%02x" % x assert 200 == r["response"]["status"], "unexpected status for char 0x%02x" % x else: assert 0 != r["rv"], "unexpected exit code for char 0x%02x" % x
def test_201_01(self): url = TestEnv.mkurl("https", "test1", "/006/006.css") r = TestEnv.curl_get(url) assert 200 == r["response"]["status"] lm = r["response"]["header"]["last-modified"] assert lm r = TestEnv.curl_get(url, options=[ "-H", "if-modified-since: %s" % lm]) assert 304 == r["response"]["status"] r = TestEnv.curl_get(url, options=[ "-H", "if-modified-since: Tue, 04 Sep 2010 11:51:59 GMT"]) assert 200 == r["response"]["status"]
def test_201_02(self): url = TestEnv.mkurl("https", "test1", "/006/006.css") r = TestEnv.curl_get(url) assert 200 == r["response"]["status"] etag = r["response"]["header"]["etag"] assert etag r = TestEnv.curl_get(url, options=[ "-H", "if-none-match: %s" % etag]) assert 304 == r["response"]["status"] r = TestEnv.curl_get(url, options=[ "-H", "if-none-match: dummy"]) assert 200 == r["response"]["status"]
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) early = r["response"]["previous"] assert early assert 103 == int(early["header"][":status"]) assert early["header"]["link"]
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" } ]
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"]
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 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='wb') as f: f.write( o["response"]["body"] ) assert len(refbody) == len(o["response"]["body"]) assert refbody == o["response"]["body"]
def setup_module(module): print("setup_module: %s" % module.__name__) TestEnv.init() HttpdConf( ).start_vhost( TestEnv.HTTPS_PORT, "push", docRoot="htdocs/test1", withSSL=True ).add_line(""" Protocols h2 http/1.1" RewriteEngine on RewriteRule ^/006-push(.*)?\.html$ /006.html <Location /006-push.html> Header add Link "</006/006.css>;rel=preload" Header add Link "</006/006.js>;rel=preloadX" </Location> <Location /006-push2.html> Header add Link "</006/006.css>;rel=preloadX, </006/006.js>; rel=preload" </Location> <Location /006-push3.html> Header add Link "</006/006.css>;rel=preloa,</006/006.js>;rel=preload" </Location> <Location /006-push4.html> Header add Link "</006/006.css;rel=preload, </006/006.js>; preload" </Location> <Location /006-push5.html> Header add Link '</006/006.css>;rel="preload push"' </Location> <Location /006-push6.html> Header add Link '</006/006.css>;rel="push preload"' </Location> <Location /006-push7.html> Header add Link '</006/006.css>;rel="abc preload push"' </Location> <Location /006-push8.html> Header add Link '</006/006.css>;rel="preload"; nopush' </Location> <Location /006-push20.html> H2PushResource "/006/006.css" critical H2PushResource "/006/006.js" </Location> <Location /006-push30.html> H2Push off Header add Link '</006/006.css>;rel="preload"' </Location> <Location /006-push31.html> 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 test_400_20(self): url = TestEnv.mkurl("https", "push", "/006-push20.html") r = TestEnv.nghttp().get(url) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 2 == len(promises) fpath = os.path.join(TestEnv.GEN_DIR, "data-400-20") with open(fpath, 'w') as f: f.write("test upload data") r = TestEnv.nghttp().upload(url, fpath) assert 200 == r["response"]["status"] promises = r["streams"][r["response"]["id"]]["promises"] assert 0 == len(promises)
def test_101_05(self): url = TestEnv.mkurl("https", "ssl", "/ssl-client-verify/index.html") r = TestEnv.run( [ TestEnv.H2LOAD, "-n", "10", "-c", "1", "-m", "1", "-vvvv", "https://%s:%s/ssl-client-verify/index.html" % (TestEnv.HTTPD_ADDR, TestEnv.HTTPS_PORT)] ) assert 0 == r["rv"] r = TestEnv.h2load_status(r) assert 10 == r["h2load"]["requests"]["total"] assert 10 == r["h2load"]["requests"]["started"] assert 10 == r["h2load"]["requests"]["done"] assert 0 == r["h2load"]["requests"]["succeeded"] assert 0 == r["h2load"]["status"]["2xx"] assert 0 == r["h2load"]["status"]["3xx"] assert 0 == r["h2load"]["status"]["4xx"] assert 0 == r["h2load"]["status"]["5xx"]
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"]
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 r["response"]["status"] >= 200 and 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"]
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"])
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, ["--tlsv1.2"]) assert 200 == r["response"]["status"] assert "HTTP/2.0" == r["response"]["json"]["protocol"] assert "on" == r["response"]["json"]["https"] tls_version = r["response"]["json"]["ssl_protocol"] assert tls_version in ["TLSv1.2", "TLSv1.3"] assert "on" == r["response"]["json"]["h2"] assert "off" == r["response"]["json"]["h2push"] r = TestEnv.curl_get(url, 5, [ "--http1.1", "--tlsv1.2"]) assert 200 == r["response"]["status"] assert "HTTP/1.1" == r["response"]["json"]["protocol"] assert "on" == r["response"]["json"]["https"] tls_version = r["response"]["json"]["ssl_protocol"] assert tls_version in ["TLSv1.2", "TLSv1.3"] 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"].decode('utf-8') 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"] body = r["response"]["body"].decode('utf-8') # our doctype varies between branches and in time, lets not compare body = re.sub(r'^<!DOCTYPE[^>]+>', '', body) assert ''' <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> ''' == 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"].decode('utf-8')) 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"].decode('utf-8')) 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"]
def setup_method(self, method): print("setup_method: %s" % method.__name__) self.test_domain = TestEnv.get_method_domain(method)
def setup_module(module): print("setup_module: %s" % module.__name__) TestEnv.init()
<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_401_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)
def test_310_100(self, confline, dns_lists, md_count): HttpdConf(text=confline).install() assert TestEnv.apache_restart() == 0 for i in range(0, len(dns_lists)): TestEnv.check_md(dns_lists[i], state=1)
def setup_method(self, method): print("setup_method: %s" % method.__name__) TestEnv.httpd_error_log_clear() TestEnv.clear_store() self.test_domain = TestEnv.get_method_domain(method)
def test_702_009(self): domain = self.test_domain domains = [domain] # # prepare md conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_drive_mode("auto") conf.add_renew_window("10d") conf.add_md(domains) conf.add_vhost(domain) conf.install() # # restart (-> drive), check that md+cert is in store, TLS is up assert TestEnv.apache_restart() == 0 assert TestEnv.await_completion([domain]) TestEnv.check_md_complete(domain) cert1 = CertUtil(TestEnv.store_domain_file(domain, 'pubcert.pem')) # compare with what md reports as status stat = TestEnv.get_certificate_status(domain) assert stat['rsa']['serial'] == cert1.get_serial() # # create self-signed cert, with critical remaining valid duration -> drive again TestEnv.create_self_signed_cert([domain], { "notBefore": -120, "notAfter": 2 }, serial=7029) cert3 = CertUtil(TestEnv.store_domain_file(domain, 'pubcert.pem')) assert cert3.get_serial() == '1B75' assert TestEnv.apache_restart() == 0 stat = TestEnv.get_certificate_status(domain) assert stat['rsa']['serial'] == cert3.get_serial() # # cert should renew and be different afterwards assert TestEnv.await_completion([domain], must_renew=True) stat = TestEnv.get_certificate_status(domain) assert stat['rsa']['serial'] != cert3.get_serial()
def test_702_001(self): domain = self.test_domain # generate config with one MD domains = [domain, "www." + domain] conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_drive_mode("auto") conf.add_md(domains) conf.install() # # restart, check that MD is synched to store assert TestEnv.apache_restart() == 0 TestEnv.check_md(domains) stat = TestEnv.get_md_status(domain) assert stat["watched"] == 0 # # add vhost for MD, restart should drive it conf.add_vhost(domains) conf.install() assert TestEnv.apache_restart() == 0 assert TestEnv.await_completion([domain]) TestEnv.check_md_complete(domain) stat = TestEnv.get_md_status(domain) assert stat["watched"] == 1 cert = TestEnv.get_cert(domain) assert domain in cert.get_san_list() # # challenges should have been removed # file system needs to have correct permissions TestEnv.check_dir_empty(TestEnv.store_challenges()) TestEnv.check_file_permissions(domain)
def test_702_030(self): domain = self.test_domain nameX = "test-x." + domain nameA = "test-a." + domain nameB = "test-b." + domain domains = [nameX, nameA, nameB] # # generate 1 MD and 2 vhosts conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_md(domains) conf.add_vhost(nameA) conf.add_vhost(nameB) conf.install() # # restart (-> drive), check that MD was synched and completes assert TestEnv.apache_restart() == 0 TestEnv.check_md(domains) assert TestEnv.await_completion([nameX]) TestEnv.check_md_complete(nameX) # # check: SSL is running OK certA = TestEnv.get_cert(nameA) assert nameA in certA.get_san_list() certB = TestEnv.get_cert(nameB) assert nameB in certB.get_san_list() assert certA.get_serial() == certB.get_serial() # # change MD by removing 1st name new_list = [nameA, nameB] conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_md(new_list) conf.add_vhost(nameA) conf.add_vhost(nameB) conf.install() # restart, check that host still works and kept the cert assert TestEnv.apache_restart() == 0 TestEnv.check_md(new_list) status = TestEnv.get_certificate_status(nameA) assert status['rsa']['serial'] == certA.get_serial()
def test_310_203(self): dns_list1 = [ "greenbytes2.de", "www.greenbytes2.de", "mail.greenbytes2.de" ] dns_list2 = [ "testdomain.org", "www.testdomain.org", "mail.testdomain.org" ] TestEnv.a2md(["add"] + dns_list1) TestEnv.a2md(["add"] + dns_list2) TestEnv.check_md(dns_list1, state=1) TestEnv.check_md(dns_list2, state=1) HttpdConf(text=""" MDomain testdomain.org www.testdomain.org mail.testdomain.org """).install() assert TestEnv.apache_restart() == 0 # all mds stay in store TestEnv.check_md(dns_list1, state=1) TestEnv.check_md(dns_list2, state=1)
def setup_module(module): print("setup_module module:%s" % module.__name__) TestEnv.init() TestEnv.check_acme()
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", [])
def test_310_301(self): TestEnv.a2md([ "add", "testdomain.org", "www.testdomain.org", "mail.testdomain.org", "mail.testdomain2.org" ]) TestEnv.a2md(["add", "testdomain2.org", "www.testdomain2.org"]) TestEnv.check_md([ "testdomain.org", "www.testdomain.org", "mail.testdomain.org", "mail.testdomain2.org" ], state=1) TestEnv.check_md(["testdomain2.org", "www.testdomain2.org"], state=1) HttpdConf(text=""" MDomain testdomain.org www.testdomain.org mail.testdomain.org MDomain testdomain2.org www.testdomain2.org mail.testdomain2.org """).install() assert TestEnv.apache_restart() == 0 TestEnv.check_md( ["testdomain.org", "www.testdomain.org", "mail.testdomain.org"], state=1) TestEnv.check_md( ["testdomain2.org", "www.testdomain2.org", "mail.testdomain2.org"], state=1)
def teardown_module(module): print("teardown_module: %s" % module.__name__) assert TestEnv.apache_stop() == 0
def test_102_02(self): url = TestEnv.mkurl("https", "ssl", "/noh2.html") r = TestEnv.curl_get(url) assert 0 == r["rv"] assert "response" in r assert 403 == r["response"]["status"]
def setup_module(module): print("setup_module: %s" % module.__name__) TestEnv.init() HttpdConf().add_vhost_cgi().install() assert TestEnv.apache_restart() == 0
def test_310_109(self): HttpdConf(text=""" MDomain testdomain.org www.testdomain.org mail.testdomain.org """).install() assert TestEnv.apache_restart() == 0 assert TestEnv.a2md(["list"])['jout']['output'][0]['renew-mode'] == 1
def test_300_01(self): url = TestEnv.mkurl("https", "test1", "/index.html") r = TestEnv.curl_post_data(url, 'XYZ') assert 200 == r["response"]["status"] assert not "previous" in r["response"]
def test_702_031(self): domain = self.test_domain nameX = "test-x." + domain nameA = "test-a." + domain nameB = "test-b." + domain nameC = "test-c." + domain domains = [nameX, nameA, nameB] # # generate 1 MD and 2 vhosts conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_md(domains) conf.add_vhost(nameA) conf.add_vhost(nameB) conf.install() # # restart (-> drive), check that MD was synched and completes assert TestEnv.apache_restart() == 0 TestEnv.check_md(domains) assert TestEnv.await_completion([nameX]) TestEnv.check_md_complete(nameX) # # check: SSL is running OK certA = TestEnv.get_cert(nameA) assert nameA in certA.get_san_list() certB = TestEnv.get_cert(nameB) assert nameB in certB.get_san_list() assert certA.get_serial() == certB.get_serial() # # change MD by removing 1st name and adding another new_list = [nameA, nameB, nameC] conf = HttpdConf() conf.add_admin("admin@" + domain) conf.add_md(new_list) conf.add_vhost(nameA) conf.add_vhost(nameB) conf.install() # restart, check that host still works and have new cert assert TestEnv.apache_restart() == 0 TestEnv.check_md(new_list) assert TestEnv.await_completion([nameA]) # certA2 = TestEnv.get_cert(nameA) assert nameA in certA2.get_san_list() assert certA.get_serial() != certA2.get_serial()
def test_310_001(self): HttpdConf(text="").install() assert TestEnv.apache_restart() == 0 jout = TestEnv.a2md(["list"])['jout'] assert 0 == len(jout["output"])
def install(self): TestEnv.install_test_conf(self.path)
def test_702_032(self): domain = self.test_domain name1 = "server1." + domain name2 = "server2.b" + domain # need a separate TLD to avoid rate limites # # generate 2 MDs and 2 vhosts conf = HttpdConf() conf.add_admin("admin@" + domain) conf._add_line("MDMembers auto") conf.add_md([name1]) conf.add_md([name2]) conf.add_vhost(name1) conf.add_vhost(name2) conf.install() # # restart (-> drive), check that MD was synched and completes assert TestEnv.apache_restart() == 0 TestEnv.check_md([name1]) TestEnv.check_md([name2]) assert TestEnv.await_completion([name1, name2]) TestEnv.check_md_complete(name2) # # check: SSL is running OK cert1 = TestEnv.get_cert(name1) assert name1 in cert1.get_san_list() cert2 = TestEnv.get_cert(name2) assert name2 in cert2.get_san_list() # # remove second md and vhost, add name2 to vhost1 conf = HttpdConf() conf.add_admin("admin@" + domain) conf._add_line("MDMembers auto") conf.add_md([name1]) conf.add_vhost([name1, name2]) conf.install() assert TestEnv.apache_restart() == 0 TestEnv.check_md([name1, name2]) assert TestEnv.await_completion([name1]) # cert1b = TestEnv.get_cert(name1) assert name1 in cert1b.get_san_list() assert name2 in cert1b.get_san_list() assert cert1.get_serial() != cert1b.get_serial()