Bug report
Bug description:
Bug description
BaseEventLoop._create_connection_transport() closes the socket only if await waiter fails:
try:
await waiter
except:
transport.close()
raise
If sock.setblocking(), protocol_factory() or _make_*_transport() raises before the transport exists, the socket is never closed
Reproducer
import asyncio
import socket
async def main():
loop = asyncio.get_running_loop()
sock = socket.socket()
try:
await loop.create_connection(lambda: 1 / 0, sock=sock)
except ZeroDivisionError:
pass
print("leak: socket not closed" if sock.fileno() != -1 else "ok: closed")
sock.close()
asyncio.run(main())
Expected: ok: closed but actually: leak: socket not closed
Proposed fix
Close the socket on error when the transport hasn't been created yet:
async def _create_connection_transport(
self, sock, protocol_factory, ssl,
server_hostname, server_side=False,
ssl_handshake_timeout=None,
ssl_shutdown_timeout=None, context=None):
transport = None
try:
sock.setblocking(False)
context = context if context is not None else contextvars.copy_context()
protocol = protocol_factory()
waiter = self.create_future()
if ssl:
sslcontext = None if isinstance(ssl, bool) else ssl
transport = self._make_ssl_transport(
sock, protocol, sslcontext, waiter,
server_side=server_side, server_hostname=server_hostname,
ssl_handshake_timeout=ssl_handshake_timeout,
ssl_shutdown_timeout=ssl_shutdown_timeout,
context=context)
else:
transport = self._make_socket_transport(sock, protocol, waiter, context=context)
await waiter
except:
if transport is None:
sock.close()
else:
transport.close()
raise
return transport, protocol
I have a fix ready
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs
Bug report
Bug description:
Bug description
BaseEventLoop._create_connection_transport()closes the socket only if await waiter fails:If
sock.setblocking(),protocol_factory()or_make_*_transport()raises before the transport exists, the socket is never closedReproducer
Expected:
ok: closedbut actually:leak: socket not closedProposed fix
Close the socket on error when the transport hasn't been created yet:
I have a fix ready
CPython versions tested on:
CPython main branch
Operating systems tested on:
macOS
Linked PRs