diff options
| author | robot-piglet <[email protected]> | 2024-03-07 13:39:40 +0300 |
|---|---|---|
| committer | robot-piglet <[email protected]> | 2024-03-07 13:48:37 +0300 |
| commit | a5bc35bb658487b44e707d555998bbec6cb14eab (patch) | |
| tree | 4df3ffcdd48c13abc65053c681eeb9ad05901f2b /contrib/python/httpcore | |
| parent | e49f2e6094ceb19570c44590cd0e5909a104b81d (diff) | |
Intermediate changes
Diffstat (limited to 'contrib/python/httpcore')
| -rw-r--r-- | contrib/python/httpcore/.dist-info/METADATA | 9 | ||||
| -rw-r--r-- | contrib/python/httpcore/httpcore/__init__.py | 2 | ||||
| -rw-r--r-- | contrib/python/httpcore/httpcore/_async/http11.py | 50 | ||||
| -rw-r--r-- | contrib/python/httpcore/httpcore/_models.py | 8 | ||||
| -rw-r--r-- | contrib/python/httpcore/httpcore/_sync/http11.py | 50 | ||||
| -rw-r--r-- | contrib/python/httpcore/ya.make | 2 |
6 files changed, 111 insertions, 10 deletions
diff --git a/contrib/python/httpcore/.dist-info/METADATA b/contrib/python/httpcore/.dist-info/METADATA index 51de714c586..7804db1a8b3 100644 --- a/contrib/python/httpcore/.dist-info/METADATA +++ b/contrib/python/httpcore/.dist-info/METADATA @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: httpcore -Version: 1.0.3 +Version: 1.0.4 Summary: A minimal low-level HTTP client. Project-URL: Documentation, https://www.encode.io/httpcore Project-URL: Homepage, https://www.encode.io/httpcore/ @@ -33,7 +33,7 @@ Requires-Dist: h2<5,>=3; extra == 'http2' Provides-Extra: socks Requires-Dist: socksio==1.*; extra == 'socks' Provides-Extra: trio -Requires-Dist: trio<0.24.0,>=0.22.0; extra == 'trio' +Requires-Dist: trio<0.25.0,>=0.22.0; extra == 'trio' Description-Content-Type: text/markdown # HTTP Core @@ -153,6 +153,11 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). +## 1.0.4 (February 21st, 2024) + +- Add `target` request extension. (#888) +- Fix support for connection `Upgrade` and `CONNECT` when some data in the stream has been read. (#882) + ## 1.0.3 (February 13th, 2024) - Fix support for async cancellations. (#880) diff --git a/contrib/python/httpcore/httpcore/__init__.py b/contrib/python/httpcore/httpcore/__init__.py index 3709fc4080c..ea2a2409219 100644 --- a/contrib/python/httpcore/httpcore/__init__.py +++ b/contrib/python/httpcore/httpcore/__init__.py @@ -130,7 +130,7 @@ __all__ = [ "WriteError", ] -__version__ = "1.0.3" +__version__ = "1.0.4" __locals = locals() diff --git a/contrib/python/httpcore/httpcore/_async/http11.py b/contrib/python/httpcore/httpcore/_async/http11.py index a5eb480840d..0493a923dc1 100644 --- a/contrib/python/httpcore/httpcore/_async/http11.py +++ b/contrib/python/httpcore/httpcore/_async/http11.py @@ -1,8 +1,10 @@ import enum import logging +import ssl import time from types import TracebackType from typing import ( + Any, AsyncIterable, AsyncIterator, List, @@ -107,6 +109,7 @@ class AsyncHTTP11Connection(AsyncConnectionInterface): status, reason_phrase, headers, + trailing_data, ) = await self._receive_response_headers(**kwargs) trace.return_value = ( http_version, @@ -115,6 +118,14 @@ class AsyncHTTP11Connection(AsyncConnectionInterface): headers, ) + network_stream = self._network_stream + + # CONNECT or Upgrade request + if (status == 101) or ( + (request.method == b"CONNECT") and (200 <= status < 300) + ): + network_stream = AsyncHTTP11UpgradeStream(network_stream, trailing_data) + return Response( status=status, headers=headers, @@ -122,7 +133,7 @@ class AsyncHTTP11Connection(AsyncConnectionInterface): extensions={ "http_version": http_version, "reason_phrase": reason_phrase, - "network_stream": self._network_stream, + "network_stream": network_stream, }, ) except BaseException as exc: @@ -167,7 +178,7 @@ class AsyncHTTP11Connection(AsyncConnectionInterface): async def _receive_response_headers( self, request: Request - ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]]]: + ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]], bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) @@ -187,7 +198,9 @@ class AsyncHTTP11Connection(AsyncConnectionInterface): # raw header casing, rather than the enforced lowercase headers. headers = event.headers.raw_items() - return http_version, event.status_code, event.reason, headers + trailing_data, _ = self._h11_state.trailing_data + + return http_version, event.status_code, event.reason, headers, trailing_data async def _receive_response_body(self, request: Request) -> AsyncIterator[bytes]: timeouts = request.extensions.get("timeout", {}) @@ -340,3 +353,34 @@ class HTTP11ConnectionByteStream: self._closed = True async with Trace("response_closed", logger, self._request): await self._connection._response_closed() + + +class AsyncHTTP11UpgradeStream(AsyncNetworkStream): + def __init__(self, stream: AsyncNetworkStream, leading_data: bytes) -> None: + self._stream = stream + self._leading_data = leading_data + + async def read(self, max_bytes: int, timeout: Optional[float] = None) -> bytes: + if self._leading_data: + buffer = self._leading_data[:max_bytes] + self._leading_data = self._leading_data[max_bytes:] + return buffer + else: + return await self._stream.read(max_bytes, timeout) + + async def write(self, buffer: bytes, timeout: Optional[float] = None) -> None: + await self._stream.write(buffer, timeout) + + async def aclose(self) -> None: + await self._stream.aclose() + + async def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: Optional[str] = None, + timeout: Optional[float] = None, + ) -> AsyncNetworkStream: + return await self._stream.start_tls(ssl_context, server_hostname, timeout) + + def get_extra_info(self, info: str) -> Any: + return self._stream.get_extra_info(info) diff --git a/contrib/python/httpcore/httpcore/_models.py b/contrib/python/httpcore/httpcore/_models.py index 11bfcd84f0f..397bd758d00 100644 --- a/contrib/python/httpcore/httpcore/_models.py +++ b/contrib/python/httpcore/httpcore/_models.py @@ -353,6 +353,14 @@ class Request: ) self.extensions = {} if extensions is None else extensions + if "target" in self.extensions: + self.url = URL( + scheme=self.url.scheme, + host=self.url.host, + port=self.url.port, + target=self.extensions["target"], + ) + def __repr__(self) -> str: return f"<{self.__class__.__name__} [{self.method!r}]>" diff --git a/contrib/python/httpcore/httpcore/_sync/http11.py b/contrib/python/httpcore/httpcore/_sync/http11.py index e108f88b124..a74ff8e8092 100644 --- a/contrib/python/httpcore/httpcore/_sync/http11.py +++ b/contrib/python/httpcore/httpcore/_sync/http11.py @@ -1,8 +1,10 @@ import enum import logging +import ssl import time from types import TracebackType from typing import ( + Any, Iterable, Iterator, List, @@ -107,6 +109,7 @@ class HTTP11Connection(ConnectionInterface): status, reason_phrase, headers, + trailing_data, ) = self._receive_response_headers(**kwargs) trace.return_value = ( http_version, @@ -115,6 +118,14 @@ class HTTP11Connection(ConnectionInterface): headers, ) + network_stream = self._network_stream + + # CONNECT or Upgrade request + if (status == 101) or ( + (request.method == b"CONNECT") and (200 <= status < 300) + ): + network_stream = HTTP11UpgradeStream(network_stream, trailing_data) + return Response( status=status, headers=headers, @@ -122,7 +133,7 @@ class HTTP11Connection(ConnectionInterface): extensions={ "http_version": http_version, "reason_phrase": reason_phrase, - "network_stream": self._network_stream, + "network_stream": network_stream, }, ) except BaseException as exc: @@ -167,7 +178,7 @@ class HTTP11Connection(ConnectionInterface): def _receive_response_headers( self, request: Request - ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]]]: + ) -> Tuple[bytes, int, bytes, List[Tuple[bytes, bytes]], bytes]: timeouts = request.extensions.get("timeout", {}) timeout = timeouts.get("read", None) @@ -187,7 +198,9 @@ class HTTP11Connection(ConnectionInterface): # raw header casing, rather than the enforced lowercase headers. headers = event.headers.raw_items() - return http_version, event.status_code, event.reason, headers + trailing_data, _ = self._h11_state.trailing_data + + return http_version, event.status_code, event.reason, headers, trailing_data def _receive_response_body(self, request: Request) -> Iterator[bytes]: timeouts = request.extensions.get("timeout", {}) @@ -340,3 +353,34 @@ class HTTP11ConnectionByteStream: self._closed = True with Trace("response_closed", logger, self._request): self._connection._response_closed() + + +class HTTP11UpgradeStream(NetworkStream): + def __init__(self, stream: NetworkStream, leading_data: bytes) -> None: + self._stream = stream + self._leading_data = leading_data + + def read(self, max_bytes: int, timeout: Optional[float] = None) -> bytes: + if self._leading_data: + buffer = self._leading_data[:max_bytes] + self._leading_data = self._leading_data[max_bytes:] + return buffer + else: + return self._stream.read(max_bytes, timeout) + + def write(self, buffer: bytes, timeout: Optional[float] = None) -> None: + self._stream.write(buffer, timeout) + + def close(self) -> None: + self._stream.close() + + def start_tls( + self, + ssl_context: ssl.SSLContext, + server_hostname: Optional[str] = None, + timeout: Optional[float] = None, + ) -> NetworkStream: + return self._stream.start_tls(ssl_context, server_hostname, timeout) + + def get_extra_info(self, info: str) -> Any: + return self._stream.get_extra_info(info) diff --git a/contrib/python/httpcore/ya.make b/contrib/python/httpcore/ya.make index e8408ed8933..66ea31672fe 100644 --- a/contrib/python/httpcore/ya.make +++ b/contrib/python/httpcore/ya.make @@ -2,7 +2,7 @@ PY3_LIBRARY() -VERSION(1.0.3) +VERSION(1.0.4) LICENSE(BSD-3-Clause) |
