From 3680479df7b72d1fcef1c76abf80727553fe573f Mon Sep 17 00:00:00 2001 From: "patchback[bot]" <45432694+patchback[bot]@users.noreply.github.com> Date: Thu, 12 Dec 2024 16:42:26 +0100 Subject: [PATCH] [PR #10156/00700458 backport][3.11] Add ALPN extension to client SSL Context (#10163) **This is a backport of PR #10156 as merged into master (00700458eb7741f15861a8616dbf77a0d82dc31f).** ## What do these changes do? Add "http/1.1" ALPN extension to aiohttp client's SSL Context. ## Are there changes in behavior for the user? ## Is it a substantial burden for the maintainers to support this? ## Related issue number Fixes #10152 ## Checklist - [x] I think the code is well written - [x] Unit tests for the changes exist - [ ] Documentation reflects the changes - [x] If you provide code modification, please add yourself to `CONTRIBUTORS.txt` * The format is <Name> <Surname>. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder Co-authored-by: Cycloctane --- CHANGES/10156.feature.rst | 3 +++ CONTRIBUTORS.txt | 1 + aiohttp/connector.py | 18 ++++++++++-------- tests/test_client_functional.py | 24 ++++++++++++++++++++++++ 4 files changed, 38 insertions(+), 8 deletions(-) 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..0ff6b6b8bd8 --- /dev/null +++ b/CHANGES/10156.feature.rst @@ -0,0 +1,3 @@ +Enabled ALPN on default SSL contexts. This improves compatibility with some +proxies which don't work without this extension. +-- by :user:`Cycloctane`. diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index ded6c463e40..5acc4de44fc 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -365,6 +365,7 @@ William S. Wilson Ong wouter bolsterlee Xavier Halloran +Xi Rui Xiang Li Yang Zhou Yannick Koechlin diff --git a/aiohttp/connector.py b/aiohttp/connector.py index a9123f82bc0..7e0986df657 100644 --- a/aiohttp/connector.py +++ b/aiohttp/connector.py @@ -780,14 +780,16 @@ def _make_ssl_context(verified: bool) -> SSLContext: # No ssl support return None 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 diff --git a/tests/test_client_functional.py b/tests/test_client_functional.py index b34ccdb600d..05af9ae25ad 100644 --- a/tests/test_client_functional.py +++ b/tests/test_client_functional.py @@ -603,6 +603,30 @@ async def handler(request): 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: + assert request.transport is not None + sslobj = request.transport.get_extra_info("ssl_object") + 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",)) + 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( aiohttp_server, aiohttp_client,