adafruit / Adafruit_CircuitPython_Requests

Requests-like interface for web interfacing
MIT License
51 stars 37 forks source link

`requests.head` doesn't work #153

Closed jepler closed 6 months ago

jepler commented 7 months ago

The following code fails with etimedout (wifi setup not shown):

r = requests.head("http://wifitest.adafruit.com/testwifi/index.html", timeout=3)
r.close()
Traceback (most recent call last):
  File "code.py", line 41, in <module>
  File "adafruit_requests.py", line 313, in close
  File "adafruit_requests.py", line 301, in _throw_away
  File "adafruit_requests.py", line 203, in _recv_into
OSError: [Errno 116] ETIMEDOUT

This appears to occur because a HEAD request may contain a content-length header, but it never actually contains any content.

A quick and dirty workaround:

diff --git a/adafruit_requests.py b/adafruit_requests.py
index 26b40f0..76c1ec4 100644
--- a/adafruit_requests.py
+++ b/adafruit_requests.py
@@ -160,7 +160,12 @@ class Response:

     encoding = None

-    def __init__(self, sock: SocketType, session: Optional["Session"] = None) -> None:
+    def __init__(
+        self,
+        sock: SocketType,
+        session: Optional["Session"] = None,
+        is_head: bool = False,
+    ) -> None:
         self.socket = sock
         self.encoding = "utf-8"
         self._cached = None
@@ -185,6 +190,8 @@ class Response:
         self.reason: bytearray = self._readto(b"\r\n")
         """The status reason returned by the server"""
         self._parse_headers()
+        if is_head:
+            self._remaining = 0
         self._raw = None
         self._session = session

@@ -695,7 +703,7 @@ class Session:
         if not socket:
             raise OutOfRetries("Repeated socket failures") from last_exc

-        resp = Response(socket, self)  # our response
+        resp = Response(socket, self, method == "HEAD")  # our response
         if allow_redirects:
             if "location" in resp.headers and 300 <= resp.status_code <= 399:
                 # a naive handler for redirects

but tagging @justmobilize for interest

justmobilize commented 7 months ago

@jepler since I was also going to look at https://github.com/adafruit/Adafruit_CircuitPython_Requests/issues/130. Which is the actual problem here. I recommend fixing that one (and looking at ESP32SPI) which would fix this one. Thoughts?

justmobilize commented 6 months ago

@jepler or @dhalbert can this be closed with my cleanup on response.close()

dhalbert commented 6 months ago

Sure: fixed by #156 and #159.

Do you know about https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue

justmobilize commented 6 months ago

I do, but don't have permissions.

dhalbert commented 6 months ago

I do, but don't have permissions.

You just put Fixes #xyz in the PR post. The link above explains the special keywords that do that linking: "Fixes", "Resolves", etc.