diff --git a/.changeset/giant-ghosts-give.md b/.changeset/giant-ghosts-give.md new file mode 100644 index 000000000000..cbe65f0e22e3 --- /dev/null +++ b/.changeset/giant-ghosts-give.md @@ -0,0 +1,5 @@ +--- +'@sveltejs/kit': patch +--- + +[fix] support etag W/ prefix diff --git a/packages/kit/src/runtime/server/index.js b/packages/kit/src/runtime/server/index.js index fedc115c2820..00b01ad7c12b 100644 --- a/packages/kit/src/runtime/server/index.js +++ b/packages/kit/src/runtime/server/index.js @@ -69,9 +69,15 @@ export async function respond(incoming, options, state = {}) { if (response.status === 200) { const cache_control = get_single_valued_header(response.headers, 'cache-control'); if (!cache_control || !/(no-store|immutable)/.test(cache_control)) { + let if_none_match_value = request.headers['if-none-match']; + // ignore W/ prefix https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match#directives + if (if_none_match_value?.startsWith('W/"')) { + if_none_match_value = if_none_match_value.substring(2); + } + const etag = `"${hash(response.body || '')}"`; - if (request.headers['if-none-match'] === etag) { + if (if_none_match_value === etag) { return { status: 304, headers: {}, diff --git a/packages/kit/test/apps/basics/src/routes/etag/_tests.js b/packages/kit/test/apps/basics/src/routes/etag/_tests.js index acb73c423bc4..62cf0dc213bc 100644 --- a/packages/kit/test/apps/basics/src/routes/etag/_tests.js +++ b/packages/kit/test/apps/basics/src/routes/etag/_tests.js @@ -47,4 +47,27 @@ export default function (test) { js: false } ); + + test( + 'support W/ etag prefix', + null, + async ({ fetch }) => { + const r1 = await fetch('/etag/text'); + const etag = r1.headers.get('etag'); + assert.ok(!!etag); + + const r2 = await fetch('/etag/text', { + headers: etag + ? { + 'if-none-match': `W/${etag}` + } + : {} + }); + + assert.equal(r2.status, 304); + }, + { + js: false + } + ); }