You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
/*! * vary * Copyright(c) 2014-2017 Douglas Christopher Wilson * MIT Licensed */
'use strict'
/** * Module exports. */
module.exports = vary module.exports.append = append
/** * RegExp to match field-name in RFC 7230 sec 3.2 * * field-name = token * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" * / DIGIT / ALPHA * ; any VCHAR, except delimiters */
var FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/
/** * Append a field to a vary header. * * @param {String} header * @param {String|Array} field * @return {String} * @public */
function append (header, field) { if (typeof header !== 'string') { throw new TypeError('header argument is required') }
if (!field) { throw new TypeError('field argument is required') }
// get fields array
var fields = !Array.isArray(field) ? parse(String(field)) : field
// assert on invalid field names
for (var j = 0; j < fields.length; j++) { if (!FIELD_NAME_REGEXP.test(fields[j])) { throw new TypeError('field argument contains an invalid header name') } }
// existing, unspecified vary
if (header === '*') { return header }
// enumerate current values
var val = header var vals = parse(header.toLowerCase())
// unspecified vary
if (fields.indexOf('*') !== -1 || vals.indexOf('*') !== -1) { return '*' }
for (var i = 0; i < fields.length; i++) { var fld = fields[i].toLowerCase()
// append value (case-preserving)
if (vals.indexOf(fld) === -1) { vals.push(fld) val = val ? val + ', ' + fields[i] : fields[i] } }
return val }
/** * Parse a vary header into an array. * * @param {String} header * @return {Array} * @private */
function parse (header) { var end = 0 var list = [] var start = 0
// gather tokens
for (var i = 0, len = header.length; i < len; i++) { switch (header.charCodeAt(i)) { case 0x20: /* */ if (start === end) { start = end = i + 1 } break case 0x2c: /* , */ list.push(header.substring(start, end)) start = end = i + 1 break default: end = i + 1 break } }
// final token
list.push(header.substring(start, end))
return list }
/** * Mark that a request is varied on a header field. * * @param {Object} res * @param {String|Array} field * @public */
function vary (res, field) { if (!res || !res.getHeader || !res.setHeader) { // quack quack
throw new TypeError('res argument is required') }
// get existing header
var val = res.getHeader('Vary') || '' var header = Array.isArray(val) ? val.join(', ') : String(val)
// set new header
if ((val = append(header, field))) { res.setHeader('Vary', val) } }
|