@@ -622,6 +622,10 @@ def request( # noqa: PLR0912,PLR0913,PLR0915 Too many branches,Too many argumen
622
622
623
623
# We may fail to send the request if the socket we got is closed already. So, try a second
624
624
# time in that case.
625
+ # Note that the loop below actually tries a second time in other failure cases too,
626
+ # namely timeout and no data from socket. This was not covered in the stated intent of the
627
+ # commit that introduced the loop, but removing the retry from those cases could prove
628
+ # problematic to callers that now depend on that resiliency.
625
629
retry_count = 0
626
630
last_exc = None
627
631
while retry_count < 2 :
@@ -643,17 +647,23 @@ def request( # noqa: PLR0912,PLR0913,PLR0915 Too many branches,Too many argumen
643
647
if ok :
644
648
# Read the H of "HTTP/1.1" to make sure the socket is alive. send can appear to work
645
649
# even when the socket is closed.
646
- if hasattr (socket , "recv" ):
647
- result = socket .recv (1 )
648
- else :
649
- result = bytearray (1 )
650
- try :
650
+ # Both recv/recv_into can raise OSError; when that happens, we need to call
651
+ # _connection_manager.close_socket(socket) or future calls to
652
+ # _connection_manager.get_socket() for the same parameter set will fail
653
+ try :
654
+ if hasattr (socket , "recv" ):
655
+ result = socket .recv (1 )
656
+ else :
657
+ result = bytearray (1 )
651
658
socket .recv_into (result )
652
- except OSError :
653
- pass
654
- if result == b"H" :
655
- # Things seem to be ok so break with socket set.
656
- break
659
+ if result == b"H" :
660
+ # Things seem to be ok so break with socket set.
661
+ break
662
+ else :
663
+ raise RuntimeError ("no data from socket" )
664
+ except (OSError , RuntimeError ) as exc :
665
+ last_exc = exc
666
+ pass
657
667
self ._connection_manager .close_socket (socket )
658
668
socket = None
659
669
0 commit comments