Skip to content

Commit c1d3458

Browse files
authored
fix: clone Headers before mutating them during prerendering (#10030)
* clone request and headers before setting x-sveltekit-prerender * add changeset * add test
1 parent 4aa976e commit c1d3458

File tree

4 files changed

+26
-1
lines changed

4 files changed

+26
-1
lines changed

.changeset/curly-onions-compare.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+
fix: gracefully handle server endpoints that return `Response`s with immutable `Headers` when prerendering

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export async function render_endpoint(event, mod, state) {
3939
}
4040

4141
try {
42-
const response = await handler(
42+
let response = await handler(
4343
/** @type {import('@sveltejs/kit').RequestEvent<Record<string, any>>} */ (event)
4444
);
4545

@@ -50,6 +50,13 @@ export async function render_endpoint(event, mod, state) {
5050
}
5151

5252
if (state.prerendering) {
53+
// the returned Response might have immutable Headers
54+
// so we should clone them before trying to mutate them
55+
response = new Response(response.body, {
56+
status: response.status,
57+
statusText: response.statusText,
58+
headers: new Headers(response.headers)
59+
});
5360
response.headers.set('x-sveltekit-prerender', String(prerender));
5461
}
5562

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
export const prerender = true;
2+
3+
export const GET = () => {
4+
const response = new Response('foo');
5+
// this simulates immutable Response Headers, like those returned by undici
6+
Object.defineProperty(response.headers, 'set', { value: null });
7+
return response;
8+
};

packages/kit/test/prerendering/basics/test/tests.spec.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,3 +223,8 @@ test('prerendered.paths omits trailing slashes for endpoints', () => {
223223
expect(content, `Missing ${path}`).toMatch(`"${path}"`);
224224
}
225225
});
226+
227+
test('prerenders responses with immutable Headers', () => {
228+
const content = read('immutable-headers');
229+
expect(content).toMatch('foo');
230+
});

0 commit comments

Comments
 (0)