Skip to content

Commit 3680479

Browse files
[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 (0070045).** ## 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 &lt;Name&gt; &lt;Surname&gt;. * Please keep alphabetical order, the file is sorted by names. - [x] Add a new news fragment into the `CHANGES/` folder Co-authored-by: Cycloctane <[email protected]>
1 parent 7f38913 commit 3680479

File tree

4 files changed

+38
-8
lines changed

4 files changed

+38
-8
lines changed

CHANGES/10156.feature.rst

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Enabled ALPN on default SSL contexts. This improves compatibility with some
2+
proxies which don't work without this extension.
3+
-- by :user:`Cycloctane`.

CONTRIBUTORS.txt

+1
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,7 @@ William S.
365365
Wilson Ong
366366
wouter bolsterlee
367367
Xavier Halloran
368+
Xi Rui
368369
Xiang Li
369370
Yang Zhou
370371
Yannick Koechlin

aiohttp/connector.py

+10-8
Original file line numberDiff line numberDiff line change
@@ -780,14 +780,16 @@ def _make_ssl_context(verified: bool) -> SSLContext:
780780
# No ssl support
781781
return None
782782
if verified:
783-
return ssl.create_default_context()
784-
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
785-
sslcontext.options |= ssl.OP_NO_SSLv2
786-
sslcontext.options |= ssl.OP_NO_SSLv3
787-
sslcontext.check_hostname = False
788-
sslcontext.verify_mode = ssl.CERT_NONE
789-
sslcontext.options |= ssl.OP_NO_COMPRESSION
790-
sslcontext.set_default_verify_paths()
783+
sslcontext = ssl.create_default_context()
784+
else:
785+
sslcontext = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
786+
sslcontext.options |= ssl.OP_NO_SSLv2
787+
sslcontext.options |= ssl.OP_NO_SSLv3
788+
sslcontext.check_hostname = False
789+
sslcontext.verify_mode = ssl.CERT_NONE
790+
sslcontext.options |= ssl.OP_NO_COMPRESSION
791+
sslcontext.set_default_verify_paths()
792+
sslcontext.set_alpn_protocols(("http/1.1",))
791793
return sslcontext
792794

793795

tests/test_client_functional.py

+24
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,30 @@ async def handler(request):
603603
assert txt == "Test message"
604604

605605

606+
async def test_ssl_client_alpn(
607+
aiohttp_server: AiohttpServer,
608+
aiohttp_client: AiohttpClient,
609+
ssl_ctx: ssl.SSLContext,
610+
) -> None:
611+
612+
async def handler(request: web.Request) -> web.Response:
613+
assert request.transport is not None
614+
sslobj = request.transport.get_extra_info("ssl_object")
615+
return web.Response(text=sslobj.selected_alpn_protocol())
616+
617+
app = web.Application()
618+
app.router.add_route("GET", "/", handler)
619+
ssl_ctx.set_alpn_protocols(("http/1.1",))
620+
server = await aiohttp_server(app, ssl=ssl_ctx)
621+
622+
connector = aiohttp.TCPConnector(ssl=False)
623+
client = await aiohttp_client(server, connector=connector)
624+
resp = await client.get("/")
625+
assert resp.status == 200
626+
txt = await resp.text()
627+
assert txt == "http/1.1"
628+
629+
606630
async def test_tcp_connector_fingerprint_ok(
607631
aiohttp_server,
608632
aiohttp_client,

0 commit comments

Comments
 (0)