adafruit / Adafruit_CircuitPython_Requests

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

Certain Feather RP2040 (ESP32SPI) chunked responses fail #75

Closed anecdata closed 2 years ago

anecdata commented 3 years ago

This one only manifests on Feather RP2040. It doesn't happen on PyPortal or FeatherS2. Some primitive behaves different? A timing quirk? Flash issue? Other??

This URL comes back as a chunked response, but loads fine: https://anecdata.dev/ada/chunked2/?oc=8&ic=4&tr=28&ot=0&it=0

But this one hangs up on receiving: https://anecdata.dev/ada/chunked2/?oc=7&ic=3&tr=17&ot=0&it=0

The parameters affect the data size. My only intuition is that round numbers seem to be fine, but less-round (odd?) numbers fail. The failures manifest as hanging on receive in line 122 of Requests:

Fetching text from https://anecdata.dev/ada/chunked2/?oc=7&ic=3&tr=17&ot=0&it=0
----------------------------------------
Traceback (most recent call last):
  File "code.py", line 34, in <module>
  File "adafruit_requests.py", line 326, in text
  File "adafruit_requests.py", line 315, in content
  File "adafruit_requests.py", line 369, in iter_content
  File "adafruit_requests.py", line 257, in close
  File "adafruit_requests.py", line 245, in _throw_away
  File "adafruit_requests.py", line 122, in _recv_into
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 132, in recv
  File "adafruit_esp32spi/adafruit_esp32spi_socket.py", line 172, in available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 731, in socket_available
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 325, in _send_command_get_response
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 281, in _wait_response_cmd
  File "adafruit_esp32spi/adafruit_esp32spi.py", line 188, in _wait_for_ready
KeyboardInterrupt: 

(^c after a minute of waiting)

or in reading the chunks, as in:

Traceback (most recent call last):
  File "code.py", line 32, in <module>
  File "adafruit_requests.py", line 326, in text
  File "adafruit_requests.py", line 315, in content
  File "adafruit_requests.py", line 361, in iter_content
  File "adafruit_requests.py", line 220, in _readinto
ValueError: invalid syntax for integer with base 16

In my 'prodution' code, it's always the latter situation. I haven't been able to run Feather RP2040 + Airlift from the beginning.

I doubt it's an Apache issue since it returns fine in the browser and with curl --http1.1. Old Requests was HTTP/1.0, chunked responses are a fact of life with HTTP/1.1.

I've tried this on various versions since the board became available, most recently with Adafruit CircuitPython 6.2.0-beta.4 on 2021-03-18; Adafruit Feather RP2040 with rp2040 and Adafruit CircuitPython 6.2.0-beta.3-142-ga5c675932 on 2021-03-12; Adafruit Feather RP2040 with rp2040 (the slower flash version from https://github.com/adafruit/circuitpython/pull/4392 )

I've spend a lot of time print-debugging this and I'm baffled. By the way, this Feather (I only have one) still has the disappearing-on-reset issue, even with the slower flash version UF2. But large file copies that were a problem before are no longer a problem in the slower flash version or in beta.4. So this could be some weird flash issue, though I've seen no other issues since the slower flash commit.

anecdata commented 3 years ago

Test code is a simplified Requests simpletest:

import board
import busio
from digitalio import DigitalInOut
import adafruit_esp32spi.adafruit_esp32spi_socket as socket
from adafruit_esp32spi import adafruit_esp32spi
import adafruit_requests as requests

from secrets import secrets

# Airlift FeatherWing:
esp32_cs = DigitalInOut(board.D13)  # Red LED
esp32_ready = DigitalInOut(board.D11)
esp32_reset = DigitalInOut(board.D12)

spi = busio.SPI(board.SCK, board.MOSI, board.MISO)
esp = adafruit_esp32spi.ESP_SPIcontrol(spi, esp32_cs, esp32_ready, esp32_reset)

print("Connecting to AP...")
esp.connect_AP(secrets["ssid"], secrets["password"])
print("Connected to", str(esp.ssid, "utf-8"), "\tRSSI:", esp.rssi)

# Initialize a requests object with a socket and esp32spi interface
socket.set_interface(esp)
requests.set_socket(socket, esp)

# out to lunch (line 122) or ValueError: invalid syntax for integer with base 16 (line 220)
TEXT_URL = "https://anecdata.dev/ada/chunked2/?oc=7&ic=3&tr=17&ot=0&it=0"

print("Fetching text from %s" % TEXT_URL)
response = requests.get(TEXT_URL)
print("-" * 40)

print("Text Response: ", response.text)
print("-" * 40)
response.close()
anecdata commented 2 years ago

Adafruit CircuitPython 7.2.0-alpha.1-224-gac7a80753 on 2022-01-26; Adafruit Feather RP2040 with rp2040 adafruit-circuitpython-bundle-7.x-mpy-20220128 NINA 1.7.4

Rested with latest CP & libs, and it's working now. Closing.