@@ -190,11 +190,12 @@ def _secure(cls, s, host, ssl_context):
190
190
return s
191
191
192
192
@classmethod
193
- def _handshake (cls , s , resolved_address ):
193
+ def _handshake (cls , s , resolved_address , deadline ):
194
194
"""
195
195
196
196
:param s: Socket
197
197
:param resolved_address:
198
+ :param deadline:
198
199
199
200
:return: (socket, version, client_handshake, server_response_data)
200
201
"""
@@ -214,46 +215,52 @@ def _handshake(cls, s, resolved_address):
214
215
log .debug ("[#%04X] C: <HANDSHAKE> %s %s %s %s" , local_port ,
215
216
* supported_versions )
216
217
217
- data = cls .Bolt .MAGIC_PREAMBLE + cls .Bolt .get_handshake ()
218
- s .sendall (data )
218
+ request = cls .Bolt .MAGIC_PREAMBLE + cls .Bolt .get_handshake ()
219
219
220
220
# Handle the handshake response
221
- ready_to_read = False
222
- with selectors .DefaultSelector () as selector :
223
- selector .register (s , selectors .EVENT_READ )
224
- selector .select (1 )
221
+ original_timeout = s .gettimeout ()
222
+ s .settimeout (deadline .to_timeout ())
225
223
try :
226
- data = s .recv (4 )
227
- except OSError :
224
+ s .sendall (request )
225
+ response = s .recv (4 )
226
+ except OSError as exc :
228
227
raise ServiceUnavailable (
229
- "Failed to read any data from server {!r} "
230
- "after connected" .format (resolved_address ))
231
- data_size = len (data )
228
+ f"Failed to read any data from server { resolved_address !r} "
229
+ f"after connected (deadline { deadline } )"
230
+ ) from exc
231
+ finally :
232
+ s .settimeout (original_timeout )
233
+ data_size = len (response )
232
234
if data_size == 0 :
233
235
# If no data is returned after a successful select
234
236
# response, the server has closed the connection
235
237
log .debug ("[#%04X] S: <CLOSE>" , local_port )
236
238
cls .close_socket (s )
237
239
raise ServiceUnavailable (
238
- "Connection to {address} closed without handshake response" .format (
239
- address = resolved_address ))
240
+ f"Connection to { resolved_address } closed without handshake "
241
+ "response"
242
+ )
240
243
if data_size != 4 :
241
244
# Some garbled data has been received
242
245
log .debug ("[#%04X] S: @*#!" , local_port )
243
246
cls .close_socket (s )
244
247
raise BoltProtocolError (
245
- "Expected four byte Bolt handshake response from %r, received %r instead; check for incorrect port number" % (
246
- resolved_address , data ), address = resolved_address )
247
- elif data == b"HTTP" :
248
+ "Expected four byte Bolt handshake response from "
249
+ f"{ resolved_address !r} , received { response !r} instead; "
250
+ "check for incorrect port number"
251
+ , address = resolved_address
252
+ )
253
+ elif response == b"HTTP" :
248
254
log .debug ("[#%04X] S: <CLOSE>" , local_port )
249
255
cls .close_socket (s )
250
256
raise ServiceUnavailable (
251
- "Cannot to connect to Bolt service on {!r} "
252
- "(looks like HTTP)" .format (resolved_address ))
253
- agreed_version = data [- 1 ], data [- 2 ]
257
+ f"Cannot to connect to Bolt service on { resolved_address !r} "
258
+ "(looks like HTTP)"
259
+ )
260
+ agreed_version = response [- 1 ], response [- 2 ]
254
261
log .debug ("[#%04X] S: <HANDSHAKE> 0x%06X%02X" , local_port ,
255
262
agreed_version [1 ], agreed_version [0 ])
256
- return cls (s ), agreed_version , handshake , data
263
+ return cls (s ), agreed_version , handshake , response
257
264
258
265
@classmethod
259
266
def close_socket (cls , socket_ ):
@@ -269,8 +276,8 @@ def close_socket(cls, socket_):
269
276
pass
270
277
271
278
@classmethod
272
- def connect (cls , address , * , timeout , custom_resolver , ssl_context ,
273
- keep_alive ):
279
+ def connect (cls , address , * , tcp_timeout , deadline , custom_resolver ,
280
+ ssl_context , keep_alive ):
274
281
""" Connect and perform a handshake and return a valid Connection object,
275
282
assuming a protocol version can be agreed.
276
283
"""
@@ -281,12 +288,19 @@ def connect(cls, address, *, timeout, custom_resolver, ssl_context,
281
288
282
289
resolved_addresses = Address (address ).resolve (resolver = custom_resolver )
283
290
for resolved_address in resolved_addresses :
291
+ deadline_timeout = deadline .to_timeout ()
292
+ if (
293
+ deadline_timeout is not None
294
+ and deadline_timeout <= tcp_timeout
295
+ ):
296
+ tcp_timeout = deadline_timeout
284
297
s = None
285
298
try :
286
- s = BoltSocket ._connect (resolved_address , timeout , keep_alive )
299
+ s = BoltSocket ._connect (resolved_address , tcp_timeout ,
300
+ keep_alive )
287
301
s = BoltSocket ._secure (s , resolved_address .host_name ,
288
302
ssl_context )
289
- return BoltSocket ._handshake (s , resolved_address )
303
+ return BoltSocket ._handshake (s , resolved_address , deadline )
290
304
except (BoltError , DriverError , OSError ) as error :
291
305
try :
292
306
local_port = s .getsockname ()[1 ]
0 commit comments