|
"use strict"; |
|
|
|
var defaultParseOptions = { |
|
decodeValues: true, |
|
map: false, |
|
silent: false, |
|
}; |
|
|
|
function isNonEmptyString(str) { |
|
return typeof str === "string" && !!str.trim(); |
|
} |
|
|
|
function parseString(setCookieValue, options) { |
|
var parts = setCookieValue.split(";").filter(isNonEmptyString); |
|
|
|
var nameValuePairStr = parts.shift(); |
|
var parsed = parseNameValuePair(nameValuePairStr); |
|
var name = parsed.name; |
|
var value = parsed.value; |
|
|
|
options = options |
|
? Object.assign({}, defaultParseOptions, options) |
|
: defaultParseOptions; |
|
|
|
try { |
|
value = options.decodeValues ? decodeURIComponent(value) : value; |
|
} catch (e) { |
|
console.error( |
|
"set-cookie-parser encountered an error while decoding a cookie with value '" + |
|
value + |
|
"'. Set options.decodeValues to false to disable this feature.", |
|
e |
|
); |
|
} |
|
|
|
var cookie = { |
|
name: name, |
|
value: value, |
|
}; |
|
|
|
parts.forEach(function (part) { |
|
var sides = part.split("="); |
|
var key = sides.shift().trimLeft().toLowerCase(); |
|
var value = sides.join("="); |
|
if (key === "expires") { |
|
cookie.expires = new Date(value); |
|
} else if (key === "max-age") { |
|
cookie.maxAge = parseInt(value, 10); |
|
} else if (key === "secure") { |
|
cookie.secure = true; |
|
} else if (key === "httponly") { |
|
cookie.httpOnly = true; |
|
} else if (key === "samesite") { |
|
cookie.sameSite = value; |
|
} else { |
|
cookie[key] = value; |
|
} |
|
}); |
|
|
|
return cookie; |
|
} |
|
|
|
function parseNameValuePair(nameValuePairStr) { |
|
|
|
|
|
var name = ""; |
|
var value = ""; |
|
var nameValueArr = nameValuePairStr.split("="); |
|
if (nameValueArr.length > 1) { |
|
name = nameValueArr.shift(); |
|
value = nameValueArr.join("="); |
|
} else { |
|
value = nameValuePairStr; |
|
} |
|
|
|
return { name: name, value: value }; |
|
} |
|
|
|
function parse(input, options) { |
|
options = options |
|
? Object.assign({}, defaultParseOptions, options) |
|
: defaultParseOptions; |
|
|
|
if (!input) { |
|
if (!options.map) { |
|
return []; |
|
} else { |
|
return {}; |
|
} |
|
} |
|
|
|
if (input.headers) { |
|
if (typeof input.headers.getSetCookie === "function") { |
|
|
|
|
|
input = input.headers.getSetCookie(); |
|
} else if (input.headers["set-cookie"]) { |
|
|
|
input = input.headers["set-cookie"]; |
|
} else { |
|
|
|
var sch = |
|
input.headers[ |
|
Object.keys(input.headers).find(function (key) { |
|
return key.toLowerCase() === "set-cookie"; |
|
}) |
|
]; |
|
|
|
if (!sch && input.headers.cookie && !options.silent) { |
|
console.warn( |
|
"Warning: set-cookie-parser appears to have been called on a request object. It is designed to parse Set-Cookie headers from responses, not Cookie headers from requests. Set the option {silent: true} to suppress this warning." |
|
); |
|
} |
|
input = sch; |
|
} |
|
} |
|
if (!Array.isArray(input)) { |
|
input = [input]; |
|
} |
|
|
|
options = options |
|
? Object.assign({}, defaultParseOptions, options) |
|
: defaultParseOptions; |
|
|
|
if (!options.map) { |
|
return input.filter(isNonEmptyString).map(function (str) { |
|
return parseString(str, options); |
|
}); |
|
} else { |
|
var cookies = {}; |
|
return input.filter(isNonEmptyString).reduce(function (cookies, str) { |
|
var cookie = parseString(str, options); |
|
cookies[cookie.name] = cookie; |
|
return cookies; |
|
}, cookies); |
|
} |
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function splitCookiesString(cookiesString) { |
|
if (Array.isArray(cookiesString)) { |
|
return cookiesString; |
|
} |
|
if (typeof cookiesString !== "string") { |
|
return []; |
|
} |
|
|
|
var cookiesStrings = []; |
|
var pos = 0; |
|
var start; |
|
var ch; |
|
var lastComma; |
|
var nextStart; |
|
var cookiesSeparatorFound; |
|
|
|
function skipWhitespace() { |
|
while (pos < cookiesString.length && /\s/.test(cookiesString.charAt(pos))) { |
|
pos += 1; |
|
} |
|
return pos < cookiesString.length; |
|
} |
|
|
|
function notSpecialChar() { |
|
ch = cookiesString.charAt(pos); |
|
|
|
return ch !== "=" && ch !== ";" && ch !== ","; |
|
} |
|
|
|
while (pos < cookiesString.length) { |
|
start = pos; |
|
cookiesSeparatorFound = false; |
|
|
|
while (skipWhitespace()) { |
|
ch = cookiesString.charAt(pos); |
|
if (ch === ",") { |
|
|
|
lastComma = pos; |
|
pos += 1; |
|
|
|
skipWhitespace(); |
|
nextStart = pos; |
|
|
|
while (pos < cookiesString.length && notSpecialChar()) { |
|
pos += 1; |
|
} |
|
|
|
|
|
if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") { |
|
|
|
cookiesSeparatorFound = true; |
|
|
|
pos = nextStart; |
|
cookiesStrings.push(cookiesString.substring(start, lastComma)); |
|
start = pos; |
|
} else { |
|
|
|
|
|
pos = lastComma + 1; |
|
} |
|
} else { |
|
pos += 1; |
|
} |
|
} |
|
|
|
if (!cookiesSeparatorFound || pos >= cookiesString.length) { |
|
cookiesStrings.push(cookiesString.substring(start, cookiesString.length)); |
|
} |
|
} |
|
|
|
return cookiesStrings; |
|
} |
|
|
|
module.exports = parse; |
|
module.exports.parse = parse; |
|
module.exports.parseString = parseString; |
|
module.exports.splitCookiesString = splitCookiesString; |
|
|