librespeed / librespeed/speedtest-rust
Upload requests with Transfer-Encoding: chunked hang forever
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 249
- Forks
- 37
- PR merge metrics
- No merged PRs in 30d
Description
Summary
The hand-written HTTP parser never chunk-decodes request bodies: BodyType::Chunked (src/http/request.rs) reads the raw stream in fixed 1024-byte read_exact blocks until EOF. With a finite payload the client keeps the connection open (keep-alive, no half-close), the final block never fills, and the server blocks forever instead of answering.
Impact
Any client that sends Transfer-Encoding: chunked stalls after its first payload. Concrete case: librespeed/speedtest-cli#122 — librespeed-cli v1.0.13+ uploads at 0.55 Mbps against librespeed-rs 1.4.0:
- The Go client wraps the upload body in a counting
io.TeeReaderwhich hides its length, so it sends chunked. - Server log from a replica of this body handling:
CHUNKED: read 1048837 raw bytes, then EOF/blocked— 1024×1024 payload + 261 bytes of chunk framing; 1048837 is not a multiple of 1024, so the lastread_exact(1024)blocks waiting for 763 more bytes that never come. - Upload rate = one payload / default 15 s duration = 1 MiB / 15 s ≈ 0.55 Mbps.
Same stall applies to curl -H "Transfer-Encoding: chunked" --data-binary @file and any chunked uploader. Content-Length requests (BodyType::Fixed) work fine.
Suggested fix
Parse chunked encoding in the Chunked branch (RFC 9112 §7.1): read the chunk-size line, the chunk data, and the terminating CRLF per chunk; stop at a 0-size chunk and consume the trailer section. Tokio's BufReader (already in use) provides lines() and read_exact for this.
Client-side note
librespeed/speedtest-cli now sends Content-Length for its fixed-size uploads (librespeed/speedtest-cli#143) as a workaround, but fixing chunked handling here makes the server robust for all clients.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start in src/http/request.rs at the BodyType::Chunked branch and review how the existing Tokio BufReader reads request bodies. Reproduce a finite chunked upload over a keep-alive connection, then verify that chunk data, the terminating CRLF, and trailers are consumed and the request completes instead of waiting for EOF.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend, networking
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100