From 616a2fe0fc3d195529ae85fa2e11c27feee30af1 Mon Sep 17 00:00:00 2001 From: bin liu Date: Thu, 25 Apr 2024 09:51:27 +0800 Subject: [PATCH 1/2] add socks5h proxy support In some case socks5h is needed to resolve the hostname. Signed-off-by: bin liu --- httpx/_config.py | 2 +- httpx/_transports/default.py | 8 ++++---- tests/client/test_proxies.py | 17 +++++++++-------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/httpx/_config.py b/httpx/_config.py index 6662ea8067..eefbb436f2 100644 --- a/httpx/_config.py +++ b/httpx/_config.py @@ -334,7 +334,7 @@ def __init__( url = URL(url) headers = Headers(headers) - if url.scheme not in ("http", "https", "socks5"): + if url.scheme not in ("http", "https", "socks5", "socks5h"): raise ValueError(f"Unknown scheme for proxy URL {url!r}") if url.username or url.password: diff --git a/httpx/_transports/default.py b/httpx/_transports/default.py index bcc8bf422b..63663db301 100644 --- a/httpx/_transports/default.py +++ b/httpx/_transports/default.py @@ -171,7 +171,7 @@ def __init__( http2=http2, socket_options=socket_options, ) - elif proxy.url.scheme == "socks5": + elif proxy.url.scheme in ("socks5", "socks5h"): try: import socksio # noqa except ImportError: # pragma: no cover @@ -197,7 +197,7 @@ def __init__( ) else: # pragma: no cover raise ValueError( - "Proxy protocol must be either 'http', 'https', or 'socks5'," + "Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h'," f" but got {proxy.url.scheme!r}." ) @@ -311,7 +311,7 @@ def __init__( http2=http2, socket_options=socket_options, ) - elif proxy.url.scheme == "socks5": + elif proxy.url.scheme in ("socks5", "socks5h"): try: import socksio # noqa except ImportError: # pragma: no cover @@ -337,7 +337,7 @@ def __init__( ) else: # pragma: no cover raise ValueError( - "Proxy protocol must be either 'http', 'https', or 'socks5'," + "Proxy protocol must be either 'http', 'https', 'socks5', or 'socks5h'," " but got {proxy.url.scheme!r}." ) diff --git a/tests/client/test_proxies.py b/tests/client/test_proxies.py index 7bba1ab2c3..5808c60e02 100644 --- a/tests/client/test_proxies.py +++ b/tests/client/test_proxies.py @@ -67,15 +67,16 @@ def test_socks_proxy_deprecated(): def test_socks_proxy(): url = httpx.URL("http://www.example.com") - client = httpx.Client(proxy="socks5://localhost/") - transport = client._transport_for_url(url) - assert isinstance(transport, httpx.HTTPTransport) - assert isinstance(transport._pool, httpcore.SOCKSProxy) + for proxy in ("socks5://localhost/", "socks5h://localhost/"): + client = httpx.Client(proxy=proxy) + transport = client._transport_for_url(url) + assert isinstance(transport, httpx.HTTPTransport) + assert isinstance(transport._pool, httpcore.SOCKSProxy) - async_client = httpx.AsyncClient(proxy="socks5://localhost/") - async_transport = async_client._transport_for_url(url) - assert isinstance(async_transport, httpx.AsyncHTTPTransport) - assert isinstance(async_transport._pool, httpcore.AsyncSOCKSProxy) + async_client = httpx.AsyncClient(proxy=proxy) + async_transport = async_client._transport_for_url(url) + assert isinstance(async_transport, httpx.AsyncHTTPTransport) + assert isinstance(async_transport._pool, httpcore.AsyncSOCKSProxy) PROXY_URL = "http://[::1]" From 8b07286d060bf9c2980fc5003e0778bed82a4f4a Mon Sep 17 00:00:00 2001 From: Tom Christie Date: Tue, 29 Oct 2024 14:07:41 +0000 Subject: [PATCH 2/2] Update CHANGELOG.md --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1d32e53dc6..460e315422 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,7 @@ This release introduces an `httpx.SSLContext()` class and `ssl_context` paramete * Ensure JSON request bodies are compact. (#3363) * Review URL percent escape sets, based on WHATWG spec. (#3371, #3373) * Ensure `certifi` and `httpcore` are only imported if required. (#3377) +* Treat `socks5h` as a valid proxy scheme. (#3178) ## 0.27.2 (27th August, 2024)