summaryrefslogtreecommitdiffstats
path: root/middleware/node_modules/vary/index.js
diff options
context:
space:
mode:
Diffstat (limited to 'middleware/node_modules/vary/index.js')
-rw-r--r--middleware/node_modules/vary/index.js149
1 files changed, 149 insertions, 0 deletions
diff --git a/middleware/node_modules/vary/index.js b/middleware/node_modules/vary/index.js
new file mode 100644
index 0000000..5b5e741
--- /dev/null
+++ b/middleware/node_modules/vary/index.js
@@ -0,0 +1,149 @@
+/*!
+ * 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)
+ }
+}