Skip to content

Commit

Permalink
add socks5h proxy support (#3178)
Browse files Browse the repository at this point in the history
Signed-off-by: bin liu <liubin0329@gmail.com>
Co-authored-by: Tom Christie <tom@tomchristie.com>
  • Loading branch information
liubin and tomchristie authored Oct 29, 2024
1 parent e9cabc8 commit 12be5c4
Show file tree
Hide file tree
Showing 4 changed files with 15 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
2 changes: 1 addition & 1 deletion httpx/_config.py
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,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:
Expand Down
8 changes: 4 additions & 4 deletions httpx/_transports/default.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,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
Expand All @@ -215,7 +215,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}."
)

Expand Down Expand Up @@ -338,7 +338,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
Expand All @@ -364,7 +364,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}."
)

Expand Down
17 changes: 9 additions & 8 deletions tests/client/test_proxies.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,15 +16,16 @@ def url_to_origin(url: str) -> httpcore.URL:
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]"
Expand Down

0 comments on commit 12be5c4

Please sign in to comment.