Skip to content

Commit

Permalink
feat: Add callback for configuring Vary header
Browse files Browse the repository at this point in the history
  • Loading branch information
gl-jkeys committed Mar 23, 2024
1 parent f038e77 commit 55122f3
Show file tree
Hide file tree
Showing 3 changed files with 213 additions and 14 deletions.
33 changes: 20 additions & 13 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
origin: '*',
methods: 'GET,HEAD,PUT,PATCH,POST,DELETE',
preflightContinue: false,
optionsSuccessStatus: 204
optionsSuccessStatus: 204,
shouldSetVaryHeader: function(req, header) { return true }
};

function isString(s) {
Expand Down Expand Up @@ -50,21 +51,25 @@
key: 'Access-Control-Allow-Origin',
value: options.origin
}]);
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
if (options.shouldSetVaryHeader(req, 'Origin')) {
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
}
} else {
isAllowed = isOriginAllowed(requestOrigin, options.origin);
// reflect origin
headers.push([{
key: 'Access-Control-Allow-Origin',
value: isAllowed ? requestOrigin : false
}]);
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
if (options.shouldSetVaryHeader(req, 'Origin')) {
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
}
}

return headers;
Expand Down Expand Up @@ -97,10 +102,12 @@

if (!allowedHeaders) {
allowedHeaders = req.headers['access-control-request-headers']; // .headers wasn't specified, so reflect the request headers
headers.push([{
key: 'Vary',
value: 'Access-Control-Request-Headers'
}]);
if (options.shouldSetVaryHeader(req, 'Access-Control-Request-Headers')) {
headers.push([{
key: 'Vary',
value: 'Access-Control-Request-Headers'
}]);
}
} else if (allowedHeaders.join) {
allowedHeaders = allowedHeaders.join(','); // .headers is an array, so turn it into a string
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "cors",
"description": "Node.js CORS middleware",
"version": "2.8.5",
"version": "2.9.0",
"author": "Troy Goode <[email protected]> (https://github.com/troygoode/)",
"license": "MIT",
"keywords": [
Expand Down
192 changes: 192 additions & 0 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,198 @@ var util = require('util')
})
});

describe('shouldSetVaryHeader', function() {
it('Vary: "Access-Control-Request-Headers" header is set by default for pre-flight requests', function (done) {
var cb = after(1, done)

var req = new FakeRequest('OPTIONS')
var res = new FakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'


res.on('finish', function () {
assert.equal(res.statusCode, 204)
assert.equal(res.getHeader('Vary'), 'Access-Control-Request-Headers')
cb()
})

cors()(req, res, function (err) {
cb(err || new Error('should not be called'))
})
})

it('Vary: "Origin, Access-Control-Request-Headers" header is set by default for pre-flight requests with origins', function (done) {
var cb = after(1, done)

var req = new FakeRequest('OPTIONS')
var res = new FakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'
var options = {
origin: 'https://example.com'
}

res.on('finish', function () {
assert.equal(res.statusCode, 204)
assert.equal(res.getHeader('Vary'), 'Origin, Access-Control-Request-Headers')
cb()
})

cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
})
})

it('Vary: "Access-Control-Request-Headers" header is set for pre-flight requests and shouldSetVaryHeader(req, \'Origin\') configured to return false with origins', function (done) {
var cb = after(1, done)

var req = new FakeRequest('OPTIONS')
var res = new FakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'
var options = {
origin: 'https://example.com',
shouldSetVaryHeader: function(req, header) {
if (header === 'Access-Control-Request-Headers') {
return true
}

if (req.originalUrl.startsWith('/images') && header === 'Origin') {
return false
} else {
return true
}
}
}

res.on('finish', function () {
assert.equal(res.statusCode, 204)
assert.equal(res.getHeader('Vary'), 'Access-Control-Request-Headers')
cb()
})

cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
})
})

it('Vary: "Access-Control-Request-Headers" header is not set for pre-flight requests when shouldSetVaryHeader(req, \'Access-Control-Request-Headers\') configured to return false', function (done) {
var cb = after(1, done)

var req = new FakeRequest('OPTIONS')
var res = new FakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'
var options = {
origin: 'https://example.com',
shouldSetVaryHeader: function(req, header) {
if (header === 'Access-Control-Request-Headers') {
return false
}

if (req.originalUrl.startsWith('/images') && header === 'Origin') {
return false
} else {
return true
}
}
}

res.on('finish', function () {
assert.equal(res.statusCode, 204)
assert.equal(res.getHeader('Vary'), undefined)
cb()
})

cors(options)(req, res, function (err) {
cb(err || new Error('should not be called'))
})
})

it('Vary: "Origin" header is set by default', function (done) {
var req = fakeRequest('GET')
var res = fakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'
var options = {
origin: 'http://example.com'
}

var next = function () {
// assert
assert.equal(res.statusCode, 200)
assert.equal(res.getHeader('Vary'), 'Origin')
done();
};

cors(options)(req, res, next)
})

it('Vary: "Origin" header is not set when shouldSetVaryHeader(req, \'Origin\') configured to return false', function (done) {
var req = fakeRequest('GET')
var res = fakeResponse()
req.host = 'http://example.com'
req.originalUrl = '/images/asdf.png'

var options = {
origin: ['http://example.com', 'http://foo.com'],
shouldSetVaryHeader: function(req, header) {
if (header === 'Access-Control-Request-Headers') {
return true
}

if (req.originalUrl.startsWith('/images') && header === 'Origin') {
return false
} else {
return true
}
}
}

var next = function () {
// assert
assert.equal(res.statusCode, 200)
assert.equal(res.getHeader('Vary'), undefined)
done();
};

cors(options)(req, res, next)
})

it('Vary: "Origin" header is set when shouldSetVaryHeader(req, \'Origin\') configured to return true', function (done) {
var req = fakeRequest('GET')
var res = fakeResponse()
req.host = 'http://example.com'

req.originalUrl = '/some/other/path'

var options = {
origin: ['http://example.com', 'http://foo.com'],
shouldSetVaryHeader: function(req, header) {
if (header === 'Access-Control-Request-Headers') {
return true
}

if (req.originalUrl.startsWith('/images') && header === 'Origin') {
return false
} else {
return true
}
}
}

var next = function () {
// assert
assert.equal(res.statusCode, 200)
assert.equal(res.getHeader('Vary'), 'Origin')
done();
};

cors(options)(req, res, next)
})
})

describe('passing static options', function () {
it('overrides defaults', function (done) {
var cb = after(1, done)
Expand Down

0 comments on commit 55122f3

Please sign in to comment.