Skip to content

Commit bf63aa8

Browse files
orinokaipieh
andauthoredJan 9, 2024
fix: ensure cdn cache control only set for get and head methods (#137)
* fix: ensure cdn cache control only for get and head * test: pass requests in tests and add HEAD and POST test cases --------- Co-authored-by: Michal Piechowiak <misiek.piechowiak@gmail.com>
1 parent d17c030 commit bf63aa8

File tree

3 files changed

+55
-12
lines changed

3 files changed

+55
-12
lines changed
 

‎src/run/handlers/server.ts

+1-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { toComputeResponse, toReqRes } from '@fastly/http-compute-js'
2-
import { HeadersSentEvent } from '@fastly/http-compute-js/dist/http-compute-js/http-outgoing.js'
32
import type { NextConfigComplete } from 'next/dist/server/config-shared.js'
43
import type { WorkerRequestHandler } from 'next/dist/server/lib/types.js'
54

@@ -55,10 +54,9 @@ export default async (request: Request) => {
5554

5655
await adjustDateHeader(response.headers, request)
5756

58-
setCacheControlHeaders(response.headers)
57+
setCacheControlHeaders(response.headers, request)
5958
setCacheTagsHeaders(response.headers, request, tagsManifest)
6059
setVaryHeaders(response.headers, request, nextConfig)
6160

62-
6361
return response
6462
}

‎src/run/headers.test.ts

+52-8
Original file line numberDiff line numberDiff line change
@@ -144,11 +144,14 @@ describe('headers', () => {
144144
})
145145

146146
describe('setCacheControlHeaders', () => {
147+
const defaultUrl = 'https://example.com'
148+
147149
test('should not set any headers if "cache-control" is not set', () => {
148150
const headers = new Headers()
151+
const request = new Request(defaultUrl)
149152
vi.spyOn(headers, 'set')
150153

151-
setCacheControlHeaders(headers)
154+
setCacheControlHeaders(headers, request)
152155

153156
expect(headers.set).toHaveBeenCalledTimes(0)
154157
})
@@ -159,9 +162,10 @@ describe('headers', () => {
159162
'cdn-cache-control': 'public, max-age=0, must-revalidate',
160163
}
161164
const headers = new Headers(givenHeaders)
165+
const request = new Request(defaultUrl)
162166
vi.spyOn(headers, 'set')
163167

164-
setCacheControlHeaders(headers)
168+
setCacheControlHeaders(headers, request)
165169

166170
expect(headers.set).toHaveBeenCalledTimes(0)
167171
})
@@ -172,21 +176,23 @@ describe('headers', () => {
172176
'netlify-cdn-cache-control': 'public, max-age=0, must-revalidate',
173177
}
174178
const headers = new Headers(givenHeaders)
179+
const request = new Request(defaultUrl)
175180
vi.spyOn(headers, 'set')
176181

177-
setCacheControlHeaders(headers)
182+
setCacheControlHeaders(headers, request)
178183

179184
expect(headers.set).toHaveBeenCalledTimes(0)
180185
})
181186

182-
test('should set expected headers if "cache-control" is set and "cdn-cache-control" and "netlify-cdn-cache-control" are not present', () => {
187+
test('should set expected headers if "cache-control" is set and "cdn-cache-control" and "netlify-cdn-cache-control" are not present (GET request)', () => {
183188
const givenHeaders = {
184189
'cache-control': 'public, max-age=0, must-revalidate',
185190
}
186191
const headers = new Headers(givenHeaders)
192+
const request = new Request(defaultUrl)
187193
vi.spyOn(headers, 'set')
188194

189-
setCacheControlHeaders(headers)
195+
setCacheControlHeaders(headers, request)
190196

191197
expect(headers.set).toHaveBeenNthCalledWith(
192198
1,
@@ -200,14 +206,50 @@ describe('headers', () => {
200206
)
201207
})
202208

209+
test('should set expected headers if "cache-control" is set and "cdn-cache-control" and "netlify-cdn-cache-control" are not present (HEAD request)', () => {
210+
const givenHeaders = {
211+
'cache-control': 'public, max-age=0, must-revalidate',
212+
}
213+
const headers = new Headers(givenHeaders)
214+
const request = new Request(defaultUrl, { method: 'HEAD' })
215+
vi.spyOn(headers, 'set')
216+
217+
setCacheControlHeaders(headers, request)
218+
219+
expect(headers.set).toHaveBeenNthCalledWith(
220+
1,
221+
'cache-control',
222+
'public, max-age=0, must-revalidate',
223+
)
224+
expect(headers.set).toHaveBeenNthCalledWith(
225+
2,
226+
'netlify-cdn-cache-control',
227+
'public, max-age=0, must-revalidate',
228+
)
229+
})
230+
231+
test('should not set any headers on POST request', () => {
232+
const givenHeaders = {
233+
'cache-control': 'public, max-age=0, must-revalidate',
234+
}
235+
const headers = new Headers(givenHeaders)
236+
const request = new Request(defaultUrl, { method: 'POST' })
237+
vi.spyOn(headers, 'set')
238+
239+
setCacheControlHeaders(headers, request)
240+
241+
expect(headers.set).toHaveBeenCalledTimes(0)
242+
})
243+
203244
test('should remove "s-maxage" from "cache-control" header', () => {
204245
const givenHeaders = {
205246
'cache-control': 'public, s-maxage=604800',
206247
}
207248
const headers = new Headers(givenHeaders)
249+
const request = new Request(defaultUrl)
208250
vi.spyOn(headers, 'set')
209251

210-
setCacheControlHeaders(headers)
252+
setCacheControlHeaders(headers, request)
211253

212254
expect(headers.set).toHaveBeenNthCalledWith(1, 'cache-control', 'public')
213255
expect(headers.set).toHaveBeenNthCalledWith(
@@ -222,9 +264,10 @@ describe('headers', () => {
222264
'cache-control': 'max-age=604800, stale-while-revalidate=86400',
223265
}
224266
const headers = new Headers(givenHeaders)
267+
const request = new Request(defaultUrl)
225268
vi.spyOn(headers, 'set')
226269

227-
setCacheControlHeaders(headers)
270+
setCacheControlHeaders(headers, request)
228271

229272
expect(headers.set).toHaveBeenNthCalledWith(1, 'cache-control', 'max-age=604800')
230273
expect(headers.set).toHaveBeenNthCalledWith(
@@ -239,9 +282,10 @@ describe('headers', () => {
239282
'cache-control': 's-maxage=604800, stale-while-revalidate=86400',
240283
}
241284
const headers = new Headers(givenHeaders)
285+
const request = new Request(defaultUrl)
242286
vi.spyOn(headers, 'set')
243287

244-
setCacheControlHeaders(headers)
288+
setCacheControlHeaders(headers, request)
245289

246290
expect(headers.set).toHaveBeenNthCalledWith(
247291
1,

‎src/run/headers.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -109,10 +109,11 @@ export const adjustDateHeader = async (headers: Headers, request: Request) => {
109109
* Ensure stale-while-revalidate and s-maxage don't leak to the client, but
110110
* assume the user knows what they are doing if CDN cache controls are set
111111
*/
112-
export const setCacheControlHeaders = (headers: Headers) => {
112+
export const setCacheControlHeaders = (headers: Headers, request: Request) => {
113113
const cacheControl = headers.get('cache-control')
114114
if (
115115
cacheControl !== null &&
116+
['GET', 'HEAD'].includes(request.method) &&
116117
!headers.has('cdn-cache-control') &&
117118
!headers.has('netlify-cdn-cache-control')
118119
) {

0 commit comments

Comments
 (0)
Please sign in to comment.