From 2f045935213f681baba86d83719298ac26e87657 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 05:24:43 +0800 Subject: [PATCH 01/23] Fixing missed arguments for pools when init transports --- httpcore/_async/connection.py | 8 ++--- httpcore/_async/connection_pool.py | 10 +++--- httpcore/_async/http_proxy.py | 48 +++++++++++++++++++-------- httpcore/_async/socks_proxy.py | 52 +++++++++++++++++++++++------- 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/httpcore/_async/connection.py b/httpcore/_async/connection.py index 45ee22a6..9b265eac 100644 --- a/httpcore/_async/connection.py +++ b/httpcore/_async/connection.py @@ -41,9 +41,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -52,9 +52,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._retries = retries - self._local_address = local_address self._uds = uds + self._local_address = local_address + self._retries = retries self._network_backend: AsyncNetworkBackend = ( AutoBackend() if network_backend is None else network_backend diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 0320c6d8..35e56540 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -51,9 +51,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -75,13 +75,13 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish a - connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish a + connection. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 4aa7d874..c0a60834 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -70,9 +70,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -101,15 +101,17 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -119,9 +121,9 @@ def __init__( http1=http1, http2=http2, network_backend=network_backend, - retries=retries, - local_address=local_address, uds=uds, + local_address=local_address, + retries=retries, socket_options=socket_options, ) @@ -148,21 +150,29 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: if origin.scheme == b"http": return AsyncForwardHTTPConnection( proxy_origin=self._proxy_url.origin, - proxy_headers=self._proxy_headers, remote_origin=origin, + proxy_ssl_context=self._proxy_ssl_context, + proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, + socket_options=self._socket_options, network_backend=self._network_backend, - proxy_ssl_context=self._proxy_ssl_context, ) return AsyncTunnelHTTPConnection( proxy_origin=self._proxy_url.origin, - proxy_headers=self._proxy_headers, remote_origin=origin, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, + proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, + socket_options=self._socket_options, network_backend=self._network_backend, ) @@ -172,18 +182,24 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, + proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, + uds: typing.Optional[str] = None, + local_address: typing.Optional[str] = None, + retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, - proxy_ssl_context: Optional[ssl.SSLContext] = None, ) -> None: self._connection = AsyncHTTPConnection( origin=proxy_origin, + ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, + uds=uds, + local_address=local_address, + retries=retries, network_backend=network_backend, socket_options=socket_options, - ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") @@ -242,15 +258,21 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, + uds: typing.Optional[str] = None, + local_address: typing.Optional[str] = None, + retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: self._connection: AsyncConnectionInterface = AsyncHTTPConnection( origin=proxy_origin, + ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, + uds=uds, + local_address=local_address, + retries=retries, network_backend=network_backend, socket_options=socket_options, - ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index f839603f..e9cbe1a9 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -118,8 +118,11 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, + uds: Optional[str] = None, + local_address: typing.Optional[str] = None, retries: int = 0, network_backend: typing.Optional[AsyncNetworkBackend] = None, + socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: """ A connection pool for making HTTP requests. @@ -127,6 +130,8 @@ def __init__( Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. + proxy_auth: Any proxy authentication as a two-tuple of + (username, password). May be either bytes or ascii-only str. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore.default_ssl_context()` will be used. @@ -141,15 +146,17 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -183,7 +190,11 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, network_backend=self._network_backend, + socket_options=self._socket_options, ) @@ -206,6 +217,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 + self._retries = retries + self._local_address = local_address + self._uds = uds self._network_backend: AsyncNetworkBackend = ( AutoBackend() if network_backend is None else network_backend @@ -223,14 +237,30 @@ async def handle_async_request(self, request: Request) -> Response: if self._connection is None: try: # Connect to the proxy - kwargs = { - "host": self._proxy_origin.host.decode("ascii"), - "port": self._proxy_origin.port, - "timeout": timeout, - } - async with Trace("connect_tcp", logger, request, kwargs) as trace: - stream = await self._network_backend.connect_tcp(**kwargs) - trace.return_value = stream + if self._uds is None: + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + "local_address": self._local_address, + "socket_options": self._socket_options, + } + async with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = await self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + else: + kwargs = { + "path": self._uds, + "timeout": timeout, + "socket_options": self._socket_options, + } + async with Trace( + "connect_unix_socket", logger, request, kwargs + ) as trace: + stream = await self._network_backend.connect_unix_socket( + **kwargs + ) + trace.return_value = stream # Connect to the remote host using socks5 kwargs = { From 21c9a6b66f0055441b80f4d8ecb0d5d9500b7ff2 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 05:39:56 +0800 Subject: [PATCH 02/23] fix --- httpcore/_async/http_proxy.py | 8 ++++---- httpcore/_async/socks_proxy.py | 15 ++++++++++----- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index c0a60834..3de0f7a2 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -185,8 +185,8 @@ def __init__( proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, + uds: Optional[str] = None, + local_address: Optional[str] = None, retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, @@ -258,8 +258,8 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, + uds: Optional[str] = None, + local_address: Optional[str] = None, retries: int = 0, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index e9cbe1a9..b6c1cc51 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -5,7 +5,7 @@ from socksio import socks5 from .._backends.auto import AutoBackend -from .._backends.base import AsyncNetworkBackend, AsyncNetworkStream +from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context @@ -118,11 +118,11 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, + uds: typing.Optional[str] = None, local_address: typing.Optional[str] = None, retries: int = 0, network_backend: typing.Optional[AsyncNetworkBackend] = None, - socket_options: Optional[Iterable[SOCKET_OPTION]] = None, + socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: """ A connection pool for making HTTP requests. @@ -208,7 +208,11 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, + uds: typing.Optional[str] = None, + local_address: typing.Optional[str] = None, + retries: int = 0, network_backend: typing.Optional[AsyncNetworkBackend] = None, + socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin @@ -217,9 +221,10 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._retries = retries - self._local_address = local_address self._uds = uds + self._local_address = local_address + self._retries = retries + self._socket_options = socket_options self._network_backend: AsyncNetworkBackend = ( AutoBackend() if network_backend is None else network_backend From 9721795f041bcdae5aca3aaf2112392f39c5dc47 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 05:48:34 +0800 Subject: [PATCH 03/23] fix --- httpcore/_async/socks_proxy.py | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index b6c1cc51..5b1d7960 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -259,12 +259,8 @@ async def handle_async_request(self, request: Request) -> Response: "timeout": timeout, "socket_options": self._socket_options, } - async with Trace( - "connect_unix_socket", logger, request, kwargs - ) as trace: - stream = await self._network_backend.connect_unix_socket( - **kwargs - ) + async with Trace("connect_unix_socket", logger, request, kwargs) as trace: + stream = await self._network_backend.connect_unix_socket(**kwargs) trace.return_value = stream # Connect to the remote host using socks5 From f27d20cd2f14b301ba47da5eb550b93b27e4d37c Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 05:59:27 +0800 Subject: [PATCH 04/23] fix --- httpcore/_async/socks_proxy.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index 5b1d7960..03ac0576 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -250,7 +250,9 @@ async def handle_async_request(self, request: Request) -> Response: "local_address": self._local_address, "socket_options": self._socket_options, } - async with Trace("connect_tcp", logger, request, kwargs) as trace: + async with Trace( + "connect_tcp", logger, request, kwargs + ) as trace: stream = await self._network_backend.connect_tcp(**kwargs) trace.return_value = stream else: @@ -259,8 +261,12 @@ async def handle_async_request(self, request: Request) -> Response: "timeout": timeout, "socket_options": self._socket_options, } - async with Trace("connect_unix_socket", logger, request, kwargs) as trace: - stream = await self._network_backend.connect_unix_socket(**kwargs) + async with Trace( + "connect_unix_socket", logger, request, kwargs + ) as trace: + stream = await self._network_backend.connect_unix_socket( + **kwargs + ) trace.return_value = stream # Connect to the remote host using socks5 From 5fe7176b62cebd2c88d144aae40615337410c7be Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:00:51 +0800 Subject: [PATCH 05/23] fix --- httpcore/_async/socks_proxy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index 03ac0576..e2aff3f5 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -252,7 +252,7 @@ async def handle_async_request(self, request: Request) -> Response: } async with Trace( "connect_tcp", logger, request, kwargs - ) as trace: + ) as trace: stream = await self._network_backend.connect_tcp(**kwargs) trace.return_value = stream else: From 35c3d6c97f14bcaca5fb44676886e78f9149709b Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:22:18 +0800 Subject: [PATCH 06/23] fix --- httpcore/_async/connection_pool.py | 8 ++--- httpcore/_async/http_proxy.py | 6 ++-- httpcore/_async/socks_proxy.py | 5 ++- httpcore/_sync/connection.py | 8 ++--- httpcore/_sync/connection_pool.py | 18 +++++----- httpcore/_sync/http_proxy.py | 52 +++++++++++++++++++-------- httpcore/_sync/socks_proxy.py | 58 +++++++++++++++++++++++------- 7 files changed, 106 insertions(+), 49 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 35e56540..601cf5d4 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -103,9 +103,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._retries = retries - self._local_address = local_address self._uds = uds + self._local_address = local_address + self._retries = retries self._pool: List[AsyncConnectionInterface] = [] self._requests: List[RequestStatus] = [] @@ -122,9 +122,9 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - retries=self._retries, - local_address=self._local_address, uds=self._uds, + local_address=self._local_address, + retries=self._retries, network_backend=self._network_backend, socket_options=self._socket_options, ) diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 3de0f7a2..a8ebf44d 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -120,10 +120,10 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - network_backend=network_backend, uds=uds, local_address=local_address, retries=retries, + network_backend=network_backend, socket_options=socket_options, ) @@ -157,8 +157,8 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: uds=self._uds, local_address=self._local_address, retries=self._retries, - socket_options=self._socket_options, network_backend=self._network_backend, + socket_options=self._socket_options, ) return AsyncTunnelHTTPConnection( proxy_origin=self._proxy_url.origin, @@ -172,8 +172,8 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: uds=self._uds, local_address=self._local_address, retries=self._retries, - socket_options=self._socket_options, network_backend=self._network_backend, + socket_options=self._socket_options, ) diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index e2aff3f5..2ad0e40a 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -165,8 +165,11 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - network_backend=network_backend, + uds=uds, + local_address=local_address, retries=retries, + network_backend=network_backend, + socket_options=socket_options, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") diff --git a/httpcore/_sync/connection.py b/httpcore/_sync/connection.py index 81e4172a..f9bb1852 100644 --- a/httpcore/_sync/connection.py +++ b/httpcore/_sync/connection.py @@ -41,9 +41,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -52,9 +52,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._retries = retries - self._local_address = local_address self._uds = uds + self._local_address = local_address + self._retries = retries self._network_backend: NetworkBackend = ( SyncBackend() if network_backend is None else network_backend diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index ccfb8d22..d2981c5a 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -51,9 +51,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -75,13 +75,13 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish a - connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish a + connection. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. @@ -103,9 +103,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._retries = retries - self._local_address = local_address self._uds = uds + self._local_address = local_address + self._retries = retries self._pool: List[ConnectionInterface] = [] self._requests: List[RequestStatus] = [] @@ -122,9 +122,9 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - retries=self._retries, - local_address=self._local_address, uds=self._uds, + local_address=self._local_address, + retries=self._retries, network_backend=self._network_backend, socket_options=self._socket_options, ) diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index 6acac9a7..a1cf94e2 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -70,9 +70,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - retries: int = 0, - local_address: Optional[str] = None, uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -101,15 +101,17 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -119,9 +121,9 @@ def __init__( http1=http1, http2=http2, network_backend=network_backend, - retries=retries, - local_address=local_address, uds=uds, + local_address=local_address, + retries=retries, socket_options=socket_options, ) @@ -148,21 +150,29 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: if origin.scheme == b"http": return ForwardHTTPConnection( proxy_origin=self._proxy_url.origin, - proxy_headers=self._proxy_headers, remote_origin=origin, + proxy_ssl_context=self._proxy_ssl_context, + proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, + socket_options=self._socket_options, network_backend=self._network_backend, - proxy_ssl_context=self._proxy_ssl_context, ) return TunnelHTTPConnection( proxy_origin=self._proxy_url.origin, - proxy_headers=self._proxy_headers, remote_origin=origin, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, + proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, + socket_options=self._socket_options, network_backend=self._network_backend, ) @@ -172,18 +182,24 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, + proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, - network_backend: Optional[NetworkBackend] = None, + uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, + network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, - proxy_ssl_context: Optional[ssl.SSLContext] = None, ) -> None: self._connection = HTTPConnection( origin=proxy_origin, + ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, + uds=uds, + local_address=local_address, + retries=retries, network_backend=network_backend, socket_options=socket_options, - ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") @@ -242,15 +258,21 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - network_backend: Optional[NetworkBackend] = None, + uds: Optional[str] = None, + local_address: Optional[str] = None, + retries: int = 0, + network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: self._connection: ConnectionInterface = HTTPConnection( origin=proxy_origin, + ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, + uds=uds, + local_address=local_address, + retries=retries, network_backend=network_backend, socket_options=socket_options, - ssl_context=proxy_ssl_context, ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin diff --git a/httpcore/_sync/socks_proxy.py b/httpcore/_sync/socks_proxy.py index 502e4d7f..33fd8126 100644 --- a/httpcore/_sync/socks_proxy.py +++ b/httpcore/_sync/socks_proxy.py @@ -118,8 +118,11 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, + uds: typing.Optional[str] = None, + local_address: typing.Optional[str] = None, retries: int = 0, - network_backend: typing.Optional[NetworkBackend] = None, + network_backend: typing.Optional[AsyncNetworkBackend] = None, + socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: """ A connection pool for making HTTP requests. @@ -127,6 +130,8 @@ def __init__( Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. + proxy_auth: Any proxy authentication as a two-tuple of + (username, password). May be either bytes or ascii-only str. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore.default_ssl_context()` will be used. @@ -141,15 +146,17 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. network_backend: A backend instance to use for handling network I/O. + socket_options: Socket options that have to be included + in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -158,8 +165,11 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - network_backend=network_backend, + uds=uds, + local_address=local_address, retries=retries, + network_backend=network_backend, + socket_options=socket_options, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") @@ -183,7 +193,11 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, + uds=self._uds, + local_address=self._local_address, + retries=self._retries, network_backend=self._network_backend, + socket_options=self._socket_options, ) @@ -223,14 +237,32 @@ def handle_request(self, request: Request) -> Response: if self._connection is None: try: # Connect to the proxy - kwargs = { - "host": self._proxy_origin.host.decode("ascii"), - "port": self._proxy_origin.port, - "timeout": timeout, - } - with Trace("connect_tcp", logger, request, kwargs) as trace: - stream = self._network_backend.connect_tcp(**kwargs) - trace.return_value = stream + if self._uds is None: + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + "local_address": self._local_address, + "socket_options": self._socket_options, + } + with Trace( + "connect_tcp", logger, request, kwargs + ) as trace: + stream = self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream + else: + kwargs = { + "path": self._uds, + "timeout": timeout, + "socket_options": self._socket_options, + } + with Trace( + "connect_unix_socket", logger, request, kwargs + ) as trace: + stream = self._network_backend.connect_unix_socket( + **kwargs + ) + trace.return_value = stream # Connect to the remote host using socks5 kwargs = { From 9272311b496beb0a18f18768fa609cafaf6c4541 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:28:24 +0800 Subject: [PATCH 07/23] fix --- httpcore/_sync/socks_proxy.py | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/httpcore/_sync/socks_proxy.py b/httpcore/_sync/socks_proxy.py index 33fd8126..beea9013 100644 --- a/httpcore/_sync/socks_proxy.py +++ b/httpcore/_sync/socks_proxy.py @@ -5,7 +5,7 @@ from socksio import socks5 from .._backends.sync import SyncBackend -from .._backends.base import NetworkBackend, NetworkStream +from .._backends.base import SOCKET_OPTION, NetworkBackend, NetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context @@ -121,7 +121,7 @@ def __init__( uds: typing.Optional[str] = None, local_address: typing.Optional[str] = None, retries: int = 0, - network_backend: typing.Optional[AsyncNetworkBackend] = None, + network_backend: typing.Optional[NetworkBackend] = None, socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: """ @@ -211,7 +211,11 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, + uds: typing.Optional[str] = None, + local_address: typing.Optional[str] = None, + retries: int = 0, network_backend: typing.Optional[NetworkBackend] = None, + socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin @@ -220,6 +224,10 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 + self._uds = uds + self._local_address = local_address + self._retries = retries + self._socket_options = socket_options self._network_backend: NetworkBackend = ( SyncBackend() if network_backend is None else network_backend From 3988a8f5eaed51715ccfc5bbbf354625d976b70a Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:29:56 +0800 Subject: [PATCH 08/23] fix --- httpcore/_sync/http_proxy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index a1cf94e2..50baba0d 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -188,7 +188,7 @@ def __init__( uds: Optional[str] = None, local_address: Optional[str] = None, retries: int = 0, - network_backend: Optional[AsyncNetworkBackend] = None, + network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: self._connection = HTTPConnection( @@ -261,7 +261,7 @@ def __init__( uds: Optional[str] = None, local_address: Optional[str] = None, retries: int = 0, - network_backend: Optional[AsyncNetworkBackend] = None, + network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: self._connection: ConnectionInterface = HTTPConnection( From cdaa11b3cc503834be121195b433862610fff959 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 06:35:11 +0800 Subject: [PATCH 09/23] fix lint --- httpcore/_sync/http_proxy.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index 50baba0d..f7ce38ba 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -120,10 +120,10 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - network_backend=network_backend, uds=uds, local_address=local_address, retries=retries, + network_backend=network_backend, socket_options=socket_options, ) @@ -157,8 +157,8 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: uds=self._uds, local_address=self._local_address, retries=self._retries, - socket_options=self._socket_options, network_backend=self._network_backend, + socket_options=self._socket_options, ) return TunnelHTTPConnection( proxy_origin=self._proxy_url.origin, @@ -172,8 +172,8 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: uds=self._uds, local_address=self._local_address, retries=self._retries, - socket_options=self._socket_options, network_backend=self._network_backend, + socket_options=self._socket_options, ) From 65f92d4643d324c2ddb5eef3a65f4727a14e9b2e Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 07:14:33 +0800 Subject: [PATCH 10/23] added test for the new uds of socks_proxy --- tests/_async/test_socks_proxy.py | 28 ++++++++++++++++++++++++++++ tests/_sync/test_socks_proxy.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 56 insertions(+) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 3f5dd1cc..9b0507dc 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -191,3 +191,31 @@ async def test_socks5_request_incorrect_auth(): assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections + + +@pytest.mark.anyio +async def test_uds_connections(): + # We're not actually testing Unix Domain Sockets here, because we're just + # using a mock backend, but at least we're covering the UDS codepath + # in `connection.py` which we may as well do. + network_backend = httpcore.AsyncMockBackend( + [ + # The initial socks CONNECT + # v5 NOAUTH + b"\x05\x00", + # v5 SUC RSV IP4 127 .0 .0 .1 :80 + b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", + # The actual response from the remote server + b"HTTP/1.1 200 OK\r\n", + b"Content-Type: plain/text\r\n", + b"Content-Length: 13\r\n", + b"\r\n", + b"Hello, world!", + ] + ) + + async with httpcore.AsyncSOCKSProxy( + network_backend=network_backend, uds="/mock/example" + ) as proxy: + response = await proxy.request("GET", "https://example.com/") + assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 2d39bb97..dc2565b9 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -191,3 +191,31 @@ def test_socks5_request_incorrect_auth(): assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections + + +@pytest.mark.anyio +async def test_uds_connections(): + # We're not actually testing Unix Domain Sockets here, because we're just + # using a mock backend, but at least we're covering the UDS codepath + # in `connection.py` which we may as well do. + network_backend = httpcore.AsyncMockBackend( + [ + # The initial socks CONNECT + # v5 NOAUTH + b"\x05\x00", + # v5 SUC RSV IP4 127 .0 .0 .1 :80 + b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", + # The actual response from the remote server + b"HTTP/1.1 200 OK\r\n", + b"Content-Type: plain/text\r\n", + b"Content-Length: 13\r\n", + b"\r\n", + b"Hello, world!", + ] + ) + + with httpcore.AsyncSOCKSProxy( + network_backend=network_backend, uds="/mock/example" + ) as proxy: + response = proxy.request("GET", "https://example.com/") + assert response.status == 200 From cbe49bc5ba2cf18eef1feb9af7341b974a256ddc Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 07:19:33 +0800 Subject: [PATCH 11/23] fix --- tests/_async/test_socks_proxy.py | 2 +- tests/_sync/test_socks_proxy.py | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 9b0507dc..9a88046a 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -215,7 +215,7 @@ async def test_uds_connections(): ) async with httpcore.AsyncSOCKSProxy( - network_backend=network_backend, uds="/mock/example" + proxy_url="", network_backend=network_backend, uds="/mock/example" ) as proxy: response = await proxy.request("GET", "https://example.com/") assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index dc2565b9..5fcc6172 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -198,7 +198,7 @@ async def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just # using a mock backend, but at least we're covering the UDS codepath # in `connection.py` which we may as well do. - network_backend = httpcore.AsyncMockBackend( + network_backend = httpcore.MockBackend( [ # The initial socks CONNECT # v5 NOAUTH @@ -214,8 +214,8 @@ async def test_uds_connections(): ] ) - with httpcore.AsyncSOCKSProxy( - network_backend=network_backend, uds="/mock/example" + with httpcore.SOCKSProxy( + proxy_url="", network_backend=network_backend, uds="/mock/example" ) as proxy: response = proxy.request("GET", "https://example.com/") assert response.status == 200 From 25c46ce89ad5f5aed8b1e533afbd4c254af53b51 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 07:44:02 +0800 Subject: [PATCH 12/23] fix lint --- tests/_async/test_socks_proxy.py | 1 + tests/_sync/test_socks_proxy.py | 1 + 2 files changed, 2 insertions(+) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 9a88046a..283c9973 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -193,6 +193,7 @@ async def test_socks5_request_incorrect_auth(): assert not proxy.connections + @pytest.mark.anyio async def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 5fcc6172..888f9478 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -193,6 +193,7 @@ def test_socks5_request_incorrect_auth(): assert not proxy.connections + @pytest.mark.anyio async def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just From 176a53a9c68084ead7a081e48cb4479730c72be2 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 07:47:21 +0800 Subject: [PATCH 13/23] fix lint --- tests/_async/test_socks_proxy.py | 1 - tests/_sync/test_socks_proxy.py | 3 +-- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 283c9973..9a88046a 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -193,7 +193,6 @@ async def test_socks5_request_incorrect_auth(): assert not proxy.connections - @pytest.mark.anyio async def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 888f9478..3696bb82 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -193,9 +193,8 @@ def test_socks5_request_incorrect_auth(): assert not proxy.connections - @pytest.mark.anyio -async def test_uds_connections(): +def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just # using a mock backend, but at least we're covering the UDS codepath # in `connection.py` which we may as well do. From ce4395c438d92be6d7649bf017645b2098c1c4fe Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 07:49:11 +0800 Subject: [PATCH 14/23] fix lint --- tests/_sync/test_socks_proxy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 3696bb82..b37404b0 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -193,6 +193,7 @@ def test_socks5_request_incorrect_auth(): assert not proxy.connections + @pytest.mark.anyio def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just From 7fedea6e161e02116794b5d90d5c0408a6c301c2 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 08:12:26 +0800 Subject: [PATCH 15/23] fix lint --- tests/_sync/test_socks_proxy.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index b37404b0..060309eb 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -194,7 +194,6 @@ def test_socks5_request_incorrect_auth(): -@pytest.mark.anyio def test_uds_connections(): # We're not actually testing Unix Domain Sockets here, because we're just # using a mock backend, but at least we're covering the UDS codepath From 6694c345c0019f497edb4f4dc0c474bb75ff5f8c Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 08:36:18 +0800 Subject: [PATCH 16/23] fix lint --- tests/_async/test_socks_proxy.py | 2 +- tests/_sync/test_socks_proxy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 9a88046a..7981f3e2 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -215,7 +215,7 @@ async def test_uds_connections(): ) async with httpcore.AsyncSOCKSProxy( - proxy_url="", network_backend=network_backend, uds="/mock/example" + proxy_url="socks5://localhost:8080/", network_backend=network_backend, uds="/mock/example" ) as proxy: response = await proxy.request("GET", "https://example.com/") assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 060309eb..169df131 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -215,7 +215,7 @@ def test_uds_connections(): ) with httpcore.SOCKSProxy( - proxy_url="", network_backend=network_backend, uds="/mock/example" + proxy_url="socks5://localhost:8080/", network_backend=network_backend, uds="/mock/example" ) as proxy: response = proxy.request("GET", "https://example.com/") assert response.status == 200 From a1235072d8ef1fe4f4b3f9ef819303715da207a2 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 08:38:10 +0800 Subject: [PATCH 17/23] fix lint --- tests/_async/test_socks_proxy.py | 4 +++- tests/_sync/test_socks_proxy.py | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 7981f3e2..671b66af 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -215,7 +215,9 @@ async def test_uds_connections(): ) async with httpcore.AsyncSOCKSProxy( - proxy_url="socks5://localhost:8080/", network_backend=network_backend, uds="/mock/example" + proxy_url="socks5://localhost:8080/", + network_backend=network_backend, + uds="/mock/example" ) as proxy: response = await proxy.request("GET", "https://example.com/") assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 169df131..5ccb0063 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -215,7 +215,9 @@ def test_uds_connections(): ) with httpcore.SOCKSProxy( - proxy_url="socks5://localhost:8080/", network_backend=network_backend, uds="/mock/example" + proxy_url="socks5://localhost:8080/", + network_backend=network_backend, + uds="/mock/example" ) as proxy: response = proxy.request("GET", "https://example.com/") assert response.status == 200 From edcc35e6c8dd3dfbc2777df37144115e5a9a952c Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Sun, 10 Dec 2023 08:41:47 +0800 Subject: [PATCH 18/23] fix lint --- tests/_async/test_socks_proxy.py | 2 +- tests/_sync/test_socks_proxy.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index 671b66af..e47f5560 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -217,7 +217,7 @@ async def test_uds_connections(): async with httpcore.AsyncSOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, - uds="/mock/example" + uds="/mock/example", ) as proxy: response = await proxy.request("GET", "https://example.com/") assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 5ccb0063..48cb7084 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -217,7 +217,7 @@ def test_uds_connections(): with httpcore.SOCKSProxy( proxy_url="socks5://localhost:8080/", network_backend=network_backend, - uds="/mock/example" + uds="/mock/example", ) as proxy: response = proxy.request("GET", "https://example.com/") assert response.status == 200 From 0e06a12487efd17f6753def9858dfcaa078d34af Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 15 Dec 2023 05:02:24 +0800 Subject: [PATCH 19/23] fix --- tests/_async/test_socks_proxy.py | 30 ------------------------------ tests/_sync/test_socks_proxy.py | 30 ------------------------------ 2 files changed, 60 deletions(-) diff --git a/tests/_async/test_socks_proxy.py b/tests/_async/test_socks_proxy.py index e47f5560..3f5dd1cc 100644 --- a/tests/_async/test_socks_proxy.py +++ b/tests/_async/test_socks_proxy.py @@ -191,33 +191,3 @@ async def test_socks5_request_incorrect_auth(): assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections - - -@pytest.mark.anyio -async def test_uds_connections(): - # We're not actually testing Unix Domain Sockets here, because we're just - # using a mock backend, but at least we're covering the UDS codepath - # in `connection.py` which we may as well do. - network_backend = httpcore.AsyncMockBackend( - [ - # The initial socks CONNECT - # v5 NOAUTH - b"\x05\x00", - # v5 SUC RSV IP4 127 .0 .0 .1 :80 - b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", - # The actual response from the remote server - b"HTTP/1.1 200 OK\r\n", - b"Content-Type: plain/text\r\n", - b"Content-Length: 13\r\n", - b"\r\n", - b"Hello, world!", - ] - ) - - async with httpcore.AsyncSOCKSProxy( - proxy_url="socks5://localhost:8080/", - network_backend=network_backend, - uds="/mock/example", - ) as proxy: - response = await proxy.request("GET", "https://example.com/") - assert response.status == 200 diff --git a/tests/_sync/test_socks_proxy.py b/tests/_sync/test_socks_proxy.py index 48cb7084..2d39bb97 100644 --- a/tests/_sync/test_socks_proxy.py +++ b/tests/_sync/test_socks_proxy.py @@ -191,33 +191,3 @@ def test_socks5_request_incorrect_auth(): assert str(exc_info.value) == "Invalid username/password" assert not proxy.connections - - - -def test_uds_connections(): - # We're not actually testing Unix Domain Sockets here, because we're just - # using a mock backend, but at least we're covering the UDS codepath - # in `connection.py` which we may as well do. - network_backend = httpcore.MockBackend( - [ - # The initial socks CONNECT - # v5 NOAUTH - b"\x05\x00", - # v5 SUC RSV IP4 127 .0 .0 .1 :80 - b"\x05\x00\x00\x01\xff\x00\x00\x01\x00\x50", - # The actual response from the remote server - b"HTTP/1.1 200 OK\r\n", - b"Content-Type: plain/text\r\n", - b"Content-Length: 13\r\n", - b"\r\n", - b"Hello, world!", - ] - ) - - with httpcore.SOCKSProxy( - proxy_url="socks5://localhost:8080/", - network_backend=network_backend, - uds="/mock/example", - ) as proxy: - response = proxy.request("GET", "https://example.com/") - assert response.status == 200 From 1fae5fa1a5976f2b6a97b9d86fe532a0656ebfd0 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 15 Dec 2023 05:29:08 +0800 Subject: [PATCH 20/23] fix --- httpcore/_async/connection_pool.py | 18 ++++----- httpcore/_async/http_proxy.py | 42 ++++++++++---------- httpcore/_async/socks_proxy.py | 64 ++++++------------------------ httpcore/_sync/connection_pool.py | 18 ++++----- httpcore/_sync/http_proxy.py | 38 +++++++++--------- httpcore/_sync/socks_proxy.py | 64 ++++++------------------------ 6 files changed, 82 insertions(+), 162 deletions(-) diff --git a/httpcore/_async/connection_pool.py b/httpcore/_async/connection_pool.py index 601cf5d4..0320c6d8 100644 --- a/httpcore/_async/connection_pool.py +++ b/httpcore/_async/connection_pool.py @@ -51,9 +51,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -75,13 +75,13 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish a + connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish a - connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. @@ -103,9 +103,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address self._retries = retries + self._local_address = local_address + self._uds = uds self._pool: List[AsyncConnectionInterface] = [] self._requests: List[RequestStatus] = [] @@ -122,9 +122,9 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index a8ebf44d..181a962b 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -70,9 +70,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -101,14 +101,14 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. @@ -120,9 +120,9 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) @@ -154,9 +154,9 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: proxy_ssl_context=self._proxy_ssl_context, proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @@ -169,9 +169,9 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @@ -182,22 +182,22 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, - proxy_ssl_context: Optional[ssl.SSLContext] = None, + ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: self._connection = AsyncHTTPConnection( origin=proxy_origin, - ssl_context=proxy_ssl_context, + ssl_context=ssl_context, keepalive_expiry=keepalive_expiry, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) @@ -258,9 +258,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -268,9 +268,9 @@ def __init__( origin=proxy_origin, ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) diff --git a/httpcore/_async/socks_proxy.py b/httpcore/_async/socks_proxy.py index 2ad0e40a..0cba17a1 100644 --- a/httpcore/_async/socks_proxy.py +++ b/httpcore/_async/socks_proxy.py @@ -5,7 +5,7 @@ from socksio import socks5 from .._backends.auto import AutoBackend -from .._backends.base import SOCKET_OPTION, AsyncNetworkBackend, AsyncNetworkStream +from .._backends.base import AsyncNetworkBackend, AsyncNetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context @@ -118,11 +118,8 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, retries: int = 0, network_backend: typing.Optional[AsyncNetworkBackend] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: """ A connection pool for making HTTP requests. @@ -130,8 +127,6 @@ def __init__( Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. - proxy_auth: Any proxy authentication as a two-tuple of - (username, password). May be either bytes or ascii-only str. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore.default_ssl_context()` will be used. @@ -146,17 +141,15 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. - socket_options: Socket options that have to be included - in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -165,11 +158,8 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - uds=uds, - local_address=local_address, retries=retries, network_backend=network_backend, - socket_options=socket_options, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") @@ -193,11 +183,7 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, - retries=self._retries, network_backend=self._network_backend, - socket_options=self._socket_options, ) @@ -211,11 +197,7 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, - retries: int = 0, network_backend: typing.Optional[AsyncNetworkBackend] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin @@ -224,10 +206,6 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address - self._retries = retries - self._socket_options = socket_options self._network_backend: AsyncNetworkBackend = ( AutoBackend() if network_backend is None else network_backend @@ -245,32 +223,14 @@ async def handle_async_request(self, request: Request) -> Response: if self._connection is None: try: # Connect to the proxy - if self._uds is None: - kwargs = { - "host": self._proxy_origin.host.decode("ascii"), - "port": self._proxy_origin.port, - "timeout": timeout, - "local_address": self._local_address, - "socket_options": self._socket_options, - } - async with Trace( - "connect_tcp", logger, request, kwargs - ) as trace: - stream = await self._network_backend.connect_tcp(**kwargs) - trace.return_value = stream - else: - kwargs = { - "path": self._uds, - "timeout": timeout, - "socket_options": self._socket_options, - } - async with Trace( - "connect_unix_socket", logger, request, kwargs - ) as trace: - stream = await self._network_backend.connect_unix_socket( - **kwargs - ) - trace.return_value = stream + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + } + async with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = await self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream # Connect to the remote host using socks5 kwargs = { diff --git a/httpcore/_sync/connection_pool.py b/httpcore/_sync/connection_pool.py index d2981c5a..ccfb8d22 100644 --- a/httpcore/_sync/connection_pool.py +++ b/httpcore/_sync/connection_pool.py @@ -51,9 +51,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -75,13 +75,13 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish a + connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish a - connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. @@ -103,9 +103,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address self._retries = retries + self._local_address = local_address + self._uds = uds self._pool: List[ConnectionInterface] = [] self._requests: List[RequestStatus] = [] @@ -122,9 +122,9 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index f7ce38ba..73ba97b7 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -70,9 +70,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -101,14 +101,14 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. socket_options: Socket options that have to be included in the TCP socket when the connection was established. @@ -120,9 +120,9 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) @@ -154,9 +154,9 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: proxy_ssl_context=self._proxy_ssl_context, proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @@ -169,9 +169,9 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, retries=self._retries, + local_address=self._local_address, + uds=self._uds, network_backend=self._network_backend, socket_options=self._socket_options, ) @@ -185,9 +185,9 @@ def __init__( proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -195,9 +195,9 @@ def __init__( origin=proxy_origin, ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) @@ -258,9 +258,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -268,9 +268,9 @@ def __init__( origin=proxy_origin, ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, - uds=uds, - local_address=local_address, retries=retries, + local_address=local_address, + uds=uds, network_backend=network_backend, socket_options=socket_options, ) diff --git a/httpcore/_sync/socks_proxy.py b/httpcore/_sync/socks_proxy.py index beea9013..2f915c87 100644 --- a/httpcore/_sync/socks_proxy.py +++ b/httpcore/_sync/socks_proxy.py @@ -5,7 +5,7 @@ from socksio import socks5 from .._backends.sync import SyncBackend -from .._backends.base import SOCKET_OPTION, NetworkBackend, NetworkStream +from .._backends.base import NetworkBackend, NetworkStream from .._exceptions import ConnectionNotAvailable, ProxyError from .._models import URL, Origin, Request, Response, enforce_bytes, enforce_url from .._ssl import default_ssl_context @@ -118,11 +118,8 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, retries: int = 0, network_backend: typing.Optional[NetworkBackend] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: """ A connection pool for making HTTP requests. @@ -130,8 +127,6 @@ def __init__( Parameters: proxy_url: The URL to use when connecting to the proxy server. For example `"http://127.0.0.1:8080/"`. - proxy_auth: Any proxy authentication as a two-tuple of - (username, password). May be either bytes or ascii-only str. ssl_context: An SSL context to use for verifying connections. If not specified, the default `httpcore.default_ssl_context()` will be used. @@ -146,17 +141,15 @@ def __init__( by the connection pool. Defaults to True. http2: A boolean indicating if HTTP/2 requests should be supported by the connection pool. Defaults to False. - uds: Path to a Unix Domain Socket to use instead of TCP sockets. + retries: The maximum number of retries when trying to establish + a connection. local_address: Local address to connect from. Can also be used to connect using a particular address family. Using `local_address="0.0.0.0"` will connect using an `AF_INET` address (IPv4), while using `local_address="::"` will connect using an `AF_INET6` address (IPv6). - retries: The maximum number of retries when trying to establish - a connection. + uds: Path to a Unix Domain Socket to use instead of TCP sockets. network_backend: A backend instance to use for handling network I/O. - socket_options: Socket options that have to be included - in the TCP socket when the connection was established. """ super().__init__( ssl_context=ssl_context, @@ -165,11 +158,8 @@ def __init__( keepalive_expiry=keepalive_expiry, http1=http1, http2=http2, - uds=uds, - local_address=local_address, retries=retries, network_backend=network_backend, - socket_options=socket_options, ) self._ssl_context = ssl_context self._proxy_url = enforce_url(proxy_url, name="proxy_url") @@ -193,11 +183,7 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, - uds=self._uds, - local_address=self._local_address, - retries=self._retries, network_backend=self._network_backend, - socket_options=self._socket_options, ) @@ -211,11 +197,7 @@ def __init__( keepalive_expiry: typing.Optional[float] = None, http1: bool = True, http2: bool = False, - uds: typing.Optional[str] = None, - local_address: typing.Optional[str] = None, - retries: int = 0, network_backend: typing.Optional[NetworkBackend] = None, - socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None, ) -> None: self._proxy_origin = proxy_origin self._remote_origin = remote_origin @@ -224,10 +206,6 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address - self._retries = retries - self._socket_options = socket_options self._network_backend: NetworkBackend = ( SyncBackend() if network_backend is None else network_backend @@ -245,32 +223,14 @@ def handle_request(self, request: Request) -> Response: if self._connection is None: try: # Connect to the proxy - if self._uds is None: - kwargs = { - "host": self._proxy_origin.host.decode("ascii"), - "port": self._proxy_origin.port, - "timeout": timeout, - "local_address": self._local_address, - "socket_options": self._socket_options, - } - with Trace( - "connect_tcp", logger, request, kwargs - ) as trace: - stream = self._network_backend.connect_tcp(**kwargs) - trace.return_value = stream - else: - kwargs = { - "path": self._uds, - "timeout": timeout, - "socket_options": self._socket_options, - } - with Trace( - "connect_unix_socket", logger, request, kwargs - ) as trace: - stream = self._network_backend.connect_unix_socket( - **kwargs - ) - trace.return_value = stream + kwargs = { + "host": self._proxy_origin.host.decode("ascii"), + "port": self._proxy_origin.port, + "timeout": timeout, + } + with Trace("connect_tcp", logger, request, kwargs) as trace: + stream = self._network_backend.connect_tcp(**kwargs) + trace.return_value = stream # Connect to the remote host using socks5 kwargs = { From 1b4276ee8080e650eb3bb55dcf3b462cddabbbe5 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 15 Dec 2023 05:35:57 +0800 Subject: [PATCH 21/23] fix --- httpcore/_async/http_proxy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 181a962b..5032944b 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -182,7 +182,7 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, - ssl_context: Optional[ssl.SSLContext] = None, + proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, keepalive_expiry: Optional[float] = None, retries: int = 0, @@ -193,7 +193,7 @@ def __init__( ) -> None: self._connection = AsyncHTTPConnection( origin=proxy_origin, - ssl_context=ssl_context, + ssl_context=proxy_ssl_context, keepalive_expiry=keepalive_expiry, retries=retries, local_address=local_address, From 465ba86dccf8d1a1e1850c102b81cfa0a1777fff Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 15 Dec 2023 05:45:25 +0800 Subject: [PATCH 22/23] fix --- httpcore/_async/connection.py | 8 ++++---- httpcore/_async/http_proxy.py | 8 ++++---- httpcore/_sync/connection.py | 8 ++++---- httpcore/_sync/http_proxy.py | 8 ++++---- 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/httpcore/_async/connection.py b/httpcore/_async/connection.py index 9b265eac..45ee22a6 100644 --- a/httpcore/_async/connection.py +++ b/httpcore/_async/connection.py @@ -41,9 +41,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[AsyncNetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -52,9 +52,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address self._retries = retries + self._local_address = local_address + self._uds = uds self._network_backend: AsyncNetworkBackend = ( AutoBackend() if network_backend is None else network_backend diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 5032944b..01998045 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -151,8 +151,8 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: return AsyncForwardHTTPConnection( proxy_origin=self._proxy_url.origin, remote_origin=origin, - proxy_ssl_context=self._proxy_ssl_context, proxy_headers=self._proxy_headers, + proxy_ssl_context=self._proxy_ssl_context, keepalive_expiry=self._keepalive_expiry, retries=self._retries, local_address=self._local_address, @@ -163,9 +163,9 @@ def create_connection(self, origin: Origin) -> AsyncConnectionInterface: return AsyncTunnelHTTPConnection( proxy_origin=self._proxy_url.origin, remote_origin=origin, + proxy_headers=self._proxy_headers, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, - proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, @@ -182,8 +182,8 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, - proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, + proxy_ssl_context: Optional[ssl.SSLContext] = None, keepalive_expiry: Optional[float] = None, retries: int = 0, local_address: Optional[str] = None, @@ -252,9 +252,9 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, + proxy_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, ssl_context: Optional[ssl.SSLContext] = None, proxy_ssl_context: Optional[ssl.SSLContext] = None, - proxy_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, diff --git a/httpcore/_sync/connection.py b/httpcore/_sync/connection.py index f9bb1852..81e4172a 100644 --- a/httpcore/_sync/connection.py +++ b/httpcore/_sync/connection.py @@ -41,9 +41,9 @@ def __init__( keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, - uds: Optional[str] = None, - local_address: Optional[str] = None, retries: int = 0, + local_address: Optional[str] = None, + uds: Optional[str] = None, network_backend: Optional[NetworkBackend] = None, socket_options: Optional[Iterable[SOCKET_OPTION]] = None, ) -> None: @@ -52,9 +52,9 @@ def __init__( self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 - self._uds = uds - self._local_address = local_address self._retries = retries + self._local_address = local_address + self._uds = uds self._network_backend: NetworkBackend = ( SyncBackend() if network_backend is None else network_backend diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index 73ba97b7..cfa7660f 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -151,8 +151,8 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: return ForwardHTTPConnection( proxy_origin=self._proxy_url.origin, remote_origin=origin, - proxy_ssl_context=self._proxy_ssl_context, proxy_headers=self._proxy_headers, + proxy_ssl_context=self._proxy_ssl_context, keepalive_expiry=self._keepalive_expiry, retries=self._retries, local_address=self._local_address, @@ -163,9 +163,9 @@ def create_connection(self, origin: Origin) -> ConnectionInterface: return TunnelHTTPConnection( proxy_origin=self._proxy_url.origin, remote_origin=origin, + proxy_headers=self._proxy_headers, ssl_context=self._ssl_context, proxy_ssl_context=self._proxy_ssl_context, - proxy_headers=self._proxy_headers, keepalive_expiry=self._keepalive_expiry, http1=self._http1, http2=self._http2, @@ -182,8 +182,8 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, - proxy_ssl_context: Optional[ssl.SSLContext] = None, proxy_headers: Union[HeadersAsMapping, HeadersAsSequence, None] = None, + proxy_ssl_context: Optional[ssl.SSLContext] = None, keepalive_expiry: Optional[float] = None, retries: int = 0, local_address: Optional[str] = None, @@ -252,9 +252,9 @@ def __init__( self, proxy_origin: Origin, remote_origin: Origin, + proxy_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, ssl_context: Optional[ssl.SSLContext] = None, proxy_ssl_context: Optional[ssl.SSLContext] = None, - proxy_headers: Optional[Sequence[Tuple[bytes, bytes]]] = None, keepalive_expiry: Optional[float] = None, http1: bool = True, http2: bool = False, From a2c1121023d2cce923f82f3abacacb46ee57ba91 Mon Sep 17 00:00:00 2001 From: NewUserHa <32261870+NewUserHa@users.noreply.github.com> Date: Fri, 15 Dec 2023 06:08:09 +0800 Subject: [PATCH 23/23] fix --- httpcore/_async/http_proxy.py | 4 ++-- httpcore/_sync/http_proxy.py | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/httpcore/_async/http_proxy.py b/httpcore/_async/http_proxy.py index 01998045..28d6a899 100644 --- a/httpcore/_async/http_proxy.py +++ b/httpcore/_async/http_proxy.py @@ -202,8 +202,8 @@ def __init__( socket_options=socket_options, ) self._proxy_origin = proxy_origin - self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._remote_origin = remote_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") async def handle_async_request(self, request: Request) -> Response: headers = merge_headers(self._proxy_headers, request.headers) @@ -276,9 +276,9 @@ def __init__( ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context - self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2 diff --git a/httpcore/_sync/http_proxy.py b/httpcore/_sync/http_proxy.py index cfa7660f..a5e3a3f4 100644 --- a/httpcore/_sync/http_proxy.py +++ b/httpcore/_sync/http_proxy.py @@ -202,8 +202,8 @@ def __init__( socket_options=socket_options, ) self._proxy_origin = proxy_origin - self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._remote_origin = remote_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") def handle_request(self, request: Request) -> Response: headers = merge_headers(self._proxy_headers, request.headers) @@ -276,9 +276,9 @@ def __init__( ) self._proxy_origin = proxy_origin self._remote_origin = remote_origin + self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._ssl_context = ssl_context self._proxy_ssl_context = proxy_ssl_context - self._proxy_headers = enforce_headers(proxy_headers, name="proxy_headers") self._keepalive_expiry = keepalive_expiry self._http1 = http1 self._http2 = http2