@@ -409,8 +409,6 @@ def on_connect(self):
409
409
# if client caching is enabled, start tracking
410
410
if self .client_cache :
411
411
self .send_command ("CLIENT" , "TRACKING" , "ON" )
412
- self .read_response ()
413
- self ._parser .set_invalidation_push_handler (self ._cache_invalidation_process )
414
412
415
413
# execute the MULTI block
416
414
try :
@@ -447,6 +445,77 @@ def _read_exec_responses(self):
447
445
raise ConnectionError (f"EXEC command did not return a list: { response } " )
448
446
return response
449
447
448
+ def _handle_responses (self , responses , auth_args ):
449
+ if not isinstance (responses , list ):
450
+ raise ConnectionError (f"EXEC command did not return a list: { responses } " )
451
+
452
+ response_iter = iter (responses )
453
+
454
+ try :
455
+ # handle HELLO + AUTH
456
+ if auth_args and self .protocol not in [2 , "2" ]:
457
+ response = next (response_iter , None )
458
+ if isinstance (response , dict ) and (
459
+ response .get (b"proto" ) != self .protocol and response .get ("proto" ) != self .protocol ):
460
+ raise ConnectionError ("Invalid RESP version" )
461
+
462
+ response = next (response_iter , None )
463
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
464
+ raise AuthenticationError ("Invalid Username or Password" )
465
+ elif auth_args :
466
+ response = next (response_iter , None )
467
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
468
+ try :
469
+ # a username and password were specified but the Redis
470
+ # server seems to be < 6.0.0 which expects a single password
471
+ # arg. retry auth with just the password.
472
+ # https://github.com/andymccurdy/redis-py/issues/1274
473
+ self .send_command ("AUTH" , auth_args [- 1 ], check_health = False )
474
+ auth_response = self .read_response ()
475
+ if isinstance (auth_response , bytes ) and str_if_bytes (
476
+ auth_response ) != "OK" :
477
+ raise AuthenticationError ("Invalid Username or Password" )
478
+ # add the retry response to the responses list for further processing
479
+ responses = [auth_response ] + list (response_iter )
480
+ response_iter = iter (responses )
481
+ except AuthenticationWrongNumberOfArgsError :
482
+ raise AuthenticationError ("Invalid Username or Password" )
483
+
484
+ # handle CLIENT SETNAME
485
+ if self .client_name :
486
+ response = next (response_iter , None )
487
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
488
+ raise ConnectionError ("Error setting client name" )
489
+
490
+ # handle CLIENT SETINFO LIB-NAME
491
+ if self .lib_name :
492
+ response = next (response_iter , None )
493
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
494
+ raise ConnectionError ("Error setting client library name" )
495
+
496
+ # handle CLIENT SETINFO LIB-VER
497
+ if self .lib_version :
498
+ response = next (response_iter , None )
499
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
500
+ raise ConnectionError ("Error setting client library version" )
501
+
502
+ # handle SELECT
503
+ if self .db :
504
+ response = next (response_iter , None )
505
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
506
+ raise ConnectionError ("Invalid Database" )
507
+
508
+ # handle CLIENT TRACKING ON
509
+ if self .client_cache :
510
+ response = next (response_iter , None )
511
+ if isinstance (response , bytes ) and str_if_bytes (response ) != "OK" :
512
+ raise ConnectionError ("Error enabling client tracking" )
513
+ self ._parser .set_invalidation_push_handler (
514
+ self ._cache_invalidation_process )
515
+ except (AuthenticationError , ConnectionError ):
516
+ raise
517
+ except Exception as e :
518
+ raise ConnectionError ("Error during response handling" ) from e
450
519
451
520
def disconnect (self , * args ):
452
521
"Disconnects from the Redis server"
0 commit comments