This repository has been archived on 2026-04-27. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
website/src/nercone_website/tools/tls_test/http3.py
T
2026-04-19 18:54:47 +09:00

51 lines
1.6 KiB
Python

from __future__ import annotations
import asyncio
from dataclasses import dataclass
@dataclass
class Http3Info:
supported: bool = False
error: str | None = None
async def probe_http3(host: str, port: int, sni: str | None, timeout: float = 6.0) -> Http3Info:
"""Attempt a QUIC handshake to determine HTTP/3 availability.
Uses aioquic if available. On any failure returns supported=False.
"""
try:
from aioquic.asyncio.client import connect
from aioquic.quic.configuration import QuicConfiguration
from aioquic.quic.events import HandshakeCompleted
except Exception as e:
return Http3Info(supported=False, error=f"aioquic unavailable: {e}")
info = Http3Info()
try:
host_for_quic = sni or host
configuration = QuicConfiguration(
is_client=True,
alpn_protocols=["h3", "h3-29"],
verify_mode=None,
server_name=host_for_quic,
)
try:
import ssl as _ssl
configuration.verify_mode = _ssl.CERT_NONE
except Exception:
pass
async def _run():
# aioquic ≥ 0.9 dropped the `server_name` kwarg on connect(); SNI
# is taken from QuicConfiguration.server_name instead.
async with connect(host, port, configuration=configuration) as client:
await client.wait_connected()
return True
ok = await asyncio.wait_for(_run(), timeout=timeout)
info.supported = bool(ok)
except Exception as e:
info.supported = False
info.error = f"{e.__class__.__name__}: {e}"
return info