Skip to content

Commit

Permalink
Support array of fields to set
Browse files Browse the repository at this point in the history
closes #2
  • Loading branch information
dougwilson committed Jun 5, 2014
1 parent 9efe5fe commit 2785675
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 23 deletions.
5 changes: 5 additions & 0 deletions History.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
unreleased
==========

* Support array of fields to set

0.0.0 / 2014-06-04
==================

Expand Down
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,18 @@ $ npm install vary
var vary = require('vary')
```

### vary(res, header)
### vary(res, field)

Adds the given `header` to the `Vary` response header of `res`.
Adds the given header `field` to the `Vary` response header of `res`.
This can be a string of a single field or an array of multiple fields.

This will append the header if not already listed, otherwise leaves
it listed in the current location.

```js
vary(res, 'Origin')
vary(res, 'User-Agent')
vary(res, ['Accept', 'Accept-Language', 'Accept-Encoding'])
```

## Testing
Expand Down
42 changes: 25 additions & 17 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,31 @@ module.exports = vary;
var separators = /[\(\)<>@,;:\\"\/\[\]\?=\{\}\u0020\u0009]/;

/**
* Mark that a request is varied on a header.
* Mark that a request is varied on a header field.
*
* @param {Object} res
* @param {String} header
* @param {String|Array} field
* @api public
*/

function vary(res, header) {
function vary(res, field) {
if (!res || !res.getHeader || !res.setHeader) {
// quack quack
throw new TypeError('res argument is required');
}

if (!header) {
throw new TypeError('header argument is required');
if (!field) {
throw new TypeError('field argument is required');
}

if (separators.test(header)) {
throw new TypeError('header argument is not a valid header');
var fields = !Array.isArray(field)
? [String(field)]
: field;

for (var i = 0; i < fields.length; i++) {
if (separators.test(fields[i])) {
throw new TypeError('field argument contains an invalid header');
}
}

var val = res.getHeader('Vary') || ''
Expand All @@ -52,20 +58,22 @@ function vary(res, header) {
var vals = headers.toLowerCase().split(/ *, */);

// unspecified vary
if (header === '*' || vals.indexOf('*') !== -1) {
if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {
res.setHeader('Vary', '*');
return;
}

if (vals.indexOf(header.toLowerCase()) !== -1) {
// already set
return;
}
for (var i = 0; i < fields.length; i++) {
field = fields[i].toLowerCase();

// append value (case-preserving)
val = headers
? headers + ', ' + header
: header;
// append value (case-preserving)
if (vals.indexOf(field) === -1) {
vals.push(field);
headers = headers
? headers + ', ' + fields[i]
: fields[i];
}
}

res.setHeader('Vary', val);
res.setHeader('Vary', headers);
}
51 changes: 47 additions & 4 deletions test/test.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,27 @@ describe('vary(res, header)', function () {
});
});

describe('header', function () {
describe('field', function () {
it('should be required', function () {
var res = createRes();
vary.bind(null, res).should.throw(/header.*required/);
vary.bind(null, res).should.throw(/field.*required/);
});

it('should accept string', function () {
var res = createRes();
vary.bind(null, res, 'foo').should.not.throw();
});

it('should accept array of string', function () {
var res = createRes();
vary.bind(null, res, ['foo', 'bar']).should.not.throw();
});

it('should not allow separators', function () {
var res = createRes();
vary.bind(null, res, 'invalid:header').should.throw(/header.*not.*valid/);
vary.bind(null, res, 'invalid header').should.throw(/header.*not.*valid/);
vary.bind(null, res, 'invalid:header').should.throw(/field.*contains.*invalid/);
vary.bind(null, res, 'invalid header').should.throw(/field.*contains.*invalid/);
vary.bind(null, res, ['invalid header']).should.throw(/field.*contains.*invalid/);
});
});
});
Expand Down Expand Up @@ -125,6 +136,38 @@ describe('vary(res, header)', function () {
res.getHeader('Vary').should.equal('*');
});
});

describe('when fields is array', function () {
it('should set value', function () {
var res = createRes();
vary(res, ['Accept', 'Accept-Language']);
res.getHeader('Vary').should.equal('Accept, Accept-Language');
});

it('should ignore double-entries', function () {
var res = createRes();
vary(res, ['Accept', 'Accept']);
res.getHeader('Vary').should.equal('Accept');
});

it('should be case-insensitive', function () {
var res = createRes();
vary(res, ['Accept', 'ACCEPT']);
res.getHeader('Vary').should.equal('Accept');
});

it('should handle contained *', function () {
var res = createRes();
vary(res, ['Origin', 'User-Agent', '*', 'Accept']);
res.getHeader('Vary').should.equal('*');
});

it('should handle existing values', function () {
var res = createRes({'vary': 'Accept, Accept-Encoding'});
vary(res, ['origin', 'accept', 'accept-charset']);
res.getHeader('Vary').should.equal('Accept, Accept-Encoding, origin, accept-charset');
});
});
});

function createRes(headers) {
Expand Down

0 comments on commit 2785675

Please sign in to comment.