Skip to content

Commit 4cfc89a

Browse files
authored
Fix closure of sockets after failed connection (#794)
1 parent 3d3035a commit 4cfc89a

File tree

1 file changed

+15
-13
lines changed

1 file changed

+15
-13
lines changed

neo4j/io/_socket.py

+15-13
Original file line numberDiff line numberDiff line change
@@ -117,8 +117,7 @@ def sendall(self, data):
117117
return self._wait_for_io(self._socket.sendall, data)
118118

119119
def close(self):
120-
self._socket.shutdown(SHUT_RDWR)
121-
self._socket.close()
120+
self.close_socket(self._socket)
122121

123122
@classmethod
124123
def _connect(cls, resolved_address, timeout, keep_alive):
@@ -160,7 +159,7 @@ def _connect(cls, resolved_address, timeout, keep_alive):
160159
log.debug("[#0000] C: <ERROR> %s %s", type(error).__name__,
161160
" ".join(map(repr, error.args)))
162161
log.debug("[#0000] C: <CLOSE> %s", resolved_address)
163-
s.close()
162+
cls.close_socket(s)
164163
raise ServiceUnavailable(
165164
"Failed to establish connection to {!r} (reason {})".format(
166165
resolved_address, error))
@@ -175,6 +174,7 @@ def _secure(cls, s, host, ssl_context):
175174
sni_host = host if HAS_SNI and host else None
176175
s = ssl_context.wrap_socket(s, server_hostname=sni_host)
177176
except (OSError, SSLError, CertificateError) as cause:
177+
cls.close_socket(s)
178178
raise BoltSecurityError(
179179
message="Failed to establish encrypted connection.",
180180
address=(host, local_port)
@@ -233,20 +233,20 @@ def _handshake(cls, s, resolved_address):
233233
# If no data is returned after a successful select
234234
# response, the server has closed the connection
235235
log.debug("[#%04X] S: <CLOSE>", local_port)
236-
BoltSocket.close_socket(s)
236+
cls.close_socket(s)
237237
raise ServiceUnavailable(
238238
"Connection to {address} closed without handshake response".format(
239239
address=resolved_address))
240240
if data_size != 4:
241241
# Some garbled data has been received
242242
log.debug("[#%04X] S: @*#!", local_port)
243-
s.close()
243+
cls.close_socket(s)
244244
raise BoltProtocolError(
245245
"Expected four byte Bolt handshake response from %r, received %r instead; check for incorrect port number" % (
246246
resolved_address, data), address=resolved_address)
247247
elif data == b"HTTP":
248248
log.debug("[#%04X] S: <CLOSE>", local_port)
249-
BoltSocket.close_socket(s)
249+
cls.close_socket(s)
250250
raise ServiceUnavailable(
251251
"Cannot to connect to Bolt service on {!r} "
252252
"(looks like HTTP)".format(resolved_address))
@@ -257,12 +257,14 @@ def _handshake(cls, s, resolved_address):
257257

258258
@classmethod
259259
def close_socket(cls, socket_):
260+
if isinstance(socket_, BoltSocket):
261+
socket_ = socket_._socket
260262
try:
261-
if isinstance(socket_, BoltSocket):
262-
socket_.close()
263-
else:
264-
socket_.shutdown(SHUT_RDWR)
265-
socket_.close()
263+
socket_.shutdown(SHUT_RDWR)
264+
except OSError:
265+
pass
266+
try:
267+
socket_.close()
266268
except OSError:
267269
pass
268270

@@ -296,11 +298,11 @@ def connect(cls, address, *, timeout, custom_resolver, ssl_context,
296298
log.debug("[#%04X] C: <CONNECTION FAILED> %s", local_port,
297299
err_str)
298300
if s:
299-
BoltSocket.close_socket(s)
301+
cls.close_socket(s)
300302
errors.append(error)
301303
except Exception:
302304
if s:
303-
BoltSocket.close_socket(s)
305+
cls.close_socket(s)
304306
raise
305307
if not errors:
306308
raise ServiceUnavailable(

0 commit comments

Comments
 (0)