Skip to content

Commit

Permalink
vary origin on delegated options (#292)
Browse files Browse the repository at this point in the history
  • Loading branch information
laat committed Jan 27, 2024
1 parent 3cf8f61 commit 034bb13
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 32 deletions.
11 changes: 6 additions & 5 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ function handleCorsOptionsDelegator (optionsResolver, fastify, opts, next) {
fastify.addHook(hook, function handleCors (req, reply, payload, next) {
const ret = optionsResolver(req)
if (ret && typeof ret.then === 'function') {
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options), req, reply, next)).catch(next)
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)).catch(next)
return
}
next(new Error('Invalid CORS origin option'))
Expand All @@ -114,7 +114,7 @@ function handleCorsOptionsDelegator (optionsResolver, fastify, opts, next) {
fastify.addHook(hook, function handleCors (req, reply, next) {
const ret = optionsResolver(req)
if (ret && typeof ret.then === 'function') {
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options), req, reply, next)).catch(next)
ret.then(options => addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)).catch(next)
return
}
next(new Error('Invalid CORS origin option'))
Expand All @@ -128,15 +128,15 @@ function handleCorsOptionsCallbackDelegator (optionsResolver, fastify, req, repl
if (err) {
next(err)
} else {
addCorsHeadersHandler(fastify, normalizeCorsOptions(options), req, reply, next)
addCorsHeadersHandler(fastify, normalizeCorsOptions(options, true), req, reply, next)
}
})
}

/**
* @param {import('./types').FastifyCorsOptions} opts
*/
function normalizeCorsOptions (opts) {
function normalizeCorsOptions (opts, dynamic) {
const corsOptions = { ...defaultOptions, ...opts }
if (Array.isArray(opts.origin) && opts.origin.indexOf('*') !== -1) {
corsOptions.origin = '*'
Expand All @@ -148,11 +148,12 @@ function normalizeCorsOptions (opts) {
// strings are applied directly and any other value is ignored
corsOptions.cacheControl = null
}
corsOptions.dynamic = dynamic || false
return corsOptions
}

function addCorsHeadersHandler (fastify, options, req, reply, next) {
if (typeof options.origin !== 'string' && options.origin !== false) {
if ((typeof options.origin !== 'string' && options.origin !== false) || options.dynamic) {
// Always set Vary header for non-static origin option
// https://fetch.spec.whatwg.org/#cors-protocol-and-http-caches
addOriginToVaryHeader(reply)
Expand Down
24 changes: 12 additions & 12 deletions test/cors.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ test('Should add cors headers (custom values)', t => {
})

test('Should support dynamic config (callback)', t => {
t.plan(18)
t.plan(16)

const configs = [{
origin: 'example.com',
Expand Down Expand Up @@ -177,9 +177,9 @@ test('Should support dynamic config (callback)', t => {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
'content-length': '2',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -202,9 +202,9 @@ test('Should support dynamic config (callback)', t => {
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': '456',
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -221,7 +221,7 @@ test('Should support dynamic config (callback)', t => {
})

test('Should support dynamic config (Promise)', t => {
t.plan(26)
t.plan(23)

const configs = [{
origin: 'example.com',
Expand Down Expand Up @@ -282,9 +282,9 @@ test('Should support dynamic config (Promise)', t => {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
'content-length': '2',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -306,9 +306,9 @@ test('Should support dynamic config (Promise)', t => {
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
t.equal(res.headers['cache-control'], undefined, 'cache-control omitted (invalid value)')
})

Expand All @@ -332,9 +332,9 @@ test('Should support dynamic config (Promise)', t => {
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'cache-control': 'public, max-age=456', // cache-control included (custom string)
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand Down
30 changes: 15 additions & 15 deletions test/hooks.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ test('Should set hook preSerialization if hook option is set to preSerialization
})

test('Should support custom hook with dynamic config', t => {
t.plan(18)
t.plan(16)

const configs = [{
origin: 'example.com',
Expand Down Expand Up @@ -375,9 +375,9 @@ test('Should support custom hook with dynamic config', t => {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
'content-length': '2',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -399,9 +399,9 @@ test('Should support custom hook with dynamic config', t => {
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -418,7 +418,7 @@ test('Should support custom hook with dynamic config', t => {
})

test('Should support custom hook with dynamic config (callback)', t => {
t.plan(18)
t.plan(16)

const configs = [{
origin: 'example.com',
Expand Down Expand Up @@ -472,9 +472,9 @@ test('Should support custom hook with dynamic config (callback)', t => {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
'content-length': '2',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -496,9 +496,9 @@ test('Should support custom hook with dynamic config (callback)', t => {
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -515,7 +515,7 @@ test('Should support custom hook with dynamic config (callback)', t => {
})

test('Should support custom hook with dynamic config (Promise)', t => {
t.plan(18)
t.plan(16)

const configs = [{
origin: 'example.com',
Expand Down Expand Up @@ -570,9 +570,9 @@ test('Should support custom hook with dynamic config (Promise)', t => {
'access-control-allow-origin': 'example.com',
'access-control-allow-credentials': 'true',
'access-control-expose-headers': 'foo, bar',
'content-length': '2'
'content-length': '2',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand All @@ -594,9 +594,9 @@ test('Should support custom hook with dynamic config (Promise)', t => {
'access-control-allow-methods': 'GET',
'access-control-allow-headers': 'baz, foo',
'access-control-max-age': '321',
'content-length': '0'
'content-length': '0',
vary: 'Origin'
})
t.notMatch(res.headers, { vary: 'Origin' })
})

fastify.inject({
Expand Down

0 comments on commit 034bb13

Please sign in to comment.