3 * Copyright(c) 2014-2015 Douglas Christopher Wilson
13 module.exports = vary;
14 module.exports.append = append;
20 var separators = /[\(\)<>@,;:\\"\/\[\]\?=\{\}\u0020\u0009]/;
23 * Append a field to a vary header.
25 * @param {String} header
26 * @param {String|Array} field
31 function append(header, field) {
32 if (typeof header !== 'string') {
33 throw new TypeError('header argument is required');
37 throw new TypeError('field argument is required');
41 var fields = !Array.isArray(field)
42 ? parse(String(field))
45 // assert on invalid fields
46 for (var i = 0; i < fields.length; i++) {
47 if (separators.test(fields[i])) {
48 throw new TypeError('field argument contains an invalid header');
52 // existing, unspecified vary
57 // enumerate current values
59 var vals = parse(header.toLowerCase());
62 if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) {
66 for (var i = 0; i < fields.length; i++) {
67 var fld = fields[i].toLowerCase();
69 // append value (case-preserving)
70 if (vals.indexOf(fld) === -1) {
73 ? val + ', ' + fields[i]
82 * Parse a vary header into an array.
84 * @param {String} header
89 function parse(header) {
90 return header.trim().split(/ *, */);
94 * Mark that a request is varied on a header field.
97 * @param {String|Array} field
101 function vary(res, field) {
102 if (!res || !res.getHeader || !res.setHeader) {
104 throw new TypeError('res argument is required');
107 // get existing header
108 var val = res.getHeader('Vary') || ''
109 var header = Array.isArray(val)
114 if ((val = append(header, field))) {
115 res.setHeader('Vary', val);