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# 27import logging 28import os 29import pytest 30 31from testenv import Env, CurlClient, LocalClient 32 33 34log = logging.getLogger(__name__) 35 36 37class 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 httpd.set_extra_config(env.domain1, [ 48 'H2EarlyHints on', 49 '<Location /push/data1>', 50 ' H2PushResource /push/data2', 51 '</Location>', 52 '<Location /push/data2>', 53 ' H2PushResource /push/data1', 54 ' H2PushResource /push/data3', 55 '</Location>', 56 ]) 57 # activate the new config 58 httpd.reload() 59 yield 60 httpd.clear_extra_configs() 61 httpd.reload() 62 63 # download a file that triggers a "103 Early Hints" response 64 def test_09_01_h2_early_hints(self, env: Env, httpd, repeat): 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, repeat): 76 # use localhost as we do not have resolve support in local client 77 url = f'https://localhost:{env.https_port}/push/data1' 78 client = LocalClient(name='h2-serverpush', env=env) 79 if not client.exists(): 80 pytest.skip(f'example client not built: {client.name}') 81 r = client.run(args=[url]) 82 r.check_exit_code(0) 83 assert os.path.exists(client.download_file(0)) 84 assert os.path.exists(os.path.join(client.run_dir, 'push0')), r.dump_logs() 85