Skip to content

Commit 25bf898

Browse files
committed
Add test coverage for proxy TLS handshake failure
1 parent 00b33c3 commit 25bf898

File tree

2 files changed

+84
-0
lines changed

2 files changed

+84
-0
lines changed

tests/_async/test_http_proxy.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,45 @@ def test_proxy_headers():
276276
assert proxy.headers == [
277277
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
278278
]
279+
280+
281+
@pytest.mark.anyio
282+
async def test_proxy_tunneling_tls_error():
283+
"""
284+
Send an HTTPS request via a proxy, but the TLS handshake fails.
285+
"""
286+
class BrokenTLSStream(AsyncMockStream):
287+
async def start_tls(
288+
self,
289+
ssl_context: ssl.SSLContext,
290+
server_hostname: typing.Optional[str] = None,
291+
timeout: typing.Optional[float] = None,
292+
) -> AsyncNetworkStream:
293+
raise OSError("TLS Failure")
294+
295+
class BrokenTLSBackend(AsyncMockBackend):
296+
async def connect_tcp(
297+
self,
298+
host: str,
299+
port: int,
300+
timeout: typing.Optional[float] = None,
301+
local_address: typing.Optional[str] = None,
302+
socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
303+
) -> AsyncNetworkStream:
304+
return BrokenTLSStream(list(self._buffer))
305+
306+
network_backend = BrokenTLSBackend(
307+
[
308+
b"HTTP/1.1 200 OK\r\n\r\n",
309+
]
310+
)
311+
312+
async with AsyncConnectionPool(
313+
proxy=Proxy("http://localhost:8080/"),
314+
network_backend=network_backend,
315+
) as proxy:
316+
with pytest.raises(OSError, match="TLS Failure"):
317+
await proxy.request("GET", "https://example.com/")
318+
319+
assert not proxy.connections
320+

tests/_sync/test_http_proxy.py

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,3 +276,45 @@ def test_proxy_headers():
276276
assert proxy.headers == [
277277
(b"Proxy-Authorization", b"Basic dXNlcm5hbWU6cGFzc3dvcmQ=")
278278
]
279+
280+
281+
282+
def test_proxy_tunneling_tls_error():
283+
"""
284+
Send an HTTPS request via a proxy, but the TLS handshake fails.
285+
"""
286+
class BrokenTLSStream(MockStream):
287+
def start_tls(
288+
self,
289+
ssl_context: ssl.SSLContext,
290+
server_hostname: typing.Optional[str] = None,
291+
timeout: typing.Optional[float] = None,
292+
) -> NetworkStream:
293+
raise OSError("TLS Failure")
294+
295+
class BrokenTLSBackend(MockBackend):
296+
def connect_tcp(
297+
self,
298+
host: str,
299+
port: int,
300+
timeout: typing.Optional[float] = None,
301+
local_address: typing.Optional[str] = None,
302+
socket_options: typing.Optional[typing.Iterable[SOCKET_OPTION]] = None,
303+
) -> NetworkStream:
304+
return BrokenTLSStream(list(self._buffer))
305+
306+
network_backend = BrokenTLSBackend(
307+
[
308+
b"HTTP/1.1 200 OK\r\n\r\n",
309+
]
310+
)
311+
312+
with ConnectionPool(
313+
proxy=Proxy("http://localhost:8080/"),
314+
network_backend=network_backend,
315+
) as proxy:
316+
with pytest.raises(OSError, match="TLS Failure"):
317+
proxy.request("GET", "https://example.com/")
318+
319+
assert not proxy.connections
320+

0 commit comments

Comments
 (0)