test_09_push.py (3464B)
1 #!/usr/bin/env python3 2 # -*- coding: utf-8 -*- 3 #*************************************************************************** 4 # _ _ ____ _ 5 # Project ___| | | | _ \| | 6 # / __| | | | |_) | | 7 # | (__| |_| | _ <| |___ 8 # \___|\___/|_| \_\_____| 9 # 10 # Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al. 11 # 12 # This software is licensed as described in the file COPYING, which 13 # you should have received as part of this distribution. The terms 14 # are also available at https://curl.se/docs/copyright.html. 15 # 16 # You may opt to use, copy, modify, merge, publish, distribute and/or sell 17 # copies of the Software, and permit persons to whom the Software is 18 # furnished to do so, under the terms of the COPYING file. 19 # 20 # This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 21 # KIND, either express or implied. 22 # 23 # SPDX-License-Identifier: curl 24 # 25 ########################################################################### 26 # 27 import logging 28 import os 29 import pytest 30 31 from testenv import Env, CurlClient, LocalClient 32 33 34 log = logging.getLogger(__name__) 35 36 37 class TestPush: 38 39 @pytest.fixture(autouse=True, scope='class') 40 def _class_scope(self, env, httpd): 41 push_dir = os.path.join(httpd.docs_dir, 'push') 42 if not os.path.exists(push_dir): 43 os.makedirs(push_dir) 44 env.make_data_file(indir=push_dir, fname="data1", fsize=1*1024) 45 env.make_data_file(indir=push_dir, fname="data2", fsize=1*1024) 46 env.make_data_file(indir=push_dir, fname="data3", fsize=1*1024) 47 48 def httpd_configure(self, env, httpd): 49 httpd.set_extra_config(env.domain1, [ 50 'H2EarlyHints on', 51 '<Location /push/data1>', 52 ' H2PushResource /push/data2', 53 '</Location>', 54 '<Location /push/data2>', 55 ' H2PushResource /push/data1', 56 ' H2PushResource /push/data3', 57 '</Location>', 58 ]) 59 # activate the new config 60 httpd.reload_if_config_changed() 61 62 # download a file that triggers a "103 Early Hints" response 63 def test_09_01_h2_early_hints(self, env: Env, httpd, configures_httpd): 64 self.httpd_configure(env, httpd) 65 curl = CurlClient(env=env) 66 url = f'https://{env.domain1}:{env.https_port}/push/data1' 67 r = curl.http_download(urls=[url], alpn_proto='h2', with_stats=False, 68 with_headers=True) 69 r.check_exit_code(0) 70 assert len(r.responses) == 2, f'{r.responses}' 71 assert r.responses[0]['status'] == 103, f'{r.responses}' 72 assert 'link' in r.responses[0]['header'], f'{r.responses[0]}' 73 assert r.responses[0]['header']['link'] == '</push/data2>; rel=preload', f'{r.responses[0]}' 74 75 def test_09_02_h2_push(self, env: Env, httpd, configures_httpd): 76 self.httpd_configure(env, httpd) 77 # use localhost as we do not have resolve support in local client 78 url = f'https://localhost:{env.https_port}/push/data1' 79 client = LocalClient(name='h2_serverpush', env=env) 80 if not client.exists(): 81 pytest.skip(f'example client not built: {client.name}') 82 r = client.run(args=[url]) 83 r.check_exit_code(0) 84 assert os.path.exists(client.download_file(0)) 85 assert os.path.exists(os.path.join(client.run_dir, 'push0')), r.dump_logs()