From cd1908dd23662d612830572fdb1b7c74b3bafc4b Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 11 Dec 2024 00:49:47 +0800 Subject: [PATCH 1/9] set alpn in `_make_ssl_context()` --- aiohttp/connector.py | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 1b7610c2831..44cc249098b 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -772,14 +772,16 @@ def _make_ssl_context(verified: bool) -> SSLContext: # No ssl support return None # type: ignore[unreachable] if verified: - return ssl.create_default_context() - sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) - sslcontext.options |= ssl.OP_NO_SSLv2 - sslcontext.options |= ssl.OP_NO_SSLv3 - sslcontext.check_hostname = False - sslcontext.verify_mode = ssl.CERT_NONE - sslcontext.options |= ssl.OP_NO_COMPRESSION - sslcontext.set_default_verify_paths() + sslcontext = ssl.create_default_context() + else: + sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT) + sslcontext.options |= ssl.OP_NO_SSLv2 + sslcontext.options |= ssl.OP_NO_SSLv3 + sslcontext.check_hostname = False + sslcontext.verify_mode = ssl.CERT_NONE + sslcontext.options |= ssl.OP_NO_COMPRESSION + sslcontext.set_default_verify_paths() + sslcontext.set_alpn_protocols(["http/1.1"]) return sslcontext From 7a7f8530fd6976bef83273aa3ae37189745cbd3f Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 11 Dec 2024 17:03:36 +0800 Subject: [PATCH 2/9] add test for client alpn --- tests/test_client_functional.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index f95ebabaf7e..cb1152edbba 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -632,6 +632,28 @@ async def handler(request: web.Request) -> web.Response: assert txt == "Test message" +async def test_ssl_client_alpn( + aiohttp_server: AiohttpServer, + aiohttp_client: AiohttpClient, + ssl_ctx: ssl.SSLContext, + ) -> None: + + async def handler(request: web.Request) -> web.Response: + sslobj = request.transport.get_extra_info("ssl_object") + assert sslobj.selected_alpn_protocol() == "http/1.1" + return web.Response(text="Test message") + + app = web.Application() + app.router.add_route("GET", "/", handler) + ssl_ctx.set_alpn_protocols(["http/1.1"]) + server = await aiohttp_server(app, ssl=ssl_ctx) + + connector = aiohttp.TCPConnector(ssl=False) + client = await aiohttp_client(server, connector=connector) + resp = await client.get("/") + assert resp.status == 200 + + async def test_tcp_connector_fingerprint_ok( aiohttp_server: AiohttpServer, aiohttp_client: AiohttpClient, From 450e7a4ba3750e7b8902b52b8ed93cc0aa3377fe Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Wed, 11 Dec 2024 09:05:35 +0000 Subject: [PATCH 3/9] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- tests/test_client_functional.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index cb1152edbba..e4f909b8be6 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -633,10 +633,10 @@ async def handler(request: web.Request) -> web.Response: async def test_ssl_client_alpn( - aiohttp_server: AiohttpServer, - aiohttp_client: AiohttpClient, - ssl_ctx: ssl.SSLContext, - ) -> None: + aiohttp_server: AiohttpServer, + aiohttp_client: AiohttpClient, + ssl_ctx: ssl.SSLContext, +) -> None: async def handler(request: web.Request) -> web.Response: sslobj = request.transport.get_extra_info("ssl_object") From 8821eb77ad53bf5587dd0cf33648e49f261c04c6 Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 11 Dec 2024 17:09:31 +0800 Subject: [PATCH 4/9] add changelog --- CHANGES/10156.feature.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 CHANGES/10156.feature.rst diff --git a/CHANGES/10156.feature.rst b/CHANGES/10156.feature.rst new file mode 100644 index 00000000000..4cd7cb1dab8 --- /dev/null +++ b/CHANGES/10156.feature.rst @@ -0,0 +1 @@ +Add TLS ALPN extension to client SSL context -- by :user:`Cycloctane`. From 26375ac15224ba54c6738abbdcdd405e3b15327b Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 11 Dec 2024 23:35:30 +0800 Subject: [PATCH 5/9] replace list with tuple --- aiohttp/connector.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/aiohttp/connector.py b/aiohttp/connector.py index 44cc249098b..d48356ae87a 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -781,7 +781,7 @@ def _make_ssl_context(verified: bool) -> SSLContext: sslcontext.verify_mode = ssl.CERT_NONE sslcontext.options |= ssl.OP_NO_COMPRESSION sslcontext.set_default_verify_paths() - sslcontext.set_alpn_protocols(["http/1.1"]) + sslcontext.set_alpn_protocols(("http/1.1",)) return sslcontext From b9f51091956ebebde7efb998748f1f63dfea391e Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Wed, 11 Dec 2024 23:35:35 +0800 Subject: [PATCH 6/9] improve alpn test --- tests/test_client_functional.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index e4f909b8be6..b80b2689798 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -640,18 +640,19 @@ async def test_ssl_client_alpn( async def handler(request: web.Request) -> web.Response: sslobj = request.transport.get_extra_info("ssl_object") - assert sslobj.selected_alpn_protocol() == "http/1.1" - return web.Response(text="Test message") + return web.Response(text=sslobj.selected_alpn_protocol()) app = web.Application() app.router.add_route("GET", "/", handler) - ssl_ctx.set_alpn_protocols(["http/1.1"]) + ssl_ctx.set_alpn_protocols(("http/1.1",)) server = await aiohttp_server(app, ssl=ssl_ctx) connector = aiohttp.TCPConnector(ssl=False) client = await aiohttp_client(server, connector=connector) resp = await client.get("/") assert resp.status == 200 + txt = await resp.text() + assert txt == "http/1.1" async def test_tcp_connector_fingerprint_ok( From 1fd6fc5478140ab372d5dfe61a71c89a6efea8e0 Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Thu, 12 Dec 2024 00:42:08 +0800 Subject: [PATCH 7/9] Update changelog Co-authored-by: Sam Bull --- CHANGES/10156.feature.rst | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGES/10156.feature.rst b/CHANGES/10156.feature.rst index 4cd7cb1dab8..0ff6b6b8bd8 100644 --- a/CHANGES/10156.feature.rst +++ b/CHANGES/10156.feature.rst @@ -1 +1,3 @@ -Add TLS ALPN extension to client SSL context -- by :user:`Cycloctane`. +Enabled ALPN on default SSL contexts. This improves compatibility with some +proxies which don't work without this extension. +-- by :user:`Cycloctane`. From d84438848729d38e2ddcd394229a55cc2e8d3332 Mon Sep 17 00:00:00 2001 From: Sam Bull Date: Wed, 11 Dec 2024 17:31:25 +0000 Subject: [PATCH 8/9] Update tests/test_client_functional.py --- tests/test_client_functional.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index b80b2689798..77d74b441d5 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -639,6 +639,7 @@ async def test_ssl_client_alpn( ) -> None: async def handler(request: web.Request) -> web.Response: + assert request.transport is not None sslobj = request.transport.get_extra_info("ssl_object") return web.Response(text=sslobj.selected_alpn_protocol()) From 4b84a4656c37688751abd2ca4a2b1537d79cad2e Mon Sep 17 00:00:00 2001 From: Cycloctane Date: Thu, 12 Dec 2024 11:49:36 +0800 Subject: [PATCH 9/9] update CONTRIBUTORS.txt --- CONTRIBUTORS.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 40fa2cb2b1a..7a7f882c885 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -376,6 +376,7 @@ William S. Wilson Ong wouter bolsterlee Xavier Halloran +Xi Rui Xiang Li Yang Zhou Yannick Koechlin