diff options
Diffstat (limited to 'test')
-rw-r--r-- | test/.gitignore | 2 | ||||
-rw-r--r-- | test/Makefile.in | 6 | ||||
-rw-r--r-- | test/conftest.py | 12 | ||||
-rw-r--r-- | test/modules/core/__init__.py | 1 | ||||
-rw-r--r-- | test/modules/core/conftest.py | 39 | ||||
-rw-r--r-- | test/modules/core/env.py | 18 | ||||
-rw-r--r-- | test/modules/core/test_001_encoding.py (renamed from test/modules/http2/test_203_encoding.py) | 28 | ||||
-rw-r--r-- | test/modules/http2/Makefile.in | 20 | ||||
-rw-r--r-- | test/modules/http2/__init__.py (renamed from test/modules/http2/htdocs/cgi/files/empty.txt) | 0 | ||||
-rw-r--r-- | test/modules/http2/conftest.py | 18 | ||||
-rw-r--r-- | test/modules/http2/env.py | 99 | ||||
-rw-r--r-- | test/modules/http2/test_000_infra.py | 17 | ||||
-rw-r--r-- | test/modules/http2/test_001_httpd_alive.py | 21 | ||||
-rw-r--r-- | test/modules/http2/test_002_curl_basics.py | 18 | ||||
-rw-r--r-- | test/modules/http2/test_003_get.py | 34 | ||||
-rw-r--r-- | test/modules/http2/test_004_post.py | 50 | ||||
-rw-r--r-- | test/modules/http2/test_005_files.py | 6 | ||||
-rw-r--r-- | test/modules/http2/test_006_assets.py | 14 | ||||
-rw-r--r-- | test/modules/http2/test_100_conn_reuse.py | 14 | ||||
-rw-r--r-- | test/modules/http2/test_101_ssl_reneg.py | 20 | ||||
-rw-r--r-- | test/modules/http2/test_102_require.py | 8 | ||||
-rw-r--r-- | test/modules/http2/test_103_upgrade.py | 28 | ||||
-rw-r--r-- | test/modules/http2/test_104_padding.py | 23 | ||||
-rw-r--r-- | test/modules/http2/test_105_timeout.py | 28 | ||||
-rw-r--r-- | test/modules/http2/test_106_shutdown.py | 8 | ||||
-rw-r--r-- | test/modules/http2/test_200_header_invalid.py | 32 | ||||
-rw-r--r-- | test/modules/http2/test_201_header_conditional.py | 12 | ||||
-rw-r--r-- | test/modules/http2/test_202_trailer.py | 14 | ||||
-rw-r--r-- | test/modules/http2/test_300_interim.py | 10 | ||||
-rw-r--r-- | test/modules/http2/test_400_push.py | 34 | ||||
-rw-r--r-- | test/modules/http2/test_401_early_hints.py | 8 | ||||
-rw-r--r-- | test/modules/http2/test_500_proxy.py | 24 | ||||
-rw-r--r-- | test/modules/http2/test_600_h2proxy.py | 6 | ||||
-rw-r--r-- | test/modules/http2/test_700_load_get.py | 8 | ||||
-rw-r--r-- | test/modules/http2/test_710_load_post_static.py | 10 | ||||
-rw-r--r-- | test/modules/http2/test_711_load_post_cgi.py | 10 | ||||
-rw-r--r-- | test/modules/http2/test_712_buffering.py | 12 | ||||
-rw-r--r-- | test/pyhttpd/__init__.py (renamed from test/modules/http2/htdocs/test1/apache.org-files/cse.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/certs.py (renamed from test/modules/http2/h2_certs.py) | 56 | ||||
-rw-r--r-- | test/pyhttpd/conf.py (renamed from test/modules/http2/h2_conf.py) | 32 | ||||
-rw-r--r-- | test/pyhttpd/conf/httpd.conf.template (renamed from test/modules/http2/conf/httpd.conf.template) | 0 | ||||
-rw-r--r-- | test/pyhttpd/conf/mime.types (renamed from test/modules/http2/conf/mime.types) | 0 | ||||
-rw-r--r-- | test/pyhttpd/conf/test.conf (renamed from test/modules/http2/conf/test.conf) | 0 | ||||
-rw-r--r-- | test/pyhttpd/config.ini.in (renamed from test/modules/http2/config.ini.in) | 7 | ||||
-rw-r--r-- | test/pyhttpd/curl.py (renamed from test/modules/http2/h2_curl.py) | 4 | ||||
-rw-r--r-- | test/pyhttpd/env.py (renamed from test/modules/http2/h2_env.py) | 178 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/alive.json (renamed from test/modules/http2/htdocs/alive.json) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/echo.py (renamed from test/modules/http2/htdocs/cgi/echo.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/echohd.py (renamed from test/modules/http2/htdocs/cgi/echohd.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/env.py (renamed from test/modules/http2/htdocs/cgi/env.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/files/empty.txt (renamed from test/modules/http2/htdocs/test1/apache.org-files/css.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/hecho.py (renamed from test/modules/http2/htdocs/cgi/hecho.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/hello.py (renamed from test/modules/http2/htdocs/cgi/hello.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/mnot164.py (renamed from test/modules/http2/htdocs/cgi/mnot164.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/necho.py (renamed from test/modules/http2/htdocs/cgi/necho.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/cgi/upload.py (renamed from test/modules/http2/htdocs/cgi/upload.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/forbidden.html (renamed from test/modules/http2/htdocs/forbidden.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/index.html (renamed from test/modules/http2/htdocs/index.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/noh2/alive.json (renamed from test/modules/http2/htdocs/noh2/alive.json) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/noh2/index.html (renamed from test/modules/http2/htdocs/noh2/index.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/001.html (renamed from test/modules/http2/htdocs/test1/001.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/002.jpg (renamed from test/modules/http2/htdocs/test1/002.jpg) | bin | 90364 -> 90364 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/003.html (renamed from test/modules/http2/htdocs/test1/003.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/003/003_img.jpg (renamed from test/modules/http2/htdocs/test1/003/003_img.jpg) | bin | 90364 -> 90364 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/004.html (renamed from test/modules/http2/htdocs/test1/004.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/004/gophertiles.jpg (renamed from test/modules/http2/htdocs/test1/004/gophertiles.jpg) | bin | 742 -> 742 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/006.html (renamed from test/modules/http2/htdocs/test1/006.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/006/006.css (renamed from test/modules/http2/htdocs/test1/006/006.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/006/006.js (renamed from test/modules/http2/htdocs/test1/006/006.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/006/header.html (renamed from test/modules/http2/htdocs/test1/006/header.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/007.html (renamed from test/modules/http2/htdocs/test1/007.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/007/007.py (renamed from test/modules/http2/htdocs/test1/007/007.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/009.py (renamed from test/modules/http2/htdocs/test1/009.py) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/alive.json (renamed from test/modules/http2/htdocs/test1/alive.json) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/ant.jpg (renamed from test/modules/http2/htdocs/test1/apache.org-files/ant.jpg) | bin | 6437 -> 6437 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/asf_logo.png (renamed from test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png) | bin | 29982 -> 29982 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js (renamed from test/modules/http2/htdocs/test1/apache.org-files/async-ads.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js.br (renamed from test/modules/http2/htdocs/test1/apache.org-files/async-ads.js.br) | bin | 50272 -> 50272 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/cse.js (renamed from test/modules/http2/htdocs/test1/apache.org-files/jsapi.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/css.css (renamed from test/modules/http2/htdocs/test2/10%abnormal.txt) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/default.css (renamed from test/modules/http2/htdocs/test1/apache.org-files/default.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/defaulten.css (renamed from test/modules/http2/htdocs/test1/apache.org-files/defaulten.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/defaulten.js (renamed from test/modules/http2/htdocs/test1/apache.org-files/defaulten.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/jquery-2.js (renamed from test/modules/http2/htdocs/test1/apache.org-files/jquery-2.js) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/jsapi.js (renamed from test/modules/http2/htdocs/test2/x%2f.test) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/min.css (renamed from test/modules/http2/htdocs/test1/apache.org-files/min.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/min.css.br (renamed from test/modules/http2/htdocs/test1/apache.org-files/min.css.br) | bin | 10116 -> 10116 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/mrunit.jpg (renamed from test/modules/http2/htdocs/test1/apache.org-files/mrunit.jpg) | bin | 4460 -> 4460 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/search_box_icon.png (renamed from test/modules/http2/htdocs/test1/apache.org-files/search_box_icon.png) | bin | 1018 -> 1018 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/small-logo.png (renamed from test/modules/http2/htdocs/test1/apache.org-files/small-logo.png) | bin | 1499 -> 1499 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/styles.css (renamed from test/modules/http2/htdocs/test1/apache.org-files/styles.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org-files/synapse.jpg (renamed from test/modules/http2/htdocs/test1/apache.org-files/synapse.jpg) | bin | 4396 -> 4396 bytes | |||
-rw-r--r-- | test/pyhttpd/htdocs/test1/apache.org.html (renamed from test/modules/http2/htdocs/test1/apache.org.html) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test1/index.html (renamed from test/modules/http2/htdocs/test1/index.html) | 0 | ||||
-rwxr-xr-x | test/pyhttpd/htdocs/test2/006/006.css (renamed from test/modules/http2/htdocs/test2/006/006.css) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test2/10%abnormal.txt | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test2/alive.json (renamed from test/modules/http2/htdocs/test2/alive.json) | 0 | ||||
-rw-r--r-- | test/pyhttpd/htdocs/test2/x%2f.test | 0 | ||||
-rw-r--r-- | test/pyhttpd/nghttp.py (renamed from test/modules/http2/h2_nghttp.py) | 2 | ||||
-rw-r--r-- | test/pyhttpd/result.py (renamed from test/modules/http2/h2_result.py) | 0 |
100 files changed, 537 insertions, 454 deletions
diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000000..f8a27a5c56 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +config.ini +gen diff --git a/test/Makefile.in b/test/Makefile.in index 15d404d208..1bfb3e3d7c 100644 --- a/test/Makefile.in +++ b/test/Makefile.in @@ -18,3 +18,9 @@ test: $(bin_PROGRAMS) # dbu_OBJECTS = dbu.lo # dbu: $(dbu_OBJECTS) # $(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD) + +clean: + rm -rf gen + +distclean: + rm -f pytest/config.ini
\ No newline at end of file diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000000..b12b1d6d78 --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,12 @@ +import sys +import os + +sys.path.append(os.path.join(os.path.dirname(__file__), '.')) + +from pyhttpd.env import HttpdTestEnv + +def pytest_report_header(config, startdir): + env = HttpdTestEnv() + return f"[apache httpd: {env.get_httpd_version()}, mpm: {env.mpm_type}, {env.prefix}]" + + diff --git a/test/modules/core/__init__.py b/test/modules/core/__init__.py new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/test/modules/core/__init__.py @@ -0,0 +1 @@ + diff --git a/test/modules/core/conftest.py b/test/modules/core/conftest.py new file mode 100644 index 0000000000..b0be4af5f4 --- /dev/null +++ b/test/modules/core/conftest.py @@ -0,0 +1,39 @@ +import logging +import os + +import pytest +import sys + +sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) + +from .env import CoreTestEnv + + +def pytest_report_header(config, startdir): + env = CoreTestEnv(setup_dirs=False) + return f"core [apache: {env.get_httpd_version()}, mpm: {env.mpm_type}, {env.prefix}]" + + +@pytest.fixture(scope="module") +def env(pytestconfig) -> CoreTestEnv: + level = logging.INFO + console = logging.StreamHandler() + console.setLevel(level) + console.setFormatter(logging.Formatter('%(levelname)s: %(message)s')) + logging.getLogger('').addHandler(console) + logging.getLogger('').setLevel(level=level) + env = CoreTestEnv(pytestconfig=pytestconfig) + env.apache_access_log_clear() + env.apache_error_log_clear() + return env + + +@pytest.fixture(autouse=True, scope="module") +def _session_scope(env): + yield + assert env.apache_stop() == 0 + errors, warnings = env.apache_errors_and_warnings() + assert (len(errors), len(warnings)) == (0, 0),\ + f"apache logged {len(errors)} errors and {len(warnings)} warnings: \n"\ + "{0}\n{1}\n".format("\n".join(errors), "\n".join(warnings)) + diff --git a/test/modules/core/env.py b/test/modules/core/env.py new file mode 100644 index 0000000000..9b09e90c61 --- /dev/null +++ b/test/modules/core/env.py @@ -0,0 +1,18 @@ +import inspect +import logging +import os + +from pyhttpd.env import HttpdTestEnv, HttpdTestSetup + +log = logging.getLogger(__name__) + + +class CoreTestEnv(HttpdTestEnv): + + def __init__(self, pytestconfig=None, setup_dirs=True): + super().__init__(pytestconfig=pytestconfig, + local_dir=os.path.dirname(inspect.getfile(CoreTestEnv))) + if setup_dirs: + self._setup = HttpdTestSetup(env=self) + self._setup.make() + self.issue_certs() diff --git a/test/modules/http2/test_203_encoding.py b/test/modules/core/test_001_encoding.py index 60d96e0bad..2099d08cf0 100644 --- a/test/modules/http2/test_203_encoding.py +++ b/test/modules/core/test_001_encoding.py @@ -1,8 +1,6 @@ -import time - import pytest -from h2_conf import HttpdConf +from pyhttpd.conf import HttpdConf class TestEncoding: @@ -11,17 +9,15 @@ class TestEncoding: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - extras = { - 'base': f""" + conf = HttpdConf(env) + conf.add(f""" <Directory "{env.gen_dir}"> AllowOverride None Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch Require all granted </Directory> - """, - } - conf = HttpdConf(env) - conf.add_vhost_test1(extras=extras) + """) + conf.add_vhost_test1() conf.add_vhost_test2(extras={ f"test2.{env.http_tld}": "AllowEncodedSlashes on", }) @@ -32,9 +28,10 @@ class TestEncoding: assert env.apache_restart() == 0 yield errors, warnings = env.apache_errors_and_warnings() + nl = "\n" assert (len(errors), len(warnings)) == (TestEncoding.EXP_AH10244_ERRS, 0),\ - f"apache logged {len(errors)} errors and {len(warnings)} warnings: \n"\ - "{0}\n{1}\n".format("\n".join(errors), "\n".join(warnings)) + f"apache logged {len(errors)} errors and {len(warnings)} warnings: \n"\ + f"{nl.join(errors)}\n{nl.join(warnings)}\n" env.apache_error_log_clear() # check handling of url encodings that are accepted @@ -47,7 +44,7 @@ class TestEncoding: "/nothing/%2e/%2e%2e/006/006.css", "/nothing/%2e/%2e%2e/006/006%2ecss", ]) - def test_203_01(self, env, path): + def test_core_001_01(self, env, path): url = env.mkurl("https", "test1", path) r = env.curl_get(url) assert r.response["status"] == 200 @@ -62,7 +59,7 @@ class TestEncoding: "/006/../006/006.css", "/006/%2e%2e/006/006.css", ]) - def test_203_03(self, env, path): + def test_core_001_03(self, env, path): url = env.mkurl("https", "test1", path) r = env.curl_get(url) assert r.response["status"] == 200 @@ -83,7 +80,7 @@ class TestEncoding: ["/nothing/%25%32%65%25%32%65/%25%32%65%25%32%65/h2_env.py", 404], ["/cgi-bin/%25%32%65%25%32%65/%25%32%65%25%32%65/h2_env.py", 404], ]) - def test_203_04(self, env, path, status): + def test_core_001_04(self, env, path, status): url = env.mkurl("https", "cgi", path) r = env.curl_get(url) assert r.response["status"] == status @@ -98,8 +95,7 @@ class TestEncoding: ["test2", "/x%252f.test", 200], ["test2", "/10%25abnormal.txt", 200], ]) - def test_203_20(self, env, host, path, status): + def test_core_001_20(self, env, host, path, status): url = env.mkurl("https", host, path) r = env.curl_get(url) assert r.response["status"] == status - diff --git a/test/modules/http2/Makefile.in b/test/modules/http2/Makefile.in deleted file mode 100644 index 15d404d208..0000000000 --- a/test/modules/http2/Makefile.in +++ /dev/null @@ -1,20 +0,0 @@ - -# no targets: we don't want to build anything by default. if you want the -# test programs, then "make test" -TARGETS = - -bin_PROGRAMS = - -PROGRAM_LDADD = $(EXTRA_LDFLAGS) $(PROGRAM_DEPENDENCIES) $(EXTRA_LIBS) -PROGRAM_DEPENDENCIES = \ - $(top_srcdir)/srclib/apr-util/libaprutil.la \ - $(top_srcdir)/srclib/apr/libapr.la - -include $(top_builddir)/build/rules.mk - -test: $(bin_PROGRAMS) - -# example for building a test proggie -# dbu_OBJECTS = dbu.lo -# dbu: $(dbu_OBJECTS) -# $(LINK) $(dbu_OBJECTS) $(PROGRAM_LDADD) diff --git a/test/modules/http2/htdocs/cgi/files/empty.txt b/test/modules/http2/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/cgi/files/empty.txt +++ b/test/modules/http2/__init__.py diff --git a/test/modules/http2/conftest.py b/test/modules/http2/conftest.py index 363abae4c2..930cc0ac7c 100644 --- a/test/modules/http2/conftest.py +++ b/test/modules/http2/conftest.py @@ -2,9 +2,11 @@ import logging import os import pytest +import sys -from h2_certs import CertificateSpec, H2TestCA -from h2_env import H2TestEnv +sys.path.append(os.path.join(os.path.dirname(__file__), '../..')) + +from .env import H2TestEnv def pytest_report_header(config, startdir): @@ -25,7 +27,7 @@ def pytest_generate_tests(metafunc): metafunc.parametrize('repeat', range(count)) -@pytest.fixture(scope="session") +@pytest.fixture(scope="module") def env(pytestconfig) -> H2TestEnv: level = logging.INFO console = logging.StreamHandler() @@ -34,20 +36,12 @@ def env(pytestconfig) -> H2TestEnv: logging.getLogger('').addHandler(console) logging.getLogger('').setLevel(level=level) env = H2TestEnv(pytestconfig=pytestconfig) - cert_specs = [ - CertificateSpec(domains=env.domains, key_type='rsa4096'), - CertificateSpec(domains=env.domains_noh2, key_type='rsa2048'), - ] - ca = H2TestCA.create_root(name=env.http_tld, - store_dir=os.path.join(env.server_dir, 'ca'), key_type="rsa4096") - ca.issue_certs(cert_specs) - env.set_ca(ca) env.apache_access_log_clear() env.apache_error_log_clear() return env -@pytest.fixture(autouse=True, scope="session") +@pytest.fixture(autouse=True, scope="module") def _session_scope(env): yield assert env.apache_stop() == 0 diff --git a/test/modules/http2/env.py b/test/modules/http2/env.py new file mode 100644 index 0000000000..6182807486 --- /dev/null +++ b/test/modules/http2/env.py @@ -0,0 +1,99 @@ +import inspect +import logging +import os +import subprocess + +from pyhttpd.certs import CertificateSpec +from pyhttpd.conf import HttpdConf +from pyhttpd.env import HttpdTestEnv, HttpdTestSetup + +log = logging.getLogger(__name__) + + +class H2TestSetup(HttpdTestSetup): + + def __init__(self, env: 'HttpdTestEnv'): + super().__init__(env=env) + + def make(self): + super().make(add_modules=["http2", "proxy_http2"]) + self._add_h2test() + + def _add_h2test(self): + p = subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'], + capture_output=True, + cwd=os.path.join(self.env.local_dir, 'mod_h2test')) + rv = p.returncode + if rv != 0: + log.error(f"compiling md_h2test failed: {p.stderr}") + raise Exception(f"compiling md_h2test failed: {p.stderr}") + + modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') + with open(modules_conf, 'a') as fd: + # load our test module which is not installed + fd.write(f"LoadModule h2test_module \"{self.env.local_dir}/mod_h2test/.libs/mod_h2test.so\"\n") + + +class H2TestEnv(HttpdTestEnv): + + def __init__(self, pytestconfig=None, setup_dirs=True): + super().__init__(pytestconfig=pytestconfig, + local_dir=os.path.dirname(inspect.getfile(H2TestEnv)), + add_base_conf=""" + H2MinWorkers 1 + H2MaxWorkers 64 + """, + interesting_modules=["http2", "proxy_http2", "h2test"]) + self.add_cert_specs([ + CertificateSpec(domains=[ + f"push.{self._http_tld}", + f"hints.{self._http_tld}", + f"ssl.{self._http_tld}", + f"pad0.{self._http_tld}", + f"pad1.{self._http_tld}", + f"pad2.{self._http_tld}", + f"pad3.{self._http_tld}", + f"pad8.{self._http_tld}", + ]), + CertificateSpec(domains=[f"noh2.{self.http_tld}"], key_type='rsa2048'), + ]) + if setup_dirs: + self._setup = H2TestSetup(env=self) + self._setup.make() + self.issue_certs() + self.setup_data_1k_1m() + + + def setup_data_1k_1m(self): + s100 = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n" + with open(os.path.join(self.gen_dir, "data-1k"), 'w') as f: + for i in range(10): + f.write(s100) + with open(os.path.join(self.gen_dir, "data-10k"), 'w') as f: + for i in range(100): + f.write(s100) + with open(os.path.join(self.gen_dir, "data-100k"), 'w') as f: + for i in range(1000): + f.write(s100) + with open(os.path.join(self.gen_dir, "data-1m"), 'w') as f: + for i in range(10000): + f.write(s100) + + +class H2Conf(HttpdConf): + + def __init__(self, env: HttpdTestEnv, path=None): + super().__init__(env=env, path=path) + + + def add_vhost_noh2(self): + self.start_vhost(self.env.https_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=True) + self.add(f""" + Protocols http/1.1 + SSLOptions +StdEnvVars""") + self.end_vhost() + self.start_vhost(self.env.http_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=False) + self.add(" Protocols http/1.1") + self.add(" SSLOptions +StdEnvVars") + self.end_vhost() + return self diff --git a/test/modules/http2/test_000_infra.py b/test/modules/http2/test_000_infra.py deleted file mode 100644 index 4a8591e62f..0000000000 --- a/test/modules/http2/test_000_infra.py +++ /dev/null @@ -1,17 +0,0 @@ -# -# mod-h2 test suite -# check that our test infrastructure is sane -# -import pytest - - -class TestStore: - - @pytest.fixture(autouse=True, scope='class') - def _class_scope(self, env): - env.setup_data_1k_1m() - yield - - def test_000_00(self): - assert 1 == 1 - diff --git a/test/modules/http2/test_001_httpd_alive.py b/test/modules/http2/test_001_httpd_alive.py index f198c18d5e..d922b44001 100644 --- a/test/modules/http2/test_001_httpd_alive.py +++ b/test/modules/http2/test_001_httpd_alive.py @@ -1,28 +1,21 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_test1().install() + H2Conf(env).add_vhost_test1().install() assert env.apache_restart() == 0 # we expect to see the document from the generic server - def test_001_01(self, env): - r = env.curl_get(f"https://{env.domain_test1}:{env.https_port}/alive.json", 5) + def test_h2_001_01(self, env): + url = env.mkurl("https", "test1", "/alive.json") + r = env.curl_get(url, 5) assert r.exit_code == 0, r.stderr + r.stdout assert r.response["json"] - assert True == r.response["json"]["alive"] - assert "test1" == r.response["json"]["host"] - - # we expect to see the document from the generic server - def test_001_02(self, env): - r = env.curl_get(f"https://{env.domain_test1}:{env.https_port}/alive.json", 5) - assert r.exit_code == 0, r.stderr - assert r.response["json"] - assert True == r.response["json"]["alive"] - assert "test1" == r.response["json"]["host"] + assert r.response["json"]["alive"] is True + assert r.response["json"]["host"] == "test1" diff --git a/test/modules/http2/test_002_curl_basics.py b/test/modules/http2/test_002_curl_basics.py index 1c1ef699a0..3f5e9694d7 100644 --- a/test/modules/http2/test_002_curl_basics.py +++ b/test/modules/http2/test_002_curl_basics.py @@ -1,17 +1,17 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_test1().add_vhost_test2().install() + H2Conf(env).add_vhost_test1().add_vhost_test2().install() assert env.apache_restart() == 0 # check that we see the correct documents when using the test1 server name over http: - def test_002_01(self, env): + def test_h2_002_01(self, env): url = env.mkurl("http", "test1", "/alive.json") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -20,7 +20,7 @@ class TestStore: assert "test1" == r.response["json"]["host"] # check that we see the correct documents when using the test1 server name over https: - def test_002_02(self, env): + def test_h2_002_02(self, env): url = env.mkurl("https", "test1", "/alive.json") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -29,21 +29,21 @@ class TestStore: assert "application/json" == r.response["header"]["content-type"] # enforce HTTP/1.1 - def test_002_03(self, env): + def test_h2_002_03(self, env): url = env.mkurl("https", "test1", "/alive.json") r = env.curl_get(url, 5, [ "--http1.1" ]) assert 200 == r.response["status"] assert "HTTP/1.1" == r.response["protocol"] # enforce HTTP/2 - def test_002_04(self, env): + def test_h2_002_04(self, env): url = env.mkurl("https", "test1", "/alive.json") r = env.curl_get(url, 5, [ "--http2" ]) assert 200 == r.response["status"] assert "HTTP/2" == r.response["protocol"] # default is HTTP/2 on this host - def test_002_04b(self, env): + def test_h2_002_04b(self, env): url = env.mkurl("https", "test1", "/alive.json") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -51,7 +51,7 @@ class TestStore: assert "test1" == r.response["json"]["host"] # although, without ALPN, we cannot select it - def test_002_05(self, env): + def test_h2_002_05(self, env): url = env.mkurl("https", "test1", "/alive.json") r = env.curl_get(url, 5, [ "--no-alpn" ]) assert 200 == r.response["status"] @@ -59,7 +59,7 @@ class TestStore: assert "test1" == r.response["json"]["host"] # default is HTTP/1.1 on the other - def test_002_06(self, env): + def test_h2_002_06(self, env): url = env.mkurl("https", "test2", "/alive.json") r = env.curl_get(url, 5) assert 200 == r.response["status"] diff --git a/test/modules/http2/test_003_get.py b/test/modules/http2/test_003_get.py index ea7c9fb39d..f8b41fc1b9 100644 --- a/test/modules/http2/test_003_get.py +++ b/test/modules/http2/test_003_get.py @@ -1,14 +1,14 @@ import re import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_cgi( + H2Conf(env).add_vhost_cgi( proxy_self=True, h2proxy_self=True ).add_vhost_test1( proxy_self=True, h2proxy_self=True @@ -16,7 +16,7 @@ class TestStore: assert env.apache_restart() == 0 # check SSL environment variables from CGI script - def test_003_01(self, env): + def test_h2_003_01(self, env): url = env.mkurl("https", "cgi", "/hello.py") r = env.curl_get(url, 5, ["--tlsv1.2"]) assert 200 == r.response["status"] @@ -37,8 +37,8 @@ class TestStore: assert "" == r.response["json"]["h2push"] # retrieve a html file from the server and compare it to its source - def test_003_02(self, env): - with open(env.test_src("htdocs/test1/index.html"), mode='rb') as file: + def test_h2_003_02(self, env): + with open(env.htdocs_src("test1/index.html"), mode='rb') as file: src = file.read() url = env.mkurl("https", "test1", "/index.html") @@ -63,23 +63,23 @@ class TestStore: exp += text + "\n" assert exp == r.response["body"].decode('utf-8') - def test_003_10(self, env): + def test_h2_003_10(self, env): self.check_necho(env, 10, "0123456789") - def test_003_11(self, env): + def test_h2_003_11(self, env): self.check_necho(env, 100, "0123456789") - def test_003_12(self, env): + def test_h2_003_12(self, env): self.check_necho(env, 1000, "0123456789") - def test_003_13(self, env): + def test_h2_003_13(self, env): self.check_necho(env, 10000, "0123456789") - def test_003_14(self, env): + def test_h2_003_14(self, env): self.check_necho(env, 100000, "0123456789") # github issue #126 - def test_003_20(self, env): + def test_h2_003_20(self, env): url = env.mkurl("https", "test1", "/006/") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -111,7 +111,7 @@ class TestStore: 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, env): + def test_h2_003_21(self, env): url = env.mkurl("https", "test1", "/index.html") r = env.curl_get(url, 5, ["-I"]) assert 200 == r.response["status"] @@ -141,7 +141,7 @@ content-type: text/html @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) - def test_003_30(self, env, path): + def test_h2_003_30(self, env, path): url = env.mkurl("https", "test1", path) r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -156,7 +156,7 @@ content-type: text/html @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) - def test_003_31(self, env, path): + def test_h2_003_31(self, env, path): url = env.mkurl("https", "test1", path) r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -168,7 +168,7 @@ content-type: text/html assert 304 == r.response["status"] # test various response body lengths to work correctly - def test_003_40(self, env): + def test_h2_003_40(self, env): n = 1001 while n <= 1025024: url = env.mkurl("https", "cgi", f"/mnot164.py?count={n}&text=X") @@ -182,7 +182,7 @@ content-type: text/html @pytest.mark.parametrize("n", [ 0, 1, 1291, 1292, 80000, 80123, 81087, 98452 ]) - def test_003_41(self, env, n): + def test_h2_003_41(self, env, n): url = env.mkurl("https", "cgi", f"/mnot164.py?count={n}&text=X") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -193,7 +193,7 @@ content-type: text/html @pytest.mark.parametrize("path", [ "/004.html", "/proxy/004.html", "/h2proxy/004.html" ]) - def test_003_50(self, env, path): + def test_h2_003_50(self, env, path): # check that the resource supports ranges and we see its raw content-length url = env.mkurl("https", "test1", path) r = env.curl_get(url, 5) diff --git a/test/modules/http2/test_004_post.py b/test/modules/http2/test_004_post.py index 16d1c7679c..ef3ff7925c 100644 --- a/test/modules/http2/test_004_post.py +++ b/test/modules/http2/test_004_post.py @@ -4,7 +4,7 @@ import os import re import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @@ -12,7 +12,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - HttpdConf(env).add_vhost_cgi().install() + H2Conf(env).add_vhost_cgi().install() assert env.apache_restart() == 0 # upload and GET again using curl, compare to original content @@ -26,32 +26,32 @@ class TestStore: r2 = env.curl_get(r.response["header"]["location"]) assert r2.exit_code == 0 assert r2.response["status"] == 200 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r2.response["body"] - def test_004_01(self, env): + def test_h2_004_01(self, env): self.curl_upload_and_verify(env, "data-1k", ["--http1.1"]) self.curl_upload_and_verify(env, "data-1k", ["--http2"]) - def test_004_02(self, env): + def test_h2_004_02(self, env): self.curl_upload_and_verify(env, "data-10k", ["--http1.1"]) self.curl_upload_and_verify(env, "data-10k", ["--http2"]) - def test_004_03(self, env): + def test_h2_004_03(self, env): self.curl_upload_and_verify(env, "data-100k", ["--http1.1"]) self.curl_upload_and_verify(env, "data-100k", ["--http2"]) - def test_004_04(self, env): + def test_h2_004_04(self, env): self.curl_upload_and_verify(env, "data-1m", ["--http1.1"]) self.curl_upload_and_verify(env, "data-1m", ["--http2"]) - def test_004_05(self, env): + def test_h2_004_05(self, env): self.curl_upload_and_verify(env, "data-1k", ["-v", "--http1.1", "-H", "Expect: 100-continue"]) self.curl_upload_and_verify(env, "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, env): + def test_h2_004_06(self, env): self.curl_upload_and_verify(env, "data-1k", ["--http1.1", "-H", "Content-Length: "]) self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length: "]) @@ -63,7 +63,7 @@ class TestStore: ("H2_STREAM_ID", "1"), ("H2_STREAM_TAG", r'\d+-1'), ]) - def test_004_07(self, env, name, value): + def test_h2_004_07(self, env, name, value): url = env.mkurl("https", "cgi", "/env.py") r = env.curl_post_value(url, "name", name) assert r.exit_code == 0 @@ -74,20 +74,20 @@ class TestStore: # verify that we parse nghttp output correctly def check_nghttp_body(self, env, ref_input, nghttp_output): - with open(env.test_src(os.path.join(env.gen_dir, ref_input)), mode='rb') as f: + with open(env.local_src(os.path.join(env.gen_dir, ref_input)), mode='rb') as f: refbody = f.read() - with open(env.test_src(nghttp_output), mode='rb') as f: + with open(env.local_src(nghttp_output), mode='rb') as f: text = f.read() o = env.nghttp().parse_output(text) assert "response" in o assert "body" in o["response"] if refbody != o["response"]["body"]: - with open(env.test_src(os.path.join(env.gen_dir, '%s.parsed' % ref_input)), mode='bw') as f: + with open(env.local_src(os.path.join(env.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, env): + def test_h2_004_20(self, env): self.check_nghttp_body(env, 'data-1k', 'data/nghttp-output-1k-1.txt') self.check_nghttp_body(env, 'data-10k', 'data/nghttp-output-10k-1.txt') self.check_nghttp_body(env, 'data-100k', 'data/nghttp-output-100k-1.txt') @@ -101,20 +101,20 @@ class TestStore: assert r.exit_code == 0 assert r.response["status"] >= 200 and r.response["status"] < 300 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r.response["body"] @pytest.mark.parametrize("name", [ "data-1k", "data-10k", "data-100k", "data-1m" ]) - def test_004_21(self, env, name): + def test_h2_004_21(self, env, name): self.nghttp_post_and_verify(env, name, []) @pytest.mark.parametrize("name", [ "data-1k", "data-10k", "data-100k", "data-1m" ]) - def test_004_22(self, env, name, repeat): + def test_h2_004_22(self, env, name, repeat): self.nghttp_post_and_verify(env, name, ["--no-content-length"]) # upload and GET again using nghttp, compare to original content @@ -130,29 +130,29 @@ class TestStore: r2 = env.nghttp().get(r.response["header"]["location"]) assert r2.exit_code == 0 assert r2.response["status"] == 200 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r2.response["body"] @pytest.mark.parametrize("name", [ "data-1k", "data-10k", "data-100k", "data-1m" ]) - def test_004_23(self, env, name, repeat): + def test_h2_004_23(self, env, name, repeat): self.nghttp_upload_and_verify(env, name, []) @pytest.mark.parametrize("name", [ "data-1k", "data-10k", "data-100k", "data-1m" ]) - def test_004_24(self, env, name, repeat): + def test_h2_004_24(self, env, name, repeat): self.nghttp_upload_and_verify(env, name, ["--expect-continue"]) @pytest.mark.parametrize("name", [ "data-1k", "data-10k", "data-100k", "data-1m" ]) - def test_004_25(self, env, name, repeat): + def test_h2_004_25(self, env, name, repeat): self.nghttp_upload_and_verify(env, name, ["--no-content-length"]) - def test_004_30(self, env): + def test_h2_004_30(self, env): # issue: #203 resource = "data-1k" full_length = 1000 @@ -161,7 +161,7 @@ class TestStore: logfile = os.path.join(env.server_logs_dir, "test_004_30") if os.path.isfile(logfile): os.remove(logfile) - HttpdConf(env).add(""" + H2Conf(env).add(""" 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() @@ -190,7 +190,7 @@ CustomLog logs/test_004_30 issue_203 assert log_h2['bytes_resp_B'] == chunk assert log_h2['bytes_tx_O'] > chunk - def test_004_40(self, env): + def test_h2_004_40(self, env): # echo content using h2test_module "echo" handler def post_and_verify(fname, options=None): url = env.mkurl("https", "cgi", "/h2test/echo") @@ -211,7 +211,7 @@ CustomLog logs/test_004_30 issue_203 if fname == part.get_filename(): filepart = part assert filepart - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == filepart.get_payload(decode=True) diff --git a/test/modules/http2/test_005_files.py b/test/modules/http2/test_005_files.py index 4969a6c6c9..91eacf3b10 100644 --- a/test/modules/http2/test_005_files.py +++ b/test/modules/http2/test_005_files.py @@ -1,7 +1,7 @@ import os import pytest -from h2_conf import HttpdConf +from .env import H2Conf def mk_text_file(fpath: str, lines: int): @@ -33,14 +33,14 @@ class TestFiles: mk_text_file(os.path.join(docs_a, fname), 8 * fsize) self.URI_PATHS.append(f"/files/{fname}") - HttpdConf(env).add_vhost_cgi( + H2Conf(env).add_vhost_cgi( proxy_self=True, h2proxy_self=True ).add_vhost_test1( proxy_self=True, h2proxy_self=True ).install() assert env.apache_restart() == 0 - def test_005_01(self, env): + def test_h2_005_01(self, env): url = env.mkurl("https", "cgi", self.URI_PATHS[2]) r = env.curl_get(url) assert r.response, r.stderr + r.stdout diff --git a/test/modules/http2/test_006_assets.py b/test/modules/http2/test_006_assets.py index 339364ee58..44558da81e 100644 --- a/test/modules/http2/test_006_assets.py +++ b/test/modules/http2/test_006_assets.py @@ -1,17 +1,17 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_test1().install() + H2Conf(env).add_vhost_test1().install() assert env.apache_restart() == 0 # single page without any assets - def test_006_01(self, env): + def test_h2_006_01(self, env): url = env.mkurl("https", "test1", "/001.html") r = env.nghttp().assets(url, options=["-Haccept-encoding: none"]) assert 0 == r.exit_code @@ -21,7 +21,7 @@ class TestStore: ] # single image without any assets - def test_006_02(self, env): + def test_h2_006_02(self, env): url = env.mkurl("https", "test1", "/002.jpg") r = env.nghttp().assets(url, options=["-Haccept-encoding: none"]) assert 0 == r.exit_code @@ -31,7 +31,7 @@ class TestStore: ] # gophertiles, yea! - def test_006_03(self, env): + def test_h2_006_03(self, env): # create the tiles files we originally had checked in exp_assets = [ {"status": 200, "size": "10K", "path": "/004.html"}, @@ -51,7 +51,7 @@ class TestStore: assert r.assets == exp_assets # page with js and css - def test_006_04(self, env): + def test_h2_006_04(self, env): url = env.mkurl("https", "test1", "/006.html") r = env.nghttp().assets(url, options=["-Haccept-encoding: none"]) assert 0 == r.exit_code @@ -63,7 +63,7 @@ class TestStore: ] # page with image, try different window size - def test_006_05(self, env): + def test_h2_006_05(self, env): url = env.mkurl("https", "test1", "/003.html") r = env.nghttp().assets(url, options=["--window-bits=24", "-Haccept-encoding: none"]) assert 0 == r.exit_code diff --git a/test/modules/http2/test_100_conn_reuse.py b/test/modules/http2/test_100_conn_reuse.py index cef2f9d07b..763288e396 100644 --- a/test/modules/http2/test_100_conn_reuse.py +++ b/test/modules/http2/test_100_conn_reuse.py @@ -1,17 +1,17 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_noh2().add_vhost_test1().add_vhost_cgi().install() + H2Conf(env).add_vhost_noh2().add_vhost_test1().add_vhost_cgi().install() assert env.apache_restart() == 0 # make sure the protocol selection on the different hosts work as expected - def test_100_01(self, env): + def test_h2_100_01(self, env): # this host defaults to h2, but we can request h1 url = env.mkurl("https", "cgi", "/hello.py") assert "2" == env.curl_protocol_version( url ) @@ -23,7 +23,7 @@ class TestStore: assert "1.1" == env.curl_protocol_version( url, options=[ "--http2" ] ) # access a ServerAlias, after using ServerName in SNI - def test_100_02(self, env): + def test_h2_100_02(self, env): url = env.mkurl("https", "cgi", "/hello.py") hostname = ("cgi-alias.%s" % env.http_tld) r = env.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) @@ -32,7 +32,7 @@ class TestStore: assert hostname == r.response["json"]["host"] # access another vhost, after using ServerName in SNI, that uses same SSL setup - def test_100_03(self, env): + def test_h2_100_03(self, env): url = env.mkurl("https", "cgi", "/") hostname = ("test1.%s" % env.http_tld) r = env.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) @@ -42,14 +42,14 @@ class TestStore: # access another vhost, after using ServerName in SNI, # that has different SSL certificate. This triggers a 421 (misdirected request) response. - def test_100_04(self, env): + def test_h2_100_04(self, env): url = env.mkurl("https", "cgi", "/hello.py") hostname = ("noh2.%s" % env.http_tld) r = env.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) assert 421 == r.response["status"] # access an unknown vhost, after using ServerName in SNI - def test_100_05(self, env): + def test_h2_100_05(self, env): url = env.mkurl("https", "cgi", "/hello.py") hostname = ("unknown.%s" % env.http_tld) r = env.curl_get(url, 5, [ "-H", "Host:%s" % hostname ]) diff --git a/test/modules/http2/test_101_ssl_reneg.py b/test/modules/http2/test_101_ssl_reneg.py index 22bfa50baa..de748292b0 100644 --- a/test/modules/http2/test_101_ssl_reneg.py +++ b/test/modules/http2/test_101_ssl_reneg.py @@ -1,14 +1,14 @@ import re import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add( + H2Conf(env).add( f""" SSLCipherSuite ECDHE-RSA-AES256-GCM-SHA384 <Directory \"{env.server_dir}/htdocs/ssl-client-verify\"> @@ -46,7 +46,7 @@ class TestStore: assert env.apache_restart() == 0 # access a resource with SSL renegotiation, using HTTP/1.1 - def test_101_01(self, env): + def test_h2_101_01(self, env): url = env.mkurl("https", "ssl", "/renegotiate/cipher/") r = env.curl_get(url, options=["-v", "--http1.1", "--tlsv1.2", "--tls-max", "1.2"]) assert 0 == r.exit_code @@ -54,7 +54,7 @@ class TestStore: assert 403 == r.response["status"] # try to renegotiate the cipher, should fail with correct code - def test_101_02(self, env): + def test_h2_101_02(self, env): url = env.mkurl("https", "ssl", "/renegotiate/cipher/") r = env.curl_get(url, options=[ "-vvv", "--tlsv1.2", "--tls-max", "1.2", "--ciphers", "ECDHE-RSA-AES256-GCM-SHA384" @@ -65,7 +65,7 @@ class TestStore: # try to renegotiate a client certificate from Location # needs to fail with correct code - def test_101_03(self, env): + def test_h2_101_03(self, env): url = env.mkurl("https", "ssl", "/renegotiate/verify/") r = env.curl_get(url, options=["-vvv", "--tlsv1.2", "--tls-max", "1.2"]) assert 0 != r.exit_code @@ -74,7 +74,7 @@ class TestStore: # try to renegotiate a client certificate from Directory # needs to fail with correct code - def test_101_04(self, env): + def test_h2_101_04(self, env): url = env.mkurl("https", "ssl", "/ssl-client-verify/index.html") r = env.curl_get(url, options=["-vvv", "--tlsv1.2", "--tls-max", "1.2"]) assert 0 != r.exit_code @@ -83,7 +83,7 @@ class TestStore: # make 10 requests on the same connection, none should produce a status code # reported by erki@example.ee - def test_101_05(self, env): + def test_h2_101_05(self, env): r = env.run([env.h2load, "-n", "10", "-c", "1", "-m", "1", "-vvvv", f"{env.https_base_url}/ssl-client-verify/index.html"]) assert 0 == r.exit_code @@ -99,7 +99,7 @@ class TestStore: # Check that "SSLRequireSSL" works on h2 connections # See <https://bz.apache.org/bugzilla/show_bug.cgi?id=62654> - def test_101_10a(self, env): + def test_h2_101_10a(self, env): url = env.mkurl("https", "ssl", "/sslrequire/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -108,7 +108,7 @@ class TestStore: # Check that "require ssl" works on h2 connections # See <https://bz.apache.org/bugzilla/show_bug.cgi?id=62654> - def test_101_10b(self, env): + def test_h2_101_10b(self, env): url = env.mkurl("https", "ssl", "/requiressl/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -116,7 +116,7 @@ class TestStore: assert 404 == r.response["status"] # Check that status works with ErrorDoc, see pull #174, fixes #172 - def test_101_11(self, env): + def test_h2_101_11(self, env): url = env.mkurl("https", "ssl", "/renegotiate/err-doc-cipher") r = env.curl_get(url, options=[ "-vvv", "--tlsv1.2", "--tls-max", "1.2", "--ciphers", "ECDHE-RSA-AES256-GCM-SHA384" diff --git a/test/modules/http2/test_102_require.py b/test/modules/http2/test_102_require.py index e8e2593c9c..9751136f59 100644 --- a/test/modules/http2/test_102_require.py +++ b/test/modules/http2/test_102_require.py @@ -1,13 +1,13 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - conf = HttpdConf(env).start_vhost(env.https_port, "ssl", with_ssl=True) + conf = H2Conf(env).start_vhost(env.https_port, "ssl", with_ssl=True) conf.add(""" Protocols h2 http/1.1 SSLOptions +StdEnvVars @@ -23,14 +23,14 @@ class TestStore: env.mkpath("%s/htdocs/ssl-client-verify" % env.server_dir) assert env.apache_restart() == 0 - def test_102_01(self, env): + def test_h2_102_01(self, env): url = env.mkurl("https", "ssl", "/h2only.html") r = env.curl_get(url) assert 0 == r.exit_code assert r.response assert 404 == r.response["status"] - def test_102_02(self, env): + def test_h2_102_02(self, env): url = env.mkurl("https", "ssl", "/noh2.html") r = env.curl_get(url) assert 0 == r.exit_code diff --git a/test/modules/http2/test_103_upgrade.py b/test/modules/http2/test_103_upgrade.py index 28ed7370d2..8dfe4a1d21 100644 --- a/test/modules/http2/test_103_upgrade.py +++ b/test/modules/http2/test_103_upgrade.py @@ -1,13 +1,13 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_test1().add_vhost_test2().add_vhost_noh2( + H2Conf(env).add_vhost_test1().add_vhost_test2().add_vhost_noh2( ).start_vhost( env.https_port, "test3", doc_root="htdocs/test1", with_ssl=True ).add( @@ -29,7 +29,7 @@ class TestStore: assert env.apache_restart() == 0 # accessing http://test1, will not try h2 and advertise h2 in the response - def test_103_01(self, env): + def test_h2_103_01(self, env): url = env.mkurl("http", "test1", "/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -38,7 +38,7 @@ class TestStore: 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, env): + def test_h2_103_02(self, env): url = env.mkurl("http", "noh2", "/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -46,7 +46,7 @@ class TestStore: assert "upgrade" not in r.response["header"] # accessing http://test2, will not advertise, because h2 has less preference than http/1.1 - def test_103_03(self, env): + def test_h2_103_03(self, env): url = env.mkurl("http", "test2", "/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -54,7 +54,7 @@ class TestStore: assert "upgrade" not in r.response["header"] # accessing https://noh2, will not advertise, because noh2 host does not have it enabled - def test_103_04(self, env): + def test_h2_103_04(self, env): url = env.mkurl("https", "noh2", "/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -62,7 +62,7 @@ class TestStore: assert "upgrade" not in r.response["header"] # accessing https://test2, will not advertise, because h2 has less preference than http/1.1 - def test_103_05(self, env): + def test_h2_103_05(self, env): url = env.mkurl("https", "test2", "/index.html") r = env.curl_get(url) assert 0 == r.exit_code @@ -70,7 +70,7 @@ class TestStore: assert "upgrade" not in r.response["header"] # accessing https://test1, will advertise h2 in the response - def test_103_06(self, env): + def test_h2_103_06(self, env): url = env.mkurl("https", "test1", "/index.html") r = env.curl_get(url, options=["--http1.1"]) assert 0 == r.exit_code @@ -79,7 +79,7 @@ class TestStore: assert "h2" == r.response["header"]["upgrade"] # accessing https://test3, will not send Upgrade since it is suppressed - def test_103_07(self, env): + def test_h2_103_07(self, env): url = env.mkurl("https", "test3", "/index.html") r = env.curl_get(url, options=["--http1.1"]) assert 0 == r.exit_code @@ -87,33 +87,33 @@ class TestStore: assert "upgrade" not in r.response["header"] # upgrade to h2c for a request, where h2c is preferred - def test_103_20(self, env): + def test_h2_103_20(self, env): url = env.mkurl("http", "test1", "/index.html") r = env.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 - def test_103_21(self, env): + def test_h2_103_21(self, env): url = env.mkurl("http", "test2", "/index.html") r = env.nghttp().get(url, options=["-u"]) assert 404 == r.response["status"] # ugrade to h2c on a host where h2c is not enabled will fail - def test_103_22(self, env): + def test_h2_103_22(self, env): url = env.mkurl("http", "noh2", "/index.html") r = env.nghttp().get(url, options=["-u"]) assert not r.response # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled - def test_103_23(self, env): + def test_h2_103_23(self, env): url = env.mkurl("http", "test1b", "/index.html") r = env.nghttp().get(url, options=["-u"]) assert not r.response # ugrade to h2c on a host where h2c is preferred, but Upgrade is disabled on the server, # but allowed for a specific location - def test_103_24(self, env): + def test_h2_103_24(self, env): url = env.mkurl("http", "test1b", "/006.html") r = env.nghttp().get(url, options=["-u"]) assert 200 == r.response["status"] diff --git a/test/modules/http2/test_104_padding.py b/test/modules/http2/test_104_padding.py index f5a481207d..976935e8e8 100644 --- a/test/modules/http2/test_104_padding.py +++ b/test/modules/http2/test_104_padding.py @@ -1,6 +1,6 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf def frame_padding(payload, padbits): @@ -12,8 +12,11 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - conf = HttpdConf(env) - conf.add_vhost_cgi() + conf = H2Conf(env) + conf.start_vhost(env.https_port, "ssl", doc_root="htdocs/cgi", with_ssl=True) + conf.add("Protocols h2 http/1.1") + conf.add("AddHandler cgi-script .py") + conf.end_vhost() conf.start_vhost(env.https_port, "pad0", doc_root="htdocs/cgi", with_ssl=True) conf.add("Protocols h2 http/1.1") conf.add("H2Padding 0") @@ -43,8 +46,8 @@ class TestStore: assert env.apache_restart() == 0 # default paddings settings: 0 bits - def test_104_01(self, env): - url = env.mkurl("https", "cgi", "/echo.py") + def test_h2_104_01(self, env): + url = env.mkurl("https", "ssl", "/echo.py") # we get 2 frames back: one with data and an empty one with EOF # check the number of padding bytes is as expected for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: @@ -56,7 +59,7 @@ class TestStore: ] # 0 bits of padding - def test_104_02(self, env): + def test_h2_104_02(self, env): url = env.mkurl("https", "pad0", "/echo.py") for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: r = env.nghttp().post_data(url, data, 5) @@ -64,7 +67,7 @@ class TestStore: assert r.results["paddings"] == [0, 0] # 1 bit of padding - def test_104_03(self, env): + def test_h2_104_03(self, env): url = env.mkurl("https", "pad1", "/echo.py") for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: r = env.nghttp().post_data(url, data, 5) @@ -73,7 +76,7 @@ class TestStore: assert i in range(0, 2) # 2 bits of padding - def test_104_04(self, env): + def test_h2_104_04(self, env): url = env.mkurl("https", "pad2", "/echo.py") for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: r = env.nghttp().post_data(url, data, 5) @@ -82,7 +85,7 @@ class TestStore: assert i in range(0, 4) # 3 bits of padding - def test_104_05(self, env): + def test_h2_104_05(self, env): url = env.mkurl("https", "pad3", "/echo.py") for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: r = env.nghttp().post_data(url, data, 5) @@ -91,7 +94,7 @@ class TestStore: assert i in range(0, 8) # 8 bits of padding - def test_104_06(self, env): + def test_h2_104_06(self, env): url = env.mkurl("https", "pad8", "/echo.py") for data in ["x", "xx", "xxx", "xxxx", "xxxxx", "xxxxxx", "xxxxxxx", "xxxxxxxx"]: r = env.nghttp().post_data(url, data, 5) diff --git a/test/modules/http2/test_105_timeout.py b/test/modules/http2/test_105_timeout.py index 88a609376b..d8e7036310 100644 --- a/test/modules/http2/test_105_timeout.py +++ b/test/modules/http2/test_105_timeout.py @@ -3,15 +3,15 @@ import time import pytest -from h2_conf import HttpdConf -from h2_curl import CurlPiper +from .env import H2Conf +from pyhttpd.curl import CurlPiper class TestStore: # Check that base servers 'Timeout' setting is observed on SSL handshake - def test_105_01(self, env): - conf = HttpdConf(env) + def test_h2_105_01(self, env): + conf = H2Conf(env) conf.add(""" AcceptFilter http none Timeout 1.5 @@ -44,8 +44,8 @@ class TestStore: sock.close() # Check that mod_reqtimeout handshake setting takes effect - def test_105_02(self, env): - conf = HttpdConf(env) + def test_h2_105_02(self, env): + conf = H2Conf(env) conf.add(""" AcceptFilter http none Timeout 10 @@ -80,8 +80,8 @@ class TestStore: # Check that mod_reqtimeout handshake setting do no longer apply to handshaked # connections. See <https://github.com/icing/mod_h2/issues/196>. - def test_105_03(self, env): - conf = HttpdConf(env) + def test_h2_105_03(self, env): + conf = H2Conf(env) conf.add(""" Timeout 10 RequestReadTimeout handshake=1 header=5 body=10 @@ -98,9 +98,9 @@ class TestStore: ]) assert 200 == r.response["status"] - def test_105_10(self, env): + def test_h2_105_10(self, env): # just a check without delays if all is fine - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi() conf.install() assert env.apache_restart() == 0 @@ -112,10 +112,10 @@ class TestStore: assert len("".join(stdout)) == 3 * 8192 @pytest.mark.skipif(True, reason="new feature in upcoming http2") - def test_105_11(self, env): + def test_h2_105_11(self, env): # short connection timeout, longer stream delay # receiving the first response chunk, then timeout - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi() conf.add("Timeout 1") conf.install() @@ -127,10 +127,10 @@ class TestStore: assert len("".join(stdout)) == 8192 @pytest.mark.skipif(True, reason="new feature in upcoming http2") - def test_105_12(self, env): + def test_h2_105_12(self, env): # long connection timeout, short stream timeout # sending a slow POST - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi() conf.add("Timeout 10") conf.add("H2StreamTimeout 1") diff --git a/test/modules/http2/test_106_shutdown.py b/test/modules/http2/test_106_shutdown.py index 37471d26ca..9f88b5caee 100644 --- a/test/modules/http2/test_106_shutdown.py +++ b/test/modules/http2/test_106_shutdown.py @@ -7,20 +7,20 @@ from threading import Thread import pytest -from h2_conf import HttpdConf -from h2_result import ExecResult +from .env import H2Conf +from pyhttpd.result import ExecResult class TestShutdown: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi() conf.install() assert env.apache_restart() == 0 - def test_106_01(self, env): + def test_h2_106_01(self, env): url = env.mkurl("https", "cgi", "/necho.py") lines = 100000 text = "123456789" diff --git a/test/modules/http2/test_200_header_invalid.py b/test/modules/http2/test_200_header_invalid.py index f0fe377272..fbaa111739 100644 --- a/test/modules/http2/test_200_header_invalid.py +++ b/test/modules/http2/test_200_header_invalid.py @@ -1,19 +1,19 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_cgi().install() + H2Conf(env).add_vhost_cgi().install() assert env.apache_restart() == 0 # let the hecho.py CGI echo chars < 0x20 in field name # for almost all such characters, the stream gets aborted with a h2 error and # there will be no http status, cr and lf are handled special - def test_200_01(self, env): + def test_h2_200_01(self, env): url = env.mkurl("https", "cgi", "/hecho.py") for x in range(1, 32): r = env.curl_post_data(url, "name=x%%%02xx&value=yz" % x) @@ -29,7 +29,7 @@ class TestStore: # let the hecho.py CGI echo chars < 0x20 in field value # for almost all such characters, the stream gets aborted with a h2 error and # there will be no http status, cr and lf are handled special - def test_200_02(self, env): + def test_h2_200_02(self, env): url = env.mkurl("https", "cgi", "/hecho.py") for x in range(1, 32): if 9 != x: @@ -41,7 +41,7 @@ class TestStore: assert 0 != r.exit_code, "unexpected exit code for char 0x%02x" % x # let the hecho.py CGI echo 0x10 and 0x7f in field name and value - def test_200_03(self, env): + def test_h2_200_03(self, env): url = env.mkurl("https", "cgi", "/hecho.py") for h in ["10", "7f"]: r = env.curl_post_data(url, "name=x%%%s&value=yz" % h) @@ -50,7 +50,7 @@ class TestStore: assert 0 != r.exit_code # test header field lengths check, LimitRequestLine (default 8190) - def test_200_10(self, env): + def test_h2_200_10(self, env): url = env.mkurl("https", "cgi", "/") val = "1234567890" # 10 chars for i in range(3): # make a 10000 char string @@ -67,7 +67,7 @@ class TestStore: assert 431 == r.response["status"] # test header field lengths check, LimitRequestFieldSize (default 8190) - def test_200_11(self, env): + def test_h2_200_11(self, env): url = env.mkurl("https", "cgi", "/") val = "1234567890" # 10 chars for i in range(3): # make a 10000 char string @@ -83,7 +83,7 @@ class TestStore: # test header field count, LimitRequestFields (default 100) # see #201: several headers with same name are mered and count only once - def test_200_12(self, env): + def test_h2_200_12(self, env): url = env.mkurl("https", "cgi", "/") opt = [] for i in range(98): # curl sends 2 headers itself (user-agent and accept) @@ -95,7 +95,7 @@ class TestStore: # test header field count, LimitRequestFields (default 100) # different header names count each - def test_200_13(self, env): + def test_h2_200_13(self, env): url = env.mkurl("https", "cgi", "/") opt = [] for i in range(98): # curl sends 2 headers itself (user-agent and accept) @@ -106,8 +106,8 @@ class TestStore: assert 431 == r.response["status"] # test "LimitRequestFields 0" setting, see #200 - def test_200_14(self, env): - conf = HttpdConf(env) + def test_h2_200_14(self, env): + conf = H2Conf(env) conf.add(""" LimitRequestFields 20 """) @@ -120,7 +120,7 @@ class TestStore: opt += ["-H", "x{0}: 1".format(i)] r = env.curl_get(url, options=opt) assert 431 == r.response["status"] - conf = HttpdConf(env) + conf = H2Conf(env) conf.add(""" LimitRequestFields 0 """) @@ -135,8 +135,8 @@ class TestStore: assert 200 == r.response["status"] # the uri limits - def test_200_15(self, env): - conf = HttpdConf(env) + def test_h2_200_15(self, env): + conf = H2Conf(env) conf.add(""" LimitRequestLine 48 """) @@ -159,8 +159,8 @@ class TestStore: assert not r.response # invalid chars in method - def test_200_16(self, env): - conf = HttpdConf(env) + def test_h2_200_16(self, env): + conf = H2Conf(env) conf.add_vhost_cgi() conf.install() assert env.apache_restart() == 0 diff --git a/test/modules/http2/test_201_header_conditional.py b/test/modules/http2/test_201_header_conditional.py index 85047422cb..755e70e9ee 100644 --- a/test/modules/http2/test_201_header_conditional.py +++ b/test/modules/http2/test_201_header_conditional.py @@ -1,13 +1,13 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add( + H2Conf(env).add( """ KeepAlive on MaxKeepAliveRequests 30 @@ -16,7 +16,7 @@ class TestStore: assert env.apache_restart() == 0 # check handling of 'if-modified-since' header - def test_201_01(self, env): + def test_h2_201_01(self, env): url = env.mkurl("https", "test1", "/006/006.css") r = env.curl_get(url) assert 200 == r.response["status"] @@ -28,7 +28,7 @@ class TestStore: assert 200 == r.response["status"] # check handling of 'if-none-match' header - def test_201_02(self, env): + def test_h2_201_02(self, env): url = env.mkurl("https", "test1", "/006/006.css") r = env.curl_get(url) assert 200 == r.response["status"] @@ -40,7 +40,7 @@ class TestStore: assert 200 == r.response["status"] @pytest.mark.skipif(True, reason="304 misses the Vary header in trunk and 2.4.x") - def test_201_03(self, env): + def test_h2_201_03(self, env): url = env.mkurl("https", "test1", "/006.html") r = env.curl_get(url, options=["-H", "Accept-Encoding: gzip"]) assert 200 == r.response["status"] @@ -59,7 +59,7 @@ class TestStore: assert "vary" in r.response["header"] # Check if "Keep-Alive" response header is removed in HTTP/2. - def test_201_04(self, env): + def test_h2_201_04(self, env): url = env.mkurl("https", "test1", "/006.html") r = env.curl_get(url, options=["--http1.1", "-H", "Connection: keep-alive"]) assert 200 == r.response["status"] diff --git a/test/modules/http2/test_202_trailer.py b/test/modules/http2/test_202_trailer.py index f43aa85080..c9081e00d4 100644 --- a/test/modules/http2/test_202_trailer.py +++ b/test/modules/http2/test_202_trailer.py @@ -1,7 +1,7 @@ import os import pytest -from h2_conf import HttpdConf +from .env import H2Conf def setup_data(env): @@ -18,11 +18,11 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): setup_data(env) - HttpdConf(env).add_vhost_cgi(h2proxy_self=True).install() + H2Conf(env).add_vhost_cgi(h2proxy_self=True).install() assert env.apache_restart() == 0 # check if the server survives a trailer or two - def test_202_01(self, env): + def test_h2_202_01(self, env): url = env.mkurl("https", "cgi", "/echo.py") fpath = os.path.join(env.gen_dir, "data-1k") r = env.nghttp().upload(url, fpath, options=["--trailer", "test: 1"]) @@ -34,7 +34,7 @@ class TestStore: assert 1000 == len(r.response["body"]) # check if the server survives a trailer without content-length - def test_202_02(self, env): + def test_h2_202_02(self, env): url = env.mkurl("https", "cgi", "/echo.py") fpath = os.path.join(env.gen_dir, "data-1k") r = env.nghttp().upload(url, fpath, options=["--trailer", "test: 2", "--no-content-length"]) @@ -42,14 +42,14 @@ class TestStore: assert 1000 == len(r.response["body"]) # check if echoing request headers in response from GET works - def test_202_03(self, env): + def test_h2_202_03(self, env): url = env.mkurl("https", "cgi", "/echohd.py?name=X") r = env.nghttp().get(url, options=["--header", "X: 3"]) assert 300 > r.response["status"] assert b"X: 3\n" == r.response["body"] # check if echoing request headers in response from POST works - def test_202_03b(self, env): + def test_h2_202_03b(self, env): url = env.mkurl("https", "cgi", "/echohd.py?name=X") r = env.nghttp().post_name(url, "Y", options=["--header", "X: 3b"]) assert 300 > r.response["status"] @@ -57,7 +57,7 @@ class TestStore: # check if echoing request headers in response from POST works, but trailers are not seen # This is the way CGI invocation works. - def test_202_04(self, env): + def test_h2_202_04(self, env): url = env.mkurl("https", "cgi", "/echohd.py?name=X") r = env.nghttp().post_name(url, "Y", options=["--header", "X: 4a", "--trailer", "X: 4b"]) assert 300 > r.response["status"] diff --git a/test/modules/http2/test_300_interim.py b/test/modules/http2/test_300_interim.py index b0c591d6f0..b3b38835ba 100644 --- a/test/modules/http2/test_300_interim.py +++ b/test/modules/http2/test_300_interim.py @@ -1,13 +1,13 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_test1().add_vhost_cgi().install() + H2Conf(env).add_vhost_test1().add_vhost_cgi().install() assert env.apache_restart() == 0 def setup_method(self, method): @@ -17,14 +17,14 @@ class TestStore: print("teardown_method: %s" % method.__name__) # check that we normally do not see an interim response - def test_300_01(self, env): + def test_h2_300_01(self, env): url = env.mkurl("https", "test1", "/index.html") r = env.curl_post_data(url, 'XYZ') assert 200 == r.response["status"] assert "previous" not in r.response # check that we see an interim response when we ask for it - def test_300_02(self, env): + def test_h2_300_02(self, env): url = env.mkurl("https", "cgi", "/echo.py") r = env.curl_post_data(url, 'XYZ', options=["-H", "expect: 100-continue"]) assert 200 == r.response["status"] @@ -32,7 +32,7 @@ class TestStore: assert 100 == r.response["previous"]["status"] # check proper answer on unexpected - def test_300_03(self, env): + def test_h2_300_03(self, env): url = env.mkurl("https", "cgi", "/echo.py") r = env.curl_post_data(url, 'XYZ', options=["-H", "expect: the-unexpected"]) assert 417 == r.response["status"] diff --git a/test/modules/http2/test_400_push.py b/test/modules/http2/test_400_push.py index 9e2e853971..564c87ddc3 100644 --- a/test/modules/http2/test_400_push.py +++ b/test/modules/http2/test_400_push.py @@ -1,7 +1,7 @@ import os import pytest -from h2_conf import HttpdConf +from .env import H2Conf # The push tests depend on "nghttp" @@ -9,7 +9,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).start_vhost( + H2Conf(env).start_vhost( env.https_port, "push", doc_root="htdocs/test1", with_ssl=True ).add(r""" Protocols h2 http/1.1" RewriteEngine on @@ -61,7 +61,7 @@ class TestStore: # Link: header handling, various combinations # plain resource without configured pushes - def test_400_00(self, env): + def test_h2_400_00(self, env): url = env.mkurl("https", "push", "/006.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -69,7 +69,7 @@ class TestStore: assert 0 == len(promises) # 2 link headers configured, only 1 triggers push - def test_400_01(self, env): + def test_h2_400_01(self, env): url = env.mkurl("https", "push", "/006-push.html") r = env.nghttp().get(url, options=["-Haccept-encoding: none"]) assert 200 == r.response["status"] @@ -79,7 +79,7 @@ class TestStore: assert 216 == len(promises[0]["response"]["body"]) # Same as 400_01, but with single header line configured - def test_400_02(self, env): + def test_h2_400_02(self, env): url = env.mkurl("https", "push", "/006-push2.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -88,7 +88,7 @@ class TestStore: assert '/006/006.js' == promises[0]["request"]["header"][":path"] # 2 Links, only one with correct rel attribue - def test_400_03(self, env): + def test_h2_400_03(self, env): url = env.mkurl("https", "push", "/006-push3.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -97,7 +97,7 @@ class TestStore: assert '/006/006.js' == promises[0]["request"]["header"][":path"] # Missing > in Link header, PUSH not triggered - def test_400_04(self, env): + def test_h2_400_04(self, env): url = env.mkurl("https", "push", "/006-push4.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -105,7 +105,7 @@ class TestStore: assert 0 == len(promises) # More than one value in "rel" parameter - def test_400_05(self, env): + def test_h2_400_05(self, env): url = env.mkurl("https", "push", "/006-push5.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -114,7 +114,7 @@ class TestStore: assert '/006/006.css' == promises[0]["request"]["header"][":path"] # Another "rel" parameter variation - def test_400_06(self, env): + def test_h2_400_06(self, env): url = env.mkurl("https", "push", "/006-push6.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -123,7 +123,7 @@ class TestStore: assert '/006/006.css' == promises[0]["request"]["header"][":path"] # Another "rel" parameter variation - def test_400_07(self, env): + def test_h2_400_07(self, env): url = env.mkurl("https", "push", "/006-push7.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -132,7 +132,7 @@ class TestStore: assert '/006/006.css' == promises[0]["request"]["header"][":path"] # Pushable link header with "nopush" attribute - def test_400_08(self, env): + def test_h2_400_08(self, env): url = env.mkurl("https", "push", "/006-push8.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -140,7 +140,7 @@ class TestStore: assert 0 == len(promises) # 2 H2PushResource config trigger on GET, but not on POST - def test_400_20(self, env): + def test_h2_400_20(self, env): url = env.mkurl("https", "push", "/006-push20.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -156,7 +156,7 @@ class TestStore: assert 0 == len(promises) # H2Push configured Off in location - def test_400_30(self, env): + def test_h2_400_30(self, env): url = env.mkurl("https", "push", "/006-push30.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -164,7 +164,7 @@ class TestStore: assert 0 == len(promises) # - suppress PUSH - def test_400_50(self, env): + def test_h2_400_50(self, env): url = env.mkurl("https", "push", "/006-push.html") r = env.nghttp().get(url, options=['-H', 'accept-push-policy: none']) assert 200 == r.response["status"] @@ -172,7 +172,7 @@ class TestStore: assert 0 == len(promises) # - default pushes desired - def test_400_51(self, env): + def test_h2_400_51(self, env): url = env.mkurl("https", "push", "/006-push.html") r = env.nghttp().get(url, options=['-H', 'accept-push-policy: default']) assert 200 == r.response["status"] @@ -180,7 +180,7 @@ class TestStore: assert 1 == len(promises) # - HEAD pushes desired - def test_400_52(self, env): + def test_h2_400_52(self, env): url = env.mkurl("https", "push", "/006-push.html") r = env.nghttp().get(url, options=['-H', 'accept-push-policy: head']) assert 200 == r.response["status"] @@ -191,7 +191,7 @@ class TestStore: assert 0 == len(promises[0]["response"]["body"]) # - fast-load pushes desired - def test_400_53(self, env): + def test_h2_400_53(self, env): url = env.mkurl("https", "push", "/006-push.html") r = env.nghttp().get(url, options=['-H', 'accept-push-policy: fast-load']) assert 200 == r.response["status"] diff --git a/test/modules/http2/test_401_early_hints.py b/test/modules/http2/test_401_early_hints.py index 1e7a028a82..984a460c72 100644 --- a/test/modules/http2/test_401_early_hints.py +++ b/test/modules/http2/test_401_early_hints.py @@ -1,6 +1,6 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf # The push tests depend on "nghttp" @@ -8,7 +8,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).start_vhost( + H2Conf(env).start_vhost( env.https_port, "hints", doc_root="htdocs/test1", with_ssl=True ).add(""" Protocols h2 http/1.1" H2EarlyHints on @@ -25,7 +25,7 @@ class TestStore: assert env.apache_restart() == 0 # H2EarlyHints enabled in general, check that it works for H2PushResource - def test_401_31(self, env): + def test_h2_401_31(self, env): url = env.mkurl("https", "hints", "/006-hints.html") r = env.nghttp().get(url) assert 200 == r.response["status"] @@ -37,7 +37,7 @@ class TestStore: assert early["header"]["link"] # H2EarlyHints enabled in general, but does not trigger on added response headers - def test_401_32(self, env): + def test_h2_401_32(self, env): url = env.mkurl("https", "hints", "/006-nohints.html") r = env.nghttp().get(url) assert 200 == r.response["status"] diff --git a/test/modules/http2/test_500_proxy.py b/test/modules/http2/test_500_proxy.py index 00d9b7f21e..32c9b01438 100644 --- a/test/modules/http2/test_500_proxy.py +++ b/test/modules/http2/test_500_proxy.py @@ -2,7 +2,7 @@ import os import re import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @@ -10,7 +10,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - HttpdConf(env).add_vhost_cgi(proxy_self=True).install() + H2Conf(env).add_vhost_cgi(proxy_self=True).install() assert env.apache_restart() == 0 def setup_method(self, method): @@ -19,7 +19,7 @@ class TestStore: def teardown_method(self, method): print("teardown_method: %s" % method.__name__) - def test_500_01(self, env): + def test_h2_500_01(self, env): url = env.mkurl("https", "cgi", "/proxy/hello.py") r = env.curl_get(url, 5) assert 200 == r.response["status"] @@ -41,11 +41,11 @@ class TestStore: r2 = env.curl_get(re.sub(r'http:', 'https:', r.response["header"]["location"])) assert r2.exit_code == 0 assert r2.response["status"] == 200 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r2.response["body"] - def test_500_10(self, env): + def test_h2_500_10(self, env): self.curl_upload_and_verify(env, "data-1k", ["--http2"]) self.curl_upload_and_verify(env, "data-10k", ["--http2"]) self.curl_upload_and_verify(env, "data-100k", ["--http2"]) @@ -58,17 +58,17 @@ class TestStore: r = env.nghttp().upload(url, fpath, options=options) assert r.exit_code == 0 assert 200 <= r.response["status"] < 300 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r.response["body"] - def test_500_20(self, env): + def test_h2_500_20(self, env): self.nghttp_post_and_verify(env, "data-1k", []) self.nghttp_post_and_verify(env, "data-10k", []) self.nghttp_post_and_verify(env, "data-100k", []) self.nghttp_post_and_verify(env, "data-1m", []) - def test_500_21(self, env): + def test_h2_500_21(self, env): self.nghttp_post_and_verify(env, "data-1k", ["--no-content-length"]) self.nghttp_post_and_verify(env, "data-10k", ["--no-content-length"]) self.nghttp_post_and_verify(env, "data-100k", ["--no-content-length"]) @@ -88,17 +88,17 @@ class TestStore: r2 = env.nghttp().get(re.sub(r'http:', 'https:', r.response["header"]["location"])) assert r2.exit_code == 0 assert r2.response["status"] == 200 - with open(env.test_src(fpath), mode='rb') as file: + with open(env.local_src(fpath), mode='rb') as file: src = file.read() assert src == r2.response["body"] - def test_500_22(self, env): + def test_h2_500_22(self, env): self.nghttp_upload_and_verify(env, "data-1k", []) self.nghttp_upload_and_verify(env, "data-10k", []) self.nghttp_upload_and_verify(env, "data-100k", []) self.nghttp_upload_and_verify(env, "data-1m", []) - def test_500_23(self, env): + def test_h2_500_23(self, env): self.nghttp_upload_and_verify(env, "data-1k", ["--no-content-length"]) self.nghttp_upload_and_verify(env, "data-10k", ["--no-content-length"]) self.nghttp_upload_and_verify(env, "data-100k", ["--no-content-length"]) @@ -114,6 +114,6 @@ class TestStore: assert 200 <= r.response["status"] < 300 assert r.response["header"]["location"] - def test_500_24(self, env): + def test_h2_500_24(self, env): for i in range(100): self.nghttp_upload_stat(env, "data-1k", ["--no-content-length"]) diff --git a/test/modules/http2/test_600_h2proxy.py b/test/modules/http2/test_600_h2proxy.py index be56d04e31..1741858025 100644 --- a/test/modules/http2/test_600_h2proxy.py +++ b/test/modules/http2/test_600_h2proxy.py @@ -1,6 +1,6 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @@ -8,14 +8,14 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi(h2proxy_self=True) if env.verbosity > 1: conf.add("LogLevel proxy:trace2 proxy_http2:trace2") conf.install() assert env.apache_restart() == 0 - def test_600_01(self, env): + def test_h2_600_01(self, env): url = env.mkurl("https", "cgi", "/h2proxy/hello.py") r = env.curl_get(url, 5) assert r.response["status"] == 200 diff --git a/test/modules/http2/test_700_load_get.py b/test/modules/http2/test_700_load_get.py index 3773bf6764..e3127d58b9 100644 --- a/test/modules/http2/test_700_load_get.py +++ b/test/modules/http2/test_700_load_get.py @@ -1,13 +1,13 @@ import pytest -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): - HttpdConf(env).add_vhost_cgi().add_vhost_test1().install() + H2Conf(env).add_vhost_cgi().add_vhost_test1().install() assert env.apache_restart() == 0 def check_h2load_ok(self, env, r, n): @@ -26,7 +26,7 @@ class TestStore: @pytest.mark.parametrize("start", [ 1000, 80000 ]) - def test_700_10(self, env, start): + def test_h2_700_10(self, env, start): text = "X" chunk = 32 for n in range(0, 5): @@ -41,7 +41,7 @@ class TestStore: @pytest.mark.parametrize("conns", [ 1, 2, 16, 32 ]) - def test_700_11(self, env, conns): + def test_h2_700_11(self, env, conns): text = "X" start = 1200 chunk = 64 diff --git a/test/modules/http2/test_710_load_post_static.py b/test/modules/http2/test_710_load_post_static.py index 2b85b0f5eb..aa7081cf64 100644 --- a/test/modules/http2/test_710_load_post_static.py +++ b/test/modules/http2/test_710_load_post_static.py @@ -1,7 +1,7 @@ import pytest import os -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @@ -9,7 +9,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - HttpdConf(env).add_vhost_test1().install() + H2Conf(env).add_vhost_test1().install() assert env.apache_restart() == 0 def check_h2load_ok(self, env, r, n): @@ -25,7 +25,7 @@ class TestStore: assert 0 == r.results["h2load"]["status"]["5xx"] # test POST on static file, slurped in by server - def test_710_00(self, env): + def test_h2_710_00(self, env): url = env.mkurl("https", "test1", "/index.html") n = 10 m = 1 @@ -37,7 +37,7 @@ class TestStore: r = env.run(args) self.check_h2load_ok(env, r, n) - def test_710_01(self, env): + def test_h2_710_01(self, env): url = env.mkurl("https", "test1", "/index.html") n = 1000 m = 100 @@ -49,7 +49,7 @@ class TestStore: r = env.run(args) self.check_h2load_ok(env, r, n) - def test_710_02(self, env): + def test_h2_710_02(self, env): url = env.mkurl("https", "test1", "/index.html") n = 100 m = 50 diff --git a/test/modules/http2/test_711_load_post_cgi.py b/test/modules/http2/test_711_load_post_cgi.py index 187abea30d..94cfec3d9d 100644 --- a/test/modules/http2/test_711_load_post_cgi.py +++ b/test/modules/http2/test_711_load_post_cgi.py @@ -1,7 +1,7 @@ import pytest import os -from h2_conf import HttpdConf +from .env import H2Conf class TestStore: @@ -9,7 +9,7 @@ class TestStore: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - HttpdConf(env).add_vhost_cgi(proxy_self=True, h2proxy_self=True).install() + H2Conf(env).add_vhost_cgi(proxy_self=True, h2proxy_self=True).install() assert env.apache_restart() == 0 def check_h2load_ok(self, env, r, n): @@ -25,7 +25,7 @@ class TestStore: assert 0 == r.results["h2load"]["status"]["5xx"] # test POST on cgi, where input is read - def test_711_10(self, env): + def test_h2_711_10(self, env): url = env.mkurl("https", "test1", "/echo.py") n = 100 m = 5 @@ -40,7 +40,7 @@ class TestStore: self.check_h2load_ok(env, r, n) # test POST on cgi via http/1.1 proxy, where input is read - def test_711_11(self, env): + def test_h2_711_11(self, env): url = env.mkurl("https", "test1", "/proxy/echo.py") n = 100 m = 5 @@ -55,7 +55,7 @@ class TestStore: self.check_h2load_ok(env, r, n) # test POST on cgi via h2proxy, where input is read - def test_711_12(self, env): + def test_h2_711_12(self, env): url = env.mkurl("https", "test1", "/h2proxy/echo.py") n = 100 m = 5 diff --git a/test/modules/http2/test_712_buffering.py b/test/modules/http2/test_712_buffering.py index ebf43239b5..12a06c8bb8 100644 --- a/test/modules/http2/test_712_buffering.py +++ b/test/modules/http2/test_712_buffering.py @@ -2,8 +2,8 @@ from datetime import timedelta import pytest -from h2_conf import HttpdConf -from h2_curl import CurlPiper +from .env import H2Conf +from pyhttpd.curl import CurlPiper class TestBuffering: @@ -11,12 +11,12 @@ class TestBuffering: @pytest.fixture(autouse=True, scope='class') def _class_scope(self, env): env.setup_data_1k_1m() - conf = HttpdConf(env) + conf = H2Conf(env) conf.add_vhost_cgi(h2proxy_self=True).install() assert env.apache_restart() == 0 @pytest.mark.skip(reason="this test shows unreliable jitter") - def test_712_01(self, env): + def test_h2_712_01(self, env): # test gRPC like requests that do not end, but give answers, see #207 # # this test works like this: @@ -38,7 +38,7 @@ class TestBuffering: piper.stutter_check(chunks, stutter) @pytest.mark.skipif(True, reason="new feature in upcoming http2") - def test_712_02(self, env): + def test_h2_712_02(self, env): # same as 712_01 but via mod_proxy_http2 # url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo") @@ -49,7 +49,7 @@ class TestBuffering: piper.stutter_check(chunks, stutter) @pytest.mark.skipif(True, reason="new feature in upcoming http2") - def test_712_03(self, env): + def test_h2_712_03(self, env): # same as 712_02 but with smaller chunks # url = env.mkurl("https", "cgi", "/h2proxy/h2test/echo") diff --git a/test/modules/http2/htdocs/test1/apache.org-files/cse.js b/test/pyhttpd/__init__.py index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/cse.js +++ b/test/pyhttpd/__init__.py diff --git a/test/modules/http2/h2_certs.py b/test/pyhttpd/certs.py index 82c6b5020a..2ce93c07b2 100644 --- a/test/modules/http2/h2_certs.py +++ b/test/pyhttpd/certs.py @@ -148,8 +148,8 @@ class Credentials: creds = self._store.load_credentials(name=spec.name, key_type=key_type, single_file=spec.single_file) \ if self._store else None if creds is None: - creds = H2TestCA.create_credentials(spec=spec, issuer=self, key_type=key_type, - valid_from=spec.valid_from, valid_to=spec.valid_to) + creds = HttpdTestCA.create_credentials(spec=spec, issuer=self, key_type=key_type, + valid_from=spec.valid_from, valid_to=spec.valid_to) if self._store: self._store.save(creds, single_file=spec.single_file) @@ -234,14 +234,14 @@ class CertStore: return None -class H2TestCA: +class HttpdTestCA: @classmethod def create_root(cls, name: str, store_dir: str, key_type: str = "rsa2048") -> Credentials: store = CertStore(fpath=store_dir) creds = store.load_credentials(name="ca", key_type=key_type) if creds is None: - creds = H2TestCA._make_ca_credentials(name=name, key_type=key_type) + creds = HttpdTestCA._make_ca_credentials(name=name, key_type=key_type) store.save(creds, name="ca") creds.set_store(store) return creds @@ -255,17 +255,17 @@ class H2TestCA: :returns: the certificate and private key PEM file paths """ if spec.domains and len(spec.domains): - creds = H2TestCA._make_server_credentials(name=spec.name, domains=spec.domains, - issuer=issuer, valid_from=valid_from, - valid_to=valid_to, key_type=key_type) + creds = HttpdTestCA._make_server_credentials(name=spec.name, domains=spec.domains, + issuer=issuer, valid_from=valid_from, + valid_to=valid_to, key_type=key_type) elif spec.client: - creds = H2TestCA._make_client_credentials(name=spec.name, issuer=issuer, - email=spec.email, valid_from=valid_from, - valid_to=valid_to, key_type=key_type) + creds = HttpdTestCA._make_client_credentials(name=spec.name, issuer=issuer, + email=spec.email, valid_from=valid_from, + valid_to=valid_to, key_type=key_type) elif spec.name: - creds = H2TestCA._make_ca_credentials(name=spec.name, issuer=issuer, - valid_from=valid_from, valid_to=valid_to, - key_type=key_type) + creds = HttpdTestCA._make_ca_credentials(name=spec.name, issuer=issuer, + valid_from=valid_from, valid_to=valid_to, + key_type=key_type) else: raise Exception(f"unrecognized certificate specification: {spec}") return creds @@ -397,11 +397,11 @@ class H2TestCA: else: issuer_subject = None issuer_key = pkey - subject = H2TestCA._make_x509_name(org_name=name, parent=issuer.subject if issuer else None) - csr = H2TestCA._make_csr(subject=subject, - issuer_subject=issuer_subject, pkey=pkey, - valid_from_delta=valid_from, valid_until_delta=valid_to) - csr = H2TestCA._add_ca_usages(csr) + subject = HttpdTestCA._make_x509_name(org_name=name, parent=issuer.subject if issuer else None) + csr = HttpdTestCA._make_csr(subject=subject, + issuer_subject=issuer_subject, pkey=pkey, + valid_from_delta=valid_from, valid_until_delta=valid_to) + csr = HttpdTestCA._add_ca_usages(csr) cert = csr.sign(private_key=issuer_key, algorithm=hashes.SHA256(), backend=default_backend()) @@ -415,11 +415,11 @@ class H2TestCA: ) -> Credentials: name = name pkey = _private_key(key_type=key_type) - subject = H2TestCA._make_x509_name(common_name=name, parent=issuer.subject) - csr = H2TestCA._make_csr(subject=subject, - issuer_subject=issuer.certificate.subject, pkey=pkey, - valid_from_delta=valid_from, valid_until_delta=valid_to) - csr = H2TestCA._add_leaf_usages(csr, domains=domains, issuer=issuer) + subject = HttpdTestCA._make_x509_name(common_name=name, parent=issuer.subject) + csr = HttpdTestCA._make_csr(subject=subject, + issuer_subject=issuer.certificate.subject, pkey=pkey, + valid_from_delta=valid_from, valid_until_delta=valid_to) + csr = HttpdTestCA._add_leaf_usages(csr, domains=domains, issuer=issuer) cert = csr.sign(private_key=issuer.private_key, algorithm=hashes.SHA256(), backend=default_backend()) @@ -433,11 +433,11 @@ class H2TestCA: valid_to: timedelta = timedelta(days=89), ) -> Credentials: pkey = _private_key(key_type=key_type) - subject = H2TestCA._make_x509_name(common_name=name, parent=issuer.subject) - csr = H2TestCA._make_csr(subject=subject, - issuer_subject=issuer.certificate.subject, pkey=pkey, - valid_from_delta=valid_from, valid_until_delta=valid_to) - csr = H2TestCA._add_client_usages(csr, issuer=issuer, rfc82name=email) + subject = HttpdTestCA._make_x509_name(common_name=name, parent=issuer.subject) + csr = HttpdTestCA._make_csr(subject=subject, + issuer_subject=issuer.certificate.subject, pkey=pkey, + valid_from_delta=valid_from, valid_until_delta=valid_to) + csr = HttpdTestCA._add_client_usages(csr, issuer=issuer, rfc82name=email) cert = csr.sign(private_key=issuer.private_key, algorithm=hashes.SHA256(), backend=default_backend()) diff --git a/test/modules/http2/h2_conf.py b/test/pyhttpd/conf.py index 4edfaa2dd0..1229929cb8 100644 --- a/test/modules/http2/h2_conf.py +++ b/test/pyhttpd/conf.py @@ -1,9 +1,9 @@ -import os +from pyhttpd.env import HttpdTestEnv class HttpdConf(object): - def __init__(self, env, path=None): + def __init__(self, env: HttpdTestEnv, path=None): self.env = env self._lines = [] self._has_ssl_vhost = False @@ -64,6 +64,13 @@ class HttpdConf(object): """) return self + def add_proxy_setup(self): + self.add("ProxyStatus on") + self.add("ProxyTimeout 5") + self.add("SSLProxyEngine on") + self.add("SSLProxyVerify none") + return self + def add_vhost_test1(self, proxy_self=False, h2proxy_self=False, extras=None): domain = f"test1.{self.env.http_tld}" if extras and 'base' in extras: @@ -86,7 +93,7 @@ class HttpdConf(object): self.add_proxies("test1", proxy_self, h2proxy_self) self.end_vhost() return self - + def add_vhost_test2(self, extras=None): domain = f"test2.{self.env.http_tld}" if extras and 'base' in extras: @@ -142,22 +149,3 @@ class HttpdConf(object): self.add(" LogLevel proxy:info") self.add(" LogLevel proxy_http:info") return self - - def add_vhost_noh2(self): - self.start_vhost(self.env.https_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=True) - self.add(f""" - Protocols http/1.1 - SSLOptions +StdEnvVars""") - self.end_vhost() - self.start_vhost(self.env.http_port, "noh2", aliases=["noh2-alias"], doc_root="htdocs/noh2", with_ssl=False) - self.add(" Protocols http/1.1") - self.add(" SSLOptions +StdEnvVars") - self.end_vhost() - return self - - def add_proxy_setup(self): - self.add("ProxyStatus on") - self.add("ProxyTimeout 5") - self.add("SSLProxyEngine on") - self.add("SSLProxyVerify none") - return self diff --git a/test/modules/http2/conf/httpd.conf.template b/test/pyhttpd/conf/httpd.conf.template index bd0606b402..bd0606b402 100644 --- a/test/modules/http2/conf/httpd.conf.template +++ b/test/pyhttpd/conf/httpd.conf.template diff --git a/test/modules/http2/conf/mime.types b/test/pyhttpd/conf/mime.types index b90b165876..b90b165876 100644 --- a/test/modules/http2/conf/mime.types +++ b/test/pyhttpd/conf/mime.types diff --git a/test/modules/http2/conf/test.conf b/test/pyhttpd/conf/test.conf index 7534af6c87..7534af6c87 100644 --- a/test/modules/http2/conf/test.conf +++ b/test/pyhttpd/conf/test.conf diff --git a/test/modules/http2/config.ini.in b/test/pyhttpd/config.ini.in index 3135a7ec81..da89451a7a 100644 --- a/test/modules/http2/config.ini.in +++ b/test/pyhttpd/config.ini.in @@ -23,7 +23,6 @@ name = @progname@ http_port = 40001 https_port = 40002 http_tld = tests.httpd.apache.org -test_dir = @abs_srcdir@ -test_src_dir = @abs_srcdir@ -server_dir = @abs_srcdir@/gen/apache -gen_dir = @abs_srcdir@/gen +test_dir = @abs_srcdir@/.. +server_dir = @abs_srcdir@/../gen/apache +gen_dir = @abs_srcdir@/../gen diff --git a/test/modules/http2/h2_curl.py b/test/pyhttpd/curl.py index fcabe7632a..338e82ce44 100644 --- a/test/modules/http2/h2_curl.py +++ b/test/pyhttpd/curl.py @@ -5,12 +5,12 @@ import sys import time from threading import Thread -from h2_env import H2TestEnv +from .env import HttpdTestEnv class CurlPiper: - def __init__(self, env: H2TestEnv, url: str): + def __init__(self, env: HttpdTestEnv, url: str): self.env = env self.url = url self.proc = None diff --git a/test/modules/http2/h2_env.py b/test/pyhttpd/env.py index 7f879870e7..1efff98c6f 100644 --- a/test/modules/http2/h2_env.py +++ b/test/pyhttpd/env.py @@ -16,9 +16,9 @@ import requests from configparser import ConfigParser, ExtendedInterpolation from urllib.parse import urlparse -from h2_certs import Credentials -from h2_nghttp import Nghttp -from h2_result import ExecResult +from .certs import Credentials, HttpdTestCA, CertificateSpec +from .nghttp import Nghttp +from .result import ExecResult log = logging.getLogger(__name__) @@ -28,7 +28,7 @@ class Dummy: pass -class H2TestSetup: +class HttpdTestSetup: # the modules we want to load MODULES = [ @@ -70,15 +70,17 @@ class H2TestSetup: "proxy_hcheck", ] - def __init__(self, env: 'H2TestEnv'): + def __init__(self, env: 'HttpdTestEnv'): self.env = env - def make(self): + def make(self, modules: List[str] = None, add_modules: List[str] = None): self._make_dirs() self._make_conf() + mod_names = modules.copy() if modules else self.MODULES.copy() + if add_modules: + mod_names.extend(add_modules) + self._make_modules_conf(modules=mod_names) self._make_htdocs() - self._make_h2test() - self._make_modules_conf() def _make_dirs(self): if os.path.exists(self.env.gen_dir): @@ -88,7 +90,8 @@ class H2TestSetup: os.makedirs(self.env.server_logs_dir) def _make_conf(self): - conf_src_dir = os.path.join(self.env.test_dir, 'conf') + our_dir = os.path.dirname(inspect.getfile(Dummy)) + conf_src_dir = os.path.join(our_dir, 'conf') conf_dest_dir = os.path.join(self.env.server_dir, 'conf') if not os.path.exists(conf_dest_dir): os.makedirs(conf_dest_dir) @@ -102,17 +105,27 @@ class H2TestSetup: def _make_template(self, src, dest): var_map = dict() - for name, value in self.env.__class__.__dict__.items(): + for name, value in HttpdTestEnv.__dict__.items(): if isinstance(value, property): var_map[name] = value.fget(self.env) t = Template(''.join(open(src).readlines())) with open(dest, 'w') as fd: fd.write(t.substitute(var_map)) + def _make_modules_conf(self, modules: List[str]): + modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') + with open(modules_conf, 'w') as fd: + # issue load directives for all modules we want that are shared + for m in modules: + mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so") + if os.path.isfile(mod_path): + fd.write(f"LoadModule {m}_module \"{mod_path}\"\n") + def _make_htdocs(self): + our_dir = os.path.dirname(inspect.getfile(Dummy)) if not os.path.exists(self.env.server_docs_dir): os.makedirs(self.env.server_docs_dir) - shutil.copytree(os.path.join(self.env.test_dir, 'htdocs'), + shutil.copytree(os.path.join(our_dir, 'htdocs'), os.path.join(self.env.server_dir, 'htdocs'), dirs_exist_ok=True) cgi_dir = os.path.join(self.env.server_dir, 'htdocs/cgi') @@ -122,35 +135,16 @@ class H2TestSetup: st = os.stat(cgi_file) os.chmod(cgi_file, st.st_mode | stat.S_IEXEC) - def _make_h2test(self): - p = subprocess.run([self.env.apxs, '-c', 'mod_h2test.c'], - capture_output=True, - cwd=os.path.join(self.env.test_dir, 'mod_h2test')) - rv = p.returncode - if rv != 0: - log.error(f"compiling md_h2test failed: {p.stderr}") - raise Exception(f"compiling md_h2test failed: {p.stderr}") - def _make_modules_conf(self): - modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') - with open(modules_conf, 'w') as fd: - # issue load directives for all modules we want that are shared - for m in self.MODULES: - mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so") - if os.path.isfile(mod_path): - fd.write(f"LoadModule {m}_module \"{mod_path}\"\n") - for m in ["http2", "proxy_http2"]: - fd.write(f"LoadModule {m}_module \"{self.env.libexec_dir}/mod_{m}.so\"\n") - # load our test module which is not installed - fd.write(f"LoadModule h2test_module \"{self.env.test_dir}/mod_h2test/.libs/mod_h2test.so\"\n") - - -class H2TestEnv: +class HttpdTestEnv: - def __init__(self, pytestconfig=None, setup_dirs=True): - our_dir = os.path.dirname(inspect.getfile(Dummy)) + def __init__(self, pytestconfig=None, + local_dir=None, add_base_conf: str = None, + interesting_modules: List[str] = None): + self._our_dir = os.path.dirname(inspect.getfile(Dummy)) + self._local_dir = local_dir if local_dir else self._our_dir self.config = ConfigParser(interpolation=ExtendedInterpolation()) - self.config.read(os.path.join(our_dir, 'config.ini')) + self.config.read(os.path.join(self._our_dir, 'config.ini')) self._apxs = self.config.get('global', 'apxs') self._prefix = self.config.get('global', 'prefix') @@ -160,13 +154,11 @@ class H2TestEnv: self._curl = self.config.get('global', 'curl_bin') self._nghttp = self.config.get('global', 'nghttp') self._h2load = self.config.get('global', 'h2load') - self._ca = None self._http_port = int(self.config.get('test', 'http_port')) self._https_port = int(self.config.get('test', 'https_port')) self._http_tld = self.config.get('test', 'http_tld') self._test_dir = self.config.get('test', 'test_dir') - self._test_src_dir = self.config.get('test', 'test_src_dir') self._gen_dir = self.config.get('test', 'gen_dir') self._server_dir = os.path.join(self._gen_dir, 'apache') self._server_conf_dir = os.path.join(self._server_dir, "conf") @@ -176,23 +168,6 @@ class H2TestEnv: self._server_error_log = os.path.join(self._server_logs_dir, "error_log") self._dso_modules = self.config.get('global', 'dso_modules').split(' ') - self._domains = [ - f"test1.{self._http_tld}", - f"test2.{self._http_tld}", - f"test3.{self._http_tld}", - f"cgi.{self._http_tld}", - f"push.{self._http_tld}", - f"hints.{self._http_tld}", - f"ssl.{self._http_tld}", - f"pad0.{self._http_tld}", - f"pad1.{self._http_tld}", - f"pad2.{self._http_tld}", - f"pad3.{self._http_tld}", - f"pad8.{self._http_tld}", - ] - self._domains_noh2 = [ - f"noh2.{self._http_tld}", - ] self._mpm_type = os.environ['MPM'] if 'MPM' in os.environ else 'event' self._httpd_addr = "127.0.0.1" @@ -202,25 +177,38 @@ class H2TestEnv: self._test_conf = os.path.join(self._server_conf_dir, "test.conf") self._httpd_base_conf = f""" LoadModule mpm_{self.mpm_type}_module \"{self.libexec_dir}/mod_mpm_{self.mpm_type}.so\" - H2MinWorkers 1 - H2MaxWorkers 64 - SSLSessionCache "shmcb:ssl_gcache_data(32000)" + <IfModule mod_ssl.c> + SSLSessionCache "shmcb:ssl_gcache_data(32000)" + </IfModule> """ + if add_base_conf: + self._httpd_base_conf += f"\n{add_base_conf}" + self._verbosity = pytestconfig.option.verbose if pytestconfig is not None else 0 if self._verbosity >= 2: + log_level = "trace2" self._httpd_base_conf += f""" - LogLevel http2:trace2 proxy_http2:info h2test:trace2 LogLevel core:trace5 mpm_{self.mpm_type}:trace5 """ elif self._verbosity >= 1: - self._httpd_base_conf += "LogLevel http2:debug proxy_http2:debug h2test:debug" + log_level = "debug" else: - self._httpd_base_conf += "LogLevel http2:info proxy_http2:info" + log_level = "info" + if interesting_modules: + self._httpd_base_conf += "\nLogLevel" + for name in interesting_modules: + self._httpd_base_conf += f" {name}:{log_level}" + self._httpd_base_conf += "\n" + + self._ca = None + self._cert_specs = [CertificateSpec(domains=[ + f"test1.{self._http_tld}", + f"test2.{self._http_tld}", + f"test3.{self._http_tld}", + f"cgi.{self._http_tld}", + ], key_type='rsa4096')] self._verify_certs = False - if setup_dirs: - self._setup = H2TestSetup(env=self) - self._setup.make() @property def apxs(self) -> str: @@ -251,18 +239,6 @@ class H2TestEnv: return self._http_tld @property - def domain_test1(self) -> str: - return self._domains[0] - - @property - def domains(self) -> List[str]: - return self._domains - - @property - def domains_noh2(self) -> List[str]: - return self._domains_noh2 - - @property def http_base_url(self) -> str: return self._http_base @@ -275,12 +251,12 @@ class H2TestEnv: return self._gen_dir @property - def test_dir(self) -> str: - return self._test_dir + def local_dir(self) -> str: + return self._local_dir @property - def test_src_dir(self) -> str: - return self._test_src_dir + def test_dir(self) -> str: + return self._test_dir @property def server_dir(self) -> str: @@ -310,6 +286,12 @@ class H2TestEnv: def httpd_base_conf(self) -> str: return self._httpd_base_conf + def local_src(self, path): + return os.path.join(self.local_dir, path) + + def htdocs_src(self, path): + return os.path.join(self._our_dir, 'htdocs', path) + @property def h2load(self) -> str: return self._h2load @@ -318,13 +300,19 @@ class H2TestEnv: def ca(self) -> Credentials: return self._ca - def set_ca(self, ca: Credentials): - self._ca = ca + def add_cert_specs(self, specs: List[CertificateSpec]): + self._cert_specs.extend(specs) + + def issue_certs(self): + if self._ca is None: + self._ca = HttpdTestCA.create_root(name=self.http_tld, + store_dir=os.path.join(self.server_dir, 'ca'), key_type="rsa4096") + self._ca.issue_certs(self._cert_specs) def get_credentials_for_name(self, dns_name) -> List['Credentials']: - for domains in [self._domains, self._domains_noh2]: - if dns_name in domains: - return self.ca.get_credentials_for_name(domains[0]) + for spec in self._cert_specs: + if dns_name in spec.domains: + return self.ca.get_credentials_for_name(spec.domains[0]) return [] def has_h2load(self): @@ -356,9 +344,6 @@ class H2TestEnv: if not os.path.exists(path): return os.makedirs(path) - def test_src(self, path): - return os.path.join(self._test_src_dir, path) - def run(self, args) -> ExecResult: log.debug("execute: %s", " ".join(args)) start = datetime.now() @@ -615,18 +600,3 @@ class H2TestEnv: } run.add_results({"h2load": stats}) return run - - def setup_data_1k_1m(self): - s100 = "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678\n" - with open(os.path.join(self.gen_dir, "data-1k"), 'w') as f: - for i in range(10): - f.write(s100) - with open(os.path.join(self.gen_dir, "data-10k"), 'w') as f: - for i in range(100): - f.write(s100) - with open(os.path.join(self.gen_dir, "data-100k"), 'w') as f: - for i in range(1000): - f.write(s100) - with open(os.path.join(self.gen_dir, "data-1m"), 'w') as f: - for i in range(10000): - f.write(s100) diff --git a/test/modules/http2/htdocs/alive.json b/test/pyhttpd/htdocs/alive.json index 2239ee2ee7..2239ee2ee7 100644 --- a/test/modules/http2/htdocs/alive.json +++ b/test/pyhttpd/htdocs/alive.json diff --git a/test/modules/http2/htdocs/cgi/echo.py b/test/pyhttpd/htdocs/cgi/echo.py index 5ffe6ed823..5ffe6ed823 100644 --- a/test/modules/http2/htdocs/cgi/echo.py +++ b/test/pyhttpd/htdocs/cgi/echo.py diff --git a/test/modules/http2/htdocs/cgi/echohd.py b/test/pyhttpd/htdocs/cgi/echohd.py index 371ae8b0f7..371ae8b0f7 100644 --- a/test/modules/http2/htdocs/cgi/echohd.py +++ b/test/pyhttpd/htdocs/cgi/echohd.py diff --git a/test/modules/http2/htdocs/cgi/env.py b/test/pyhttpd/htdocs/cgi/env.py index 5c9c0b1adb..5c9c0b1adb 100644 --- a/test/modules/http2/htdocs/cgi/env.py +++ b/test/pyhttpd/htdocs/cgi/env.py diff --git a/test/modules/http2/htdocs/test1/apache.org-files/css.css b/test/pyhttpd/htdocs/cgi/files/empty.txt index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/css.css +++ b/test/pyhttpd/htdocs/cgi/files/empty.txt diff --git a/test/modules/http2/htdocs/cgi/hecho.py b/test/pyhttpd/htdocs/cgi/hecho.py index 5c1f79a302..5c1f79a302 100644 --- a/test/modules/http2/htdocs/cgi/hecho.py +++ b/test/pyhttpd/htdocs/cgi/hecho.py diff --git a/test/modules/http2/htdocs/cgi/hello.py b/test/pyhttpd/htdocs/cgi/hello.py index 191acb2fed..191acb2fed 100644 --- a/test/modules/http2/htdocs/cgi/hello.py +++ b/test/pyhttpd/htdocs/cgi/hello.py diff --git a/test/modules/http2/htdocs/cgi/mnot164.py b/test/pyhttpd/htdocs/cgi/mnot164.py index 949b0f195b..949b0f195b 100644 --- a/test/modules/http2/htdocs/cgi/mnot164.py +++ b/test/pyhttpd/htdocs/cgi/mnot164.py diff --git a/test/modules/http2/htdocs/cgi/necho.py b/test/pyhttpd/htdocs/cgi/necho.py index b9249b8969..b9249b8969 100644 --- a/test/modules/http2/htdocs/cgi/necho.py +++ b/test/pyhttpd/htdocs/cgi/necho.py diff --git a/test/modules/http2/htdocs/cgi/upload.py b/test/pyhttpd/htdocs/cgi/upload.py index 2c8d63aa10..2c8d63aa10 100644 --- a/test/modules/http2/htdocs/cgi/upload.py +++ b/test/pyhttpd/htdocs/cgi/upload.py diff --git a/test/modules/http2/htdocs/forbidden.html b/test/pyhttpd/htdocs/forbidden.html index e186310c73..e186310c73 100644 --- a/test/modules/http2/htdocs/forbidden.html +++ b/test/pyhttpd/htdocs/forbidden.html diff --git a/test/modules/http2/htdocs/index.html b/test/pyhttpd/htdocs/index.html index 3c07626144..3c07626144 100644 --- a/test/modules/http2/htdocs/index.html +++ b/test/pyhttpd/htdocs/index.html diff --git a/test/modules/http2/htdocs/noh2/alive.json b/test/pyhttpd/htdocs/noh2/alive.json index 7b54893ee5..7b54893ee5 100644 --- a/test/modules/http2/htdocs/noh2/alive.json +++ b/test/pyhttpd/htdocs/noh2/alive.json diff --git a/test/modules/http2/htdocs/noh2/index.html b/test/pyhttpd/htdocs/noh2/index.html index 696068e9dc..696068e9dc 100644 --- a/test/modules/http2/htdocs/noh2/index.html +++ b/test/pyhttpd/htdocs/noh2/index.html diff --git a/test/modules/http2/htdocs/test1/001.html b/test/pyhttpd/htdocs/test1/001.html index 184952d28c..184952d28c 100644 --- a/test/modules/http2/htdocs/test1/001.html +++ b/test/pyhttpd/htdocs/test1/001.html diff --git a/test/modules/http2/htdocs/test1/002.jpg b/test/pyhttpd/htdocs/test1/002.jpg Binary files differindex 3feefb070a..3feefb070a 100644 --- a/test/modules/http2/htdocs/test1/002.jpg +++ b/test/pyhttpd/htdocs/test1/002.jpg diff --git a/test/modules/http2/htdocs/test1/003.html b/test/pyhttpd/htdocs/test1/003.html index d5b08c52bb..d5b08c52bb 100644 --- a/test/modules/http2/htdocs/test1/003.html +++ b/test/pyhttpd/htdocs/test1/003.html diff --git a/test/modules/http2/htdocs/test1/003/003_img.jpg b/test/pyhttpd/htdocs/test1/003/003_img.jpg Binary files differindex 3feefb070a..3feefb070a 100644 --- a/test/modules/http2/htdocs/test1/003/003_img.jpg +++ b/test/pyhttpd/htdocs/test1/003/003_img.jpg diff --git a/test/modules/http2/htdocs/test1/004.html b/test/pyhttpd/htdocs/test1/004.html index 768cb825b4..768cb825b4 100644 --- a/test/modules/http2/htdocs/test1/004.html +++ b/test/pyhttpd/htdocs/test1/004.html diff --git a/test/modules/http2/htdocs/test1/004/gophertiles.jpg b/test/pyhttpd/htdocs/test1/004/gophertiles.jpg Binary files differindex e45ac3b02b..e45ac3b02b 100644 --- a/test/modules/http2/htdocs/test1/004/gophertiles.jpg +++ b/test/pyhttpd/htdocs/test1/004/gophertiles.jpg diff --git a/test/modules/http2/htdocs/test1/006.html b/test/pyhttpd/htdocs/test1/006.html index 6b730255a1..6b730255a1 100644 --- a/test/modules/http2/htdocs/test1/006.html +++ b/test/pyhttpd/htdocs/test1/006.html diff --git a/test/modules/http2/htdocs/test1/006/006.css b/test/pyhttpd/htdocs/test1/006/006.css index de6aa5fd18..de6aa5fd18 100644 --- a/test/modules/http2/htdocs/test1/006/006.css +++ b/test/pyhttpd/htdocs/test1/006/006.css diff --git a/test/modules/http2/htdocs/test1/006/006.js b/test/pyhttpd/htdocs/test1/006/006.js index b450067b53..b450067b53 100644 --- a/test/modules/http2/htdocs/test1/006/006.js +++ b/test/pyhttpd/htdocs/test1/006/006.js diff --git a/test/modules/http2/htdocs/test1/006/header.html b/test/pyhttpd/htdocs/test1/006/header.html index bace20ee88..bace20ee88 100644 --- a/test/modules/http2/htdocs/test1/006/header.html +++ b/test/pyhttpd/htdocs/test1/006/header.html diff --git a/test/modules/http2/htdocs/test1/007.html b/test/pyhttpd/htdocs/test1/007.html index 4db93e4c5a..4db93e4c5a 100644 --- a/test/modules/http2/htdocs/test1/007.html +++ b/test/pyhttpd/htdocs/test1/007.html diff --git a/test/modules/http2/htdocs/test1/007/007.py b/test/pyhttpd/htdocs/test1/007/007.py index 02b5466f96..02b5466f96 100644 --- a/test/modules/http2/htdocs/test1/007/007.py +++ b/test/pyhttpd/htdocs/test1/007/007.py diff --git a/test/modules/http2/htdocs/test1/009.py b/test/pyhttpd/htdocs/test1/009.py index 8fd9095af3..8fd9095af3 100644 --- a/test/modules/http2/htdocs/test1/009.py +++ b/test/pyhttpd/htdocs/test1/009.py diff --git a/test/modules/http2/htdocs/test1/alive.json b/test/pyhttpd/htdocs/test1/alive.json index 93e7f95972..93e7f95972 100644 --- a/test/modules/http2/htdocs/test1/alive.json +++ b/test/pyhttpd/htdocs/test1/alive.json diff --git a/test/modules/http2/htdocs/test1/apache.org-files/ant.jpg b/test/pyhttpd/htdocs/test1/apache.org-files/ant.jpg Binary files differindex 2ebd7ad717..2ebd7ad717 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/ant.jpg +++ b/test/pyhttpd/htdocs/test1/apache.org-files/ant.jpg diff --git a/test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png b/test/pyhttpd/htdocs/test1/apache.org-files/asf_logo.png Binary files differindex 07c0113c7b..07c0113c7b 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/asf_logo.png +++ b/test/pyhttpd/htdocs/test1/apache.org-files/asf_logo.png diff --git a/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js b/test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js index eee04abfaf..eee04abfaf 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js +++ b/test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js diff --git a/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js.br b/test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js.br Binary files differindex 6dc14a36f9..6dc14a36f9 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/async-ads.js.br +++ b/test/pyhttpd/htdocs/test1/apache.org-files/async-ads.js.br diff --git a/test/modules/http2/htdocs/test1/apache.org-files/jsapi.js b/test/pyhttpd/htdocs/test1/apache.org-files/cse.js index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/jsapi.js +++ b/test/pyhttpd/htdocs/test1/apache.org-files/cse.js diff --git a/test/modules/http2/htdocs/test2/10%abnormal.txt b/test/pyhttpd/htdocs/test1/apache.org-files/css.css index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/test2/10%abnormal.txt +++ b/test/pyhttpd/htdocs/test1/apache.org-files/css.css diff --git a/test/modules/http2/htdocs/test1/apache.org-files/default.css b/test/pyhttpd/htdocs/test1/apache.org-files/default.css index 6e2e2c4dad..6e2e2c4dad 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/default.css +++ b/test/pyhttpd/htdocs/test1/apache.org-files/default.css diff --git a/test/modules/http2/htdocs/test1/apache.org-files/defaulten.css b/test/pyhttpd/htdocs/test1/apache.org-files/defaulten.css index cd2c1c6264..cd2c1c6264 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/defaulten.css +++ b/test/pyhttpd/htdocs/test1/apache.org-files/defaulten.css diff --git a/test/modules/http2/htdocs/test1/apache.org-files/defaulten.js b/test/pyhttpd/htdocs/test1/apache.org-files/defaulten.js index 1afe448ec5..1afe448ec5 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/defaulten.js +++ b/test/pyhttpd/htdocs/test1/apache.org-files/defaulten.js diff --git a/test/modules/http2/htdocs/test1/apache.org-files/jquery-2.js b/test/pyhttpd/htdocs/test1/apache.org-files/jquery-2.js index dc93a13e88..dc93a13e88 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/jquery-2.js +++ b/test/pyhttpd/htdocs/test1/apache.org-files/jquery-2.js diff --git a/test/modules/http2/htdocs/test2/x%2f.test b/test/pyhttpd/htdocs/test1/apache.org-files/jsapi.js index e69de29bb2..e69de29bb2 100644 --- a/test/modules/http2/htdocs/test2/x%2f.test +++ b/test/pyhttpd/htdocs/test1/apache.org-files/jsapi.js diff --git a/test/modules/http2/htdocs/test1/apache.org-files/min.css b/test/pyhttpd/htdocs/test1/apache.org-files/min.css index 908a2e8b8c..908a2e8b8c 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/min.css +++ b/test/pyhttpd/htdocs/test1/apache.org-files/min.css diff --git a/test/modules/http2/htdocs/test1/apache.org-files/min.css.br b/test/pyhttpd/htdocs/test1/apache.org-files/min.css.br Binary files differindex a58ad52f3d..a58ad52f3d 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/min.css.br +++ b/test/pyhttpd/htdocs/test1/apache.org-files/min.css.br diff --git a/test/modules/http2/htdocs/test1/apache.org-files/mrunit.jpg b/test/pyhttpd/htdocs/test1/apache.org-files/mrunit.jpg Binary files differindex 7e5093da53..7e5093da53 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/mrunit.jpg +++ b/test/pyhttpd/htdocs/test1/apache.org-files/mrunit.jpg diff --git a/test/modules/http2/htdocs/test1/apache.org-files/search_box_icon.png b/test/pyhttpd/htdocs/test1/apache.org-files/search_box_icon.png Binary files differindex bae336a45a..bae336a45a 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/search_box_icon.png +++ b/test/pyhttpd/htdocs/test1/apache.org-files/search_box_icon.png diff --git a/test/modules/http2/htdocs/test1/apache.org-files/small-logo.png b/test/pyhttpd/htdocs/test1/apache.org-files/small-logo.png Binary files differindex b2d6ebb807..b2d6ebb807 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/small-logo.png +++ b/test/pyhttpd/htdocs/test1/apache.org-files/small-logo.png diff --git a/test/modules/http2/htdocs/test1/apache.org-files/styles.css b/test/pyhttpd/htdocs/test1/apache.org-files/styles.css index a5e5565c63..a5e5565c63 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/styles.css +++ b/test/pyhttpd/htdocs/test1/apache.org-files/styles.css diff --git a/test/modules/http2/htdocs/test1/apache.org-files/synapse.jpg b/test/pyhttpd/htdocs/test1/apache.org-files/synapse.jpg Binary files differindex fb2f4570ff..fb2f4570ff 100644 --- a/test/modules/http2/htdocs/test1/apache.org-files/synapse.jpg +++ b/test/pyhttpd/htdocs/test1/apache.org-files/synapse.jpg diff --git a/test/modules/http2/htdocs/test1/apache.org.html b/test/pyhttpd/htdocs/test1/apache.org.html index 0265fcc174..0265fcc174 100644 --- a/test/modules/http2/htdocs/test1/apache.org.html +++ b/test/pyhttpd/htdocs/test1/apache.org.html diff --git a/test/modules/http2/htdocs/test1/index.html b/test/pyhttpd/htdocs/test1/index.html index 9f752b52f0..9f752b52f0 100644 --- a/test/modules/http2/htdocs/test1/index.html +++ b/test/pyhttpd/htdocs/test1/index.html diff --git a/test/modules/http2/htdocs/test2/006/006.css b/test/pyhttpd/htdocs/test2/006/006.css index de6aa5fd18..de6aa5fd18 100755 --- a/test/modules/http2/htdocs/test2/006/006.css +++ b/test/pyhttpd/htdocs/test2/006/006.css diff --git a/test/pyhttpd/htdocs/test2/10%abnormal.txt b/test/pyhttpd/htdocs/test2/10%abnormal.txt new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/pyhttpd/htdocs/test2/10%abnormal.txt diff --git a/test/modules/http2/htdocs/test2/alive.json b/test/pyhttpd/htdocs/test2/alive.json index 6a742235fa..6a742235fa 100644 --- a/test/modules/http2/htdocs/test2/alive.json +++ b/test/pyhttpd/htdocs/test2/alive.json diff --git a/test/pyhttpd/htdocs/test2/x%2f.test b/test/pyhttpd/htdocs/test2/x%2f.test new file mode 100644 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/pyhttpd/htdocs/test2/x%2f.test diff --git a/test/modules/http2/h2_nghttp.py b/test/pyhttpd/nghttp.py index d06798e868..362b2fdd49 100644 --- a/test/modules/http2/h2_nghttp.py +++ b/test/pyhttpd/nghttp.py @@ -6,7 +6,7 @@ from typing import Dict from urllib.parse import urlparse -from h2_result import ExecResult +from .result import ExecResult def _get_path(x): diff --git a/test/modules/http2/h2_result.py b/test/pyhttpd/result.py index 06fc9e5300..06fc9e5300 100644 --- a/test/modules/http2/h2_result.py +++ b/test/pyhttpd/result.py |