Files
syn-chat-bot/.venv/lib/python3.9/site-packages/qh3/quic/configuration.py
Hyungi Ahn c2257d3a86 fix: 포트 충돌 회피 — note_bridge 8098, intent_service 8099
Jellyfin(8096), OrbStack(8097) 포트 충돌으로 변경.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-19 13:53:55 +09:00

192 lines
5.1 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from os import PathLike
from re import split
from typing import TYPE_CHECKING, TextIO
if TYPE_CHECKING:
from .._hazmat import Certificate as X509Certificate
from .._hazmat import DsaPrivateKey, EcPrivateKey, Ed25519PrivateKey, RsaPrivateKey
from ..tls import (
CipherSuite,
SessionTicket,
load_pem_private_key,
load_pem_x509_certificates,
)
from .logger import QuicLogger
from .packet import QuicProtocolVersion
from .packet_builder import PACKET_MAX_SIZE
@dataclass
class QuicConfiguration:
"""
A QUIC configuration.
"""
alpn_protocols: list[str] | None = None
"""
A list of supported ALPN protocols.
"""
connection_id_length: int = 8
"""
The length in bytes of local connection IDs.
"""
idle_timeout: float = 60.0
"""
The idle timeout in seconds.
The connection is terminated if nothing is received for the given duration.
"""
is_client: bool = True
"""
Whether this is the client side of the QUIC connection.
"""
max_data: int = 1048576
"""
Connection-wide flow control limit.
"""
max_datagram_size: int = PACKET_MAX_SIZE
"""
The maximum QUIC payload size in bytes to send, excluding UDP or IP overhead.
"""
probe_datagram_size: bool = True
"""
Enable path MTU discovery. Client-only.
"""
max_stream_data: int = 1048576
"""
Per-stream flow control limit.
"""
quic_logger: QuicLogger | None = None
"""
The :class:`~qh3.quic.logger.QuicLogger` instance to log events to.
"""
secrets_log_file: TextIO = None
"""
A file-like object in which to log traffic secrets.
This is useful to analyze traffic captures with Wireshark.
"""
server_name: str | None = None
"""
The server name to send during the TLS handshake the Server Name Indication.
.. note:: This is only used by clients.
"""
session_ticket: SessionTicket | None = None
"""
The TLS session ticket which should be used for session resumption.
"""
hostname_checks_common_name: bool = False
assert_fingerprint: str | None = None
verify_hostname: bool = True
cadata: bytes | None = None
cafile: str | None = None
capath: str | None = None
certificate: X509Certificate | None = None
certificate_chain: list[X509Certificate] = field(default_factory=list)
cipher_suites: list[CipherSuite] | None = None
initial_rtt: float = 0.1
max_datagram_frame_size: int | None = None
original_version: int | None = None
private_key: (
EcPrivateKey | Ed25519PrivateKey | DsaPrivateKey | RsaPrivateKey | None
) = None
quantum_readiness_test: bool = False
supported_versions: list[int] = field(
default_factory=lambda: [
QuicProtocolVersion.VERSION_1,
QuicProtocolVersion.VERSION_2,
]
)
verify_mode: int | None = None
def load_cert_chain(
self,
certfile: str | bytes | PathLike,
keyfile: str | bytes | PathLike | None = None,
password: bytes | str | None = None,
) -> None:
"""
Load a private key and the corresponding certificate.
"""
if isinstance(certfile, str):
certfile = certfile.encode()
elif isinstance(certfile, PathLike):
certfile = str(certfile).encode()
if keyfile is not None:
if isinstance(keyfile, str):
keyfile = keyfile.encode()
elif isinstance(keyfile, PathLike):
keyfile = str(keyfile).encode()
# we either have the certificate or a file path in certfile/keyfile.
if b"-----BEGIN" not in certfile:
with open(certfile, "rb") as fp:
certfile = fp.read()
if keyfile is not None:
with open(keyfile, "rb") as fp:
keyfile = fp.read()
is_crlf = b"-----\r\n" in certfile
boundary = (
b"-----BEGIN PRIVATE KEY-----\n"
if not is_crlf
else b"-----BEGIN PRIVATE KEY-----\r\n"
)
chunks = split(b"\n" + boundary, certfile)
certificates = load_pem_x509_certificates(chunks[0])
if len(chunks) == 2:
private_key = boundary + chunks[1]
self.private_key = load_pem_private_key(private_key)
self.certificate = certificates[0]
self.certificate_chain = certificates[1:]
if keyfile is not None:
self.private_key = load_pem_private_key(
keyfile,
password=(
password.encode("utf8") if isinstance(password, str) else password
),
)
def load_verify_locations(
self,
cafile: str | None = None,
capath: str | None = None,
cadata: bytes | None = None,
) -> None:
"""
Load a set of "certification authority" (CA) certificates used to
validate other peers' certificates.
"""
self.cafile = cafile
self.capath = capath
self.cadata = cadata