bpo-37322: Fix ResourceWarning and exception handling in test (GH-25553)

Revert 73ea546, increase logging, and improve stability of test.

Handle all OSErrors in a single block. OSError also takes care of
SSLError and socket's connection errors.

Partly reverts commit fb7e750. The
threaded connection handler must not raise an unhandled exception.
This commit is contained in:
Christian Heimes 2021-04-24 09:17:54 +02:00 committed by GitHub
parent f05c2aed7e
commit c8666cfa7c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -2390,7 +2390,10 @@ class ThreadedEchoServer(threading.Thread):
sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n") sys.stdout.write(" client cert is " + pprint.pformat(cert) + "\n")
cert_binary = self.sslconn.getpeercert(True) cert_binary = self.sslconn.getpeercert(True)
if support.verbose and self.server.chatty: if support.verbose and self.server.chatty:
sys.stdout.write(" cert binary is " + str(len(cert_binary)) + " bytes\n") if cert_binary is None:
sys.stdout.write(" client did not provide a cert\n")
else:
sys.stdout.write(f" cert binary is {len(cert_binary)}b\n")
cipher = self.sslconn.cipher() cipher = self.sslconn.cipher()
if support.verbose and self.server.chatty: if support.verbose and self.server.chatty:
sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n") sys.stdout.write(" server: connection cipher is now " + str(cipher) + "\n")
@ -2486,31 +2489,22 @@ class ThreadedEchoServer(threading.Thread):
sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n" sys.stdout.write(" server: read %r (%s), sending back %r (%s)...\n"
% (msg, ctype, msg.lower(), ctype)) % (msg, ctype, msg.lower(), ctype))
self.write(msg.lower()) self.write(msg.lower())
except (ConnectionResetError, ConnectionAbortedError): except OSError as e:
# XXX: OpenSSL 1.1.1 sometimes raises ConnectionResetError # handles SSLError and socket errors
# when connection is not shut down gracefully.
if self.server.chatty and support.verbose: if self.server.chatty and support.verbose:
sys.stdout.write( if isinstance(e, ConnectionError):
" Connection reset by peer: {}\n".format( # OpenSSL 1.1.1 sometimes raises
self.addr) # ConnectionResetError when connection is not
) # shut down gracefully.
self.close() print(
self.running = False f" Connection reset by peer: {self.addr}"
except ssl.SSLError as err: )
# On Windows sometimes test_pha_required_nocert receives the else:
# PEER_DID_NOT_RETURN_A_CERTIFICATE exception handle_error("Test server failure:\n")
# before the 'tlsv13 alert certificate required' exception. try:
# If the server is stopped when PEER_DID_NOT_RETURN_A_CERTIFICATE self.write(b"ERROR\n")
# is received test_pha_required_nocert fails with ConnectionResetError except OSError:
# because the underlying socket is closed pass
if 'PEER_DID_NOT_RETURN_A_CERTIFICATE' == err.reason:
if self.server.chatty and support.verbose:
sys.stdout.write(err.args[1])
# test_pha_required_nocert is expecting this exception
raise ssl.SSLError('tlsv13 alert certificate required')
except OSError:
if self.server.chatty:
handle_error("Test server failure:\n")
self.close() self.close()
self.running = False self.running = False
@ -4416,24 +4410,30 @@ class TestPostHandshakeAuth(unittest.TestCase):
server_context.verify_mode = ssl.CERT_REQUIRED server_context.verify_mode = ssl.CERT_REQUIRED
client_context.post_handshake_auth = True client_context.post_handshake_auth = True
# Ignore expected SSLError in ConnectionHandler of ThreadedEchoServer def msg_cb(conn, direction, version, content_type, msg_type, data):
# (it is only raised sometimes on Windows) if support.verbose and content_type == _TLSContentType.ALERT:
with threading_helper.catch_threading_exception() as cm: info = (conn, direction, version, content_type, msg_type, data)
server = ThreadedEchoServer(context=server_context, chatty=False) sys.stdout.write(f"TLS: {info!r}\n")
with server:
with client_context.wrap_socket(socket.socket(), server_context._msg_callback = msg_cb
server_hostname=hostname) as s: client_context._msg_callback = msg_cb
s.connect((HOST, server.port))
s.write(b'PHA') server = ThreadedEchoServer(context=server_context, chatty=True)
with server:
with client_context.wrap_socket(socket.socket(),
server_hostname=hostname) as s:
s.connect((HOST, server.port))
s.write(b'PHA')
with self.assertRaisesRegex(
ssl.SSLError,
'tlsv13 alert certificate required'
):
# receive CertificateRequest # receive CertificateRequest
self.assertEqual(s.recv(1024), b'OK\n') self.assertEqual(s.recv(1024), b'OK\n')
# send empty Certificate + Finish # send empty Certificate + Finish
s.write(b'HASCERT') s.write(b'HASCERT')
# receive alert # receive alert
with self.assertRaisesRegex( s.recv(1024)
ssl.SSLError,
'tlsv13 alert certificate required'):
s.recv(1024)
def test_pha_optional(self): def test_pha_optional(self):
if support.verbose: if support.verbose: