Splitting the handlers (preparation for creating a separate "actual" handler)

This commit is contained in:
rprieto 2014-05-08 22:47:51 +10:00
parent 0e5633b2e8
commit a9f370e474
4 changed files with 92 additions and 60 deletions

View file

@ -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 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
View 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
View 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
View 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');
});
});