You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
New tests verify body consumption with fixed Content-Length and chunked
Transfer-Encoding (POST-CL-BODY, CHUNKED-BODY, CHUNKED-MULTI, etc.)
plus edge cases (undersend, missing terminator, GET-with-body, chunk
extensions). Also adds the 22 STRICT dict entries that were missing
from the previous commit (upgrade, method, trailer, chunk funky tests).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
HTTP/1.1 defines two mechanisms for framing a request body: **Content-Length** (fixed-size) and **Transfer-Encoding: chunked** (variable-size). RFC 9112 Sections 6 and 7 specify how servers must read, validate, and terminate body data.
10
+
11
+
## Key Rules
12
+
13
+
**Content-Length** — the sender declares the exact byte count:
14
+
15
+
> "If a valid Content-Length header field is present without Transfer-Encoding, its decimal value defines the expected message body length in octets." — RFC 9112 Section 6.2
16
+
17
+
**Chunked encoding** — body is split into self-terminating chunks:
18
+
19
+
> "The chunked transfer coding wraps the payload body in order to transfer it as a series of chunks, each with its own size indicator, followed by an OPTIONAL trailer section containing trailer fields." — RFC 9112 Section 7.1
20
+
21
+
**No CL, no TE** — with neither header, the body length is zero:
22
+
23
+
> "If this is a request message and none of the above are true, then the message body length is zero (no message body is present)." — RFC 9112 Section 6.3
24
+
25
+
## Tests
26
+
27
+
{{< cards >}}
28
+
{{< card link="post-cl-body" title="POST-CL-BODY" subtitle="POST with Content-Length and matching body. Must return 2xx." >}}
29
+
{{< card link="post-cl-zero" title="POST-CL-ZERO" subtitle="POST with Content-Length: 0, no body. Must return 2xx." >}}
30
+
{{< card link="post-no-cl-no-te" title="POST-NO-CL-NO-TE" subtitle="POST with neither CL nor TE. Implicit zero-length body." >}}
31
+
{{< card link="post-cl-undersend" title="POST-CL-UNDERSEND" subtitle="POST with CL:10 but only 5 bytes sent. Incomplete body." >}}
32
+
{{< card link="get-with-cl-body" title="GET-WITH-CL-BODY" subtitle="GET with Content-Length and body. Unusual but allowed." >}}
33
+
{{< card link="chunked-body" title="CHUNKED-BODY" subtitle="Valid single-chunk POST. Must return 2xx." >}}
34
+
{{< card link="chunked-multi" title="CHUNKED-MULTI" subtitle="Valid multi-chunk POST. Must return 2xx." >}}
A valid chunked POST with a single 5-byte chunk followed by the zero terminator.
18
+
19
+
```http
20
+
POST / HTTP/1.1\r\n
21
+
Host: localhost\r\n
22
+
Transfer-Encoding: chunked\r\n
23
+
\r\n
24
+
5\r\n
25
+
hello\r\n
26
+
0\r\n
27
+
\r\n
28
+
```
29
+
30
+
## What the RFC says
31
+
32
+
> "The chunked transfer coding wraps the payload body in order to transfer it as a series of chunks, each with its own size indicator, followed by an OPTIONAL trailer section containing trailer fields." — RFC 9112 Section 7.1
33
+
34
+
A server that supports HTTP/1.1 must be able to decode chunked transfer encoding.
35
+
36
+
## Why it matters
37
+
38
+
Chunked encoding is fundamental to HTTP/1.1 — it enables streaming, server-sent data, and requests where the body size isn't known in advance. If a server can't decode a basic chunked body, it cannot fully participate in HTTP/1.1.
A chunked POST with only the zero terminator — a zero-length body.
18
+
19
+
```http
20
+
POST / HTTP/1.1\r\n
21
+
Host: localhost\r\n
22
+
Transfer-Encoding: chunked\r\n
23
+
\r\n
24
+
0\r\n
25
+
\r\n
26
+
```
27
+
28
+
## What the RFC says
29
+
30
+
> "The last chunk has a chunk size of zero, indicating the end of the chunk data." — RFC 9112 Section 7.1
31
+
32
+
A zero-size first chunk is valid and indicates an empty body. The server must recognize the terminator and not block waiting for additional data.
33
+
34
+
## Why it matters
35
+
36
+
Empty chunked bodies occur when a client starts a chunked transfer but has nothing to send, or when a proxy rewrites a zero-length CL body into chunked encoding. The server must handle this edge case cleanly.
A chunked POST where the chunk size line includes a valid extension: `5;ext=value`.
18
+
19
+
```http
20
+
POST / HTTP/1.1\r\n
21
+
Host: localhost\r\n
22
+
Transfer-Encoding: chunked\r\n
23
+
\r\n
24
+
5;ext=value\r\n
25
+
hello\r\n
26
+
0\r\n
27
+
\r\n
28
+
```
29
+
30
+
## What the RFC says
31
+
32
+
> "The chunked encoding allows each chunk to include zero or more chunk extensions, immediately following the chunk-size, for the sake of supplying per-chunk metadata." — RFC 9112 Section 7.1.1
33
+
34
+
Chunk extensions are part of the chunked encoding grammar. A compliant parser should skip unrecognized extensions and process the chunk data normally.
35
+
36
+
## Why it matters
37
+
38
+
While chunk extensions are rarely used in practice, they are syntactically valid. A server that rejects them has an overly strict chunk parser that may break with legitimate clients or proxies that add extensions for metadata (e.g., checksums, signatures).
0 commit comments