tough-cookie 2.0.0 → 2.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE CHANGED
@@ -17,58 +17,11 @@ The following exceptions apply:
17
17
 
18
18
  ===
19
19
 
20
- `pubSufTest()` of generate-pubsuffix.js is in the public domain.
21
-
22
- // Any copyright is dedicated to the Public Domain.
23
- // http://creativecommons.org/publicdomain/zero/1.0/
24
-
25
- ===
26
-
27
- `public-suffix.txt` was obtained from
28
- <https://mxr.mozilla.org/mozilla-central/source/netwerk/dns/effective_tld_names.dat?raw=1>
29
- via <http://publicsuffix.org>.
30
-
31
- That file contains the usual Mozilla triple-license, for which this project uses it
32
- under the terms of the MPL 1.1:
33
-
34
- // ***** BEGIN LICENSE BLOCK *****
35
- // Version: MPL 1.1/GPL 2.0/LGPL 2.1
36
- //
37
- // The contents of this file are subject to the Mozilla Public License Version
38
- // 1.1 (the "License"); you may not use this file except in compliance with
39
- // the License. You may obtain a copy of the License at
40
- // http://www.mozilla.org/MPL/
41
- //
42
- // Software distributed under the License is distributed on an "AS IS" basis,
43
- // WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
44
- // for the specific language governing rights and limitations under the
45
- // License.
46
- //
47
- // The Original Code is the Public Suffix List.
48
- //
49
- // The Initial Developer of the Original Code is
50
- // Jo Hermans <jo.hermans@gmail.com>.
51
- // Portions created by the Initial Developer are Copyright (C) 2007
52
- // the Initial Developer. All Rights Reserved.
53
- //
54
- // Contributor(s):
55
- // Ruben Arakelyan <ruben@rubenarakelyan.com>
56
- // Gervase Markham <gerv@gerv.net>
57
- // Pamela Greene <pamg.bugs@gmail.com>
58
- // David Triendl <david@triendl.name>
59
- // Jothan Frakes <jothan@gmail.com>
60
- // The kind representatives of many TLD registries
61
- //
62
- // Alternatively, the contents of this file may be used under the terms of
63
- // either the GNU General Public License Version 2 or later (the "GPL"), or
64
- // the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
65
- // in which case the provisions of the GPL or the LGPL are applicable instead
66
- // of those above. If you wish to allow use of your version of this file only
67
- // under the terms of either the GPL or the LGPL, and not to allow others to
68
- // use your version of this file under the terms of the MPL, indicate your
69
- // decision by deleting the provisions above and replace them with the notice
70
- // and other provisions required by the GPL or the LGPL. If you do not delete
71
- // the provisions above, a recipient may use your version of this file under
72
- // the terms of any one of the MPL, the GPL or the LGPL.
73
- //
74
- // ***** END LICENSE BLOCK *****
20
+ `public_suffix_list.dat` was obtained from
21
+ <https://publicsuffix.org/list/public_suffix_list.dat> via
22
+ <http://publicsuffix.org>. The license for this file is MPL/2.0. The header of
23
+ that file reads as follows:
24
+
25
+ // This Source Code Form is subject to the terms of the Mozilla Public
26
+ // License, v. 2.0. If a copy of the MPL was not distributed with this
27
+ // file, You can obtain one at http://mozilla.org/MPL/2.0/.
package/README.md CHANGED
@@ -68,9 +68,9 @@ Answers "does the request-path path-match a given cookie-path?" as per RFC6265 S
68
68
 
69
69
  This is essentially a prefix-match where `cookiePath` is a prefix of `reqPath`.
70
70
 
71
- ### `parse(header)`
71
+ ### `parse(cookieString[, options])`
72
72
 
73
- alias for `Cookie.parse(header)`
73
+ alias for `Cookie.parse(cookieString[, options])`
74
74
 
75
75
  ### `fromJSON(string)`
76
76
 
@@ -112,15 +112,21 @@ Generates a list of all possible paths that `pathMatch()` the parameter. May be
112
112
 
113
113
  Exported via `tough.Cookie`.
114
114
 
115
- ### `Cookie.parse(header)`
115
+ ### `Cookie.parse(cookieString[, options])`
116
116
 
117
117
  Parses a single Cookie or Set-Cookie HTTP header into a `Cookie` object. Returns `undefined` if the string can't be parsed.
118
118
 
119
+ The options parameter is not required and currently has only one property:
120
+
121
+ * _loose_ - boolean - if `true` enable parsing of key-less cookies like `=abc` and `=`, which are not RFC-compliant.
122
+
123
+ If options is not an object, it is ignored, which means you can use `Array#map` with it.
124
+
119
125
  Here's how to process the Set-Cookie header(s) on a node HTTP/HTTPS response:
120
126
 
121
127
  ``` javascript
122
128
  if (res.headers['set-cookie'] instanceof Array)
123
- cookies = res.headers['set-cookie'].map(function (c) { return (Cookie.parse(c)); });
129
+ cookies = res.headers['set-cookie'].map(Cookie.parse);
124
130
  else
125
131
  cookies = [Cookie.parse(res.headers['set-cookie'])];
126
132
  ```
@@ -231,15 +237,15 @@ if (cookie.validate() === true) {
231
237
 
232
238
  Exported via `tough.CookieJar`.
233
239
 
234
- ### `CookieJar([store],[rejectPublicSuffixes])`
240
+ ### `CookieJar([store],[options])`
235
241
 
236
242
  Simply use `new CookieJar()`. If you'd like to use a custom store, pass that to the constructor otherwise a `MemoryCookieStore` will be created and used.
237
243
 
238
- ### Properties
239
-
240
- CookieJar object properties:
244
+ The `options` object can be omitted and can have the following properties:
241
245
 
242
- * _rejectPublicSuffixes_ - boolean - reject cookies with domains like "com" and "co.uk" (default: `true`)
246
+ * _rejectPublicSuffixes_ - boolean - default `true` - reject cookies with domains like "com" and "co.uk"
247
+ * _looseMode_ - boolean - default `false` - accept malformed cookies like `bar` and `=bar`, which have an implied empty name.
248
+ This is not in the standard, but is used sometimes on the web and is accepted by (most) browsers.
243
249
 
244
250
  Since eventually this module would like to support database/remote/etc. CookieJars, continuation passing style is used for CookieJar methods.
245
251
 
@@ -450,7 +456,7 @@ A just-in-memory CookieJar synchronous store implementation, used by default. De
450
456
 
451
457
  # Copyright and License
452
458
 
453
- (tl;dr: BSD-3-Clause with some MPL/1.1)
459
+ (tl;dr: BSD-3-Clause with some MPL/2.0)
454
460
 
455
461
  ```text
456
462
  Copyright (c) 2015, Salesforce.com, Inc.
@@ -483,4 +489,4 @@ A just-in-memory CookieJar synchronous store implementation, used by default. De
483
489
  POSSIBILITY OF SUCH DAMAGE.
484
490
  ```
485
491
 
486
- Portions may be licensed under different licenses (in particular public-suffix.txt is MPL/1.1); please read the LICENSE file for full details.
492
+ Portions may be licensed under different licenses (in particular `public_suffix_list.dat` is MPL/2.0); please read that file and the LICENSE file for full details.
package/lib/cookie.js CHANGED
@@ -49,14 +49,20 @@ var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
49
49
  // From RFC6265 S4.1.1
50
50
  // note that it excludes \x3B ";"
51
51
  var COOKIE_OCTET = /[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/;
52
- var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'$');
52
+ var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$');
53
+
54
+ var CONTROL_CHARS = /[\x00-\x1F]/;
53
55
 
54
56
  // Double quotes are part of the value (see: S4.1.1).
55
57
  // '\r', '\n' and '\0' should be treated as a terminator in the "relaxed" mode
56
58
  // (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60)
57
59
  // '=' and ';' are attribute/values separators
58
60
  // (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64)
59
- var COOKIE_PAIR = /^([^=;]+)\s*=\s*(("?)[^\n\r\0]*\3)/;
61
+ var COOKIE_PAIR = /^(([^=;]+))\s*=\s*([^\n\r\0]*)/;
62
+
63
+ // Used to parse non-RFC-compliant cookies like '=abc' when given the `loose`
64
+ // option in Cookie.parse:
65
+ var LOOSE_COOKIE_PAIR = /^((?:=)?([^=;]*)\s*=\s*)?([^\n\r\0]*)/;
60
66
 
61
67
  // RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"'
62
68
  // Note ';' is \x3B
@@ -315,7 +321,10 @@ function defaultPath(path) {
315
321
  }
316
322
 
317
323
 
318
- function parse(str) {
324
+ function parse(str, options) {
325
+ if (!options || typeof options !== 'object') {
326
+ options = {};
327
+ }
319
328
  str = str.trim();
320
329
 
321
330
  // S4.1.1 Trailing semi-colons are not part of the specification.
@@ -326,7 +335,8 @@ function parse(str) {
326
335
 
327
336
  // We use a regex to parse the "name-value-pair" part of S5.2
328
337
  var firstSemi = str.indexOf(';'); // S5.2 step 1
329
- var result = COOKIE_PAIR.exec(firstSemi === -1 ? str : str.substr(0,firstSemi));
338
+ var pairRe = options.loose ? LOOSE_COOKIE_PAIR : COOKIE_PAIR;
339
+ var result = pairRe.exec(firstSemi === -1 ? str : str.substr(0,firstSemi));
330
340
 
331
341
  // Rx satisfies the "the name string is empty" and "lacks a %x3D ("=")"
332
342
  // constraints as well as trimming any whitespace.
@@ -335,8 +345,15 @@ function parse(str) {
335
345
  }
336
346
 
337
347
  var c = new Cookie();
338
- c.key = result[1].trim();
339
- c.value = result[2].trim();
348
+ if (result[1]) {
349
+ c.key = result[2].trim();
350
+ } else {
351
+ c.key = '';
352
+ }
353
+ c.value = result[3].trim();
354
+ if (CONTROL_CHARS.test(c.key) || CONTROL_CHARS.test(c.value)) {
355
+ return;
356
+ }
340
357
 
341
358
  if (firstSemi === -1) {
342
359
  return c;
@@ -586,15 +603,15 @@ function getCookieContext(url) {
586
603
  return urlParse(url);
587
604
  }
588
605
 
589
- function Cookie(opts) {
590
- opts = opts || {};
606
+ function Cookie(options) {
607
+ options = options || {};
591
608
 
592
- Object.keys(opts).forEach(function(prop) {
609
+ Object.keys(options).forEach(function(prop) {
593
610
  if (Cookie.prototype.hasOwnProperty(prop) &&
594
- Cookie.prototype[prop] !== opts[prop] &&
611
+ Cookie.prototype[prop] !== options[prop] &&
595
612
  prop.substr(0,1) !== '_')
596
613
  {
597
- this[prop] = opts[prop];
614
+ this[prop] = options[prop];
598
615
  }
599
616
  }, this);
600
617
 
@@ -745,6 +762,9 @@ Cookie.prototype.cookieString = function cookieString() {
745
762
  if (val == null) {
746
763
  val = '';
747
764
  }
765
+ if (this.key === '') {
766
+ return val;
767
+ }
748
768
  return this.key+'='+val;
749
769
  };
750
770
 
@@ -858,9 +878,17 @@ Cookie.prototype.canonicalizedDomain = function canonicalizedDomain() {
858
878
  return canonicalDomain(this.domain);
859
879
  };
860
880
 
861
- function CookieJar(store, rejectPublicSuffixes) {
862
- if (rejectPublicSuffixes != null) {
863
- this.rejectPublicSuffixes = rejectPublicSuffixes;
881
+ function CookieJar(store, options) {
882
+ if (typeof options === "boolean") {
883
+ options = {rejectPublicSuffixes: options};
884
+ } else if (options == null) {
885
+ options = {};
886
+ }
887
+ if (options.rejectPublicSuffixes != null) {
888
+ this.rejectPublicSuffixes = options.rejectPublicSuffixes;
889
+ }
890
+ if (options.looseMode != null) {
891
+ this.enableLooseMode = options.looseMode;
864
892
  }
865
893
 
866
894
  if (!store) {
@@ -870,6 +898,7 @@ function CookieJar(store, rejectPublicSuffixes) {
870
898
  }
871
899
  CookieJar.prototype.store = null;
872
900
  CookieJar.prototype.rejectPublicSuffixes = true;
901
+ CookieJar.prototype.enableLooseMode = false;
873
902
  var CAN_BE_SYNC = [];
874
903
 
875
904
  CAN_BE_SYNC.push('setCookie');
@@ -882,10 +911,14 @@ CookieJar.prototype.setCookie = function(cookie, url, options, cb) {
882
911
  }
883
912
 
884
913
  var host = canonicalDomain(context.hostname);
914
+ var loose = this.enableLooseMode;
915
+ if (options.loose != null) {
916
+ loose = options.loose;
917
+ }
885
918
 
886
919
  // S5.3 step 1
887
920
  if (!(cookie instanceof Cookie)) {
888
- cookie = Cookie.parse(cookie);
921
+ cookie = Cookie.parse(cookie, { loose: loose });
889
922
  }
890
923
  if (!cookie) {
891
924
  err = new Error("Cookie failed to parse");
@@ -1232,7 +1265,6 @@ CookieJar.deserialize = function(strOrObj, store, cb) {
1232
1265
  });
1233
1266
  };
1234
1267
 
1235
- CookieJar.fromJSON = CookieJar.deserializeSync;
1236
1268
  CookieJar.deserializeSync = function(strOrObj, store) {
1237
1269
  var serialized = typeof strOrObj === 'string' ?
1238
1270
  JSON.parse(strOrObj) : strOrObj;
@@ -1246,6 +1278,7 @@ CookieJar.deserializeSync = function(strOrObj, store) {
1246
1278
  jar._importCookiesSync(serialized);
1247
1279
  return jar;
1248
1280
  };
1281
+ CookieJar.fromJSON = CookieJar.deserializeSync;
1249
1282
 
1250
1283
  CAN_BE_SYNC.push('clone');
1251
1284
  CookieJar.prototype.clone = function(newStore, cb) {