Uh oh!
There was an error while loading. Please reload this page.
- Notifications
You must be signed in to change notification settings - Fork 191
Add HTTP3 support#829
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Uh oh!
There was an error while loading. Please reload this page.
Add HTTP3 support #829
Changes from all commits
bd31869383d4ceacce83a0d5bf6637cb6b4bcd3934d21d675306c3b408c6271c00b2f5c29901b94d4c22ca5e5ad120c8d16baead4File filter
Filter by extension
Conversations
Uh oh!
There was an error while loading. Please reload this page.
Jump to
Uh oh!
There was an error while loading. Please reload this page.
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -41,6 +41,7 @@ def __init__( | ||
| keepalive_expiry: Optional[float] = None, | ||
| http1: bool = True, | ||
| http2: bool = False, | ||
| http3: bool = False, | ||
| retries: int = 0, | ||
| local_address: Optional[str] = None, | ||
| uds: Optional[str] = None, | ||
| @@ -52,6 +53,7 @@ def __init__( | ||
| self._keepalive_expiry = keepalive_expiry | ||
| self._http1 = http1 | ||
| self._http2 = http2 | ||
| self._http3 = http3 | ||
| self._retries = retries | ||
| self._local_address = local_address | ||
| self._uds = uds | ||
| @@ -80,7 +82,18 @@ async def handle_async_request(self, request: Request) -> Response: | ||
| ssl_object is not None | ||
| and ssl_object.selected_alpn_protocol() == "h2" | ||
| ) | ||
| if http2_negotiated or (self._http2 and not self._http1): | ||
| if self._http3 and not ( | ||
| self._http1 or self._http2 | ||
| ): # pragma: no cover | ||
| from .http3 import AsyncHTTP3Connection | ||
karpetrosyan marked this conversation as resolved.
Uh oh!There was an error while loading. Please reload this page. | ||
| stream = await self._connect_http3(request) | ||
Contributor There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be doing happy eyeballs | ||
| self._connection = AsyncHTTP3Connection( | ||
| origin=self._origin, | ||
| stream=stream, | ||
| keepalive_expiry=self._keepalive_expiry, | ||
| ) | ||
| elif http2_negotiated or (self._http2 and not self._http1): | ||
| from .http2 import AsyncHTTP2Connection | ||
| self._connection = AsyncHTTP2Connection( | ||
| @@ -162,6 +175,30 @@ async def _connect(self, request: Request) -> AsyncNetworkStream: | ||
| async with Trace("retry", logger, request, kwargs) as trace: | ||
| await self._network_backend.sleep(delay) | ||
| async def _connect_http3( | ||
| self, request: Request | ||
| ) -> AsyncNetworkStream: # pragma: nocover | ||
| retries_left = self._retries | ||
| delays = exponential_backoff(factor=RETRIES_BACKOFF_FACTOR) | ||
| while True: | ||
| try: | ||
| kwargs = { | ||
| "host": self._origin.host.decode("ascii"), | ||
| "port": self._origin.port, | ||
| } | ||
| async with Trace("connect_udp", logger, request, kwargs) as trace: | ||
| stream = await self._network_backend.connect_udp(**kwargs) # type: ignore | ||
| trace.return_value = stream | ||
| return stream | ||
| except (ConnectError, ConnectTimeout): | ||
| if retries_left <= 0: | ||
| raise | ||
| retries_left -= 1 | ||
| delay = next(delays) | ||
| async with Trace("retry", logger, request, kwargs) as trace: | ||
| await self._network_backend.sleep(delay) | ||
| def can_handle_request(self, origin: Origin) -> bool: | ||
| return origin == self._origin | ||
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.