Skip to content

feat(layer7): add the private HTTP/1.1 message grammar - #214

Draft
EONRaider wants to merge 1 commit into
masterfrom
claude/http-grammar-core
Draft

EONRaider wants to merge 1 commit into
masterfrom
claude/http-grammar-core

Conversation

@EONRaider

Copy link
Copy Markdown
Owner

Summary

This adds the byte-level HTTP/1.1 grammar (RFC 9112 framing, RFC 9110 fields) that an upcoming HTTP codec class will build on. It decodes one complete, already-reassembled message from a buffer. Stream reassembly is out of scope and remains the caller's job.

A passive security decoder should surface ambiguity rather than settle it silently. So the grammar raises only when a message cannot be represented:

  • the input is not HTTP/1.x;
  • a hard size limit is exceeded;
  • the decode context is misused;
  • a body boundary is lost mid-body;
  • with closed=True, the message is incomplete.

Everything else decodes using the RFC's own resolution and is reported as a located, aggregated anomaly. That covers CL+TE, bare LF, obs-fold, whitespace before the colon, Content-Length lists, TE parameters or odd octets, chunk-extension and chunk-line variants, and misplaced framing fields.

Draft: the nightly survivor gate added in #213 currently fails for this module. See Notes.

What's included

  • src/netprotocols/layer7/http.py:
    • The parsing stages: head scan, start line, field lines, RFC 9110 §5.6.1 lists, Transfer-Encoding, Content-Length, §6.3 framing, chunked body plus trailers, and connection disposition (CONTINUE / CLOSE / TUNNEL).
    • The enums HTTPAnomalyKind, HTTPFraming and HTTPDisposition, plus the HTTPAnomaly record.
    • Every rule is an undecorated module-level function, so mutmut reaches all of it.
    • Nothing is exported yet.
  • tests/test_http.py has one vector per rule, including:
    • exhaustive 256-byte checks of the tchar, VCHAR, HEXDIG, obs-text and quoted-string tables against the ABNF;
    • the head bound tested exactly at the limit and one byte over;
    • TLS fast-fail and the HTTP/2 preface;
    • the Funky-chunks chunk-line classes.
  • Mutation scope: pyproject.toml (only_mutate and the test selection), mutation.yml, EXPECTED_FILTERS and CONTRIBUTING all gain 'netprotocols.layer7.http.x__*'.

Verification

  • uv run ruff check and uv run ruff format --check are clean
  • uv run mypy is clean (strict)
  • uv run pytest passes; layer7/http.py has 100% line and branch coverage
  • CHANGELOG.md has an entry under ## [Unreleased]

Notes

  • Why this is a draft. A local run of the full scoped audit gives the HTTP module 1,338 killed, 15 timeouts and 323 survivors. Roughly 100 of the survivors are in diagnostics: error messages and the field/offset/expected/actual values on raised errors and anomalies, which the tests don't yet assert. The rest are spread across chunk and trailer parsing, start lines and message ends. Those need killing tests, not allowlist entries, before this leaves draft.
  • Deferred: Host-field checks (HOST_* anomalies) move to the HTTP class PR.

🤖 Generated with Claude Code

https://claude.ai/code/session_01CEQCZGyuvpMyZwUbDucF3G


Generated by Claude Code

The byte-level grammar the HTTP codec will be built on, per RFC 9112
and RFC 9110: head scan, request/status line, field lines, list
parsing, Transfer-Encoding, Content-Length, §6.3 framing, chunked
bodies and trailers, and connection disposition. It raises only when a
message cannot be represented (not HTTP/1.x, a hard size limit, decode
context misuse, a body boundary lost mid-body, or incomplete at close);
every other departure from the RFCs decodes by the defined resolution
and is reported as a located, aggregated anomaly, so desync and
smuggling signatures are surfaced rather than silently resolved.

Every rule is an undecorated module-level function so mutmut reaches
it, and the module joins the nightly audit. Nothing is exported; the
HTTP Protocol class comes next. Host checks are deferred to it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CEQCZGyuvpMyZwUbDucF3G
@coderabbitai

coderabbitai Bot commented Oct 8, 2026

Copy link
Copy Markdown

Important

Draft PR not reviewed

Draft PRs are not automatically reviewed by default.

  • Trigger a manual review

To automatically review draft PRs, update your CodeRabbit configuration:

reviews:
  auto_review:
    drafts: true
  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants