Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/content/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Http11Probe
description: "Http11Probe tests HTTP/1.1 server implementations against RFC 9110 and RFC 9112, covering protocol compliance, request smuggling, and malformed input handling across frameworks."
layout: hextra-home
---

Expand Down
1 change: 1 addition & 0 deletions docs/content/add-a-framework/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Add a Framework
description: "How to add an HTTP server to Http11Probe: implement the required endpoints, add a Dockerfile and probe.json, and get automatic RFC 9110/9112 compliance results."
toc: true
---

Expand Down
6 changes: 4 additions & 2 deletions docs/content/add-a-test.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Add a Test
description: "How to add a new HTTP/1.1 compliance, smuggling, or malformed-input test case to Http11Probe, including the test case definition, documentation page, and category index entry."
---

A step-by-step guide to adding a new test to Http11Probe. Every test touches four places: the suite file, the docs URL map (sometimes), a documentation page, and the category index.
Expand Down Expand Up @@ -94,6 +95,7 @@ Expected = new ExpectedBehavior
- Set `AllowConnectionClose = true` only when connection close is an acceptable alternative to a status code.
- Set `Scored = false` for MAY-level or informational tests.
- Use `"RFC 9112 §5.1"` format for `RfcReference` (section sign, not "Section").
- Give the doc page a readable `title` (e.g. `"My Test — HTTP/1.1 Compliance"`), not the raw test ID — it's rendered as the page heading and browser tab title. Write a `description` that's a specific, one-sentence summary of the request and its RFC basis, not a generic placeholder — it's used as the page's meta description for search results.

## 2. Add a docs URL mapping (if needed)

Expand All @@ -117,8 +119,8 @@ Use this template:

```markdown
---
title: "MY-TEST"
description: "MY-TEST test documentation"
title: "My Test — HTTP/1.1 Compliance"
description: "One or two sentences describing the request and what makes it non-conforming, ideally ending with the RFC section it's tested against."
weight: 1
---

Expand Down
1 change: 1 addition & 0 deletions docs/content/add-with-ai-agent.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Add with AI Agent
description: "Use an AI coding agent with Http11Probe's machine-readable AGENTS.md guide to add a new compliance test or HTTP server framework."
---

Use an AI coding agent (Claude Code, Cursor, Copilot, etc.) to add a new test or framework to Http11Probe. The repository includes a machine-readable contribution guide at [`AGENTS.md`](https://github.com/MDA2AV/blob/main/AGENTS.md) designed specifically for LLM consumption.
Expand Down
1 change: 1 addition & 0 deletions docs/content/caching/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Caching
description: "Conditional request support across HTTP/1.1 servers, covering ETag, Last-Modified, If-None-Match precedence, and weak comparison behavior."
layout: wide
toc: false
---
Expand Down
1 change: 1 addition & 0 deletions docs/content/compliance/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Compliance
description: "RFC 9110/9112 compliance results for HTTP/1.1 servers, covering request-line parsing, header syntax, Host validation, and body framing requirements."
layout: wide
toc: false
---
Expand Down
1 change: 1 addition & 0 deletions docs/content/cookies/_index.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
---
title: Cookies
description: "Cookie header parsing resilience across HTTP servers, testing oversized values, NUL bytes, control characters, and malformed pairs per RFC 6265."
layout: wide
toc: false
---
Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/_index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Glossary
description: "Glossary — Http11Probe documentation"
description: "Reference documentation for every Http11Probe test, organized by topic, explaining the RFC requirement, request payload, expected response, and rationale."
breadcrumbs: false
sidebar:
open: false
Expand Down
4 changes: 2 additions & 2 deletions docs/content/docs/baseline.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: "BASELINE"
description: "BASELINE test documentation"
title: "Baseline Reachability Test"
description: "The COMP-BASELINE sanity check that confirms a target HTTP/1.1 server is reachable and parses well-formed requests before running negative tests."
weight: 4
---

Expand Down
2 changes: 1 addition & 1 deletion docs/content/docs/body/_index.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
title: Body Handling
description: "Body Handling — Http11Probe documentation"
description: "How HTTP/1.1 servers must read and terminate request bodies using Content-Length and chunked Transfer-Encoding, per RFC 9112 Sections 6 and 7."
weight: 9
sidebar:
open: false
Expand Down
188 changes: 94 additions & 94 deletions docs/content/docs/body/chunked-body.md
Original file line number Diff line number Diff line change
@@ -1,94 +1,94 @@
---
title: "CHUNKED-BODY"
description: "CHUNKED-BODY test documentation"
weight: 6
---

| | |
|---|---|
| **Test ID** | `COMP-CHUNKED-BODY` |
| **Category** | Compliance |
| **RFC** | [RFC 9112 Section 7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) |
| **Requirement** | MUST accept |
| **Expected** | `2xx` |

## What it sends

A valid chunked POST with a single 5-byte chunk followed by the zero terminator.

```http
POST / HTTP/1.1\r\n
Host: localhost\r\n
Transfer-Encoding: chunked\r\n
\r\n
5\r\n
hello\r\n
0\r\n
\r\n
```

## What the RFC says

> "The chunked transfer coding wraps content 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

> "A recipient MUST be able to parse and decode the chunked transfer coding." — RFC 9112 Section 7.1

> "A recipient MUST be able to parse the chunked transfer coding because it plays a crucial role in framing messages when the content size is not known in advance." — RFC 9112 Section 6.1

A server that supports HTTP/1.1 must be able to decode chunked transfer encoding. This is a MUST-level requirement.

## Why it matters

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.

## Deep Analysis

### Relevant ABNF grammar

From RFC 9112 Section 7.1:

```
chunked-body = *chunk
last-chunk
trailer-section
CRLF

chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = 1*HEXDIG
last-chunk = 1*("0") [ chunk-ext ] CRLF

chunk-data = 1*OCTET ; a sequence of chunk-size octets
trailer-section = *( field-line CRLF )
```

### Direct RFC quotes

> "The chunked transfer coding wraps content 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

> "A recipient MUST be able to parse and decode the chunked transfer coding." -- RFC 9112 Section 7.1

> "A recipient MUST be able to parse the chunked transfer coding because it plays a crucial role in framing messages when the content size is not known in advance." -- RFC 9112 Section 6.1

### Chain of reasoning

1. The test sends `Transfer-Encoding: chunked`, which triggers chunked body parsing per RFC 9112 Section 6.1.
2. Per the ABNF, the server must parse the chunk-size `5` (1*HEXDIG = "5"), read the CRLF, then read exactly 5 octets of chunk-data (`hello`), then read the trailing CRLF.
3. The next line is `0\r\n`, which matches `last-chunk = 1*("0") [ chunk-ext ] CRLF` -- this signals the end of chunked data.
4. The final `\r\n` satisfies the trailing CRLF in the `chunked-body` production.
5. The entire message is syntactically valid against the ABNF grammar. The server has no grounds to reject it.
6. RFC 9112 Section 7.1 uses "MUST be able to parse and decode" -- the strongest normative keyword. Failure to accept this request is a protocol violation.

### Scored / Unscored justification

**Scored.** The requirement uses MUST ("A recipient MUST be able to parse and decode the chunked transfer coding"). This is a non-negotiable RFC requirement. Any server claiming HTTP/1.1 support that rejects a syntactically valid single-chunk body is non-compliant. The test expects `2xx` with no fallback to `400` because there is no ambiguity in the grammar or the requirement level.

### Edge cases

- Some servers reject chunked encoding on POST if they expect `Content-Length` only -- this violates RFC 9112 Section 6.1 which mandates chunked parsing support.
- Servers behind load balancers may never see chunked requests if the LB de-chunks first, but the server itself must still support it.
- A few lightweight embedded HTTP servers omit chunked support entirely, treating it as an HTTP/1.0-only implementation. This test correctly flags that deficiency.

## Sources

- [RFC 9112 Section 7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1)
---
title: "Chunked Body — HTTP/1.1 Compliance"
description: "A valid chunked POST with a single 5-byte chunk followed by the zero terminator. Tested against RFC 9112 Section 7.1."
weight: 6
---
| | |
|---|---|
| **Test ID** | `COMP-CHUNKED-BODY` |
| **Category** | Compliance |
| **RFC** | [RFC 9112 Section 7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1) |
| **Requirement** | MUST accept |
| **Expected** | `2xx` |
## What it sends
A valid chunked POST with a single 5-byte chunk followed by the zero terminator.
```http
POST / HTTP/1.1\r\n
Host: localhost\r\n
Transfer-Encoding: chunked\r\n
\r\n
5\r\n
hello\r\n
0\r\n
\r\n
```
## What the RFC says
> "The chunked transfer coding wraps content 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
> "A recipient MUST be able to parse and decode the chunked transfer coding." — RFC 9112 Section 7.1
> "A recipient MUST be able to parse the chunked transfer coding because it plays a crucial role in framing messages when the content size is not known in advance." — RFC 9112 Section 6.1
A server that supports HTTP/1.1 must be able to decode chunked transfer encoding. This is a MUST-level requirement.
## Why it matters
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.
## Deep Analysis
### Relevant ABNF grammar
From RFC 9112 Section 7.1:
```
chunked-body = *chunk
last-chunk
trailer-section
CRLF
chunk = chunk-size [ chunk-ext ] CRLF
chunk-data CRLF
chunk-size = 1*HEXDIG
last-chunk = 1*("0") [ chunk-ext ] CRLF
chunk-data = 1*OCTET ; a sequence of chunk-size octets
trailer-section = *( field-line CRLF )
```
### Direct RFC quotes
> "The chunked transfer coding wraps content 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
> "A recipient MUST be able to parse and decode the chunked transfer coding." -- RFC 9112 Section 7.1
> "A recipient MUST be able to parse the chunked transfer coding because it plays a crucial role in framing messages when the content size is not known in advance." -- RFC 9112 Section 6.1
### Chain of reasoning
1. The test sends `Transfer-Encoding: chunked`, which triggers chunked body parsing per RFC 9112 Section 6.1.
2. Per the ABNF, the server must parse the chunk-size `5` (1*HEXDIG = "5"), read the CRLF, then read exactly 5 octets of chunk-data (`hello`), then read the trailing CRLF.
3. The next line is `0\r\n`, which matches `last-chunk = 1*("0") [ chunk-ext ] CRLF` -- this signals the end of chunked data.
4. The final `\r\n` satisfies the trailing CRLF in the `chunked-body` production.
5. The entire message is syntactically valid against the ABNF grammar. The server has no grounds to reject it.
6. RFC 9112 Section 7.1 uses "MUST be able to parse and decode" -- the strongest normative keyword. Failure to accept this request is a protocol violation.
### Scored / Unscored justification
**Scored.** The requirement uses MUST ("A recipient MUST be able to parse and decode the chunked transfer coding"). This is a non-negotiable RFC requirement. Any server claiming HTTP/1.1 support that rejects a syntactically valid single-chunk body is non-compliant. The test expects `2xx` with no fallback to `400` because there is no ambiguity in the grammar or the requirement level.
### Edge cases
- Some servers reject chunked encoding on POST if they expect `Content-Length` only -- this violates RFC 9112 Section 6.1 which mandates chunked parsing support.
- Servers behind load balancers may never see chunked requests if the LB de-chunks first, but the server itself must still support it.
- A few lightweight embedded HTTP servers omit chunked support entirely, treating it as an HTTP/1.0-only implementation. This test correctly flags that deficiency.
## Sources
- [RFC 9112 Section 7.1](https://www.rfc-editor.org/rfc/rfc9112#section-7.1)
Loading
Loading