Fix start_tls() loses buffer data and hangs when upgrading the connection#708
Fix start_tls() loses buffer data and hangs when upgrading the connection#708fizzi01 wants to merge 8 commits intoMagicStack:masterfrom
Conversation
|
The current fix breaks the Test: async def start_tls(self, transport, protocol, ...):
# Transfer buffered data from the old protocol to the new one.
stream_buff = None
if hasattr(protocol, '_stream_reader'):
stream_reader = protocol._stream_reader
if stream_reader is not None and hasattr(stream_reader, '_buffer'):
stream_buff = stream_reader._buffer
if stream_buff is not None:
ssl_protocol._incoming.write(stream_buff)
stream_buff.clear()or to modify the base protocol class implementation in `test_context.py: class _BaseProtocol(asyncio.BaseProtocol):
def __init__(self, cvar, *, loop=None):
...
self._stream_reader: asyncio.StreamReader = asyncio.StreamReader(loop=loop)Do we always have a protocol with a _stream_reader attribute? |
|
Thanks for the PR!
No I don't think so. Though, I don't understand the test failure - looks like you already have |
The function transport = await self.loop.start_tls(
proto.transport, proto, client_sslctx,
server_hostname='127.0.0.1',
) |
|
@fantix Everything should be fine now, can you review please? |
This PR fixes a critical issue where buffered data in StreamReader is lost when upgrading a connection to TLS using StreamWriter.start_tls() or loop.start_tls(), causing the call to hang indefinitely. The issue exists in both asyncio (see python/cpython#142352) and uvloop.
The main focus is to verify and guarantee that any data buffered before upgrading a connection to TLS is not lost and is correctly transferred. These changes are effectively a port of python/cpython#142354 with absolutely no difference, except for the test that creates a TCP server, establishes a connection, buffers data, performs a TLS upgrade, and verifies that all messages (both pre-upgrade and post-upgrade) are received correctly.
Fixes #707