async def test_throughput(server: Server, configuration: QuicConfiguration): failures = 0 if server.throughput_path is None: return for size in [5000000, 10000000]: path = server.throughput_path % {"size": size} print("Testing %d bytes download: %s" % (size, path)) # perform HTTP request over TCP start = time.time() response = httpx.get("https://" + server.host + path, verify=False) tcp_octets = len(response.content) tcp_elapsed = time.time() - start assert tcp_octets == size, "HTTP/TCP response size mismatch" # perform HTTP request over QUIC if server.http3: configuration.alpn_protocols = H3_ALPN port = server.http3_port or server.port else: configuration.alpn_protocols = H0_ALPN port = server.port start = time.time() async with connect( server.host, port, configuration=configuration, create_protocol=HttpClient, ) as protocol: protocol = cast(HttpClient, protocol) http_events = await protocol.get("https://{}:{}{}".format( server.host, server.port, path)) quic_elapsed = time.time() - start quic_octets = 0 for http_event in http_events: if isinstance(http_event, DataReceived): quic_octets += len(http_event.data) assert quic_octets == size, "HTTP/QUIC response size mismatch" print(" - HTTP/TCP completed in %.3f s" % tcp_elapsed) print(" - HTTP/QUIC completed in %.3f s" % quic_elapsed) if quic_elapsed > 1.1 * tcp_elapsed: failures += 1 print(" => FAIL") else: print(" => PASS") if failures == 0: server.result |= Result.T
async def test_http_3(server: Server, configuration: QuicConfiguration): if server.path is None: return configuration.alpn_protocols = H3_ALPN async with connect( server.host, server.port, configuration=configuration, create_protocol=HttpClient, ) as protocol: protocol = cast(HttpClient, protocol) # perform HTTP request events = await protocol.get("https://{}:{}{}".format( server.host, server.port, server.path)) if events and isinstance(events[0], HeadersReceived): server.result |= Result.D server.result |= Result.three # perform more HTTP requests to use QPACK dynamic tables for i in range(2): events = await protocol.get("https://{}:{}{}".format( server.host, server.port, server.path)) if events and isinstance(events[0], HeadersReceived): http = cast(H3Connection, protocol._http) protocol._quic._logger.info( "QPACK decoder bytes RX %d TX %d", http._decoder_bytes_received, http._decoder_bytes_sent, ) protocol._quic._logger.info( "QPACK encoder bytes RX %d TX %d", http._encoder_bytes_received, http._encoder_bytes_sent, ) if (http._decoder_bytes_received and http._decoder_bytes_sent and http._encoder_bytes_received and http._encoder_bytes_sent): server.result |= Result.d # check push support if server.push_path is not None: protocol.pushes.clear() await protocol.get("https://{}:{}{}".format( server.host, server.port, server.push_path)) await asyncio.sleep(0.5) for push_id, events in protocol.pushes.items(): if (len(events) >= 3 and isinstance(events[0], PushPromiseReceived) and isinstance(events[1], HeadersReceived) and isinstance(events[2], DataReceived)): protocol._quic._logger.info( "Push promise %d for %s received (status %s)", push_id, dict(events[0].headers)[b":path"].decode("ascii"), int(dict(events[1].headers)[b":status"]), ) server.result |= Result.p
async def test_http_0(server: Server, configuration: QuicConfiguration): if server.path is None: return configuration.alpn_protocols = ["hq-22"] async with connect( server.host, server.port, configuration=configuration, create_protocol=HttpClient, ) as protocol: protocol = cast(HttpClient, protocol) # perform HTTP request events = await protocol.get(server.host, server.path) if events and isinstance(events[0], ResponseReceived): server.result |= Result.D
async def test_http_0(server: Server, configuration: QuicConfiguration): if server.path is None: return configuration.alpn_protocols = H0_ALPN async with connect( server.host, server.port, configuration=configuration, create_protocol=HttpClient, ) as protocol: protocol = cast(HttpClient, protocol) # perform HTTP request events = await protocol.get("https://{}:{}{}".format( server.host, server.port, server.path)) if events and isinstance(events[0], HeadersReceived): server.result |= Result.D
async def test_http_3(server: Server, configuration: QuicConfiguration): if server.path is None: return configuration.alpn_protocols = H3_ALPN async with connect( server.host, server.port, configuration=configuration, create_protocol=HttpClient, ) as protocol: protocol = cast(HttpClient, protocol) # perform HTTP request events = await protocol.get("https://{}:{}{}".format( server.host, server.port, server.path)) if events and isinstance(events[0], HeadersReceived): server.result |= Result.D server.result |= Result.three # perform more HTTP requests to use QPACK dynamic tables for i in range(2): events = await protocol.get("https://{}:{}{}".format( server.host, server.port, server.path)) if events and isinstance(events[0], HeadersReceived): http = cast(H3Connection, protocol._http) protocol._quic._logger.info( "QPACK decoder bytes RX %d TX %d", http._decoder_bytes_received, http._decoder_bytes_sent, ) protocol._quic._logger.info( "QPACK encoder bytes RX %d TX %d", http._encoder_bytes_received, http._encoder_bytes_sent, ) if (http._decoder_bytes_received and http._decoder_bytes_sent and http._encoder_bytes_received and http._encoder_bytes_sent): server.result |= Result.d # check push support if protocol.pushes: server.result |= Result.p