The LM Control website. Simple yet efficient.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

index.js 4.0KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. /*!
  2. * cookie
  3. * Copyright(c) 2012-2014 Roman Shtylman
  4. * Copyright(c) 2015 Douglas Christopher Wilson
  5. * MIT Licensed
  6. */
  7. 'use strict';
  8. /**
  9. * Module exports.
  10. * @public
  11. */
  12. exports.parse = parse;
  13. exports.serialize = serialize;
  14. /**
  15. * Module variables.
  16. * @private
  17. */
  18. var decode = decodeURIComponent;
  19. var encode = encodeURIComponent;
  20. var pairSplitRegExp = /; */;
  21. /**
  22. * RegExp to match field-content in RFC 7230 sec 3.2
  23. *
  24. * field-content = field-vchar [ 1*( SP / HTAB ) field-vchar ]
  25. * field-vchar = VCHAR / obs-text
  26. * obs-text = %x80-FF
  27. */
  28. var fieldContentRegExp = /^[\u0009\u0020-\u007e\u0080-\u00ff]+$/;
  29. /**
  30. * Parse a cookie header.
  31. *
  32. * Parse the given cookie header string into an object
  33. * The object has the various cookies as keys(names) => values
  34. *
  35. * @param {string} str
  36. * @param {object} [options]
  37. * @return {object}
  38. * @public
  39. */
  40. function parse(str, options) {
  41. if (typeof str !== 'string') {
  42. throw new TypeError('argument str must be a string');
  43. }
  44. var obj = {}
  45. var opt = options || {};
  46. var pairs = str.split(pairSplitRegExp);
  47. var dec = opt.decode || decode;
  48. for (var i = 0; i < pairs.length; i++) {
  49. var pair = pairs[i];
  50. var eq_idx = pair.indexOf('=');
  51. // skip things that don't look like key=value
  52. if (eq_idx < 0) {
  53. continue;
  54. }
  55. var key = pair.substr(0, eq_idx).trim()
  56. var val = pair.substr(++eq_idx, pair.length).trim();
  57. // quoted values
  58. if ('"' == val[0]) {
  59. val = val.slice(1, -1);
  60. }
  61. // only assign once
  62. if (undefined == obj[key]) {
  63. obj[key] = tryDecode(val, dec);
  64. }
  65. }
  66. return obj;
  67. }
  68. /**
  69. * Serialize data into a cookie header.
  70. *
  71. * Serialize the a name value pair into a cookie string suitable for
  72. * http headers. An optional options object specified cookie parameters.
  73. *
  74. * serialize('foo', 'bar', { httpOnly: true })
  75. * => "foo=bar; httpOnly"
  76. *
  77. * @param {string} name
  78. * @param {string} val
  79. * @param {object} [options]
  80. * @return {string}
  81. * @public
  82. */
  83. function serialize(name, val, options) {
  84. var opt = options || {};
  85. var enc = opt.encode || encode;
  86. if (typeof enc !== 'function') {
  87. throw new TypeError('option encode is invalid');
  88. }
  89. if (!fieldContentRegExp.test(name)) {
  90. throw new TypeError('argument name is invalid');
  91. }
  92. var value = enc(val);
  93. if (value && !fieldContentRegExp.test(value)) {
  94. throw new TypeError('argument val is invalid');
  95. }
  96. var str = name + '=' + value;
  97. if (null != opt.maxAge) {
  98. var maxAge = opt.maxAge - 0;
  99. if (isNaN(maxAge) || !isFinite(maxAge)) {
  100. throw new TypeError('option maxAge is invalid')
  101. }
  102. str += '; Max-Age=' + Math.floor(maxAge);
  103. }
  104. if (opt.domain) {
  105. if (!fieldContentRegExp.test(opt.domain)) {
  106. throw new TypeError('option domain is invalid');
  107. }
  108. str += '; Domain=' + opt.domain;
  109. }
  110. if (opt.path) {
  111. if (!fieldContentRegExp.test(opt.path)) {
  112. throw new TypeError('option path is invalid');
  113. }
  114. str += '; Path=' + opt.path;
  115. }
  116. if (opt.expires) {
  117. if (typeof opt.expires.toUTCString !== 'function') {
  118. throw new TypeError('option expires is invalid');
  119. }
  120. str += '; Expires=' + opt.expires.toUTCString();
  121. }
  122. if (opt.httpOnly) {
  123. str += '; HttpOnly';
  124. }
  125. if (opt.secure) {
  126. str += '; Secure';
  127. }
  128. if (opt.sameSite) {
  129. var sameSite = typeof opt.sameSite === 'string'
  130. ? opt.sameSite.toLowerCase() : opt.sameSite;
  131. switch (sameSite) {
  132. case true:
  133. str += '; SameSite=Strict';
  134. break;
  135. case 'lax':
  136. str += '; SameSite=Lax';
  137. break;
  138. case 'strict':
  139. str += '; SameSite=Strict';
  140. break;
  141. case 'none':
  142. str += '; SameSite=None';
  143. break;
  144. default:
  145. throw new TypeError('option sameSite is invalid');
  146. }
  147. }
  148. return str;
  149. }
  150. /**
  151. * Try decoding a string using a decoding function.
  152. *
  153. * @param {string} str
  154. * @param {function} decode
  155. * @private
  156. */
  157. function tryDecode(str, decode) {
  158. try {
  159. return decode(str);
  160. } catch (e) {
  161. return str;
  162. }
  163. }