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');
|
||||
|
||||
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);
|
||||
};
|
||||
}
|
||||
var util = require('util');
|
||||
var restify = require('restify');
|
||||
var preflight = require('./preflight');
|
||||
|
||||
module.exports = function(options) {
|
||||
|
||||
|
@ -71,7 +15,7 @@ module.exports = function(options) {
|
|||
headers: options.exposeHeaders
|
||||
}),
|
||||
|
||||
preflight: preflightHandler({
|
||||
preflight: preflight.handler({
|
||||
origins: options.origins,
|
||||
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