Skip to content

Commit 830b942

Browse files
authored
Fix ValueError with ClientTimeout(total=0) in TLS connections (#12067)
1 parent 19f904e commit 830b942

3 files changed

Lines changed: 34 additions & 2 deletions

File tree

CHANGES/11859.bugfix.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fixed :exc:`ValueError` when creating a TLS connection with ``ClientTimeout(total=0)`` by converting ``0`` to ``None`` before passing to ``ssl_handshake_timeout`` in :py:meth:`asyncio.loop.start_tls` -- by :user:`veeceey`.

aiohttp/connector.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1436,7 +1436,7 @@ async def _start_tls_connection(
14361436
tls_proto,
14371437
sslcontext,
14381438
server_hostname=req.server_hostname or req.host,
1439-
ssl_handshake_timeout=timeout.total,
1439+
ssl_handshake_timeout=timeout.total or None,
14401440
ssl_shutdown_timeout=self._ssl_shutdown_timeout,
14411441
)
14421442
else:
@@ -1445,7 +1445,7 @@ async def _start_tls_connection(
14451445
tls_proto,
14461446
sslcontext,
14471447
server_hostname=req.server_hostname or req.host,
1448-
ssl_handshake_timeout=timeout.total,
1448+
ssl_handshake_timeout=timeout.total or None,
14491449
)
14501450
except BaseException:
14511451
# We need to close the underlying transport since

tests/test_connector.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
_ConnectTunnelConnection,
3737
_DNSCacheTable,
3838
)
39+
from aiohttp.pytest_plugin import AiohttpClient, AiohttpServer
3940
from aiohttp.resolver import ResolveResult
4041
from aiohttp.test_utils import unused_port
4142
from aiohttp.tracing import Trace
@@ -2515,6 +2516,36 @@ async def test_start_tls_exception_with_ssl_shutdown_timeout_nonzero_pre_311(
25152516
underlying_transport.abort.assert_not_called()
25162517

25172518

2519+
async def test_start_tls_with_zero_total_timeout(
2520+
aiohttp_server: AiohttpServer,
2521+
aiohttp_client: AiohttpClient,
2522+
ssl_ctx: ssl.SSLContext,
2523+
client_ssl_ctx: ssl.SSLContext,
2524+
) -> None:
2525+
"""Test that ClientTimeout(total=0) works with TLS connections.
2526+
2527+
Regression test for https://github.com/aio-libs/aiohttp/issues/11859
2528+
When total=0 (meaning no timeout), ssl_handshake_timeout should receive
2529+
None instead of 0, as asyncio raises ValueError for 0.
2530+
"""
2531+
2532+
async def handler(request: web.Request) -> web.Response:
2533+
return web.Response(text="ok")
2534+
2535+
app = web.Application()
2536+
app.router.add_get("/", handler)
2537+
server = await aiohttp_server(app, ssl=ssl_ctx)
2538+
2539+
connector = aiohttp.TCPConnector(ssl=client_ssl_ctx)
2540+
client = await aiohttp_client(server, connector=connector)
2541+
2542+
# This used to raise ValueError: ssl_handshake_timeout should be a
2543+
# positive number, got 0
2544+
async with client.get("/", timeout=ClientTimeout(total=0)) as resp:
2545+
assert resp.status == 200
2546+
assert await resp.text() == "ok"
2547+
2548+
25182549
async def test_invalid_ssl_param() -> None:
25192550
with pytest.raises(TypeError):
25202551
aiohttp.TCPConnector(ssl=object()) # type: ignore[arg-type]

0 commit comments

Comments
 (0)