mirror of
https://github.com/python/cpython.git
synced 2025-07-24 03:35:53 +00:00
bpo-29406: asyncio SSL contexts leak sockets after calling close with certain servers (#409)
* asyncio SSL contexts leak sockets after calling close with certain servers * cleanup _shutdown_timeout_handle on _fatal_error
This commit is contained in:
parent
34792d25ab
commit
a608d2d5a7
3 changed files with 62 additions and 1 deletions
|
@ -6,6 +6,8 @@ except ImportError: # pragma: no cover
|
|||
ssl = None
|
||||
|
||||
from . import base_events
|
||||
from . import compat
|
||||
from . import futures
|
||||
from . import protocols
|
||||
from . import transports
|
||||
from .log import logger
|
||||
|
@ -407,7 +409,7 @@ class SSLProtocol(protocols.Protocol):
|
|||
|
||||
def __init__(self, loop, app_protocol, sslcontext, waiter,
|
||||
server_side=False, server_hostname=None,
|
||||
call_connection_made=True):
|
||||
call_connection_made=True, shutdown_timeout=5.0):
|
||||
if ssl is None:
|
||||
raise RuntimeError('stdlib ssl module not available')
|
||||
|
||||
|
@ -438,6 +440,8 @@ class SSLProtocol(protocols.Protocol):
|
|||
self._session_established = False
|
||||
self._in_handshake = False
|
||||
self._in_shutdown = False
|
||||
self._shutdown_timeout = shutdown_timeout
|
||||
self._shutdown_timeout_handle = None
|
||||
# transport, ex: SelectorSocketTransport
|
||||
self._transport = None
|
||||
self._call_connection_made = call_connection_made
|
||||
|
@ -552,6 +556,15 @@ class SSLProtocol(protocols.Protocol):
|
|||
self._in_shutdown = True
|
||||
self._write_appdata(b'')
|
||||
|
||||
if self._shutdown_timeout is not None:
|
||||
self._shutdown_timeout_handle = self._loop.call_later(
|
||||
self._shutdown_timeout, self._on_shutdown_timeout)
|
||||
|
||||
def _on_shutdown_timeout(self):
|
||||
if self._transport is not None:
|
||||
self._fatal_error(
|
||||
futures.TimeoutError(), 'Can not complete shitdown operation')
|
||||
|
||||
def _write_appdata(self, data):
|
||||
self._write_backlog.append((data, 0))
|
||||
self._write_buffer_size += len(data)
|
||||
|
@ -679,12 +692,22 @@ class SSLProtocol(protocols.Protocol):
|
|||
})
|
||||
if self._transport:
|
||||
self._transport._force_close(exc)
|
||||
self._transport = None
|
||||
|
||||
if self._shutdown_timeout_handle is not None:
|
||||
self._shutdown_timeout_handle.cancel()
|
||||
self._shutdown_timeout_handle = None
|
||||
|
||||
def _finalize(self):
|
||||
self._sslpipe = None
|
||||
|
||||
if self._transport is not None:
|
||||
self._transport.close()
|
||||
self._transport = None
|
||||
|
||||
if self._shutdown_timeout_handle is not None:
|
||||
self._shutdown_timeout_handle.cancel()
|
||||
self._shutdown_timeout_handle = None
|
||||
|
||||
def _abort(self):
|
||||
try:
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue