UNPKG

@foxify/http

Version:
126 lines 4.2 kB
"use strict"; /** * (The MIT License) * * Copyright (c) 2014-2017 Douglas Christopher Wilson * * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * 'Software'), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: * * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. * IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY * CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /** * This module is modified and optimized for Foxify specifically */ const assert_1 = __importDefault(require("assert")); /** * RegExp to match field-name in RFC 7230 sec 3.2 * * field-name = token * token = 1*tchar * tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" * / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" * / DIGIT / ALPHA * ; any VCHAR, except delimiters */ const FIELD_NAME_REGEXP = /^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/; /** * Parse a vary header into an array. * * @private */ const parse = (header) => { const list = []; let start = 0; let end = 0; // Gather tokens for (let 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; }; /** * Append a field to a vary header. * * @param {String} header * @param {String|Array} field * @return {String} * @public */ const append = (header, field) => { // Get fields array const fields = Array.isArray(field) ? field : parse(String(field)); // Assert on invalid field names // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let j = 0; j < fields.length; j++) { (0, assert_1.default)(FIELD_NAME_REGEXP.test(fields[j]), "Argument 'field' contains an invalid header name"); } // Existing, unspecified vary if (header === "*") return header; // Enumerate current values const vals = parse(header.toLowerCase()); let val = header; // Unspecified vary if (fields.includes("*") || vals.includes("*")) return "*"; // eslint-disable-next-line @typescript-eslint/prefer-for-of for (let i = 0; i < fields.length; i++) { const fld = fields[i].toLowerCase(); // Append value (case-preserving) if (!vals.includes(fld)) { vals.push(fld); val = val ? `${val}, ${fields[i]}` : fields[i]; } } return val; }; /** * Mark that a request is varied on a header field. * * @public */ function vary(res, field) { // Get existing header let value = res.get("vary") ?? ""; const header = Array.isArray(value) ? value.join(", ") : `${value}`; value = append(header, field); // Set new header if (value) res.setHeader("vary", value); return res; } exports.default = vary; //# sourceMappingURL=vary.js.map