Skip to content

Commit a0518da

Browse files
committed
[fix] handle set-cookie in setHeaders
Fixes #6032
1 parent 7b305af commit a0518da

File tree

7 files changed

+44
-4
lines changed

7 files changed

+44
-4
lines changed

.changeset/lemon-kids-double.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@sveltejs/kit': patch
3+
---
4+
5+
handle `set-cookie` in `setHeaders`

packages/kit/src/runtime/server/index.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -143,12 +143,28 @@ export async function respond(request, options, state) {
143143
const lower = key.toLowerCase();
144144

145145
if (lower in headers) {
146-
throw new Error(`"${key}" header is already set`);
146+
if (lower === 'set-cookie') {
147+
if (!Array.isArray(headers[lower])) {
148+
headers[lower] = [/**@type{string} */ (headers[lower])];
149+
}
150+
const cookies = /**@type{string[]} */ (headers[lower]);
151+
const new_cookies = /**@type{string[]} */ (
152+
Array.isArray(new_headers[key]) ? new_headers[key] : [new_headers[key]]
153+
);
154+
for (const new_cookie of new_cookies) {
155+
if (cookies.includes(new_cookie)) {
156+
throw new Error(`"${key}" header already has cookie with same value`);
157+
}
158+
cookies.push(new_cookie);
159+
}
160+
} else {
161+
throw new Error(`"${key}" header is already set`);
162+
}
163+
} else {
164+
// TODO apply these headers to the response <- is this TODO outdated?
165+
headers[lower] = new_headers[key];
147166
}
148167

149-
// TODO apply these headers to the response
150-
headers[lower] = new_headers[key];
151-
152168
if (state.prerendering && lower === 'cache-control') {
153169
state.prerendering.cache = /** @type {string} */ (new_headers[key]);
154170
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function load({ setHeaders }) {
2+
setHeaders({
3+
'set-cookie': 'cookie1=value1'
4+
});
5+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
<slot />
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
export function load({ setHeaders }) {
2+
setHeaders({
3+
'set-cookie': 'cookie2=value2'
4+
});
5+
}

packages/kit/test/apps/basics/src/routes/headers/set-cookie/sub/+page.svelte

Whitespace-only changes.

packages/kit/test/apps/basics/test/server.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -314,6 +314,14 @@ test.describe('Static files', () => {
314314
});
315315
});
316316

317+
test.describe('setHeaders', () => {
318+
test('allows multiple set-cookie headers with different values', async ({ page }) => {
319+
const response = await page.goto('/headers/set-cookie/sub');
320+
const cookies = (await response?.allHeaders())['set-cookie'];
321+
expect(cookies.includes('cookie1=value1') && cookies.includes('cookie2=value2')).toBe(true);
322+
});
323+
});
324+
317325
test.describe('Miscellaneous', () => {
318326
test('does not serve version.json with an immutable cache header', async ({ request }) => {
319327
// this isn't actually a great test, because caching behaviour is down to adapters.

0 commit comments

Comments
 (0)