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
39 changes: 39 additions & 0 deletions .github/workflows/probe-comment.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
name: Post Probe Comment

on:
workflow_run:
workflows: ["Probe"]
types: [completed]

jobs:
comment:
name: Post PR Comment
if: >
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
runs-on: ubuntu-latest

permissions:
pull-requests: write

steps:
- name: Download artifact
uses: actions/download-artifact@v4
with:
name: probe-pr-comment
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}

- name: Post or update comment
run: |
PR_NUMBER=$(cat pr-number.txt)
COMMENT_ID=$(gh api repos/${{ github.repository }}/issues/${PR_NUMBER}/comments \
--jq '.[] | select(.body | contains("<!-- http11probe-results -->")) | .id' | head -1)
if [ -n "$COMMENT_ID" ]; then
gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID \
-X PATCH -f body="$(cat probe-comment.md)"
else
gh pr comment "$PR_NUMBER" --body-file probe-comment.md
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
24 changes: 11 additions & 13 deletions .github/workflows/probe.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ jobs:
runs-on: ubuntu-latest

permissions:
pull-requests: write
contents: write
actions: write

Expand Down Expand Up @@ -284,19 +283,18 @@ jobs:
name: probe-results
path: probe-*.json

- name: Comment on PR
- name: Save PR metadata
if: github.event_name == 'pull_request' && steps.changes.outputs.servers != '[]'
run: |
COMMENT_ID=$(gh api repos/${{ github.repository }}/issues/${{ github.event.number }}/comments \
--jq '.[] | select(.body | contains("<!-- http11probe-results -->")) | .id' | head -1)
if [ -n "$COMMENT_ID" ]; then
gh api repos/${{ github.repository }}/issues/comments/$COMMENT_ID \
-X PATCH -f body="$(cat probe-comment.md)"
else
gh pr comment ${{ github.event.number }} --body-file probe-comment.md
fi
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: echo '${{ github.event.number }}' > pr-number.txt

- name: Upload PR comment
if: github.event_name == 'pull_request' && steps.changes.outputs.servers != '[]'
uses: actions/upload-artifact@v4
with:
name: probe-pr-comment
path: |
probe-comment.md
pr-number.txt

- name: Push to latest-results
if: github.event_name == 'workflow_dispatch' && github.ref == 'refs/heads/main'
Expand Down
87 changes: 87 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,65 @@

All notable changes to Http11Probe are documented in this file.

## [2026-02-16]

### Added
- **Sequence tests** — new multi-step test infrastructure (`SequenceTestCase`, `SequenceStep`, `SequenceSendPart`) for desync and smuggling detection with timed partial sends and behavioral analysis (#74)
- **26 new smuggling tests** — multi-step sequence tests for CL.TE, TE.CL, and desync detection:
- `SMUG-CLTE-SMUGGLED-GET` — CL.TE with embedded GET; multiple responses indicate boundary confusion
- `SMUG-CLTE-SMUGGLED-HEAD` — CL.TE with embedded HEAD
- `SMUG-CLTE-SMUGGLED-GET-CL-PLUS` — CL.TE smuggled GET with malformed CL (+N)
- `SMUG-CLTE-SMUGGLED-GET-CL-NON-NUMERIC` — CL.TE smuggled GET with non-numeric CL
- `SMUG-CLTE-SMUGGLED-GET-TE-OBS-FOLD` — CL.TE smuggled GET with obs-folded TE
- `SMUG-CLTE-SMUGGLED-GET-TE-TRAILING-SPACE` — CL.TE smuggled GET with TE trailing space
- `SMUG-CLTE-SMUGGLED-GET-TE-LEADING-COMMA` — CL.TE smuggled GET with TE leading comma
- `SMUG-CLTE-SMUGGLED-GET-TE-CASE-MISMATCH` — CL.TE smuggled GET with TE case mismatch
- `SMUG-TE-DUPLICATE-HEADERS-SMUGGLED-GET` — duplicate TE headers with embedded GET
- `SMUG-TECL-SMUGGLED-GET` — TE.CL with embedded GET (chunk-size prefix trick)
- `SMUG-DUPLICATE-CL-SMUGGLED-GET` — duplicate Content-Length with embedded GET
- `SMUG-GET-CL-PREFIX-DESYNC` — GET with CL prefix desync
- `SMUG-CLTE-DESYNC` — CL.TE desync with pause-based detection
- `SMUG-TECL-DESYNC` — TE.CL desync with pause-based detection
- `SMUG-CLTE-CONN-CLOSE` — CL.TE desync with Connection: close
- `SMUG-TECL-CONN-CLOSE` — TE.CL desync with Connection: close
- `SMUG-PIPELINE-SAFE` — safe pipeline baseline (no smuggling)
- `SMUG-CL0-BODY-POISON` — CL:0 body poison follow-up check
- `SMUG-GET-CL-BODY-DESYNC` — GET with CL body desync
- `SMUG-OPTIONS-CL-BODY-DESYNC` — OPTIONS with CL body desync
- `SMUG-EXPECT-100-CL-DESYNC` — Expect: 100-continue CL desync
- `SMUG-OPTIONS-TE-OBS-FOLD` — OPTIONS with obs-fold TE follow-up check
- `SMUG-CHUNK-INVALID-SIZE-DESYNC` — invalid chunk size + poison follow-up
- `SMUG-CHUNK-EXT-INVALID-TOKEN` — invalid token in chunk extension name
- `SMUG-CHUNK-SIZE-PLUS` — chunk size with leading plus sign
- `SMUG-CHUNK-SIZE-TRAILING-OWS` — chunk size with trailing whitespace
- **11 new compliance tests**:
- `COMP-RANGE-POST` — Range header on POST should be ignored (RFC 9110 §14.2)
- `COMP-UPGRADE-HTTP10` — Upgrade header in HTTP/1.0 request
- `COMP-DATE-FORMAT` — Date header format validation (RFC 9110 §5.6.7)
- `COMP-VERSION-CASE` — HTTP version case sensitivity (RFC 9112 §2.6)
- `COMP-LONG-URL-OK` — long URL within valid range should be accepted
- `COMP-SPACE-IN-TARGET` — space in request target should be rejected
- `COMP-DUPLICATE-CT` — duplicate Content-Type headers
- `COMP-TRACE-SENSITIVE` — TRACE method security sensitivity (RFC 9110 §9.3.8)
- `COMP-RANGE-INVALID` — invalid Range header format
- `COMP-ACCEPT-NONSENSE` — nonsensical Accept header value
- `COMP-POST-UNSUPPORTED-CT` — POST with unsupported Content-Type
- **FastEndpoints framework** — new test server added to the probe suite (#70)
- **Local probe script** — `scripts/probe-local.sh` for running probes against local servers
- **Sequence tests UI** — probe results page displays sequence test steps with per-step request/response details

### Changed
- **SMUG-CLTE-PIPELINE and SMUG-TECL-PIPELINE** — re-evaluated scoring and validation logic
- **GenHTTP server** — clean-up and simplification (contributed by Andreas Nägeli)
- **RFC Requirement Dashboard** — updated with all 37 new tests and counts

### Fixed
- **Traefik server** — fixed POST / to echo request body (contributed by SAILESH4406, #79)
- **Sequence test UI rendering** — fixed display of multi-step test results on probe results page
- **Second read from wire** — improved response capture with additional socket read for slow/partial responses (#71)
- **PR comment score** — fixed score calculation in probe workflow CI comments
- **NGINX server** — fixed implementation (#63)

## [2026-02-14]

### Added
Expand All @@ -13,6 +72,9 @@ All notable changes to Http11Probe are documented in this file.
- **`RfcLevel` enum** — `Must`, `Should`, `May`, `OughtTo`, `NotApplicable` classification for every test case
- **RFC Level annotations** — all tests across Compliance, Smuggling, MalformedInput, and Normalization suites annotated with their RFC 2119 requirement level
- **Verbose Probe workflow** — new `probe-verbose.yml` GitHub Action for manual single-server probing with `--verbose` output, triggered via `workflow_dispatch` with a server name input (#60)
- **Giscus comments** — added comment system to website documentation pages
- **AI Contribution guide** — `AGENTS.md` for AI-agent contributions and `add-with-ai-agent` docs page
- **RFC Requirement Dashboard page** — comprehensive per-test RFC requirement tracking with counts and cross-references
- **9 new RFC 9110 compliance tests** sourced from [mohammed90/http-compliance-testing](https://github.com/mohammed90/http-compliance-testing):
- `COMP-HEAD-NO-BODY` — HEAD response must not contain a message body (RFC 9110 §9.3.2, MUST)
- `COMP-UNKNOWN-METHOD` — unrecognized method should be rejected with 501/405 (RFC 9110 §9.1, SHOULD)
Expand Down Expand Up @@ -40,6 +102,31 @@ All notable changes to Http11Probe are documented in this file.
- **Method extraction** — handles leading CRLF in raw requests and tab-delimited request lines; non-HTTP pseudo-methods (PRI) shown as '?'
- **Category-scoped filters** — Method and RFC Level filters now only show options relevant to the current category page

## [2026-02-13]

### Added
- **Server configuration pages** — per-server docs pages showing Dockerfile, source code, and config files for all 36 tested servers (`docs/content/servers/`) (#28)
- **Clickable server names** — server names in the probe results table and summary bar chart now link to their configuration page
- **Sticky first column** — server name column stays pinned to the left edge while scrolling horizontally through result tables
- **Collapsible sub-groups** — group headers in result tables are now clickable to collapse/expand, with a chevron indicator and a "Collapse All / Expand All" toggle button
- **Row-click detail popup** — clicking a server row opens a modal showing that server's results for the current table in a vertical layout (Test, Expected, Got, Description) with section and table name in the header
- **Truncation notice** — tooltip and modal now show a `[Truncated]` notice at the top when raw request/response data exceeds the 8,192-byte display limit
- **Header normalization section** — new test category for header normalization tests (#32)
- **"Add a Framework" section improvements** — expanded documentation for adding new server frameworks (#42)

### Changed
- **Scrollable tooltips** — hover tooltips are now interactive and scrollable for large payloads (removed `pointer-events:none`, increased `max-height` to `60vh`)
- **Larger click modal** — expanded from `max-width:700px` to `90vw` and `max-height` from `80vh` to `85vh` to better accommodate large request/response data
- Raw request capture now includes truncation metadata when payload exceeds 8,192 bytes
- Raw response capture now includes truncation metadata when response exceeds 8,192 bytes
- **Test re-evaluation** — reviewed and re-scored multiple tests for RFC alignment (#29)

### Fixed
- **Kestrel server** — fixed HEAD and OPTIONS headers allowed (#39)
- **Node.js server** — fixed errors in Express server (#37)
- **CLI and PR scores** — fixed score calculation in CLI output and PR comments
- GenHTTP server re-enabled in probe suite

## [2026-02-12]

### Added
Expand Down
Loading