Skip to content

feat(matching): match header names case-insensitively#334

Merged
gwleclerc merged 1 commit into
mainfrom
feat/case-insensitive-header-match
Jul 19, 2026
Merged

feat(matching): match header names case-insensitively#334
gwleclerc merged 1 commit into
mainfrom
feat/case-insensitive-header-match

Conversation

@gwleclerc

Copy link
Copy Markdown
Collaborator

Fixes #281.

Problem

HTTP header field names are case-insensitive (RFC 7230 §3.2), but Smocker matched them with an exact map lookup. Combined with Go's net/http, which canonicalizes incoming request header names (content-typeContent-Type), a mock declaring a header in any non-canonical case (e.g. content-type) would never match — a real footgun.

Fix

Header names are now matched case-insensitively via http.Header.Values, which canonicalizes only the lookup key. The declared casing is never altered (stored mock keys and response headers keep their exact case — see §3.4). Header values and query-parameter names stay case-sensitive, preserving the "faithful, not lenient" intent of #179.

PRINCIPLES.md §3.4 is amended to reflect this (names case-insensitive; values + query params case-sensitive; casing preserved on the wire, modulo net/http's own canonicalization of incoming request / upstream proxy headers).

Verified

  • New unit test: content-typeContent-Type match; header values stay case-sensitive; query-parameter names stay case-sensitive; an absent header still fails to match.
  • Golden serialization + JSON-schema tests unchanged; full server suite green.

Note: response headers declared in a mock are already returned with their exact case (#313); this PR only changes matching, not what's written on the wire.

🤖 Generated with Claude Code

HTTP header field names are case-insensitive (RFC 7230 §3.2), and Go's net/http
canonicalizes incoming request header names, so a mock declaring "content-type"
never matched a "Content-Type" request. Match header names case-insensitively
via http.Header.Values, which canonicalizes only the lookup key — the declared
casing is never altered. Header values and query-parameter names stay
case-sensitive.

Amends PRINCIPLES.md §3.4 accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@gwleclerc
gwleclerc merged commit 1ecdd82 into main Jul 19, 2026
6 checks passed
@gwleclerc
gwleclerc deleted the feat/case-insensitive-header-match branch July 19, 2026 22:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Headers match are case-sensitive

1 participant