Reputation: 595
I am writing a HTTP client in Python.
In order to select the correct HTTP version, I use ALPN.
While there is an easy and documented way to get the selected protocol from a ssl-wrapped socket (SSLSocket.selected_alpn_protocol()
), I have found no official way to do this for asyncio
streams.
I am quite new to asyncio, so maybe I have completely misunderstood the concept, but this is still puzzling. Although I have found a way to retrieve the selected protocol, it's too complex to be the official way. Additionally, I have found little to no information on this subject online.
I've found the following:
writer.transport._ssl_protocol._sslobj.selected_alpn_protocol()
reader._transport._ssl_protocol._sslpipe.ssl_object.selected_alpn_protocol()
These sometimes don't work though, so I have no idea whether this is version specific or I'm just doing something completely wrong.
Code to reproduce
import asyncio
import ssl
async def test_alpn():
ctx = ssl.create_default_context()
ctx.set_alpn_protocols(["http/1.1", "h2"])
reader, writer = await asyncio.open_connection('example.org', 443, ssl = ctx, server_hostname = 'example.org')
return writer.transport._ssl_protocol._sslobj.selected_alpn_protocol()
print(asyncio.run(test_alpn()))
Upvotes: 0
Views: 184
Reputation: 595
I found this out way too late, but use the get_extra_info() function for this. Extract the SSL object using
writer.transport.get_extra_info("ssl_object")
and then call the selected_alpn_protocol()
function on it.
This is certainly better than messing around with asyncio's internals, as I did originally.
Upvotes: 0