Skip to content

Commit

Permalink
[PR #10156/00700458 backport][3.11] Add ALPN extension to client SSL …
Browse files Browse the repository at this point in the history
…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 <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 <[email protected]>
  • Loading branch information
patchback[bot] and Cycloctane authored Dec 12, 2024
1 parent 7f38913 commit 3680479
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 8 deletions.
3 changes: 3 additions & 0 deletions CHANGES/10156.feature.rst
Original file line number Diff line number Diff line change
@@ -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`.
1 change: 1 addition & 0 deletions CONTRIBUTORS.txt
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,7 @@ William S.
Wilson Ong
wouter bolsterlee
Xavier Halloran
Xi Rui
Xiang Li
Yang Zhou
Yannick Koechlin
Expand Down
18 changes: 10 additions & 8 deletions aiohttp/connector.py
Original file line number Diff line number Diff line change
Expand Up @@ -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


Expand Down
24 changes: 24 additions & 0 deletions tests/test_client_functional.py
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down

0 comments on commit 3680479

Please sign in to comment.