You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							221 lines
						
					
					
						
							6.2 KiB
						
					
					
				
			
		
		
	
	
							221 lines
						
					
					
						
							6.2 KiB
						
					
					
				"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; // decode cookie 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) {
 | 
						|
  // Parses name-value-pair according to rfc6265bis draft
 | 
						|
 | 
						|
  var name = "";
 | 
						|
  var value = "";
 | 
						|
  var nameValueArr = nameValuePairStr.split("=");
 | 
						|
  if (nameValueArr.length > 1) {
 | 
						|
    name = nameValueArr.shift();
 | 
						|
    value = nameValueArr.join("="); // everything after the first =, joined by a "=" if there was more than one part
 | 
						|
  } 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 && input.headers["set-cookie"]) {
 | 
						|
    // fast-path for node.js (which automatically normalizes header names to lower-case
 | 
						|
    input = input.headers["set-cookie"];
 | 
						|
  } else if (input.headers) {
 | 
						|
    // slow-path for other environments - see #25
 | 
						|
    var sch =
 | 
						|
      input.headers[
 | 
						|
        Object.keys(input.headers).find(function (key) {
 | 
						|
          return key.toLowerCase() === "set-cookie";
 | 
						|
        })
 | 
						|
      ];
 | 
						|
    // warn if called on a request-like object with a cookie header rather than a set-cookie header - see #34, 36
 | 
						|
    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);
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
/*
 | 
						|
  Set-Cookie header field-values are sometimes comma joined in one string. This splits them without choking on commas
 | 
						|
  that are within a single set-cookie field-value, such as in the Expires portion.
 | 
						|
 | 
						|
  This is uncommon, but explicitly allowed - see https://tools.ietf.org/html/rfc2616#section-4.2
 | 
						|
  Node.js does this for every header *except* set-cookie - see https://github.com/nodejs/node/blob/d5e363b77ebaf1caf67cd7528224b651c86815c1/lib/_http_incoming.js#L128
 | 
						|
  React Native's fetch does this for *every* header, including set-cookie.
 | 
						|
 | 
						|
  Based on: https://github.com/google/j2objc/commit/16820fdbc8f76ca0c33472810ce0cb03d20efe25
 | 
						|
  Credits to: https://github.com/tomball for original and https://github.com/chrusart for JavaScript implementation
 | 
						|
*/
 | 
						|
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 === ",") {
 | 
						|
        // ',' is a cookie separator if we have later first '=', not ';' or ','
 | 
						|
        lastComma = pos;
 | 
						|
        pos += 1;
 | 
						|
 | 
						|
        skipWhitespace();
 | 
						|
        nextStart = pos;
 | 
						|
 | 
						|
        while (pos < cookiesString.length && notSpecialChar()) {
 | 
						|
          pos += 1;
 | 
						|
        }
 | 
						|
 | 
						|
        // currently special character
 | 
						|
        if (pos < cookiesString.length && cookiesString.charAt(pos) === "=") {
 | 
						|
          // we found cookies separator
 | 
						|
          cookiesSeparatorFound = true;
 | 
						|
          // pos is inside the next cookie, so back up and return it.
 | 
						|
          pos = nextStart;
 | 
						|
          cookiesStrings.push(cookiesString.substring(start, lastComma));
 | 
						|
          start = pos;
 | 
						|
        } else {
 | 
						|
          // in param ',' or param separator ';',
 | 
						|
          // we continue from that comma
 | 
						|
          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;
 |