[PR #173] [MERGED] fix: preserve multiple Set-Cookie headers in middleware forwarding #370

Closed
opened 2026-05-06 12:39:28 +02:00 by BreizhHardware · 0 comments

📋 Pull Request Information

Original PR: https://github.com/cloudflare/vinext/pull/173
Author: @southpolesteve
Created: 2/27/2026
Status: Merged
Merged: 2/27/2026
Merged by: @southpolesteve

Base: mainHead: fix/preserve-set-cookie-in-middleware


📝 Commits (2)

  • b814c78 fix: preserve multiple Set-Cookie headers in middleware forwarding
  • 75a2e30 fix: add type annotations for Headers.forEach callback in prod-server

📊 Changes

4 files changed (+35 additions, -14 deletions)

View changed files

📝 packages/vinext/src/index.ts (+4 -4)
📝 packages/vinext/src/server/app-dev-server.ts (+4 -4)
📝 packages/vinext/src/server/middleware.ts (+3 -3)
📝 packages/vinext/src/server/prod-server.ts (+24 -3)

📄 Description

Summary

Middleware header forwarding used Headers.set() which overwrites previous values with the same key. When middleware sets multiple Set-Cookie headers (e.g. session + CSRF + consent cookies), only the last one survived. This brings our behavior in line with how Next.js handles multi-value headers.

Changes

  • middleware.ts -- .set() to .append() in both the x-middleware-next and x-middleware-rewrite paths
  • app-dev-server.ts -- .set() to .append() in both the collection phase (where middleware headers are gathered) and the emission phase (where they are merged into the final response)
  • prod-server.ts -- Array accumulation for Set-Cookie in the middleware header merge path, and getSetCookie() pattern for custom middleware responses (replaces Object.fromEntries() which collapsed multi-value headers)
  • index.ts codegen -- .set() to .append() in the generated App Router production middleware runner
  • index.ts Pages dev -- res.setHeader() to res.appendHeader() for middleware header forwarding

All changes use the same pattern: iterate response headers and use .append() (or appendHeader for Node responses) instead of .set(), which preserves separate entries for headers like Set-Cookie that cannot be combined with commas per RFC 6265.


🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.

## 📋 Pull Request Information **Original PR:** https://github.com/cloudflare/vinext/pull/173 **Author:** [@southpolesteve](https://github.com/southpolesteve) **Created:** 2/27/2026 **Status:** ✅ Merged **Merged:** 2/27/2026 **Merged by:** [@southpolesteve](https://github.com/southpolesteve) **Base:** `main` ← **Head:** `fix/preserve-set-cookie-in-middleware` --- ### 📝 Commits (2) - [`b814c78`](https://github.com/cloudflare/vinext/commit/b814c78073acc61abbc31dced3129ddb4ccc0194) fix: preserve multiple Set-Cookie headers in middleware forwarding - [`75a2e30`](https://github.com/cloudflare/vinext/commit/75a2e30de8648f7eb3a0b366cca932a5764606ab) fix: add type annotations for Headers.forEach callback in prod-server ### 📊 Changes **4 files changed** (+35 additions, -14 deletions) <details> <summary>View changed files</summary> 📝 `packages/vinext/src/index.ts` (+4 -4) 📝 `packages/vinext/src/server/app-dev-server.ts` (+4 -4) 📝 `packages/vinext/src/server/middleware.ts` (+3 -3) 📝 `packages/vinext/src/server/prod-server.ts` (+24 -3) </details> ### 📄 Description ## Summary Middleware header forwarding used `Headers.set()` which overwrites previous values with the same key. When middleware sets multiple `Set-Cookie` headers (e.g. session + CSRF + consent cookies), only the last one survived. This brings our behavior in line with how Next.js handles multi-value headers. ## Changes - **`middleware.ts`** -- `.set()` to `.append()` in both the `x-middleware-next` and `x-middleware-rewrite` paths - **`app-dev-server.ts`** -- `.set()` to `.append()` in both the collection phase (where middleware headers are gathered) and the emission phase (where they are merged into the final response) - **`prod-server.ts`** -- Array accumulation for `Set-Cookie` in the middleware header merge path, and `getSetCookie()` pattern for custom middleware responses (replaces `Object.fromEntries()` which collapsed multi-value headers) - **`index.ts` codegen** -- `.set()` to `.append()` in the generated App Router production middleware runner - **`index.ts` Pages dev** -- `res.setHeader()` to `res.appendHeader()` for middleware header forwarding All changes use the same pattern: iterate response headers and use `.append()` (or `appendHeader` for Node responses) instead of `.set()`, which preserves separate entries for headers like `Set-Cookie` that cannot be combined with commas per RFC 6265. --- <sub>🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.</sub>
BreizhHardware 2026-05-06 12:39:28 +02:00
Sign in to join this conversation.
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
starred/vinext#370
No description provided.