@@ -269,7 +269,7 @@ async def restore(self):
269269class Server (events .AbstractServer ):
270270
271271 def __init__ (self , loop , sockets , protocol_factory , ssl_context , backlog ,
272- ssl_handshake_timeout ):
272+ ssl_handshake_timeout , ssl_shutdown_timeout = None ):
273273 self ._loop = loop
274274 self ._sockets = sockets
275275 self ._active_count = 0
@@ -278,6 +278,7 @@ def __init__(self, loop, sockets, protocol_factory, ssl_context, backlog,
278278 self ._backlog = backlog
279279 self ._ssl_context = ssl_context
280280 self ._ssl_handshake_timeout = ssl_handshake_timeout
281+ self ._ssl_shutdown_timeout = ssl_shutdown_timeout
281282 self ._serving = False
282283 self ._serving_forever_fut = None
283284
@@ -309,7 +310,8 @@ def _start_serving(self):
309310 sock .listen (self ._backlog )
310311 self ._loop ._start_serving (
311312 self ._protocol_factory , sock , self ._ssl_context ,
312- self , self ._backlog , self ._ssl_handshake_timeout )
313+ self , self ._backlog , self ._ssl_handshake_timeout ,
314+ self ._ssl_shutdown_timeout )
313315
314316 def get_loop (self ):
315317 return self ._loop
@@ -463,6 +465,7 @@ def _make_ssl_transport(
463465 * , server_side = False , server_hostname = None ,
464466 extra = None , server = None ,
465467 ssl_handshake_timeout = None ,
468+ ssl_shutdown_timeout = None ,
466469 call_connection_made = True ):
467470 """Create SSL transport."""
468471 raise NotImplementedError
@@ -965,6 +968,7 @@ async def create_connection(
965968 proto = 0 , flags = 0 , sock = None ,
966969 local_addr = None , server_hostname = None ,
967970 ssl_handshake_timeout = None ,
971+ ssl_shutdown_timeout = None ,
968972 happy_eyeballs_delay = None , interleave = None ):
969973 """Connect to a TCP server.
970974
@@ -1000,6 +1004,10 @@ async def create_connection(
10001004 raise ValueError (
10011005 'ssl_handshake_timeout is only meaningful with ssl' )
10021006
1007+ if ssl_shutdown_timeout is not None and not ssl :
1008+ raise ValueError (
1009+ 'ssl_shutdown_timeout is only meaningful with ssl' )
1010+
10031011 if happy_eyeballs_delay is not None and interleave is None :
10041012 # If using happy eyeballs, default to interleave addresses by family
10051013 interleave = 1
@@ -1075,7 +1083,8 @@ async def create_connection(
10751083
10761084 transport , protocol = await self ._create_connection_transport (
10771085 sock , protocol_factory , ssl , server_hostname ,
1078- ssl_handshake_timeout = ssl_handshake_timeout )
1086+ ssl_handshake_timeout = ssl_handshake_timeout ,
1087+ ssl_shutdown_timeout = ssl_shutdown_timeout )
10791088 if self ._debug :
10801089 # Get the socket from the transport because SSL transport closes
10811090 # the old socket and creates a new SSL socket
@@ -1087,7 +1096,8 @@ async def create_connection(
10871096 async def _create_connection_transport (
10881097 self , sock , protocol_factory , ssl ,
10891098 server_hostname , server_side = False ,
1090- ssl_handshake_timeout = None ):
1099+ ssl_handshake_timeout = None ,
1100+ ssl_shutdown_timeout = None ):
10911101
10921102 sock .setblocking (False )
10931103
@@ -1098,7 +1108,8 @@ async def _create_connection_transport(
10981108 transport = self ._make_ssl_transport (
10991109 sock , protocol , sslcontext , waiter ,
11001110 server_side = server_side , server_hostname = server_hostname ,
1101- ssl_handshake_timeout = ssl_handshake_timeout )
1111+ ssl_handshake_timeout = ssl_handshake_timeout ,
1112+ ssl_shutdown_timeout = ssl_shutdown_timeout )
11021113 else :
11031114 transport = self ._make_socket_transport (sock , protocol , waiter )
11041115
@@ -1189,7 +1200,8 @@ async def _sendfile_fallback(self, transp, file, offset, count):
11891200 async def start_tls (self , transport , protocol , sslcontext , * ,
11901201 server_side = False ,
11911202 server_hostname = None ,
1192- ssl_handshake_timeout = None ):
1203+ ssl_handshake_timeout = None ,
1204+ ssl_shutdown_timeout = None ):
11931205 """Upgrade transport to TLS.
11941206
11951207 Return a new transport that *protocol* should start using
@@ -1212,6 +1224,7 @@ async def start_tls(self, transport, protocol, sslcontext, *,
12121224 self , protocol , sslcontext , waiter ,
12131225 server_side , server_hostname ,
12141226 ssl_handshake_timeout = ssl_handshake_timeout ,
1227+ ssl_shutdown_timeout = ssl_shutdown_timeout ,
12151228 call_connection_made = False )
12161229
12171230 # Pause early so that "ssl_protocol.data_received()" doesn't
@@ -1397,6 +1410,7 @@ async def create_server(
13971410 reuse_address = None ,
13981411 reuse_port = None ,
13991412 ssl_handshake_timeout = None ,
1413+ ssl_shutdown_timeout = None ,
14001414 start_serving = True ):
14011415 """Create a TCP server.
14021416
@@ -1420,6 +1434,10 @@ async def create_server(
14201434 raise ValueError (
14211435 'ssl_handshake_timeout is only meaningful with ssl' )
14221436
1437+ if ssl_shutdown_timeout is not None and ssl is None :
1438+ raise ValueError (
1439+ 'ssl_shutdown_timeout is only meaningful with ssl' )
1440+
14231441 if host is not None or port is not None :
14241442 if sock is not None :
14251443 raise ValueError (
@@ -1492,7 +1510,8 @@ async def create_server(
14921510 sock .setblocking (False )
14931511
14941512 server = Server (self , sockets , protocol_factory ,
1495- ssl , backlog , ssl_handshake_timeout )
1513+ ssl , backlog , ssl_handshake_timeout ,
1514+ ssl_shutdown_timeout )
14961515 if start_serving :
14971516 server ._start_serving ()
14981517 # Skip one loop iteration so that all 'loop.add_reader'
@@ -1506,17 +1525,23 @@ async def create_server(
15061525 async def connect_accepted_socket (
15071526 self , protocol_factory , sock ,
15081527 * , ssl = None ,
1509- ssl_handshake_timeout = None ):
1528+ ssl_handshake_timeout = None ,
1529+ ssl_shutdown_timeout = None ):
15101530 if sock .type != socket .SOCK_STREAM :
15111531 raise ValueError (f'A Stream Socket was expected, got { sock !r} ' )
15121532
15131533 if ssl_handshake_timeout is not None and not ssl :
15141534 raise ValueError (
15151535 'ssl_handshake_timeout is only meaningful with ssl' )
15161536
1537+ if ssl_shutdown_timeout is not None and not ssl :
1538+ raise ValueError (
1539+ 'ssl_shutdown_timeout is only meaningful with ssl' )
1540+
15171541 transport , protocol = await self ._create_connection_transport (
15181542 sock , protocol_factory , ssl , '' , server_side = True ,
1519- ssl_handshake_timeout = ssl_handshake_timeout )
1543+ ssl_handshake_timeout = ssl_handshake_timeout ,
1544+ ssl_shutdown_timeout = ssl_shutdown_timeout )
15201545 if self ._debug :
15211546 # Get the socket from the transport because SSL transport closes
15221547 # the old socket and creates a new SSL socket
0 commit comments