--
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
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:
|
||||
configuration = QuicConfiguration(
|
||||
is_client=True,
|
||||
alpn_protocols=["h3", "h3-29"],
|
||||
verify_mode=None,
|
||||
)
|
||||
try:
|
||||
import ssl as _ssl
|
||||
configuration.verify_mode = _ssl.CERT_NONE
|
||||
except Exception:
|
||||
pass
|
||||
host_for_quic = sni or host
|
||||
|
||||
async def _run():
|
||||
async with connect(host, port, configuration=configuration, server_name=host_for_quic) 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
|
||||
Reference in New Issue
Block a user