Skip to content

[3.14] gh-159875: Keep the SSL protocol of a closed transport after connection loss (GH-160069) - #161208

Merged
asvetlov merged 1 commit into
python:3.14from
miss-islington:backport-0626b14-3.14
Nov 2, 2026
Merged

asvetlov merged 1 commit into
python:3.14from
miss-islington:backport-0626b14-3.14

Conversation

@miss-islington

Copy link
Copy Markdown
Contributor

An application that closes its transport from connection_lost(), as aiohttp
does, must be left with a transport whose write(), get_write_buffer_size()
and set_protocol() behave as after closing a live connection, and
loop.sendfile()'s fallback must then raise ConnectionError rather than
AttributeError from set_protocol().

The sendfile test reads the file synchronously, so that the fallback is
waiting in drain() when the connection is lost; a read in the executor that
completes in the same loop iteration as the reset lets the fallback finish
first and hides the bug.

test_create_connection_memory_leak now keeps the transport past its check,
as its comment says it covers, so that it would see an SSLContext kept alive
by a transport the application still holds.

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com

_SSLProtocolTransport.close() dropped its _ssl_protocol when called a second
time, and the transport is already marked closed once the connection is lost,
so an application closing it from connection_lost() left a transport whose
write(), set_protocol(), get_write_buffer_size(), ... raise AttributeError.
That branch was also what released the SSLContext of a transport the
application keeps. Keep the protocol, and release the TLS state from
SSLProtocol.connection_lost() instead: one loop iteration later when the
application's connection_lost() was scheduled, so that it can still read
get_extra_info('ssl_object') and ('sslcontext').

Co-Authored-By: Claude Opus 5.5 noreply@anthropic.com


(cherry picked from commit 0626b14)

Co-authored-by: Mauricio Paez jose.m.paez@icloud.com
Co-authored-by: Claude Opus 5.5 noreply@anthropic.com

…nnection loss (pythonGH-160069)

* pythongh-159875: Add tests for an SSL transport closed after connection loss

An application that closes its transport from connection_lost(), as aiohttp
does, must be left with a transport whose write(), get_write_buffer_size()
and set_protocol() behave as after closing a live connection, and
loop.sendfile()'s fallback must then raise ConnectionError rather than
AttributeError from set_protocol().

The sendfile test reads the file synchronously, so that the fallback is
waiting in drain() when the connection is lost; a read in the executor that
completes in the same loop iteration as the reset lets the fallback finish
first and hides the bug.

test_create_connection_memory_leak now keeps the transport past its check,
as its comment says it covers, so that it would see an SSLContext kept alive
by a transport the application still holds.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* pythongh-159875: Keep the SSL protocol of a closed transport after connection loss

_SSLProtocolTransport.close() dropped its _ssl_protocol when called a second
time, and the transport is already marked closed once the connection is lost,
so an application closing it from connection_lost() left a transport whose
write(), set_protocol(), get_write_buffer_size(), ... raise AttributeError.
That branch was also what released the SSLContext of a transport the
application keeps. Keep the protocol, and release the TLS state from
SSLProtocol.connection_lost() instead: one loop iteration later when the
application's connection_lost() was scheduled, so that it can still read
get_extra_info('ssl_object') and ('sslcontext').

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

---------
(cherry picked from commit 0626b14)

Co-authored-by: Mauricio Paez <jose.m.paez@icloud.com>
Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants