fix: create mutable copy of cached changelog response (#19)

This commit is contained in:
Zack Pollard
2026-04-04 21:39:41 +01:00
committed by GitHub
parent 47ea9ee7e7
commit c2e91c15d5
2 changed files with 30 additions and 1 deletions
+29
View File
@@ -596,3 +596,32 @@ describe('Cron sync', () => {
expect(body.published_at).toBe('2025-03-01T00:00:00Z');
});
});
describe('CDN cache immutable headers fix', () => {
it('cached responses must be wrapped to allow header mutation', async () => {
const cache = caches.default;
const key = new Request('https://example.com/test-immutable-headers');
const original = new Response(JSON.stringify({ data: 'test' }), {
headers: { 'Content-Type': 'application/json', 'Cache-Control': 'public, max-age=300' },
});
await cache.put(key, original.clone());
const cached = await cache.match(key);
expect(cached).not.toBeNull();
// Cached responses have immutable headers - setting directly would throw
expect(() => cached!.headers.set('Server-Timing', 'test;dur=1')).toThrow();
// The fix: wrapping in new Response() creates mutable headers
const mutable = new Response(cached!.body, cached!);
expect(() => mutable.headers.set('Server-Timing', 'test;dur=1')).not.toThrow();
expect(mutable.headers.get('Server-Timing')).toBe('test;dur=1');
// Verify body is preserved
const body = (await mutable.json()) as any;
expect(body.data).toBe('test');
await cache.delete(key);
});
});
+1 -1
View File
@@ -107,7 +107,7 @@ export default {
.addTag('cache', 'cdn')
.intField('invocation', 1),
);
return cached;
return new Response(cached.body, cached);
}
}