You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2023/06/30 07:22:41 UTC

svn commit: r1910699 [2/2] - in /httpd/httpd/branches/2.4.x: ./ changes-entries/ docs/manual/mod/ modules/http2/ test/modules/http2/

Modified: httpd/httpd/branches/2.4.x/test/modules/http2/test_008_ranges.py
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/test/modules/http2/test_008_ranges.py?rev=1910699&r1=1910698&r2=1910699&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/test/modules/http2/test_008_ranges.py (original)
+++ httpd/httpd/branches/2.4.x/test/modules/http2/test_008_ranges.py Fri Jun 30 07:22:40 2023
@@ -109,6 +109,150 @@ class TestRanges:
 
     # send a paced curl download that aborts in the middle of the transfer
     def test_h2_008_03(self, env, repeat):
+        path = '/data-100m'
+        url = env.mkurl("https", "test1", f'{path}?03broken')
+        r = env.curl_get(url, 5, options=[
+            '--limit-rate', '2k', '-m', '2'
+        ])
+        assert r.exit_code != 0, f'{r}'
+        found = False
+        for line in open(TestRanges.LOGFILE).readlines():
+            e = json.loads(line)
+            if e['request'] == f'GET {path}?03broken HTTP/2.0':
+                assert e['bytes_rx_I'] > 0
+                assert e['bytes_resp_B'] == 100*1024*1024
+                assert e['bytes_tx_O'] > 1024
+                assert e['bytes_tx_O'] < 5*1024*1024  # curl buffers, but not that much
+                found = True
+                break
+        assert found, f'request not found in {self.LOGFILE}'
+
+    # upload and GET again using curl, compare to original content
+    def curl_upload_and_verify(self, env, fname, options=None):
+        url = env.mkurl("https", "cgi", "/upload.py")
+        fpath = os.path.join(env.gen_dir, fname)
+        r = env.curl_upload(url, fpath, options=options)
+        assert r.exit_code == 0, f"{r}"
+        assert 200 <= r.response["status"] < 300
+
+        r2 = env.curl_get(r.response["header"]["location"])
+        assert r2.exit_code == 0
+        assert r2.response["status"] == 200
+        with open(os.path.join(TestRanges.SRCDIR, fpath), mode='rb') as file:
+            src = file.read()
+        assert src == r2.response["body"]
+
+import inspect
+import json
+import os
+import pytest
+
+from .env import H2Conf, H2TestEnv
+
+
+@pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
+class TestRanges:
+
+    LOGFILE = ""
+
+    @pytest.fixture(autouse=True, scope='class')
+    def _class_scope(self, env):
+        TestRanges.LOGFILE = os.path.join(env.server_logs_dir, "test_008")
+        TestRanges.SRCDIR = os.path.dirname(inspect.getfile(TestRanges))
+        if os.path.isfile(TestRanges.LOGFILE):
+            os.remove(TestRanges.LOGFILE)
+        destdir = os.path.join(env.gen_dir, 'apache/htdocs/test1')
+        env.make_data_file(indir=destdir, fname="data-100m", fsize=100*1024*1024)
+        conf = H2Conf(env=env)
+        conf.add([
+            "CustomLog logs/test_008 combined"
+        ])
+        conf.add_vhost_cgi()
+        conf.add_vhost_test1()
+        conf.install()
+        assert env.apache_restart() == 0
+
+    def test_h2_008_01(self, env):
+        # issue: #203
+        resource = "data-1k"
+        full_length = 1000
+        chunk = 200
+        self.curl_upload_and_verify(env, resource, ["-v", "--http2"])
+        assert env.apache_restart() == 0
+        url = env.mkurl("https", "cgi", f"/files/{resource}?01full")
+        r = env.curl_get(url, 5, options=["--http2"])
+        assert r.response["status"] == 200
+        url = env.mkurl("https", "cgi", f"/files/{resource}?01range")
+        r = env.curl_get(url, 5, options=["--http1.1", "-H", "Range: bytes=0-{0}".format(chunk-1)])
+        assert 206 == r.response["status"]
+        assert chunk == len(r.response["body"].decode('utf-8'))
+        r = env.curl_get(url, 5, options=["--http2", "-H", "Range: bytes=0-{0}".format(chunk-1)])
+        assert 206 == r.response["status"]
+        assert chunk == len(r.response["body"].decode('utf-8'))
+        # Restart for logs to be flushed out
+        assert env.apache_restart() == 0
+        # now check what response lengths have actually been reported
+        detected = {}
+        for line in open(TestRanges.LOGFILE).readlines():
+            e = json.loads(line)
+            if e['request'] == f'GET /files/{resource}?01full HTTP/2.0':
+                assert e['bytes_rx_I'] > 0
+                assert e['bytes_resp_B'] == full_length
+                assert e['bytes_tx_O'] > full_length
+                detected['h2full'] = 1
+            elif e['request'] == f'GET /files/{resource}?01range HTTP/2.0':
+                assert e['bytes_rx_I'] > 0
+                assert e['bytes_resp_B'] == chunk
+                assert e['bytes_tx_O'] > chunk
+                assert e['bytes_tx_O'] < chunk + 256 # response + frame stuff
+                detected['h2range'] = 1
+            elif e['request'] == f'GET /files/{resource}?01range HTTP/1.1':
+                assert e['bytes_rx_I'] > 0         # input bytes received
+                assert e['bytes_resp_B'] == chunk  # response bytes sent (payload)
+                assert e['bytes_tx_O'] > chunk     # output bytes sent
+                detected['h1range'] = 1
+        assert 'h1range' in detected, f'HTTP/1.1 range request not found in {TestRanges.LOGFILE}'
+        assert 'h2range' in detected, f'HTTP/2 range request not found in {TestRanges.LOGFILE}'
+        assert 'h2full' in detected, f'HTTP/2 full request not found in {TestRanges.LOGFILE}'
+
+    def test_h2_008_02(self, env, repeat):
+        path = '/002.jpg'
+        res_len = 90364
+        url = env.mkurl("https", "test1", f'{path}?02full')
+        r = env.curl_get(url, 5)
+        assert r.response["status"] == 200
+        assert "HTTP/2" == r.response["protocol"]
+        h = r.response["header"]
+        assert "accept-ranges" in h
+        assert "bytes" == h["accept-ranges"]
+        assert "content-length" in h
+        clen = h["content-length"]
+        assert int(clen) == res_len
+        # get the first 1024 bytes of the resource, 206 status, but content-length as original
+        url = env.mkurl("https", "test1", f'{path}?02range')
+        r = env.curl_get(url, 5, options=["-H", "range: bytes=0-1023"])
+        assert 206 == r.response["status"]
+        assert "HTTP/2" == r.response["protocol"]
+        assert 1024 == len(r.response["body"])
+        assert "content-length" in h
+        assert clen == h["content-length"]
+        # Restart for logs to be flushed out
+        assert env.apache_restart() == 0
+        # now check what response lengths have actually been reported
+        found = False
+        for line in open(TestRanges.LOGFILE).readlines():
+            e = json.loads(line)
+            if e['request'] == f'GET {path}?02range HTTP/2.0':
+                assert e['bytes_rx_I'] > 0
+                assert e['bytes_resp_B'] == 1024
+                assert e['bytes_tx_O'] > 1024
+                assert e['bytes_tx_O'] < 1024 + 256  # response  and frame stuff
+                found = True
+                break
+        assert found, f'request not found in {self.LOGFILE}'
+
+    # send a paced curl download that aborts in the middle of the transfer
+    def test_h2_008_03(self, env, repeat):
         if not env.httpd_is_at_least('2.5.0'):
             pytest.skip(f'needs r1909769 from trunk')
         path = '/data-100m'

Modified: httpd/httpd/branches/2.4.x/test/modules/http2/test_009_timing.py
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/test/modules/http2/test_009_timing.py?rev=1910699&r1=1910698&r2=1910699&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/test/modules/http2/test_009_timing.py (original)
+++ httpd/httpd/branches/2.4.x/test/modules/http2/test_009_timing.py Fri Jun 30 07:22:40 2023
@@ -48,6 +48,80 @@ class TestTiming:
     # test issue #253, where time_taken in a keepalive situation is not
     # reported until the next request arrives
     def test_h2_009_02(self, env):
+        baseurl = env.mkurl("https", "test1", '/')
+        tscript = os.path.join(env.gen_dir, 'h2load-timing-009_02')
+        with open(tscript, 'w') as fd:
+            fd.write('\n'.join([
+                f'0.0\t/002.jpg?02a',        # 1st request right away
+                f'1000.0\t/002.jpg?02b',     # 2nd a second later
+            ]))
+        args = [
+            env.h2load,
+            f'--timing-script-file={tscript}',
+            f"--connect-to=localhost:{env.https_port}",
+            f"--base-uri={baseurl}"
+        ]
+        r = env.run(args)
+        # Restart for logs to be flushed out
+        assert env.apache_restart() == 0
+        found = False
+        for line in open(TestTiming.LOGFILE).readlines():
+            e = json.loads(line)
+            if e['request'] == f'GET /002.jpg?02a HTTP/2.0':
+                assert e['time_taken'] > 0
+                assert e['time_taken'] < 500 * 1000, f'time for 1st request not reported correctly'
+                found = True
+        assert found, f'request not found in {TestTiming.LOGFILE}'
+import inspect
+import json
+import os
+import pytest
+
+from .env import H2Conf, H2TestEnv
+
+
+@pytest.mark.skipif(condition=H2TestEnv.is_unsupported, reason="mod_http2 not supported here")
+class TestTiming:
+
+    LOGFILE = ""
+
+    @pytest.fixture(autouse=True, scope='class')
+    def _class_scope(self, env):
+        TestTiming.LOGFILE = os.path.join(env.server_logs_dir, "test_009")
+        if os.path.isfile(TestTiming.LOGFILE):
+            os.remove(TestTiming.LOGFILE)
+        conf = H2Conf(env=env)
+        conf.add([
+            "CustomLog logs/test_009 combined"
+        ])
+        conf.add_vhost_cgi()
+        conf.add_vhost_test1()
+        conf.install()
+        assert env.apache_restart() == 0
+
+    # check that we get a positive time_taken reported on a simple GET
+    def test_h2_009_01(self, env):
+        path = '/002.jpg'
+        url = env.mkurl("https", "test1", f'{path}?01')
+        args = [
+            env.h2load, "-n", "1", "-c", "1", "-m", "1",
+            f"--connect-to=localhost:{env.https_port}",
+            f"--base-uri={url}", url
+        ]
+        r = env.run(args)
+        # Restart for logs to be flushed out
+        assert env.apache_restart() == 0
+        found = False
+        for line in open(TestTiming.LOGFILE).readlines():
+            e = json.loads(line)
+            if e['request'] == f'GET {path}?01 HTTP/2.0':
+                assert e['time_taken'] > 0
+                found = True
+        assert found, f'request not found in {TestTiming.LOGFILE}'
+
+    # test issue #253, where time_taken in a keepalive situation is not
+    # reported until the next request arrives
+    def test_h2_009_02(self, env):
         if not env.httpd_is_at_least('2.5.0'):
             pytest.skip(f'needs r1909769 from trunk')
         baseurl = env.mkurl("https", "test1", '/')

Modified: httpd/httpd/branches/2.4.x/test/modules/http2/test_107_frame_lengths.py
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/test/modules/http2/test_107_frame_lengths.py?rev=1910699&r1=1910698&r2=1910699&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/test/modules/http2/test_107_frame_lengths.py (original)
+++ httpd/httpd/branches/2.4.x/test/modules/http2/test_107_frame_lengths.py Fri Jun 30 07:22:40 2023
@@ -32,8 +32,6 @@ class TestFrameLengths:
         99, 1024, 8192
     ])
     def test_h2_107_01(self, env, data_frame_len):
-        if not env.httpd_is_at_least('2.5.0'):
-            pytest.skip(f'needs r1907696+r1907697 from trunk')
         conf = H2Conf(env, extras={
             f'cgi.{env.http_tld}': [
                 f'H2MaxDataFrameLen {data_frame_len}',

Modified: httpd/httpd/branches/2.4.x/test/modules/http2/test_500_proxy.py
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.4.x/test/modules/http2/test_500_proxy.py?rev=1910699&r1=1910698&r2=1910699&view=diff
==============================================================================
--- httpd/httpd/branches/2.4.x/test/modules/http2/test_500_proxy.py (original)
+++ httpd/httpd/branches/2.4.x/test/modules/http2/test_500_proxy.py Fri Jun 30 07:22:40 2023
@@ -61,6 +61,12 @@ class TestProxy:
         ])
         self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"])
 
+    def test_h2_500_11(self, env):
+        self.curl_upload_and_verify(env, "data-1k", [
+            "--http1.1", "-H", "Content-Length:", "-H", "Transfer-Encoding: chunked"
+        ])
+        self.curl_upload_and_verify(env, "data-1k", ["--http2", "-H", "Content-Length:"])
+
     # POST some data using nghttp and see it echo'ed properly back
     def nghttp_post_and_verify(self, env, fname, options=None):
         url = env.mkurl("https", "cgi", "/proxy/echo.py")