]> git.ipfire.org Git - thirdparty/curl.git/commitdiff
tests-httpd: add proxy tests
authorStefan Eissing <stefan@eissing.org>
Wed, 15 Feb 2023 11:39:46 +0000 (12:39 +0100)
committerDaniel Stenberg <daniel@haxx.se>
Fri, 17 Feb 2023 10:40:57 +0000 (11:40 +0100)
for direct and tunneling checks on http: and https:

Closes #10519

tests/tests-httpd/config.ini.in
tests/tests-httpd/test_10_proxy.py
tests/tests-httpd/testenv/env.py
tests/tests-httpd/testenv/httpd.py

index 3b1d28de846658ddaa88116c2c72f828e670a1ef..68ab0d360f5c15ee07b25a67a88615f777a8759c 100644 (file)
@@ -34,11 +34,13 @@ apachectl = @APACHECTL@
 http_port = 5001
 https_port = 5002
 h3_port = 5002
+proxy_port = 5004
+proxys_port = 5005
 
 [nghttpx]
 nghttpx = @HTTPD_NGHTTPX@
 
 [caddy]
 caddy = @CADDY@
-http_port = 5003
-https_port = 5004
+http_port = 5010
+https_port = 5011
index 1c444eec0f0cf69e750c7fb44d294914c1915a80..cde69e5efae891e5364a02bc96b8fa6dbcbe1fd2 100644 (file)
@@ -45,26 +45,89 @@ class TestProxy:
             os.makedirs(push_dir)
 
     # download via http: proxy (no tunnel)
-    def test_10_01_http_get(self, env: Env, httpd, repeat):
+    def test_10_01_proxy_http(self, env: Env, httpd, repeat):
         curl = CurlClient(env=env)
         url = f'http://localhost:{env.http_port}/data.json'
         r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
                                extra_args=[
-                                 '--proxy', f'http://{env.proxy_domain}:{env.http_port}/',
-                                 '--resolve', f'{env.proxy_domain}:{env.http_port}:127.0.0.1',
+                                 '--proxy', f'http://{env.proxy_domain}:{env.proxy_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxy_port}:127.0.0.1',
                                ])
         assert r.exit_code == 0
         r.check_stats(count=1, exp_status=200)
 
     # download via https: proxy (no tunnel)
-    def test_10_02_http_get(self, env: Env, httpd, repeat):
+    def test_10_02_proxy_https(self, env: Env, httpd, repeat):
         curl = CurlClient(env=env)
         url = f'http://localhost:{env.http_port}/data.json'
         r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
                                extra_args=[
-                                 '--proxy', f'https://{env.proxy_domain}:{env.https_port}/',
-                                 '--resolve', f'{env.proxy_domain}:{env.https_port}:127.0.0.1',
+                                 '--proxy', f'https://{env.proxy_domain}:{env.proxys_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxys_port}:127.0.0.1',
                                  '--proxy-cacert', env.ca.cert_file,
                                ])
         assert r.exit_code == 0
         r.check_stats(count=1, exp_status=200)
+
+    # download http: via http: proxytunnel
+    def test_10_03_proxytunnel_http(self, env: Env, httpd, repeat):
+        curl = CurlClient(env=env)
+        url = f'http://localhost:{env.http_port}/data.json'
+        r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
+                               extra_args=[
+                                 '--proxytunnel',
+                                 '--proxy', f'http://{env.proxy_domain}:{env.proxy_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxy_port}:127.0.0.1',
+                               ])
+        assert r.exit_code == 0
+        r.check_stats(count=1, exp_status=200)
+
+    # download http: via https: proxytunnel
+    def test_10_04_proxy_https(self, env: Env, httpd, repeat):
+        curl = CurlClient(env=env)
+        url = f'http://localhost:{env.http_port}/data.json'
+        r = curl.http_download(urls=[url], alpn_proto='http/1.1', with_stats=True,
+                               extra_args=[
+                                 '--proxytunnel',
+                                 '--proxy', f'https://{env.proxy_domain}:{env.proxys_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxys_port}:127.0.0.1',
+                                 '--proxy-cacert', env.ca.cert_file,
+                               ])
+        assert r.exit_code == 0
+        r.check_stats(count=1, exp_status=200)
+
+    # download https: with proto via http: proxytunnel
+    @pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
+    def test_10_05_proxytunnel_http(self, env: Env, httpd, proto, repeat):
+        curl = CurlClient(env=env)
+        url = f'https://localhost:{env.https_port}/data.json'
+        r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True,
+                               with_headers=True,
+                               extra_args=[
+                                 '--proxytunnel',
+                                 '--proxy', f'http://{env.proxy_domain}:{env.proxy_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxy_port}:127.0.0.1',
+                               ])
+        assert r.exit_code == 0
+        r.check_stats(count=1, exp_status=200)
+        exp_proto = 'HTTP/2' if proto == 'h2' else 'HTTP/1.1'
+        assert r.response['protocol'] == exp_proto
+
+    # download https: with proto via https: proxytunnel
+    @pytest.mark.parametrize("proto", ['http/1.1', 'h2'])
+    def test_10_06_proxy_https(self, env: Env, httpd, proto, repeat):
+        curl = CurlClient(env=env)
+        url = f'https://localhost:{env.https_port}/data.json'
+        r = curl.http_download(urls=[url], alpn_proto=proto, with_stats=True,
+                               with_headers=True,
+                               extra_args=[
+                                 '--proxytunnel',
+                                 '--proxy', f'https://{env.proxy_domain}:{env.proxys_port}/',
+                                 '--resolve', f'{env.proxy_domain}:{env.proxys_port}:127.0.0.1',
+                                 '--proxy-cacert', env.ca.cert_file,
+                               ])
+        assert r.exit_code == 0
+        r.check_stats(count=1, exp_status=200)
+        exp_proto = 'HTTP/2' if proto == 'h2' else 'HTTP/1.1'
+        assert r.response['protocol'] == exp_proto
+
index 07eb999e9e47ed3d535f46021917bf69e5fd5ccd..f468043dd8524c4fdabe0b2c3be9c665eed7b6ae 100644 (file)
@@ -97,6 +97,8 @@ class EnvConfig:
 
         self.http_port = self.config['test']['http_port']
         self.https_port = self.config['test']['https_port']
+        self.proxy_port = self.config['test']['proxy_port']
+        self.proxys_port = self.config['test']['proxys_port']
         self.h3_port = self.config['test']['h3_port']
         self.httpd = self.config['httpd']['httpd']
         self.apachectl = self.config['httpd']['apachectl']
@@ -115,7 +117,7 @@ class EnvConfig:
         self.domain2 = f"two.{self.tld}"
         self.proxy_domain = f"proxy.{self.tld}"
         self.cert_specs = [
-            CertificateSpec(domains=[self.domain1], key_type='rsa2048'),
+            CertificateSpec(domains=[self.domain1, 'localhost'], key_type='rsa2048'),
             CertificateSpec(domains=[self.domain2], key_type='rsa2048'),
             CertificateSpec(domains=[self.proxy_domain], key_type='rsa2048'),
             CertificateSpec(name="clientsX", sub_specs=[
@@ -300,7 +302,6 @@ class Env:
     def proxy_domain(self) -> str:
         return self.CONFIG.proxy_domain
 
-
     @property
     def http_port(self) -> str:
         return self.CONFIG.http_port
@@ -313,6 +314,14 @@ class Env:
     def h3_port(self) -> str:
         return self.CONFIG.h3_port
 
+    @property
+    def proxy_port(self) -> str:
+        return self.CONFIG.proxy_port
+
+    @property
+    def proxys_port(self) -> str:
+        return self.CONFIG.proxys_port
+
     @property
     def caddy(self) -> str:
         return self.CONFIG.caddy
index 21e10e65ccb5ccdf95eb7266058f6b8cd6785760..4e027dfb54c5707054daf5e6cb18d1e066b3e95c 100644 (file)
@@ -226,6 +226,8 @@ class Httpd:
                 f'H2MaxWorkers 128',
                 f'Listen {self.env.http_port}',
                 f'Listen {self.env.https_port}',
+                f'Listen {self.env.proxy_port}',
+                f'Listen {self.env.proxys_port}',
                 f'TypesConfig "{self._conf_dir}/mime.types',
             ]
             conf.extend([  # plain http host for domain1
@@ -239,33 +241,6 @@ class Httpd:
                 f'</VirtualHost>',
                 f'',
             ])
-            conf.extend([  # http forward proxy
-                f'<VirtualHost *:{self.env.http_port}>',
-                f'    ServerName {proxy_domain}',
-                f'    Protocols http/1.1',
-                f'    ProxyRequests On',
-                f'    ProxyVia On',
-                f'    AllowCONNECT {self.env.http_port} {self.env.https_port}',
-                f'    <Proxy "*">',
-                f'      Require ip 127.0.0.1',
-                f'    </Proxy>',
-                f'</VirtualHost>',
-            ])
-            conf.extend([  # https forward proxy
-                f'<VirtualHost *:{self.env.https_port}>',
-                f'    ServerName {proxy_domain}',
-                f'    Protocols http/1.1',
-                f'    SSLEngine on',
-                f'    SSLCertificateFile {proxy_creds.cert_file}',
-                f'    SSLCertificateKeyFile {proxy_creds.pkey_file}',
-                f'    ProxyRequests On',
-                f'    ProxyVia On',
-                f'    AllowCONNECT {self.env.http_port} {self.env.https_port}',
-                f'    <Proxy "*">',
-                f'      Require ip 127.0.0.1',
-                f'    </Proxy>',
-                f'</VirtualHost>',
-            ])
             conf.extend([  # https host for domain1, h1 + h2
                 f'<VirtualHost *:{self.env.https_port}>',
                 f'    ServerName {domain1}',
@@ -298,6 +273,33 @@ class Httpd:
                 f'</VirtualHost>',
                 f'',
             ])
+            conf.extend([  # http forward proxy
+                f'<VirtualHost *:{self.env.proxy_port}>',
+                f'    ServerName {proxy_domain}',
+                f'    Protocols h2c, http/1.1',
+                f'    ProxyRequests On',
+                f'    ProxyVia On',
+                f'    AllowCONNECT {self.env.http_port} {self.env.https_port}',
+                f'    <Proxy "*">',
+                f'      Require ip 127.0.0.1',
+                f'    </Proxy>',
+                f'</VirtualHost>',
+            ])
+            conf.extend([  # https forward proxy
+                f'<VirtualHost *:{self.env.proxys_port}>',
+                f'    ServerName {proxy_domain}',
+                f'    Protocols h2, http/1.1',
+                f'    SSLEngine on',
+                f'    SSLCertificateFile {proxy_creds.cert_file}',
+                f'    SSLCertificateKeyFile {proxy_creds.pkey_file}',
+                f'    ProxyRequests On',
+                f'    ProxyVia On',
+                f'    AllowCONNECT {self.env.http_port} {self.env.https_port}',
+                f'    <Proxy "*">',
+                f'      Require ip 127.0.0.1',
+                f'    </Proxy>',
+                f'</VirtualHost>',
+            ])
             fd.write("\n".join(conf))
         with open(os.path.join(self._conf_dir, 'mime.types'), 'w') as fd:
             fd.write("\n".join([