Skip to content

fix(cookie): dedup cookies with leading-dot / mixed-case domains#1462

Merged
pi0 merged 1 commit into
mainfrom
fix/cookie-domain-dedup
Jul 14, 2026
Merged

fix(cookie): dedup cookies with leading-dot / mixed-case domains#1462
pi0 merged 1 commit into
mainfrom
fix/cookie-domain-dedup

Conversation

@pi0x

@pi0x pi0x commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Cookie dedup in setCookie keyed new cookies on the raw options.domain, but keyed existing cookies on the normalized domain from parseSetCookie (leading . stripped, lowercased). For domains like .Example.com the keys never matched, so two Set-Cookie headers were emitted instead of a replacement.

This normalizes the domain (strip leading ., lowercase) on both sides in _getDistinctCookieKey, per RFC 6265 where Domain is case-insensitive and a leading . is ignored. Adds a regression test covering setting the same cookie twice with domain: ".Example.com".

🤖 Generated with Claude Code

Summary by CodeRabbit

  • Bug Fixes
    • Improved cookie deduplication by treating domain names consistently, regardless of leading dots or letter casing.
    • Ensured the latest value is retained when equivalent cookies are set multiple times.

Cookie dedup compared the raw `options.domain` of a new cookie against
the normalized domain from `parseSetCookie` (leading "." stripped,
lowercased). For domains like `.Example.com` the keys never matched, so
two `Set-Cookie` headers were emitted instead of a replacement.

Normalize the domain (strip leading ".", lowercase) on both sides in
`_getDistinctCookieKey`, per RFC 6265 (Domain is case-insensitive and a
leading "." is ignored).

Co-Authored-By: Claude Fable 5 <[email protected]>
@pi0x
pi0x requested a review from pi0 as a code owner July 14, 2026 12:33
@pi0
pi0 merged commit 2264316 into main Jul 14, 2026
8 of 9 checks passed
@pi0
pi0 deleted the fix/cookie-domain-dedup branch July 14, 2026 12:35

@pi0x pi0x left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review verdict: LGTM (approve) — posting as a comment since GitHub blocks self-approval on this account.

Clean, correct, minimal fix.

Correctness

  • Normalizing inside _getDistinctCookieKey fixes both sides at once: the new-cookie key (options.domain) and the existing-cookie key (from parseSetCookie) now go through identical normalization, so they match regardless of leading dot or casing. It's the single shared chokepoint, so no missed call sites — setCookie is the only consumer, and deleteCookie/chunked helpers route through it.
  • (options.domain || "").replace(/^\./, "").toLowerCase() handles empty/undefined domain (→ "") and idempotently re-normalizes the already-normalized parseSetCookie output. Path and cookie name are left untouched, which is correct: RFC 6265 treats path and name as case-sensitive, only Domain as case-insensitive with a single leading dot ignored.
  • The actual emitted Set-Cookie header still carries the user's raw Domain=.Example.com — only the dedup key is normalized. Correct: we dedup without mutating the requested cookie.

Verification

  • Reverted the source change and confirmed the new test fails as expected (two Set-Cookie headers emitted); restored, and all 98 cookie tests pass in both web and node matrix modes. pnpm lint (oxlint + oxfmt) clean.
  • Test quality is good: covers both leading-dot and mixed-case in one case, asserts exact single-header output.

Matches AGENTS.md conventions and RFC 6265 §4.1.2/§5.1.3.

🤖 Generated with Claude Code

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 50d7c205-d07a-474b-aa0a-0bfbf7c18897

📥 Commits

Reviewing files that changed from the base of the PR and between 8ed97e4 and d3f5a6f.

📒 Files selected for processing (2)
  • src/utils/cookie.ts
  • test/cookies.test.ts

📝 Walkthrough

Walkthrough

Changes

Cookie deduplication

Layer / File(s) Summary
Normalize cookie domains
src/utils/cookie.ts, test/cookies.test.ts
Cookie uniqueness keys now strip leading dots and lowercase domains; tests verify equivalent domains produce one latest Set-Cookie entry.

Estimated code review effort: 2 (Simple) | ~5 minutes

Suggested reviewers: pi0, danielroe

Poem

I’m a bunny, hopping light,
Dots and capitals now unite.
One cookie stays, the latest gleams,
Neatly sorted in header streams.
Hop, hop—dedupe dreams!

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/cookie-domain-dedup

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.

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