Skip to content

Commit

Permalink
#42: now passing all tests again
Browse files Browse the repository at this point in the history
  • Loading branch information
troygoode committed May 28, 2015
1 parent fcd2b56 commit 8ec22a9
Show file tree
Hide file tree
Showing 4 changed files with 51 additions and 30 deletions.
1 change: 0 additions & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ CORS is a node.js package for providing a [connect](http://www.senchalabs.org/co
```bash
$ npm install
$ npm test
$ npm run lint
```

## Interactive Testing Harness
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ app.listen(80, function(){

## Configuration Options

* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Expects a string (ex: "http://example.com"). Set to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`. Set to `false` to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second.
* `origin`: Configures the **Access-Control-Allow-Origin** CORS header. Expects a string (ex: "http://example.com"). Set to `true` to reflect the [request origin](http://tools.ietf.org/html/draft-abarth-origin-09), as defined by `req.header('Origin')`. Set to `false` to disable CORS. Can also be set to a function, which takes the request origin as the first parameter and a callback (which expects the signature `err [object], allow [bool]`) as the second. Finally, it can also be a regular expression (`/example\.com$/`) or an array of regular expressions and/or strings to match against.
* `methods`: Configures the **Access-Control-Allow-Methods** CORS header. Expects a comma-delimited string (ex: 'GET,PUT,POST') or an array (ex: `['GET', 'PUT', 'POST']`).
* `allowedHeaders`: Configures the **Access-Control-Allow-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Type,Authorization') or an array (ex: `['Content-Type', 'Authorization']`). If not specified, defaults to reflecting the headers specified in the request's **Access-Control-Request-Headers** header.
* `exposedHeaders`: Configures the **Access-Control-Expose-Headers** CORS header. Expects a comma-delimited string (ex: 'Content-Range,X-Content-Range') or an array (ex: `['Content-Range', 'X-Content-Range']`). If not specified, no custom headers are exposed.
Expand Down
63 changes: 35 additions & 28 deletions lib/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,57 +10,64 @@
preflightContinue: false
};

function varyHeadersOn(vary, headers) {
vary = Array.isArray(vary) ? vary : [vary];
headers = Array.isArray(headers) ? headers.slice(0) : [headers];
for (var i = 0; i < vary.length; ++i) {
headers.push({ key: 'Vary', value: vary[i] });
}
return headers;
}

function isString(what) {
return typeof what === 'string' || what instanceof String;
function isString(s) {
return typeof s === 'string' || s instanceof String;
}

function matchOrigin(origin, check) {
if (Array.isArray(check)) {
for (var i = 0; i < check.length; ++i) {
if (matchOrigin(origin, check[i])) {
function isOriginAllowed(origin, allowedOrigin) {
if (Array.isArray(allowedOrigin)) {
for (var i = 0; i < allowedOrigin.length; ++i) {
if (isOriginAllowed(origin, allowedOrigin[i])) {
return true;
}
}
return false;
} else if (isString(check)) {
return origin === check;
} else if (check instanceof RegExp) {
return check.test(origin);
} else if (isString(allowedOrigin)) {
return origin === allowedOrigin;
} else if (allowedOrigin instanceof RegExp) {
return allowedOrigin.test(origin);
} else {
return !!check;
return !!allowedOrigin;
}
}

function configureOrigin(options, req) {
var origin = req.headers.origin;
var requestOrigin = req.headers.origin,
headers = [],
isAllowed;

if (!options.origin || options.origin === '*') {
// allow any origin
return {
headers.push([{
key: 'Access-Control-Allow-Origin',
value: '*'
};
}]);
} else if (isString(options.origin)) {
// fixed origin
return varyHeadersOn('Origin', {
headers.push([{
key: 'Access-Control-Allow-Origin',
value: options.origin
});
}]);
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
} else {
isAllowed = isOriginAllowed(requestOrigin, options.origin);
// reflect origin
return varyHeadersOn('Origin', {
headers.push([{
key: 'Access-Control-Allow-Origin',
value: matchOrigin(origin, options.origin) ? origin : false
});
value: isAllowed ? requestOrigin : false
}]);
if (isAllowed) {
headers.push([{
key: 'Vary',
value: 'Origin'
}]);
}
}

return headers;
}

function configureMethods(options) {
Expand Down
15 changes: 15 additions & 0 deletions test/cors.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@
cors(options)(req, res, function(err) {
should.not.exist(err);
res.getHeader('Access-Control-Allow-Origin').should.equal(req.headers.origin);
should.exist(res.getHeader('Vary'));
res.getHeader('Vary').should.equal('Origin');
return done();
});
Expand All @@ -204,11 +205,24 @@
cors(options)(req, res, function(err) {
should.not.exist(err);
res.getHeader('Access-Control-Allow-Origin').should.equal(req.headers.origin);
should.exist(res.getHeader('Vary'));
res.getHeader('Vary').should.equal('Origin');
return done();
});
});

it('doesn\'t match request origin against array of invalid origin checks', function(done) {
var req = fakeRequest();
var res = fakeResponse();
var options = { origin: [ /foo\.com$/, 'bar.com' ] };
cors(options)(req, res, function(err) {
should.not.exist(err);
should.not.exist(res.getHeader('Access-Control-Allow-Origin'));
should.not.exist(res.getHeader('Vary'));
return done();
});
});

it('origin of false disables cors', function (done) {
// arrange
var req, res, next, options;
Expand Down Expand Up @@ -263,6 +277,7 @@
res = fakeResponse();
next = function () {
// assert
should.exist(res.getHeader('Vary'));
res.getHeader('Vary').should.equal('Origin');
done();
};
Expand Down

0 comments on commit 8ec22a9

Please sign in to comment.