Как включить TLS в уже подключенном потоке Python asyncio? - PullRequest
2 голосов
/ 11 июля 2020

У меня есть асинхронный сервер Python, написанный с использованием высокоуровневого Streams API . Я хочу включить TLS для уже установленного соединения, как в STARTTLS в протоколах SMTP и IMAP. Событие asyncio l oop имеет функцию start_tls () (добавлено в Python 3.7), но для него требуется протокол и транспорт, а не поток. API потоков позволяет получить транспорт через StreamWriter.transport . Но я не вижу способа изменить транспорт, который потребовался бы после вызова start_tls (). Можно ли использовать start_tls () с API потоков?

1 Ответ

0 голосов
/ 11 июля 2020

Глядя на код для потокового API, вы заметите, что StreamReader и StreamWriter хранят свой транспорт во внутренней _transport переменной. Оказывается, если вы вызываете start_tls () и затем сохраняете новый транспорт в этих переменных, он работает нормально. Конечно, действуют все обычные предостережения при использовании внутреннего API. Вот как это выглядит для сервера. На клиенте, я думаю, вы можете просто отбросить биты load_cert_chain и server_side.

transport = writer.transport
protocol = transport.get_protocol()
loop = asyncio.get_event_loop()
ssl_context = ssl.SSLContext()
ssl_context.load_cert_chain("/path/to/certchain", "/path/to/key")
new_transport = await loop.start_tls(
    transport, protocol, ssl_context, server_side=True)
writer._transport = new_transport
reader._transport = new_transport
...