Skip to content

Commit 8a0b3c1

Browse files
authored
Merge pull request #205 from PCPartPicker/main
Fixes for exceptions in Session.request leading to sockets not properly closed
2 parents 2db92cd + 4c9372b commit 8a0b3c1

File tree

1 file changed

+20
-10
lines changed

1 file changed

+20
-10
lines changed

adafruit_requests.py

+20-10
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)