mirror of
https://github.com/scratchfoundation/restify-cors-middleware.git
synced 2024-12-18 11:52:26 -05:00
Splitting the handlers (preparation for creating a separate "actual" handler)
This commit is contained in:
parent
0e5633b2e8
commit
a9f370e474
4 changed files with 92 additions and 60 deletions
64
src/index.js
64
src/index.js
|
@ -1,62 +1,6 @@
|
||||||
var restify = require('restify');
|
var util = require('util');
|
||||||
var util = require('util');
|
var restify = require('restify');
|
||||||
|
var preflight = require('./preflight');
|
||||||
DEFAULT_ALLOW_HEADERS = restify.CORS.ALLOW_HEADERS;
|
|
||||||
|
|
||||||
var HTTP_NO_CONTENT = 204;
|
|
||||||
|
|
||||||
function matchOrigin(req, origins) {
|
|
||||||
var origin = req.headers["origin"];
|
|
||||||
function belongs(o) {
|
|
||||||
if (origin === o || o === "*") {
|
|
||||||
origin = o;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
if (origin && origins.some(belongs)) {
|
|
||||||
return origin;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function preflightHandler(options) {
|
|
||||||
return function(req, res, next) {
|
|
||||||
if (req.method !== 'OPTIONS') return next();
|
|
||||||
|
|
||||||
// 6.2.1 and 6.2.2
|
|
||||||
if (matchOrigin(req, options.origins) === false) return next();
|
|
||||||
|
|
||||||
// 6.2.3
|
|
||||||
requestedMethod = req.headers['access-control-request-method'];
|
|
||||||
if (!requestedMethod) return next();
|
|
||||||
|
|
||||||
// 6.2.4
|
|
||||||
requestedHeaders = req.headers['access-control-request-headers'];
|
|
||||||
requestedHeaders = requestedHeaders ? requestedHeaders.split(', ') : [];
|
|
||||||
|
|
||||||
allowedMethods = [requestedMethod, 'OPTIONS'];
|
|
||||||
allowedHeaders = DEFAULT_ALLOW_HEADERS.concat(['x-requested-with'])
|
|
||||||
.concat(options.allowHeaders);
|
|
||||||
|
|
||||||
res.once('header', function() {
|
|
||||||
|
|
||||||
// 6.2.7
|
|
||||||
res.header('Access-Control-Allow-Origin', req.headers['origin']);
|
|
||||||
res.header('Access-Control-Allow-Credentials', true);
|
|
||||||
|
|
||||||
// 6.2.9
|
|
||||||
res.header('Access-Control-Allow-Methods', allowedMethods.join(', '));
|
|
||||||
|
|
||||||
// 6.2.10
|
|
||||||
res.header('Access-Control-Allow-Headers', allowedHeaders.join(', '));
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
res.send(HTTP_NO_CONTENT);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = function(options) {
|
module.exports = function(options) {
|
||||||
|
|
||||||
|
@ -71,7 +15,7 @@ module.exports = function(options) {
|
||||||
headers: options.exposeHeaders
|
headers: options.exposeHeaders
|
||||||
}),
|
}),
|
||||||
|
|
||||||
preflight: preflightHandler({
|
preflight: preflight.handler({
|
||||||
origins: options.origins,
|
origins: options.origins,
|
||||||
allowHeaders: options.allowHeaders
|
allowHeaders: options.allowHeaders
|
||||||
})
|
})
|
||||||
|
|
11
src/origin.js
Normal file
11
src/origin.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
|
||||||
|
exports.match = function(origin, list) {
|
||||||
|
function belongs(o) {
|
||||||
|
return (origin === o || o === "*");
|
||||||
|
}
|
||||||
|
if (origin && list.some(belongs)) {
|
||||||
|
return origin;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
46
src/preflight.js
Normal file
46
src/preflight.js
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
var restify = require('restify');
|
||||||
|
var origin = require('./origin');
|
||||||
|
|
||||||
|
var DEFAULT_ALLOW_HEADERS = restify.CORS.ALLOW_HEADERS;
|
||||||
|
var HTTP_NO_CONTENT = 204;
|
||||||
|
|
||||||
|
exports.handler = function(options) {
|
||||||
|
|
||||||
|
return function(req, res, next) {
|
||||||
|
if (req.method !== 'OPTIONS') return next();
|
||||||
|
|
||||||
|
// 6.2.1 and 6.2.2
|
||||||
|
originHeader = req.headers['origin'];
|
||||||
|
if (origin.match(originHeader, options.origins) === false) return next();
|
||||||
|
|
||||||
|
// 6.2.3
|
||||||
|
requestedMethod = req.headers['access-control-request-method'];
|
||||||
|
if (!requestedMethod) return next();
|
||||||
|
|
||||||
|
// 6.2.4
|
||||||
|
requestedHeaders = req.headers['access-control-request-headers'];
|
||||||
|
requestedHeaders = requestedHeaders ? requestedHeaders.split(', ') : [];
|
||||||
|
|
||||||
|
allowedMethods = [requestedMethod, 'OPTIONS'];
|
||||||
|
allowedHeaders = DEFAULT_ALLOW_HEADERS.concat(['x-requested-with'])
|
||||||
|
.concat(options.allowHeaders);
|
||||||
|
|
||||||
|
res.once('header', function() {
|
||||||
|
|
||||||
|
// 6.2.7
|
||||||
|
res.header('Access-Control-Allow-Origin', originHeader);
|
||||||
|
res.header('Access-Control-Allow-Credentials', true);
|
||||||
|
|
||||||
|
// 6.2.9
|
||||||
|
res.header('Access-Control-Allow-Methods', allowedMethods.join(', '));
|
||||||
|
|
||||||
|
// 6.2.10
|
||||||
|
res.header('Access-Control-Allow-Headers', allowedHeaders.join(', '));
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
res.send(HTTP_NO_CONTENT);
|
||||||
|
};
|
||||||
|
|
||||||
|
};
|
||||||
|
|
31
test/origin.spec.js
Normal file
31
test/origin.spec.js
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
var should = require('should');
|
||||||
|
var origin = require('../src/origin');
|
||||||
|
|
||||||
|
describe('Origin list', function() {
|
||||||
|
|
||||||
|
var list = [
|
||||||
|
'http://api.myapp.com',
|
||||||
|
'http://www.myapp.com'
|
||||||
|
];
|
||||||
|
|
||||||
|
it('returns null if the origin is not in the list', function() {
|
||||||
|
var o = origin.match('http://random-website.com', list);
|
||||||
|
o.should.eql(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('does not do partial matches', function() {
|
||||||
|
var o = origin.match('api.myapp.com', list);
|
||||||
|
o.should.eql(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the origin if it matched', function() {
|
||||||
|
var o = origin.match('http://api.myapp.com', list);
|
||||||
|
o.should.eql('http://api.myapp.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('returns the origin if the list contains *', function() {
|
||||||
|
var o = origin.match('http://random-website.com', ['*']);
|
||||||
|
o.should.eql('http://random-website.com');
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
Loading…
Reference in a new issue