Skip to content

Commit 3030506

Browse files
authored
fix: unsafe methods not causing cache purge (#3739)
* fix: unsafe methods not causing cache purge Fixes bug introduced in #3733 where unsafe methods no longer make it to the cache handler and cause a cache purge for an origin. Also removes a duplicate test file. Signed-off-by: flakey5 <[email protected]> * Update cache.js * extend test to check that safe methods we're not caching don't purge the cache Signed-off-by: flakey5 <[email protected]> * code review Signed-off-by: flakey5 <[email protected]> --------- Signed-off-by: flakey5 <[email protected]>
1 parent 8e025d1 commit 3030506

File tree

4 files changed

+61
-250
lines changed

4 files changed

+61
-250
lines changed

lib/handler/cache-handler.js

+2-8
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,6 @@ class CacheHandler extends DecoratorHandler {
1616
*/
1717
#store
1818

19-
/**
20-
* @type {import('../../types/cache-interceptor.d.ts').default.CacheMethods}
21-
*/
22-
#methods
23-
2419
/**
2520
* @type {import('../../types/dispatcher.d.ts').default.RequestOptions}
2621
*/
@@ -42,14 +37,13 @@ class CacheHandler extends DecoratorHandler {
4237
* @param {import('../../types/dispatcher.d.ts').default.DispatchHandlers} handler
4338
*/
4439
constructor (opts, requestOptions, handler) {
45-
const { store, methods } = opts
40+
const { store } = opts
4641

4742
super(handler)
4843

4944
this.#store = store
5045
this.#requestOptions = requestOptions
5146
this.#handler = handler
52-
this.#methods = methods
5347
}
5448

5549
/**
@@ -75,7 +69,7 @@ class CacheHandler extends DecoratorHandler {
7569
)
7670

7771
if (
78-
!this.#methods.includes(this.#requestOptions.method) &&
72+
!util.safeHTTPMethods.includes(this.#requestOptions.method) &&
7973
statusCode >= 200 &&
8074
statusCode <= 399
8175
) {

lib/interceptor/cache.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@ module.exports = (opts = {}) => {
3030
methods
3131
}
3232

33+
const safeMethodsToNotCache = util.safeHTTPMethods.filter(method => methods.includes(method) === false)
34+
3335
return dispatch => {
3436
return (opts, handler) => {
35-
if (!opts.origin || !methods.includes(opts.method)) {
37+
if (!opts.origin || safeMethodsToNotCache.includes(opts.method)) {
3638
// Not a method we want to cache or we don't have the origin, skip
3739
return dispatch(opts, handler)
3840
}

test/cache-interceptor/interceptor.js

-240
This file was deleted.

test/interceptors/cache.js

+56-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
'use strict'
22

33
const { describe, test, after } = require('node:test')
4-
const { strictEqual, notEqual, fail } = require('node:assert')
4+
const { strictEqual, notEqual, fail, equal } = require('node:assert')
55
const { createServer } = require('node:http')
66
const { once } = require('node:events')
77
const FakeTimers = require('@sinonjs/fake-timers')
@@ -250,4 +250,59 @@ describe('Cache Interceptor', () => {
250250
}
251251
})
252252
})
253+
254+
test('unsafe methods call the store\'s deleteByOrigin function', async () => {
255+
const server = createServer((_, res) => {
256+
res.end('asd')
257+
}).listen(0)
258+
259+
after(() => server.close())
260+
await once(server, 'listening')
261+
262+
let deleteByOriginCalled = false
263+
const store = new cacheStores.MemoryCacheStore()
264+
265+
const originalDeleteByOrigin = store.deleteByOrigin.bind(store)
266+
store.deleteByOrigin = (origin) => {
267+
deleteByOriginCalled = true
268+
originalDeleteByOrigin(origin)
269+
}
270+
271+
const client = new Client(`http://localhost:${server.address().port}`)
272+
.compose(interceptors.cache({
273+
store,
274+
methods: ['GET'] // explicitly only cache GET methods
275+
}))
276+
277+
// Make sure safe methods that we want to cache don't cause a cache purge
278+
await client.request({
279+
origin: 'localhost',
280+
method: 'GET',
281+
path: '/'
282+
})
283+
284+
equal(deleteByOriginCalled, false)
285+
286+
// Make sure other safe methods that we don't want to cache don't cause a cache purge
287+
await client.request({
288+
origin: 'localhost',
289+
method: 'HEAD',
290+
path: '/'
291+
})
292+
293+
strictEqual(deleteByOriginCalled, false)
294+
295+
// Make sure the common unsafe methods cause cache purges
296+
for (const method of ['POST', 'PUT', 'PATCH', 'DELETE']) {
297+
deleteByOriginCalled = false
298+
299+
await client.request({
300+
origin: 'localhost',
301+
method,
302+
path: '/'
303+
})
304+
305+
equal(deleteByOriginCalled, true, method)
306+
}
307+
})
253308
})

0 commit comments

Comments
 (0)