@@ -622,6 +622,10 @@ def request( # noqa: PLR0912,PLR0913,PLR0915 Too many branches,Too many argumen
622622
623623 # We may fail to send the request if the socket we got is closed already. So, try a second
624624 # 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.
625629 retry_count = 0
626630 last_exc = None
627631 while retry_count < 2 :
@@ -643,17 +647,23 @@ def request( # noqa: PLR0912,PLR0913,PLR0915 Too many branches,Too many argumen
643647 if ok :
644648 # Read the H of "HTTP/1.1" to make sure the socket is alive. send can appear to work
645649 # 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 )
651658 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
657667 self ._connection_manager .close_socket (socket )
658668 socket = None
659669
0 commit comments