版博士V2.0程序
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.
 
 
 
 

146 line
4.0 KiB

  1. "use strict";
  2. Object.defineProperty(exports, "__esModule", { value: true });
  3. const CookiePairRegex = /([^=]+)(?:=([\s\S]*))?/;
  4. /**
  5. * Cookie.
  6. */
  7. class Cookie {
  8. /**
  9. * Constructor.
  10. *
  11. * @param cookie Cookie.
  12. */
  13. constructor(cookie) {
  14. this.pairs = {};
  15. //
  16. this.key = '';
  17. this.value = '';
  18. this.size = 0;
  19. // Optional
  20. this.domain = '';
  21. this.path = '';
  22. this.expriesOrMaxAge = null;
  23. this.httpOnly = false;
  24. this.secure = false;
  25. this.sameSite = '';
  26. let match;
  27. const parts = cookie.split(';').filter(Boolean);
  28. // Part[0] is the key-value pair.
  29. match = new RegExp(CookiePairRegex).exec(parts[0]);
  30. if (!match) {
  31. throw new Error(`Invalid cookie: ${cookie}`);
  32. }
  33. this.key = match[1].trim();
  34. this.value = match[2];
  35. // Set key is empty if match[2] is undefined.
  36. if (!match[2]) {
  37. this.value = this.key;
  38. this.key = '';
  39. }
  40. this.pairs[this.key] = this.value;
  41. this.size = this.key.length + this.value.length;
  42. // Attribute.
  43. for (const part of parts.slice(1)) {
  44. match = new RegExp(CookiePairRegex).exec(part);
  45. if (!match) {
  46. throw new Error(`Invalid cookie: ${part}`);
  47. }
  48. const key = match[1].trim();
  49. const value = match[2];
  50. switch (key.toLowerCase()) {
  51. case 'expires':
  52. this.expriesOrMaxAge = new Date(value);
  53. break;
  54. case 'max-age':
  55. this.expriesOrMaxAge = new Date(parseInt(value, 10) * 1000 + Date.now());
  56. break;
  57. case 'domain':
  58. this.domain = value;
  59. break;
  60. case 'path':
  61. this.path = value.startsWith('/') ? value : `/${value}`;
  62. break;
  63. case 'httponly':
  64. this.httpOnly = true;
  65. break;
  66. case 'secure':
  67. this.secure = true;
  68. break;
  69. case 'samesite':
  70. this.sameSite = value;
  71. break;
  72. default:
  73. continue; // Skip.
  74. }
  75. // Skip unknown key-value pair.
  76. if (['expires', 'max-age', 'domain', 'path', 'httponly', 'secure', 'samesite'].indexOf(key.toLowerCase()) === -1) {
  77. continue;
  78. }
  79. this.pairs[key] = value;
  80. }
  81. }
  82. /**
  83. * Returns a raw string of the cookie.
  84. */
  85. rawString() {
  86. return Object.keys(this.pairs)
  87. .map((key) => {
  88. if (key) {
  89. return `${key}=${this.pairs[key]}`;
  90. }
  91. return this.pairs[key];
  92. })
  93. .join('; ');
  94. }
  95. /**
  96. *
  97. */
  98. cookieString() {
  99. if (this.key) {
  100. return `${this.key}=${this.value}`;
  101. }
  102. return this.value;
  103. }
  104. /**
  105. *
  106. */
  107. isExpired() {
  108. // If the expries/maxage is set, then determine whether it is expired.
  109. if (this.expriesOrMaxAge && this.expriesOrMaxAge.getTime() < Date.now()) {
  110. return true;
  111. }
  112. // If the expries/maxage is not set, it's a session-level cookie that will expire when the browser is closed.
  113. // (it's never expired in happy-dom)
  114. return false;
  115. }
  116. /**
  117. *
  118. */
  119. isHttpOnly() {
  120. return this.httpOnly;
  121. }
  122. /**
  123. *
  124. */
  125. isSecure() {
  126. return this.secure;
  127. }
  128. /**
  129. * Parse a cookie string.
  130. *
  131. * @param cookieString
  132. */
  133. static parse(cookieString) {
  134. return new Cookie(cookieString);
  135. }
  136. /**
  137. * Stringify a Cookie object.
  138. *
  139. * @param cookie
  140. */
  141. static stringify(cookie) {
  142. return cookie.toString();
  143. }
  144. }
  145. exports.default = Cookie;
  146. //# sourceMappingURL=Cookie.js.map