Skip to content

Commit 1f2ab33

Browse files
authored
Merge pull request #149 from technige/1.2-socket-cleanup
Close socket when failing to establish connection
2 parents 2cc0a87 + 26b27c1 commit 1f2ab33

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

neo4j/bolt/connection.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,7 @@ def connect(address, ssl_context=None, **config):
453453
s.connect(address)
454454
s.setsockopt(SOL_SOCKET, SO_KEEPALIVE, 1 if config.get("keep_alive", True) else 0)
455455
except SocketError as error:
456+
s.close()
456457
if error.errno in (61, 111, 10061):
457458
raise ServiceUnavailable("Failed to establish connection to {!r}".format(address))
458459
else:
@@ -465,6 +466,7 @@ def connect(address, ssl_context=None, **config):
465466
try:
466467
s = ssl_context.wrap_socket(s, server_hostname=host if HAS_SNI else None)
467468
except SSLError as cause:
469+
s.close()
468470
error = SecurityError("Failed to establish secure connection to {!r}".format(cause.args[1]))
469471
error.__cause__ = cause
470472
raise error
@@ -473,13 +475,15 @@ def connect(address, ssl_context=None, **config):
473475
# Check that the server provides a certificate
474476
der_encoded_server_certificate = s.getpeercert(binary_form=True)
475477
if der_encoded_server_certificate is None:
478+
s.close()
476479
raise ProtocolError("When using a secure socket, the server should always "
477480
"provide a certificate")
478481
trust = config.get("trust", TRUST_DEFAULT)
479482
if trust == TRUST_ON_FIRST_USE:
480483
from neo4j.bolt.cert import PersonalCertificateStore
481484
store = PersonalCertificateStore()
482485
if not store.match_or_trust(host, der_encoded_server_certificate):
486+
s.close()
483487
raise ProtocolError("Server certificate does not match known certificate "
484488
"for %r; check details in file %r" % (host, KNOWN_HOSTS))
485489
else:
@@ -502,10 +506,12 @@ def connect(address, ssl_context=None, **config):
502506
# If no data is returned after a successful select
503507
# response, the server has closed the connection
504508
log_error("S: [CLOSE]")
509+
s.close()
505510
raise ProtocolError("Connection to %r closed without handshake response" % (address,))
506511
if data_size != 4:
507512
# Some garbled data has been received
508513
log_error("S: @*#!")
514+
s.close()
509515
raise ProtocolError("Expected four byte handshake response, received %r instead" % data)
510516
agreed_version, = struct_unpack(">I", data)
511517
log_info("S: [HANDSHAKE] %d", agreed_version)
@@ -517,8 +523,10 @@ def connect(address, ssl_context=None, **config):
517523
return Connection(s, der_encoded_server_certificate=der_encoded_server_certificate, **config)
518524
elif agreed_version == 0x48545450:
519525
log_error("S: [CLOSE]")
526+
s.close()
520527
raise ServiceUnavailable("Cannot to connect to Bolt service on {!r} "
521528
"(looks like HTTP)".format(address))
522529
else:
523530
log_error("S: [CLOSE]")
531+
s.close()
524532
raise ProtocolError("Unknown Bolt protocol version: {}".format(agreed_version))

0 commit comments

Comments
 (0)