@@ -190,11 +190,12 @@ def _secure(cls, s, host, ssl_context):
190190 return s
191191
192192 @classmethod
193- def _handshake (cls , s , resolved_address ):
193+ def _handshake (cls , s , resolved_address , deadline ):
194194 """
195195
196196 :param s: Socket
197197 :param resolved_address:
198+ :param deadline:
198199
199200 :return: (socket, version, client_handshake, server_response_data)
200201 """
@@ -214,46 +215,52 @@ def _handshake(cls, s, resolved_address):
214215 log .debug ("[#%04X] C: <HANDSHAKE> %s %s %s %s" , local_port ,
215216 * supported_versions )
216217
217- data = cls .Bolt .MAGIC_PREAMBLE + cls .Bolt .get_handshake ()
218- s .sendall (data )
218+ request = cls .Bolt .MAGIC_PREAMBLE + cls .Bolt .get_handshake ()
219219
220220 # 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 ())
225223 try :
226- data = s .recv (4 )
227- except OSError :
224+ s .sendall (request )
225+ response = s .recv (4 )
226+ except OSError as exc :
228227 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 )
232234 if data_size == 0 :
233235 # If no data is returned after a successful select
234236 # response, the server has closed the connection
235237 log .debug ("[#%04X] S: <CLOSE>" , local_port )
236238 cls .close_socket (s )
237239 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+ )
240243 if data_size != 4 :
241244 # Some garbled data has been received
242245 log .debug ("[#%04X] S: @*#!" , local_port )
243246 cls .close_socket (s )
244247 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" :
248254 log .debug ("[#%04X] S: <CLOSE>" , local_port )
249255 cls .close_socket (s )
250256 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 ]
254261 log .debug ("[#%04X] S: <HANDSHAKE> 0x%06X%02X" , local_port ,
255262 agreed_version [1 ], agreed_version [0 ])
256- return cls (s ), agreed_version , handshake , data
263+ return cls (s ), agreed_version , handshake , response
257264
258265 @classmethod
259266 def close_socket (cls , socket_ ):
@@ -269,8 +276,8 @@ def close_socket(cls, socket_):
269276 pass
270277
271278 @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 ):
274281 """ Connect and perform a handshake and return a valid Connection object,
275282 assuming a protocol version can be agreed.
276283 """
@@ -281,12 +288,19 @@ def connect(cls, address, *, timeout, custom_resolver, ssl_context,
281288
282289 resolved_addresses = Address (address ).resolve (resolver = custom_resolver )
283290 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
284297 s = None
285298 try :
286- s = BoltSocket ._connect (resolved_address , timeout , keep_alive )
299+ s = BoltSocket ._connect (resolved_address , tcp_timeout ,
300+ keep_alive )
287301 s = BoltSocket ._secure (s , resolved_address .host_name ,
288302 ssl_context )
289- return BoltSocket ._handshake (s , resolved_address )
303+ return BoltSocket ._handshake (s , resolved_address , deadline )
290304 except (BoltError , DriverError , OSError ) as error :
291305 try :
292306 local_port = s .getsockname ()[1 ]
0 commit comments