Skip to content

Commit

Permalink
fix: prevent reuse mutated route option for head (#4273)
Browse files Browse the repository at this point in the history
* fix: prevent reuse mutated route option for head

* test: ensure no regression

* fix: typo
  • Loading branch information
climba03003 committed Sep 14, 2022
1 parent 1237537 commit 21f209f
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 5 deletions.
13 changes: 8 additions & 5 deletions lib/route.js
Expand Up @@ -155,6 +155,12 @@ function buildRouting (options) {
// Since we are mutating/assigning only top level props, it is fine to have a shallow copy using the spread operator
const opts = { ...options }

const { exposeHeadRoute } = opts
const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes
// we need to clone a set of initial options for HEAD route
const headOpts = shouldExposeHead && options.method === 'GET' ? { ...options } : null

throwIfAlreadyStarted('Cannot add route when fastify instance is already started!')

const path = opts.url || opts.path || ''
Expand Down Expand Up @@ -342,13 +348,10 @@ function buildRouting (options) {

// register head route in sync
// we must place it after the `this.after`
const { exposeHeadRoute } = opts
const hasRouteExposeHeadRouteFlag = exposeHeadRoute != null
const shouldExposeHead = hasRouteExposeHeadRouteFlag ? exposeHeadRoute : globalExposeHeadRoutes

if (shouldExposeHead && options.method === 'GET' && !hasHEADHandler) {
const onSendHandlers = parseHeadOnSendHandlers(opts.onSend)
prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...opts, onSend: onSendHandlers }, isFastify: true })
const onSendHandlers = parseHeadOnSendHandlers(headOpts.onSend)
prepareRoute.call(this, { method: 'HEAD', url: path, options: { ...headOpts, onSend: onSendHandlers }, isFastify: true })
} else if (hasHEADHandler && exposeHeadRoute) {
warning.emit('FSTDEP007')
}
Expand Down
29 changes: 29 additions & 0 deletions test/route.test.js
Expand Up @@ -1464,3 +1464,32 @@ test('invalid url attribute - non string URL', t => {
t.equal(error.code, FST_ERR_INVALID_URL().code)
}
})

test('exposeHeadRoute should not reuse the same route option', async t => {
t.plan(2)

const fastify = Fastify()

// we update the onRequest hook in onRoute hook
// if we reuse the same route option
// that means we will append another function inside the array
fastify.addHook('onRoute', function (routeOption) {
if (Array.isArray(routeOption.onRequest)) {
routeOption.onRequest.push(() => {})
} else {
routeOption.onRequest = [() => {}]
}
})

fastify.addHook('onRoute', function (routeOption) {
t.equal(routeOption.onRequest.length, 1)
})

fastify.route({
method: 'GET',
path: '/more-coffee',
async handler () {
return 'hello world'
}
})
})

0 comments on commit 21f209f

Please sign in to comment.