Skip to content

Commit

Permalink
Update tests for new proxy API, and nocover old classes.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomchristie committed Oct 29, 2024
1 parent b11db99 commit 0f9dfb0
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 74 deletions.
10 changes: 3 additions & 7 deletions httpcore/_async/http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ def merge_headers(
return default_headers + override_headers


def build_auth_header(username: bytes, password: bytes) -> bytes:
userpass = username + b":" + password
return b"Basic " + base64.b64encode(userpass)


class AsyncHTTPProxy(AsyncConnectionPool):
class AsyncHTTPProxy(AsyncConnectionPool): # pragma: nocover
"""
A connection pool that sends requests via an HTTP proxy.
"""
Expand Down Expand Up @@ -142,7 +137,8 @@ def __init__(
if proxy_auth is not None:
username = enforce_bytes(proxy_auth[0], name="proxy_auth")
password = enforce_bytes(proxy_auth[1], name="proxy_auth")
authorization = build_auth_header(username, password)
userpass = username + b":" + password
authorization = b"Basic " + base64.b64encode(userpass)
self._proxy_headers = [
(b"Proxy-Authorization", authorization)
] + self._proxy_headers
Expand Down
2 changes: 1 addition & 1 deletion httpcore/_async/socks_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ async def _init_socks5_connection(
raise ProxyError(f"Proxy Server could not connect: {reply_code}.")


class AsyncSOCKSProxy(AsyncConnectionPool):
class AsyncSOCKSProxy(AsyncConnectionPool): # pragma: nocover
"""
A connection pool that sends requests via an HTTP proxy.
"""
Expand Down
10 changes: 3 additions & 7 deletions httpcore/_sync/http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,7 @@ def merge_headers(
return default_headers + override_headers


def build_auth_header(username: bytes, password: bytes) -> bytes:
userpass = username + b":" + password
return b"Basic " + base64.b64encode(userpass)


class HTTPProxy(ConnectionPool):
class HTTPProxy(ConnectionPool): # pragma: nocover
"""
A connection pool that sends requests via an HTTP proxy.
"""
Expand Down Expand Up @@ -142,7 +137,8 @@ def __init__(
if proxy_auth is not None:
username = enforce_bytes(proxy_auth[0], name="proxy_auth")
password = enforce_bytes(proxy_auth[1], name="proxy_auth")
authorization = build_auth_header(username, password)
userpass = username + b":" + password
authorization = b"Basic " + base64.b64encode(userpass)
self._proxy_headers = [
(b"Proxy-Authorization", authorization)
] + self._proxy_headers
Expand Down
2 changes: 1 addition & 1 deletion httpcore/_sync/socks_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def _init_socks5_connection(
raise ProxyError(f"Proxy Server could not connect: {reply_code}.")


class SOCKSProxy(ConnectionPool):
class SOCKSProxy(ConnectionPool): # pragma: nocover
"""
A connection pool that sends requests via an HTTP proxy.
"""
Expand Down
41 changes: 24 additions & 17 deletions tests/_async/test_http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@

from httpcore import (
SOCKET_OPTION,
AsyncHTTPProxy,
AsyncConnectionPool,
AsyncMockBackend,
AsyncMockStream,
AsyncNetworkStream,
Origin,
Proxy,
ProxyError,
)

Expand All @@ -31,8 +32,8 @@ async def test_proxy_forwarding():
]
)

async with AsyncHTTPProxy(
proxy_url="http://localhost:8080/",
async with AsyncConnectionPool(
proxy=Proxy("http://localhost:8080/"),
max_connections=10,
network_backend=network_backend,
) as proxy:
Expand Down Expand Up @@ -87,8 +88,8 @@ async def test_proxy_tunneling():
]
)

async with AsyncHTTPProxy(
proxy_url="http://localhost:8080/",
async with AsyncConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -178,8 +179,8 @@ async def test_proxy_tunneling_http2():
],
)

async with AsyncHTTPProxy(
proxy_url="http://localhost:8080/",
async with AsyncConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
http2=True,
) as proxy:
Expand Down Expand Up @@ -227,8 +228,8 @@ async def test_proxy_tunneling_with_403():
]
)

async with AsyncHTTPProxy(
proxy_url="http://localhost:8080/",
async with AsyncConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
) as proxy:
with pytest.raises(ProxyError) as exc_info:
Expand All @@ -255,17 +256,23 @@ async def test_proxy_tunneling_with_auth():
]
)

async with AsyncHTTPProxy(
proxy_url="http://localhost:8080/",
proxy_auth=("username", "password"),
async with AsyncConnectionPool(
proxy=Proxy(
url="http://localhost:8080/",
auth=("username", "password"),
),
network_backend=network_backend,
) as proxy:
response = await proxy.request("GET", "https://example.com/")
assert response.status == 200
assert response.content == b"Hello, world!"

# Dig into this private property as a cheap lazy way of
# checking that the proxy header is set correctly.
assert proxy._proxy_headers == [ # type: ignore
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
]

def test_proxy_headers():
proxy = Proxy(
url="http://localhost:8080/",
auth=("username", "password"),
)
assert proxy.headers == [
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
]
28 changes: 16 additions & 12 deletions tests/_async/test_socks_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ async def test_socks5_request():
]
)

async with httpcore.AsyncSOCKSProxy(
proxy_url="socks5://localhost:8080/",
async with httpcore.AsyncConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -84,9 +84,11 @@ async def test_authenticated_socks5_request():
]
)

async with httpcore.AsyncSOCKSProxy(
proxy_url="socks5://localhost:8080/",
proxy_auth=(b"username", b"password"),
async with httpcore.AsyncConnectionPool(
proxy=httpcore.Proxy(
url="socks5://localhost:8080/",
auth=(b"username", b"password"),
),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -123,8 +125,8 @@ async def test_socks5_request_connect_failed():
]
)

async with httpcore.AsyncSOCKSProxy(
proxy_url="socks5://localhost:8080/",
async with httpcore.AsyncConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand All @@ -150,8 +152,8 @@ async def test_socks5_request_failed_to_provide_auth():
]
)

async with httpcore.AsyncSOCKSProxy(
proxy_url="socks5://localhost:8080/",
async with httpcore.AsyncConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand Down Expand Up @@ -180,9 +182,11 @@ async def test_socks5_request_incorrect_auth():
]
)

async with httpcore.AsyncSOCKSProxy(
proxy_url="socks5://localhost:8080/",
proxy_auth=(b"invalid", b"invalid"),
async with httpcore.AsyncConnectionPool(
proxy=httpcore.Proxy(
url="socks5://localhost:8080/",
auth=(b"invalid", b"invalid"),
),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand Down
41 changes: 24 additions & 17 deletions tests/_sync/test_http_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,12 @@

from httpcore import (
SOCKET_OPTION,
HTTPProxy,
ConnectionPool,
MockBackend,
MockStream,
NetworkStream,
Origin,
Proxy,
ProxyError,
)

Expand All @@ -31,8 +32,8 @@ def test_proxy_forwarding():
]
)

with HTTPProxy(
proxy_url="http://localhost:8080/",
with ConnectionPool(
proxy=Proxy("http://localhost:8080/"),
max_connections=10,
network_backend=network_backend,
) as proxy:
Expand Down Expand Up @@ -87,8 +88,8 @@ def test_proxy_tunneling():
]
)

with HTTPProxy(
proxy_url="http://localhost:8080/",
with ConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -178,8 +179,8 @@ def test_proxy_tunneling_http2():
],
)

with HTTPProxy(
proxy_url="http://localhost:8080/",
with ConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
http2=True,
) as proxy:
Expand Down Expand Up @@ -227,8 +228,8 @@ def test_proxy_tunneling_with_403():
]
)

with HTTPProxy(
proxy_url="http://localhost:8080/",
with ConnectionPool(
proxy=Proxy("http://localhost:8080/"),
network_backend=network_backend,
) as proxy:
with pytest.raises(ProxyError) as exc_info:
Expand All @@ -255,17 +256,23 @@ def test_proxy_tunneling_with_auth():
]
)

with HTTPProxy(
proxy_url="http://localhost:8080/",
proxy_auth=("username", "password"),
with ConnectionPool(
proxy=Proxy(
url="http://localhost:8080/",
auth=("username", "password"),
),
network_backend=network_backend,
) as proxy:
response = proxy.request("GET", "https://example.com/")
assert response.status == 200
assert response.content == b"Hello, world!"

# Dig into this private property as a cheap lazy way of
# checking that the proxy header is set correctly.
assert proxy._proxy_headers == [ # type: ignore
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
]

def test_proxy_headers():
proxy = Proxy(
url="http://localhost:8080/",
auth=("username", "password"),
)
assert proxy.headers == [
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
]
28 changes: 16 additions & 12 deletions tests/_sync/test_socks_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def test_socks5_request():
]
)

with httpcore.SOCKSProxy(
proxy_url="socks5://localhost:8080/",
with httpcore.ConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -84,9 +84,11 @@ def test_authenticated_socks5_request():
]
)

with httpcore.SOCKSProxy(
proxy_url="socks5://localhost:8080/",
proxy_auth=(b"username", b"password"),
with httpcore.ConnectionPool(
proxy=httpcore.Proxy(
url="socks5://localhost:8080/",
auth=(b"username", b"password"),
),
network_backend=network_backend,
) as proxy:
# Sending an intial request, which once complete will return to the pool, IDLE.
Expand Down Expand Up @@ -123,8 +125,8 @@ def test_socks5_request_connect_failed():
]
)

with httpcore.SOCKSProxy(
proxy_url="socks5://localhost:8080/",
with httpcore.ConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand All @@ -150,8 +152,8 @@ def test_socks5_request_failed_to_provide_auth():
]
)

with httpcore.SOCKSProxy(
proxy_url="socks5://localhost:8080/",
with httpcore.ConnectionPool(
proxy=httpcore.Proxy("socks5://localhost:8080/"),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand Down Expand Up @@ -180,9 +182,11 @@ def test_socks5_request_incorrect_auth():
]
)

with httpcore.SOCKSProxy(
proxy_url="socks5://localhost:8080/",
proxy_auth=(b"invalid", b"invalid"),
with httpcore.ConnectionPool(
proxy=httpcore.Proxy(
url="socks5://localhost:8080/",
auth=(b"invalid", b"invalid"),
),
network_backend=network_backend,
) as proxy:
# Sending a request, which the proxy rejects
Expand Down

0 comments on commit 0f9dfb0

Please sign in to comment.