quickjs-tart

quickjs-based runtime for wallet-core logic
Log | Files | Refs | README | LICENSE

test_12_reuse.py (8565B)


      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 from datetime import datetime, timedelta
     30 import pytest
     31 
     32 from testenv import Env, CurlClient
     33 
     34 
     35 log = logging.getLogger(__name__)
     36 
     37 
     38 @pytest.mark.skipif(condition=not Env.have_ssl_curl(), reason="curl without SSL")
     39 class TestReuse:
     40 
     41     # check if HTTP/1.1 handles 'Connection: close' correctly
     42     @pytest.mark.parametrize("proto", ['http/1.1'])
     43     def test_12_01_h1_conn_close(self, env: Env, httpd, configures_httpd, nghttpx, proto):
     44         httpd.reset_config()
     45         httpd.set_extra_config('base', [
     46             'MaxKeepAliveRequests 1',
     47         ])
     48         httpd.reload_if_config_changed()
     49         count = 100
     50         curl = CurlClient(env=env)
     51         urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]'
     52         r = curl.http_download(urls=[urln], alpn_proto=proto)
     53         r.check_response(count=count, http_status=200)
     54         # Server sends `Connection: close` on every 2nd request, requiring
     55         # a new connection
     56         delta = 5
     57         assert (count/2 - delta) < r.total_connects < (count/2 + delta)
     58 
     59     @pytest.mark.skipif(condition=Env.httpd_is_at_least('2.5.0'),
     60                         reason="httpd 2.5+ handles KeepAlives different")
     61     @pytest.mark.parametrize("proto", ['http/1.1'])
     62     def test_12_02_h1_conn_timeout(self, env: Env, httpd, configures_httpd, nghttpx, proto):
     63         httpd.reset_config()
     64         httpd.set_extra_config('base', [
     65             'KeepAliveTimeout 1',
     66         ])
     67         httpd.reload_if_config_changed()
     68         count = 5
     69         curl = CurlClient(env=env)
     70         urln = f'https://{env.authority_for(env.domain1, proto)}/data.json?[0-{count-1}]'
     71         r = curl.http_download(urls=[urln], alpn_proto=proto, extra_args=[
     72             '--rate', '30/m',
     73         ])
     74         r.check_response(count=count, http_status=200)
     75         # Connections time out on server before we send another request,
     76         assert r.total_connects == count
     77 
     78     @pytest.mark.skipif(condition=not Env.have_h3(), reason="h3 not supported")
     79     def test_12_03_as_follow_h2h3(self, env: Env, httpd, configures_httpd, nghttpx):
     80         # write an alt-svc file that advises h3 instead of h2
     81         asfile = os.path.join(env.gen_dir, 'alt-svc-12_03.txt')
     82         self.create_asfile(asfile, f'h2 {env.domain1} {env.https_port} h3 {env.domain1} {env.h3_port}')
     83         curl = CurlClient(env=env)
     84         urln = f'https://{env.authority_for(env.domain1, "h2")}/data.json'
     85         r = curl.http_download(urls=[urln], with_stats=True, extra_args=[
     86             '--alt-svc', f'{asfile}',
     87         ])
     88         r.check_response(count=1, http_status=200)
     89         assert r.stats[0]['http_version'] == '3', f'{r.stats}'
     90 
     91     @pytest.mark.skipif(condition=not Env.have_h3(), reason="h3 not supported")
     92     def test_12_04_as_follow_h3h2(self, env: Env, httpd, configures_httpd, nghttpx):
     93         count = 2
     94         # write an alt-svc file the advises h2 instead of h3
     95         asfile = os.path.join(env.gen_dir, 'alt-svc-12_04.txt')
     96         ts = datetime.now() + timedelta(hours=24)
     97         expires = f'{ts.year:04}{ts.month:02}{ts.day:02} {ts.hour:02}:{ts.minute:02}:{ts.second:02}'
     98         with open(asfile, 'w') as fd:
     99             fd.write(f'h3 {env.domain1} {env.https_port} h2 {env.domain1} {env.https_port} "{expires}" 0 0')
    100         log.info(f'altscv: {open(asfile).readlines()}')
    101         curl = CurlClient(env=env)
    102         urln = f'https://{env.authority_for(env.domain1, "h3")}/data.json?[0-{count-1}]'
    103         r = curl.http_download(urls=[urln], with_stats=True, extra_args=[
    104             '--alt-svc', f'{asfile}', '--http3'
    105         ])
    106         r.check_response(count=count, http_status=200)
    107         # We expect the connection to be reused and use HTTP/2
    108         assert r.total_connects == 1
    109         for s in r.stats:
    110             assert s['http_version'] == '2', f'{s}'
    111 
    112     @pytest.mark.skipif(condition=not Env.have_h3(), reason="h3 not supported")
    113     def test_12_05_as_follow_h3h1(self, env: Env, httpd, configures_httpd, nghttpx):
    114         # With '--http3` an Alt-Svc redirection from h3 to h1 is allowed
    115         count = 2
    116         # write an alt-svc file the advises h1 instead of h3
    117         asfile = os.path.join(env.gen_dir, 'alt-svc-12_05.txt')
    118         ts = datetime.now() + timedelta(hours=24)
    119         expires = f'{ts.year:04}{ts.month:02}{ts.day:02} {ts.hour:02}:{ts.minute:02}:{ts.second:02}'
    120         with open(asfile, 'w') as fd:
    121             fd.write(f'h3 {env.domain1} {env.https_port} http/1.1 {env.domain1} {env.https_port} "{expires}" 0 0')
    122         log.info(f'altscv: {open(asfile).readlines()}')
    123         curl = CurlClient(env=env)
    124         urln = f'https://{env.authority_for(env.domain1, "h3")}/data.json?[0-{count-1}]'
    125         r = curl.http_download(urls=[urln], with_stats=True, extra_args=[
    126             '--alt-svc', f'{asfile}', '--http3'
    127         ])
    128         r.check_response(count=count, http_status=200)
    129         # We expect the connection to be reused and use HTTP/1.1
    130         assert r.total_connects == 1
    131         for s in r.stats:
    132             assert s['http_version'] == '1.1', f'{s}'
    133 
    134     @pytest.mark.skipif(condition=not Env.have_h3(), reason="h3 not supported")
    135     def test_12_06_as_ignore_h3h1(self, env: Env, httpd, configures_httpd, nghttpx):
    136         # With '--http3-only` an Alt-Svc redirection from h3 to h1 is ignored
    137         count = 2
    138         # write an alt-svc file the advises h1 instead of h3
    139         asfile = os.path.join(env.gen_dir, 'alt-svc-12_05.txt')
    140         ts = datetime.now() + timedelta(hours=24)
    141         expires = f'{ts.year:04}{ts.month:02}{ts.day:02} {ts.hour:02}:{ts.minute:02}:{ts.second:02}'
    142         with open(asfile, 'w') as fd:
    143             fd.write(f'h3 {env.domain1} {env.https_port} http/1.1 {env.domain1} {env.https_port} "{expires}" 0 0')
    144         log.info(f'altscv: {open(asfile).readlines()}')
    145         curl = CurlClient(env=env)
    146         urln = f'https://{env.authority_for(env.domain1, "h3")}/data.json?[0-{count-1}]'
    147         r = curl.http_download(urls=[urln], with_stats=True, extra_args=[
    148             '--alt-svc', f'{asfile}', '--http3-only'
    149         ])
    150         r.check_response(count=count, http_status=200)
    151         # We expect the connection to be stay on h3, since we used --http3-only
    152         assert r.total_connects == 1
    153         for s in r.stats:
    154             assert s['http_version'] == '3', f'{s}'
    155 
    156     @pytest.mark.skipif(condition=not Env.have_h3(), reason="h3 not supported")
    157     def test_12_07_as_ignore_h2h3(self, env: Env, httpd, configures_httpd, nghttpx):
    158         # With '--http2` an Alt-Svc redirection from h2 to h3 is ignored
    159         # write an alt-svc file that advises h3 instead of h2
    160         asfile = os.path.join(env.gen_dir, 'alt-svc-12_03.txt')
    161         self.create_asfile(asfile, f'h2 {env.domain1} {env.https_port} h3 {env.domain1} {env.h3_port}')
    162         curl = CurlClient(env=env)
    163         urln = f'https://{env.authority_for(env.domain1, "h2")}/data.json'
    164         r = curl.http_download(urls=[urln], with_stats=True, extra_args=[
    165             '--alt-svc', f'{asfile}', '--http2'
    166         ])
    167         r.check_response(count=1, http_status=200)
    168         assert r.stats[0]['http_version'] == '2', f'{r.stats}'
    169 
    170     def create_asfile(self, fpath, line):
    171         ts = datetime.now() + timedelta(hours=24)
    172         expires = f'{ts.year:04}{ts.month:02}{ts.day:02} {ts.hour:02}:{ts.minute:02}:{ts.second:02}'
    173         with open(fpath, 'w') as fd:
    174             fd.write(f'{line} "{expires}" 0 0')
    175         log.info(f'altscv: {open(fpath).readlines()}')