Upstream Sync Report 2026-09-16: RFC 9112 §6.3 Transfer-Encoding / Content-Length framing rewrite
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 4.9k
- Forks
- 409
- Avg merge
- 6h 47m
- Merged PRs (30d)
- 7
Description
Upstream Changes
Go stdlib net/http rewrote the message-framing (body length determination) logic in src/net/http/transfer.go, restructuring it to follow the numbered algorithm of RFC 9112 §6.3:
- Commit: db450d3 (2026-09-14, CL 818663)
parseTransferEncoding+fixLength+ the HEAD special-case inreadTransferare replaced by a singletransferReader.determineBodyLength(isResponse)that walks the RFC items in ordertransferReadergains aRealBodyLengthfield, separating the actual body length (0 for HEAD/bodyless) from the reportedContentLength- New sentinel errors:
errTooManyTransferEncodings,errUnsupportedTransferEncoding,errTooManyContentLengths parseContentLengthnow returns(string, int64, error)— the trimmed header value alongside the parsed length
Behavior differences vs req's copy
req's inlined transfer.go still carries the pre-rewrite logic (readTransfer → parseTransferEncoding → fixLength), so porting changes behavior in these edge cases:
| Case | req today | After sync |
|---|---|---|
HTTP/1.0 response with Transfer-Encoding |
TE silently ignored; connection reuse decided by shouldClose |
Framing treated as faulty per RFC 9112 §6.1: TE dropped, Close = true |
2xx response to CONNECT |
No special case: body framed by Content-Length if present, otherwise unbounded |
Explicit tunnel semantics: body unbounded, Content-Length ignored, Close = true |
Multiple differing Content-Length values |
Error message echoes the values (got %q) |
Sentinel error without values |
| Multiple/oddly-formed TE values | Error messages echo raw values | Sentinel errors without values |
Content-Length header map entry |
Deduplicated in place when multiple; left as-is otherwise | Deleted up front, re-set (trimmed, single value) only in branches that actually use it |
The HEAD / 1xx / 204 / 304 / chunked / plain-CL / unbounded-response paths keep their net semantics; the rewrite mainly makes the decision table explicit and consistent.
Impact on req
- req inlines
transfer.go(root, modified stdlib). Only the read side is affected —readTransferin req's copy handles*http.Responseonly (requests go throughtransferWriter), so the RFC table applies to response framing. - The 2xx
CONNECTchange is the one visible to users doing CONNECT tunneling: today a tunnel response carryingContent-Lengthgets a CL-framed body, which is wrong for a tunnel (the body is the raw tunnel stream until close). Aligning would make tunnel framing correct. - The HTTP/1.0+TE hardening is a strictness improvement on a request-smuggling-adjacent surface; for a client library it mostly affects responses from non-conforming servers (connection now closed instead of reused).
- No security advisory is attached to this change; it is a correctness/alignment refactor.
Suggested sync
Port db450d3 into transfer.go (merge upstream net/http: <date>(<hash>) style). Port notes:
- req's
readTransferhas local deviations to preserve: nomaxTrailerHeadersparameter (req'sbodystruct andfixTrailersignature differ),headerishttp.Headerfromnet/httprather than stdlib's ownHeadertype, and thehttplaxContentLengthgodebug var is locally renamed. parseContentLength's new 3-value signature has call sites inreadTransfer(HEAD case) that must be adapted.- The
*Requestbranch of stdlib'sdetermineBodyLength(RFC item 7) is dead code for req sincereadTransferonly accepts*http.Response; keep the response-side cases. - No public API change; req's
Response.ContentLength/TransferEncodingoutputs keep their meaning.
Not security-related, no workaround needed — behavior alignment, low priority.
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 req's root transfer.go, especially readTransfer, and compare it with upstream commit db450d3. Account for req's local body, trailer, Header, and godebug differences while porting the response-side framing logic. Done means the RFC 9112 response cases and CONNECT behavior are aligned without changing the public response fields.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- networking
- Issue type
- Refactor
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 55/100