'use strict'; /** * Parse the `Sec-WebSocket-Extensions` header into an object. * * @param {String} value field value of the header * @return {Object} The parsed object * @public */ const parse = (value) => { value = value || ''; const extensions = {}; value.split(',').forEach((v) => { const params = v.split(';'); const token = params.shift().trim(); const paramsList = extensions[token] = extensions[token] || []; const parsedParams = {}; params.forEach((param) => { const parts = param.trim().split('='); const key = parts[0]; var value = parts[1]; if (value === undefined) { value = true; } else { // unquote value if (value[0] === '"') { value = value.slice(1); } if (value[value.length - 1] === '"') { value = value.slice(0, value.length - 1); } } (parsedParams[key] = parsedParams[key] || []).push(value); }); paramsList.push(parsedParams); }); return extensions; }; /** * Serialize a parsed `Sec-WebSocket-Extensions` header to a string. * * @param {Object} value The object to format * @return {String} A string representing the given value * @public */ const format = (value) => { return Object.keys(value).map((token) => { var paramsList = value[token]; if (!Array.isArray(paramsList)) paramsList = [paramsList]; return paramsList.map((params) => { return [token].concat(Object.keys(params).map((k) => { var p = params[k]; if (!Array.isArray(p)) p = [p]; return p.map((v) => v === true ? k : `${k}=${v}`).join('; '); })).join('; '); }).join(', '); }).join(', '); }; module.exports = { format, parse };