]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Merge of r1911718 from trunk
authorStefan Eissing <icing@apache.org>
Wed, 16 Aug 2023 10:49:41 +0000 (10:49 +0000)
committerStefan Eissing <icing@apache.org>
Wed, 16 Aug 2023 10:49:41 +0000 (10:49 +0000)
Tests, workarounds for bugs in curl 8.1.x

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1911719 13f79535-47bb-0310-9956-ffa450edef68

test/modules/http2/test_101_ssl_reneg.py
test/modules/http2/test_200_header_invalid.py
test/modules/http2/test_601_h2proxy_twisted.py
test/pyhttpd/env.py

index 66f2638a7b5afa374b22150dd38f318358632fc3..528002fb88af8ef0c865068db074544218c3c19a 100644 (file)
@@ -59,6 +59,8 @@ class TestSslRenegotiation:
         
     # try to renegotiate the cipher, should fail with correct code
     def test_h2_101_02(self, env):
+        if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
+            pytest.skip("need curl != 8.1.x version")
         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"
@@ -70,6 +72,8 @@ class TestSslRenegotiation:
     # try to renegotiate a client certificate from Location 
     # needs to fail with correct code
     def test_h2_101_03(self, env):
+        if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
+            pytest.skip("need curl != 8.1.x version")
         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
@@ -79,6 +83,8 @@ class TestSslRenegotiation:
     # try to renegotiate a client certificate from Directory 
     # needs to fail with correct code
     def test_h2_101_04(self, env):
+        if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
+            pytest.skip("need curl != 8.1.x version")
         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, f"{r}"
@@ -121,6 +127,8 @@ class TestSslRenegotiation:
         
     # Check that status works with ErrorDoc, see pull #174, fixes #172
     def test_h2_101_11(self, env):
+        if not (env.curl_is_at_least('8.2.0') or env.curl_is_less_than('8.1.0')):
+            pytest.skip("need curl != 8.1.x version")
         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"
index fe9448784059f359b2c68041b1c0fd9b2c853681..5b3aafd8fab4753685d16dd289296261df4114f6 100644 (file)
@@ -64,36 +64,49 @@ class TestInvalidHeaders:
             else:
                 assert 0 != r.exit_code
 
-    # test header field lengths check, LimitRequestLine (default 8190)
+    # test header field lengths check, LimitRequestLine
     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
-            val = "%s%s%s%s%s%s%s%s%s%s" % (val, val, val, val, val, val, val, val, val, val)
-        # LimitRequestLine 8190 ok, one more char -> 431
-        r = env.curl_get(url, options=["-H", "x: %s" % (val[:8187])])
-        assert r.response["status"] == 200
-        r = env.curl_get(url, options=["-H", "x: %sx" % (val[:8188])])
-        assert 431 == r.response["status"]
-        # same with field name
-        r = env.curl_get(url, options=["-H", "y%s: 1" % (val[:8186])])
+        conf = H2Conf(env)
+        conf.add("""
+            LimitRequestLine 1024
+            """)
+        conf.add_vhost_cgi()
+        conf.install()
+        assert env.apache_restart() == 0
+        val = 200*"1234567890"
+        url = env.mkurl("https", "cgi", f'/?{val[:1022]}')
+        r = env.curl_get(url)
         assert r.response["status"] == 200
-        r = env.curl_get(url, options=["-H", "y%s: 1" % (val[:8188])])
-        assert 431 == r.response["status"]
+        url = env.mkurl("https", "cgi", f'/?{val[:1023]}')
+        r = env.curl_get(url)
+        # URI too long
+        assert 414 == r.response["status"]
 
     # test header field lengths check, LimitRequestFieldSize (default 8190)
     def test_h2_200_11(self, env):
+        conf = H2Conf(env)
+        conf.add("""
+            LimitRequestFieldSize 1024
+            """)
+        conf.add_vhost_cgi()
+        conf.install()
+        assert env.apache_restart() == 0
         url = env.mkurl("https", "cgi", "/")
-        val = "1234567890"  # 10 chars
-        for i in range(3):  # make a 10000 char string
-            val = "%s%s%s%s%s%s%s%s%s%s" % (val, val, val, val, val, val, val, val, val, val)
-        # LimitRequestFieldSize 8190 ok, one more char -> 400 in HTTP/1.1
-        # (we send 4000+4185 since they are concatenated by ", " and start with "x: "
-        r = env.curl_get(url, options=["-H", "x: %s" % (val[:4000]),  "-H", "x: %s" % (val[:4185])])
-        assert r.response["status"] == 200
-        r = env.curl_get(url, options=["--http1.1", "-H", "x: %s" % (val[:4000]),  "-H", "x: %s" % (val[:4189])])
+        val = 200*"1234567890"
+        # two fields, concatenated with ', '
+        # LimitRequestFieldSize, one more char -> 400 in HTTP/1.1
+        r = env.curl_get(url, options=[
+            '-H', f'x: {val[:500]}', '-H', f'x: {val[:519]}'
+        ])
+        assert r.exit_code == 0, f'{r}'
+        assert r.response["status"] == 200, f'{r}'
+        r = env.curl_get(url, options=[
+            '--http1.1', '-H', f'x: {val[:500]}', '-H', f'x: {val[:523]}'
+        ])
         assert 400 == r.response["status"]
-        r = env.curl_get(url, options=["-H", "x: %s" % (val[:4000]),  "-H", "x: %s" % (val[:4191])])
+        r = env.curl_get(url, options=[
+            '-H', f'x: {val[:500]}', '-H', f'x: {val[:520]}'
+        ])
         assert 431 == r.response["status"]
 
     # test header field count, LimitRequestFields (default 100)
index 276558eeed555c8f33fc0507c0e0b79fe7c8d911..06b8ce76ebb1dcad9f2365b4dcca9bb839e29f70 100644 (file)
@@ -63,7 +63,11 @@ class TestH2ProxyTwisted:
         url = env.mkurl("https", "cgi", f"/h2proxy/h2test/echo?fail_after={os.path.getsize(fpath)}")
         r = env.curl_upload(url, fpath, options=[])
         # 92 is curl's CURLE_HTTP2_STREAM
-        assert r.exit_code == 92 or r.response["status"] == 502
+        if r.exit_code != 0:
+            # H2 stream or partial file error
+            assert r.exit_code == 92 or r.exit_code == 18, f'{r}'
+        else:
+            assert r.response["status"] == 502, f'{r}'
 
     def test_h2_601_05_echo_fail_many(self, env):
         if not env.httpd_is_at_least('2.5.0'):
@@ -88,4 +92,8 @@ class TestH2ProxyTwisted:
             stats.append(json.loads(line))
         assert len(stats) == count
         for st in stats:
-            assert st['exitcode'] == 92 or st['http_code'] == 502, f'unexpected: {st}'
+            if st['exitcode'] != 0:
+                # H2 stream or partial file error
+                assert st['exitcode'] == 92 or st['exitcode'] == 18, f'{r}'
+            else:
+                assert st['http_code'] == 502, f'{r}'
index 842e369cbced47a8e4e15f283aa291a80667e670..39741cd684df3155fc8cd13a1eee5181f1727452 100644 (file)
@@ -493,6 +493,20 @@ class HttpdTestEnv:
             return self._curl_version >= self._versiontuple(minv)
         return False
 
+    def curl_is_less_than(self, version):
+        if self._curl_version is None:
+            p = subprocess.run([self._curl, '-V'], capture_output=True, text=True)
+            if p.returncode != 0:
+                return False
+            for l in p.stdout.splitlines():
+                m = re.match(r'curl ([0-9.]+)[- ].*', l)
+                if m:
+                    self._curl_version = self._versiontuple(m.group(1))
+                    break
+        if self._curl_version is not None:
+            return self._curl_version < self._versiontuple(version)
+        return False
+
     def has_nghttp(self):
         return self._nghttp != ""