From f3916b380ddc843ef4a72c8bb1df94630af414c2 Mon Sep 17 00:00:00 2001 From: Vantroy Date: Wed, 20 Aug 2025 15:18:22 +0700 Subject: [PATCH 1/6] allow to override cors options by route config Signed-off-by: Vantroy --- index.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/index.js b/index.js index ca946f9..0b67535 100644 --- a/index.js +++ b/index.js @@ -156,7 +156,9 @@ function normalizeCorsOptions (opts, dynamic) { return corsOptions } -function addCorsHeadersHandler (fastify, options, req, reply, next) { +function addCorsHeadersHandler (fastify, globalOptions, req, reply, next) { + const options = { ...globalOptions, ...(req.routeOptions.config?.cors } + 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 From 4f8b24510c5cb552d5e562fbcf3977dd18061ff2 Mon Sep 17 00:00:00 2001 From: Vantroy Date: Wed, 20 Aug 2025 15:29:08 +0700 Subject: [PATCH 2/6] Update README.md Signed-off-by: Vantroy --- README.md | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 271214c..ac26317 100644 --- a/README.md +++ b/README.md @@ -116,20 +116,34 @@ fastify.register(async function (fastify) { fastify.listen({ port: 3000 }) ``` -### Disabling CORS for a specific route +### Route-Level CORS Overrides -CORS can be disabled at the route level by setting the `cors` option to `false`. +You can override or disable CORS on a per-route basis using the `config.cors` option:. ```js const fastify = require('fastify')() -fastify.register(require('@fastify/cors'), { origin: '*' }) +fastify.register(require('@fastify/cors'), { origin: 'https://example.com' }) fastify.get('/cors-enabled', (_req, reply) => { - reply.send('CORS headers') + reply.send('CORS headers applied') }) -fastify.get('/cors-disabled', { cors: false }, (_req, reply) => { +fastify.get('/cors-allow-all', { + config: { + cors: { + origin: '*', // Allow all origins for this route + }, + }, +}, (_req, reply) => { + reply.send('Custom CORS headers applied') +}) + +fastify.get('/cors-disabled', { + config: { + cors: false, // Disable CORS for this route + }, +}, (_req, reply) => { reply.send('No CORS headers') }) @@ -195,4 +209,4 @@ The code is a port for Fastify of [`expressjs/cors`](https://github.com/expressj ## License Licensed under [MIT](./LICENSE).
-[`expressjs/cors` license](https://github.com/expressjs/cors/blob/master/LICENSE) \ No newline at end of file +[`expressjs/cors` license](https://github.com/expressjs/cors/blob/master/LICENSE) From 63edaa9e8bd87cac3280ac8868aa8c2a426d0ad8 Mon Sep 17 00:00:00 2001 From: vimutti Date: Wed, 20 Aug 2025 15:34:13 +0700 Subject: [PATCH 3/6] fix syntax error --- index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.js b/index.js index 0b67535..4e64c05 100644 --- a/index.js +++ b/index.js @@ -157,7 +157,7 @@ function normalizeCorsOptions (opts, dynamic) { } function addCorsHeadersHandler (fastify, globalOptions, req, reply, next) { - const options = { ...globalOptions, ...(req.routeOptions.config?.cors } + const options = { ...globalOptions, ...req.routeOptions.config?.cors } if ((typeof options.origin !== 'string' && options.origin !== false) || options.dynamic) { // Always set Vary header for non-static origin option From 3db2862ab49a659fde88af162b52b0c14c680398 Mon Sep 17 00:00:00 2001 From: vimutti Date: Wed, 20 Aug 2025 15:45:33 +0700 Subject: [PATCH 4/6] add test --- test/cors.test.js | 72 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 72 insertions(+) diff --git a/test/cors.test.js b/test/cors.test.js index d64c48a..75cfcc1 100644 --- a/test/cors.test.js +++ b/test/cors.test.js @@ -1050,3 +1050,75 @@ test('Should allow routes to disable CORS individually', async t => { t.assert.strictEqual(res.statusCode, 200) t.assert.strictEqual(res.headers['access-control-allow-origin'], undefined) }) + +test('Should support route-level config', async t => { + t.plan(9) + + const fastify = Fastify() + fastify.register(cors, { + origin: 'https://default-example.com' + }) + + // ✅ Route with default CORS (inherits plugin config) + fastify.get('/cors-enabled', (_req, reply) => { + reply.send('CORS headers applied') + }) + + // 🌍 Route with custom CORS origin + fastify.get('/cors-allow-all', { + config: { + cors: { + origin: '*' + } + } + }, (_req, reply) => { + reply.send('Custom CORS headers applied') + }) + + // 🚫 Route with CORS disabled + fastify.get('/cors-disabled', { + config: { + cors: false + } + }, (_req, reply) => { + reply.send('No CORS headers') + }) + + await fastify.ready() + + // ✅ Default CORS + const resDefault = await fastify.inject({ + method: 'GET', + url: '/cors-enabled', + headers: { + origin: 'https://default-example.com' + } + }) + t.assert.ok(resDefault) + t.assert.strictEqual(resDefault.statusCode, 200) + t.assert.strictEqual(resDefault.headers['access-control-allow-origin'], 'https://default-example.com') + + // 🌍 Custom CORS + const resCustom = await fastify.inject({ + method: 'GET', + url: '/cors-allow-all', + headers: { + origin: 'https://example.com' + } + }) + t.assert.ok(resCustom) + t.assert.strictEqual(resCustom.statusCode, 200) + t.assert.strictEqual(resCustom.headers['access-control-allow-origin'], '*') + + // 🚫 CORS disabled + const resDisabled = await fastify.inject({ + method: 'GET', + url: '/cors-disabled', + headers: { + origin: 'https://example.com' + } + }) + t.assert.ok(resDisabled) + t.assert.strictEqual(resDisabled.statusCode, 200) + t.assert.strictEqual(resDisabled.headers['access-control-allow-origin'], undefined) +}) From 059dc3d09d91bb6f8a9a314140281eac6420b689 Mon Sep 17 00:00:00 2001 From: Vantroy Date: Fri, 7 Nov 2025 20:07:44 +0700 Subject: [PATCH 5/6] Update README.md Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> Signed-off-by: Vantroy --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index ac26317..2f0fc39 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ fastify.listen({ port: 3000 }) ### Route-Level CORS Overrides -You can override or disable CORS on a per-route basis using the `config.cors` option:. +You can override or disable CORS on a per-route basis using the `config.cors` option: ```js const fastify = require('fastify')() From 3cafefac1354bba16edf2af25626f328fc629d7e Mon Sep 17 00:00:00 2001 From: Manuel Spigolon Date: Sat, 8 Nov 2025 11:54:58 +0100 Subject: [PATCH 6/6] chore: Update README.md Signed-off-by: Manuel Spigolon --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 2f0fc39..5b5442e 100644 --- a/README.md +++ b/README.md @@ -118,7 +118,7 @@ fastify.listen({ port: 3000 }) ### Route-Level CORS Overrides -You can override or disable CORS on a per-route basis using the `config.cors` option: +It is possible to override the CORS plugin options provided during registration on a per-route basis using the `config.cors` option. ```js const fastify = require('fastify')()