Skip to content

requests: HTTP/1.1 with Content-Length and streaming raw#1124

Open
pablogventura wants to merge 5 commits into
micropython:masterfrom
pablogventura:requests-http11-streaming
Open

requests: HTTP/1.1 with Content-Length and streaming raw#1124
pablogventura wants to merge 5 commits into
micropython:masterfrom
pablogventura:requests-http11-streaming

Conversation

@pablogventura

@pablogventura pablogventura commented Jun 19, 2026

Copy link
Copy Markdown

Summary

  • Send HTTP/1.1 requests (was HTTP/1.0).
  • Parse response status/headers via a small _http module.
  • Support Content-Length response bodies without buffering in request().
  • Preserve .raw as a live BodyStream wrapper; .content remains lazy.

Closes the approach in #1119 (which buffered the full body and closed the socket). Chunked responses, max_body, and relative redirects are intentionally left for follow-up PRs.

Testing

  • micropython test_requests.py (unix port) — 13 mock tests including incremental .raw.read().
  • CI: ruff, codespell, package tests.

Trade-offs and Alternatives

  • Chunked response bodies still raise ValueError (unchanged from master until a follow-up PR).
  • BodyStream adds a small wrapper object (~two fields) instead of buffering the body in request().
  • stream=True is not implemented yet (issue requests: stream parameter is noop #777).

Generative AI

I used generative AI tools when creating this PR, but a human has checked the
code and is responsible for the code and the description above.

Introduce read_status_line(), read_headers(), and BodyStream with
Content-Length and until-close modes. No request() changes yet.

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Wire _http into request(); send HTTP/1.1; return BodyStream as .raw
without reading or closing the socket in request().

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Adapt outbound tests to HTTP/1.1; add Content-Length and incremental
.raw.read() coverage.

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Document HTTP/1.1 requests and Content-Length body reads via .raw.

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
Read part of the body via .raw then the remainder via .content; avoid
"hel" token flagged by codespell.

Signed-off-by: Pablo Ventura <pablogventura@gmail.com>
@pablogventura

Copy link
Copy Markdown
Author

ESP32 hardware testing

Tested on device connected via /dev/ttyACM0:

Board ESP32
Firmware MicroPython v1.29.0-preview.337 (2026-06-01)
WiFi LosMius (STA), device IP 192.168.1.151
Package deployed /lib/requests/__init__.py + /lib/requests/_http.py from this PR

Mock tests (test_requests.py) — 13/13 OK

All existing mock tests pass on-device (outbound HTTP/1.1, Content-Length inbound, incremental .raw.read(), chunked response still raises ValueError).

Live tests (LAN HTTP server at 192.168.1.72:58080) — 4/4 OK

Test Result
GET /get with Content-Length body 200, 11 bytes
GET /bytes/8 via .content abcdefgh, socket closed after read
GET /bytes/10 incremental .raw.read(3) + .raw.read(3) + .raw.read() 3+3+4 bytes → 0123456789
GET /chunked ValueError: Unsupported Transfer-Encoding: chunked (expected for v1)

Server log confirmed outbound requests use HTTP/1.1:

GET /get HTTP/1.1
GET /bytes/8 HTTP/1.1
GET /bytes/10 HTTP/1.1
GET /chunked HTTP/1.1

Notes

  • httpbin.org returned 503 from this network, so live body tests used a local test server instead.
  • Mock tests replace sys.modules["socket"]; live tests reload usocket afterwards before hitting the network.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant