UNPKG

http-header-list

Version:

Parser and logic functions for HTTP header lists

109 lines (90 loc) 2.38 kB
/** @typedef {object} HeaderValue * * @property {string} value Option value * @property {number} weight Weight of option * @property {{[key: string]: string}} parameters Option parameters */ /** @constructor * Create a parse header object that contains the parsed header * * @param {string} header Header value to parse */ export function HeaderList(header) { if (typeof header !== 'string') { throw new Error('headerValue should be a string'); } /** * The original header value */ this.header = header; /** @type {HeaderValue[]} * The parsed and sorted list of header values. The header values are * sorted in descending order by the weight factor, q. If a header value * does not have a weight factor, it will default to 1 */ this.list; if (!header) { this.list = []; return; } const headerParts = header.split(/ *, */); const headerOptions = []; for (let i = 0; i < headerParts.length; i++) { const parts = headerParts[i].split(/ *; */); const option = { value: parts.shift(), weight: 1, parameters: {} }; for (let j = 0; j < parts.length; j++) { const parameters = parts[j].split(/ *= */); if (parameters[0] === 'q') { const weight = Number(parameters[1]); if (!isNaN(weight)) { option.weight = weight; } } else { option.parameters[parameters[0]] = parameters[1]; } } headerOptions.push(option); } headerOptions.sort((a, b) => { if (a.weight < b.weight) { return 1; } if (a.weight > b.weight) { return -1; } return 0; }); this.list = headerOptions; } /** * Find the first matching value that matches one of the values in the * given array * * @param {string[]} possibleValues Possible values to match against */ HeaderList.prototype.firstMatch = function firstMatch(possibleValues) { for (let i = 0; i < this.list.length; i++) { if (possibleValues.indexOf(this.list[i].value) !== -1) { return this.list[i]; } } }; /** * Parse the given header and find the first matching value * * @param {string} header Header value to parse * @param {string[]} possibleValues Possible values to match on * * @returns {HeaderValue} The first matching header value */ export const firstHeaderMatch = (header, possibleValues) => { if (!header) { return null; } const list = new HeaderList(header); return list.firstMatch(possibleValues); };