@@ -284,6 +284,22 @@ def test_ca_from_pem(tmp_path: Path) -> None:
284284 assert ca1 .private_key_pem .bytes () == ca2 .private_key_pem .bytes ()
285285
286286
287+ def safe_close (sock : Optional [Union [socket .socket , SslSocket ]]) -> None :
288+ if sock is None :
289+ return
290+ try :
291+ if isinstance (sock , (socket .socket , ssl .SSLSocket )):
292+ sock .shutdown (socket .SHUT_RDWR )
293+ elif isinstance (sock , OpenSSL .SSL .Connection ):
294+ sock .shutdown ()
295+ except Exception :
296+ pass
297+ try :
298+ sock .close ()
299+ except Exception :
300+ pass
301+
302+
287303def check_connection_end_to_end (
288304 wrap_client : Callable [[CA , socket .socket , str ], SslSocket ],
289305 wrap_server : Callable [[LeafCert , socket .socket ], SslSocket ],
@@ -296,12 +312,12 @@ def fake_ssl_client(ca: CA, raw_client_sock: socket.socket, hostname: str) -> No
296312 # Send and receive some data to prove the connection is good
297313 wrapped_client_sock .send (b"x" )
298314 assert wrapped_client_sock .recv (1 ) == b"y"
299- wrapped_client_sock . close ( )
315+ safe_close ( wrapped_client_sock )
300316 except : # pragma: no cover
301317 sys .excepthook (* sys .exc_info ())
302318 raise
303319 finally :
304- raw_client_sock . close ( )
320+ safe_close ( raw_client_sock )
305321
306322 # Server side
307323 def fake_ssl_server (server_cert : LeafCert , raw_server_sock : socket .socket ) -> None :
@@ -310,23 +326,25 @@ def fake_ssl_server(server_cert: LeafCert, raw_server_sock: socket.socket) -> No
310326 # Prove that we're connected
311327 assert wrapped_server_sock .recv (1 ) == b"x"
312328 wrapped_server_sock .send (b"y" )
313- wrapped_server_sock . close ( )
329+ safe_close ( wrapped_server_sock )
314330 except : # pragma: no cover
315331 sys .excepthook (* sys .exc_info ())
316332 raise
317333 finally :
318- raw_server_sock . close ( )
334+ safe_close ( raw_server_sock )
319335
320336 def doit (ca : CA , hostname : str , server_cert : LeafCert ) -> None :
321337 # socketpair and ssl don't work together on py2, because... reasons.
322338 # So we need to do this the hard way.
323339 listener = socket .socket ()
324- listener .bind (("127.0.0.1" , 0 ))
325- listener .listen (1 )
326- raw_client_sock = socket .socket ()
327- raw_client_sock .connect (listener .getsockname ())
328- raw_server_sock , _ = listener .accept ()
329- listener .close ()
340+ try :
341+ listener .bind (("127.0.0.1" , 0 ))
342+ listener .listen (1 )
343+ raw_client_sock = socket .socket ()
344+ raw_client_sock .connect (listener .getsockname ())
345+ raw_server_sock , _ = listener .accept ()
346+ finally :
347+ safe_close (listener )
330348 with ThreadPoolExecutor (2 ) as tpe :
331349 f1 = tpe .submit (fake_ssl_client , ca , raw_client_sock , hostname )
332350 f2 = tpe .submit (fake_ssl_server , server_cert , raw_server_sock )
0 commit comments