tough-cookie 2.3.3 → 2.5.0
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 +0 -15
- package/README.md +28 -10
- package/lib/cookie.js +253 -112
- package/lib/memstore.js +11 -0
- package/lib/permuteDomain.js +1 -1
- package/lib/pubsuffix-psl.js +38 -0
- package/lib/store.js +4 -0
- package/lib/version.js +2 -0
- package/package.json +10 -6
- package/lib/pubsuffix.js +0 -98
package/LICENSE
CHANGED
|
@@ -10,18 +10,3 @@ Redistribution and use in source and binary forms, with or without modification,
|
|
|
10
10
|
3. Neither the name of Salesforce.com nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
|
|
11
11
|
|
|
12
12
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
13
|
-
|
|
14
|
-
===
|
|
15
|
-
|
|
16
|
-
The following exceptions apply:
|
|
17
|
-
|
|
18
|
-
===
|
|
19
|
-
|
|
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
|
@@ -57,7 +57,7 @@ Transforms a domain-name into a canonical domain-name. The canonical domain-nam
|
|
|
57
57
|
|
|
58
58
|
Answers "does this real domain match the domain in a cookie?". The `str` is the "current" domain-name and the `domStr` is the "cookie" domain-name. Matches according to RFC6265 Section 5.1.3, but it helps to think of it as a "suffix match".
|
|
59
59
|
|
|
60
|
-
The `canonicalize` parameter will run the other two
|
|
60
|
+
The `canonicalize` parameter will run the other two parameters through `canonicalDomain` or not.
|
|
61
61
|
|
|
62
62
|
### `defaultPath(path)`
|
|
63
63
|
|
|
@@ -85,7 +85,7 @@ Returns the public suffix of this hostname. The public suffix is the shortest d
|
|
|
85
85
|
|
|
86
86
|
For example: `www.example.com` and `www.subdomain.example.com` both have public suffix `example.com`.
|
|
87
87
|
|
|
88
|
-
For further information, see http://publicsuffix.org/. This module derives its list from that site.
|
|
88
|
+
For further information, see http://publicsuffix.org/. This module derives its list from that site. This call is currently a wrapper around [`psl`](https://www.npmjs.com/package/psl)'s [get() method](https://www.npmjs.com/package/psl#pslgetdomain).
|
|
89
89
|
|
|
90
90
|
### `cookieCompare(a,b)`
|
|
91
91
|
|
|
@@ -134,7 +134,7 @@ else
|
|
|
134
134
|
cookies = [Cookie.parse(res.headers['set-cookie'])];
|
|
135
135
|
```
|
|
136
136
|
|
|
137
|
-
|
|
137
|
+
_Note:_ in version 2.3.3, tough-cookie limited the number of spaces before the `=` to 256 characters. This limitation has since been removed.
|
|
138
138
|
See [Issue 92](https://github.com/salesforce/tough-cookie/issues/92)
|
|
139
139
|
|
|
140
140
|
### Properties
|
|
@@ -186,7 +186,7 @@ sets the maxAge in seconds. Coerces `-Infinity` to `"-Infinity"` and `Infinity`
|
|
|
186
186
|
|
|
187
187
|
expiryTime() Computes the absolute unix-epoch milliseconds that this cookie expires. expiryDate() works similarly, except it returns a `Date` object. Note that in both cases the `now` parameter should be milliseconds.
|
|
188
188
|
|
|
189
|
-
Max-Age takes precedence over Expires (as per the RFC). The `.creation` attribute -- or, by default, the `now`
|
|
189
|
+
Max-Age takes precedence over Expires (as per the RFC). The `.creation` attribute -- or, by default, the `now` parameter -- is used to offset the `.maxAge` attribute.
|
|
190
190
|
|
|
191
191
|
If Expires (`.expires`) is set, that's returned.
|
|
192
192
|
|
|
@@ -198,7 +198,7 @@ compute the TTL relative to `now` (milliseconds). The same precedence rules as
|
|
|
198
198
|
|
|
199
199
|
The "number" `Infinity` is returned for cookies without an explicit expiry and `0` is returned if the cookie is expired. Otherwise a time-to-live in milliseconds is returned.
|
|
200
200
|
|
|
201
|
-
### `.
|
|
201
|
+
### `.canonicalizedDomain()`
|
|
202
202
|
|
|
203
203
|
### `.cdomain()`
|
|
204
204
|
|
|
@@ -354,6 +354,16 @@ The `store` argument is optional, but must be a _synchronous_ `Store` instance i
|
|
|
354
354
|
|
|
355
355
|
The _source_ and _destination_ must both be synchronous `Store`s. If one or both stores are asynchronous, use `.clone` instead. Recall that `MemoryCookieStore` supports both synchronous and asynchronous API calls.
|
|
356
356
|
|
|
357
|
+
### `.removeAllCookies(cb(err))`
|
|
358
|
+
|
|
359
|
+
Removes all cookies from the jar.
|
|
360
|
+
|
|
361
|
+
This is a new backwards-compatible feature of `tough-cookie` version 2.5, so not all Stores will implement it efficiently. For Stores that do not implement `removeAllCookies`, the fallback is to call `removeCookie` after `getAllCookies`. If `getAllCookies` fails or isn't implemented in the Store, that error is returned. If one or more of the `removeCookie` calls fail, only the first error is returned.
|
|
362
|
+
|
|
363
|
+
### `.removeAllCookiesSync()`
|
|
364
|
+
|
|
365
|
+
Sync version of `.removeAllCookies()`
|
|
366
|
+
|
|
357
367
|
## Store
|
|
358
368
|
|
|
359
369
|
Base class for CookieJar stores. Available as `tough.Store`.
|
|
@@ -418,19 +428,29 @@ Removes matching cookies from the store. The `path` parameter is optional, and
|
|
|
418
428
|
|
|
419
429
|
Pass an error ONLY if removing any existing cookies failed.
|
|
420
430
|
|
|
431
|
+
### `store.removeAllCookies(cb(err))`
|
|
432
|
+
|
|
433
|
+
_Optional_. Removes all cookies from the store.
|
|
434
|
+
|
|
435
|
+
Pass an error if one or more cookies can't be removed.
|
|
436
|
+
|
|
437
|
+
**Note**: New method as of `tough-cookie` version 2.5, so not all Stores will implement this, plus some stores may choose not to implement this.
|
|
438
|
+
|
|
421
439
|
### `store.getAllCookies(cb(err, cookies))`
|
|
422
440
|
|
|
423
|
-
Produces an `Array` of all cookies during `jar.serialize()`. The items in the array can be true `Cookie` objects or generic `Object`s with the [Serialization Format] data structure.
|
|
441
|
+
_Optional_. Produces an `Array` of all cookies during `jar.serialize()`. The items in the array can be true `Cookie` objects or generic `Object`s with the [Serialization Format] data structure.
|
|
424
442
|
|
|
425
443
|
Cookies SHOULD be returned in creation order to preserve sorting via `compareCookies()`. For reference, `MemoryCookieStore` will sort by `.creationIndex` since it uses true `Cookie` objects internally. If you don't return the cookies in creation order, they'll still be sorted by creation time, but this only has a precision of 1ms. See `compareCookies` for more detail.
|
|
426
444
|
|
|
427
445
|
Pass an error if retrieval fails.
|
|
428
446
|
|
|
447
|
+
**Note**: not all Stores can implement this due to technical limitations, so it is optional.
|
|
448
|
+
|
|
429
449
|
## MemoryCookieStore
|
|
430
450
|
|
|
431
451
|
Inherits from `Store`.
|
|
432
452
|
|
|
433
|
-
A just-in-memory CookieJar synchronous store implementation, used by default. Despite being a synchronous implementation, it's usable with both the synchronous and asynchronous forms of the `CookieJar` API.
|
|
453
|
+
A just-in-memory CookieJar synchronous store implementation, used by default. Despite being a synchronous implementation, it's usable with both the synchronous and asynchronous forms of the `CookieJar` API. Supports serialization, `getAllCookies`, and `removeAllCookies`.
|
|
434
454
|
|
|
435
455
|
## Community Cookie Stores
|
|
436
456
|
|
|
@@ -473,7 +493,7 @@ These are some Store implementations authored and maintained by the community. T
|
|
|
473
493
|
|
|
474
494
|
# Copyright and License
|
|
475
495
|
|
|
476
|
-
|
|
496
|
+
BSD-3-Clause:
|
|
477
497
|
|
|
478
498
|
```text
|
|
479
499
|
Copyright (c) 2015, Salesforce.com, Inc.
|
|
@@ -505,5 +525,3 @@ These are some Store implementations authored and maintained by the community. T
|
|
|
505
525
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
506
526
|
POSSIBILITY OF SUCH DAMAGE.
|
|
507
527
|
```
|
|
508
|
-
|
|
509
|
-
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
|
@@ -31,50 +31,38 @@
|
|
|
31
31
|
'use strict';
|
|
32
32
|
var net = require('net');
|
|
33
33
|
var urlParse = require('url').parse;
|
|
34
|
-
var
|
|
34
|
+
var util = require('util');
|
|
35
|
+
var pubsuffix = require('./pubsuffix-psl');
|
|
35
36
|
var Store = require('./store').Store;
|
|
36
37
|
var MemoryCookieStore = require('./memstore').MemoryCookieStore;
|
|
37
38
|
var pathMatch = require('./pathMatch').pathMatch;
|
|
38
|
-
var VERSION = require('
|
|
39
|
+
var VERSION = require('./version');
|
|
39
40
|
|
|
40
41
|
var punycode;
|
|
41
42
|
try {
|
|
42
43
|
punycode = require('punycode');
|
|
43
44
|
} catch(e) {
|
|
44
|
-
console.warn("cookie: can't load punycode; won't use punycode for domain normalization");
|
|
45
|
+
console.warn("tough-cookie: can't load punycode; won't use punycode for domain normalization");
|
|
45
46
|
}
|
|
46
47
|
|
|
47
|
-
var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
|
|
48
|
-
|
|
49
48
|
// From RFC6265 S4.1.1
|
|
50
49
|
// note that it excludes \x3B ";"
|
|
51
|
-
var
|
|
52
|
-
var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$');
|
|
50
|
+
var COOKIE_OCTETS = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
|
|
53
51
|
|
|
54
52
|
var CONTROL_CHARS = /[\x00-\x1F]/;
|
|
55
53
|
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
// https://github.com/
|
|
59
|
-
|
|
60
|
-
// Double quotes are part of the value (see: S4.1.1).
|
|
61
|
-
// '\r', '\n' and '\0' should be treated as a terminator in the "relaxed" mode
|
|
62
|
-
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60)
|
|
63
|
-
// '=' and ';' are attribute/values separators
|
|
64
|
-
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64)
|
|
65
|
-
var COOKIE_PAIR = /^(([^=;]+))\s{0,256}=\s*([^\n\r\0]*)/;
|
|
66
|
-
|
|
67
|
-
// Used to parse non-RFC-compliant cookies like '=abc' when given the `loose`
|
|
68
|
-
// option in Cookie.parse:
|
|
69
|
-
var LOOSE_COOKIE_PAIR = /^((?:=)?([^=;]*)\s{0,256}=\s*)?([^\n\r\0]*)/;
|
|
54
|
+
// From Chromium // '\r', '\n' and '\0' should be treated as a terminator in
|
|
55
|
+
// the "relaxed" mode, see:
|
|
56
|
+
// https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60
|
|
57
|
+
var TERMINATORS = ['\n', '\r', '\0'];
|
|
70
58
|
|
|
71
59
|
// RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"'
|
|
72
60
|
// Note ';' is \x3B
|
|
73
61
|
var PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/;
|
|
74
62
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
var
|
|
63
|
+
// date-time parsing constants (RFC6265 S5.1.1)
|
|
64
|
+
|
|
65
|
+
var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
|
|
78
66
|
|
|
79
67
|
var MONTH_TO_NUM = {
|
|
80
68
|
jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
|
|
@@ -87,13 +75,80 @@ var NUM_TO_DAY = [
|
|
|
87
75
|
'Sun','Mon','Tue','Wed','Thu','Fri','Sat'
|
|
88
76
|
];
|
|
89
77
|
|
|
90
|
-
var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits
|
|
91
|
-
|
|
92
78
|
var MAX_TIME = 2147483647000; // 31-bit max
|
|
93
79
|
var MIN_TIME = 0; // 31-bit min
|
|
94
80
|
|
|
81
|
+
/*
|
|
82
|
+
* Parses a Natural number (i.e., non-negative integer) with either the
|
|
83
|
+
* <min>*<max>DIGIT ( non-digit *OCTET )
|
|
84
|
+
* or
|
|
85
|
+
* <min>*<max>DIGIT
|
|
86
|
+
* grammar (RFC6265 S5.1.1).
|
|
87
|
+
*
|
|
88
|
+
* The "trailingOK" boolean controls if the grammar accepts a
|
|
89
|
+
* "( non-digit *OCTET )" trailer.
|
|
90
|
+
*/
|
|
91
|
+
function parseDigits(token, minDigits, maxDigits, trailingOK) {
|
|
92
|
+
var count = 0;
|
|
93
|
+
while (count < token.length) {
|
|
94
|
+
var c = token.charCodeAt(count);
|
|
95
|
+
// "non-digit = %x00-2F / %x3A-FF"
|
|
96
|
+
if (c <= 0x2F || c >= 0x3A) {
|
|
97
|
+
break;
|
|
98
|
+
}
|
|
99
|
+
count++;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// constrain to a minimum and maximum number of digits.
|
|
103
|
+
if (count < minDigits || count > maxDigits) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
if (!trailingOK && count != token.length) {
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return parseInt(token.substr(0,count), 10);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
function parseTime(token) {
|
|
115
|
+
var parts = token.split(':');
|
|
116
|
+
var result = [0,0,0];
|
|
117
|
+
|
|
118
|
+
/* RF6256 S5.1.1:
|
|
119
|
+
* time = hms-time ( non-digit *OCTET )
|
|
120
|
+
* hms-time = time-field ":" time-field ":" time-field
|
|
121
|
+
* time-field = 1*2DIGIT
|
|
122
|
+
*/
|
|
123
|
+
|
|
124
|
+
if (parts.length !== 3) {
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
95
127
|
|
|
96
|
-
|
|
128
|
+
for (var i = 0; i < 3; i++) {
|
|
129
|
+
// "time-field" must be strictly "1*2DIGIT", HOWEVER, "hms-time" can be
|
|
130
|
+
// followed by "( non-digit *OCTET )" so therefore the last time-field can
|
|
131
|
+
// have a trailer
|
|
132
|
+
var trailingOK = (i == 2);
|
|
133
|
+
var num = parseDigits(parts[i], 1, 2, trailingOK);
|
|
134
|
+
if (num === null) {
|
|
135
|
+
return null;
|
|
136
|
+
}
|
|
137
|
+
result[i] = num;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
return result;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function parseMonth(token) {
|
|
144
|
+
token = String(token).substr(0,3).toLowerCase();
|
|
145
|
+
var num = MONTH_TO_NUM[token];
|
|
146
|
+
return num >= 0 ? num : null;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
/*
|
|
150
|
+
* RFC6265 S5.1.1 date parser (see RFC for full grammar)
|
|
151
|
+
*/
|
|
97
152
|
function parseDate(str) {
|
|
98
153
|
if (!str) {
|
|
99
154
|
return;
|
|
@@ -109,9 +164,9 @@ function parseDate(str) {
|
|
|
109
164
|
}
|
|
110
165
|
|
|
111
166
|
var hour = null;
|
|
112
|
-
var
|
|
113
|
-
var
|
|
114
|
-
var
|
|
167
|
+
var minute = null;
|
|
168
|
+
var second = null;
|
|
169
|
+
var dayOfMonth = null;
|
|
115
170
|
var month = null;
|
|
116
171
|
var year = null;
|
|
117
172
|
|
|
@@ -129,22 +184,12 @@ function parseDate(str) {
|
|
|
129
184
|
* the date-token, respectively. Skip the remaining sub-steps and continue
|
|
130
185
|
* to the next date-token.
|
|
131
186
|
*/
|
|
132
|
-
if (
|
|
133
|
-
result =
|
|
187
|
+
if (second === null) {
|
|
188
|
+
result = parseTime(token);
|
|
134
189
|
if (result) {
|
|
135
|
-
hour =
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
/* RFC6265 S5.1.1.5:
|
|
139
|
-
* [fail if]
|
|
140
|
-
* * the hour-value is greater than 23,
|
|
141
|
-
* * the minute-value is greater than 59, or
|
|
142
|
-
* * the second-value is greater than 59.
|
|
143
|
-
*/
|
|
144
|
-
if(hour > 23 || minutes > 59 || seconds > 59) {
|
|
145
|
-
return;
|
|
146
|
-
}
|
|
147
|
-
|
|
190
|
+
hour = result[0];
|
|
191
|
+
minute = result[1];
|
|
192
|
+
second = result[2];
|
|
148
193
|
continue;
|
|
149
194
|
}
|
|
150
195
|
}
|
|
@@ -154,16 +199,11 @@ function parseDate(str) {
|
|
|
154
199
|
* the day-of-month-value to the number denoted by the date-token. Skip
|
|
155
200
|
* the remaining sub-steps and continue to the next date-token.
|
|
156
201
|
*/
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
* [fail if] the day-of-month-value is less than 1 or greater than 31
|
|
163
|
-
*/
|
|
164
|
-
if(day < 1 || day > 31) {
|
|
165
|
-
return;
|
|
166
|
-
}
|
|
202
|
+
if (dayOfMonth === null) {
|
|
203
|
+
// "day-of-month = 1*2DIGIT ( non-digit *OCTET )"
|
|
204
|
+
result = parseDigits(token, 1, 2, true);
|
|
205
|
+
if (result !== null) {
|
|
206
|
+
dayOfMonth = result;
|
|
167
207
|
continue;
|
|
168
208
|
}
|
|
169
209
|
}
|
|
@@ -174,47 +214,63 @@ function parseDate(str) {
|
|
|
174
214
|
* continue to the next date-token.
|
|
175
215
|
*/
|
|
176
216
|
if (month === null) {
|
|
177
|
-
result =
|
|
178
|
-
if (result) {
|
|
179
|
-
month =
|
|
217
|
+
result = parseMonth(token);
|
|
218
|
+
if (result !== null) {
|
|
219
|
+
month = result;
|
|
180
220
|
continue;
|
|
181
221
|
}
|
|
182
222
|
}
|
|
183
223
|
|
|
184
|
-
/* 2.4. If the found-year flag is not set and the date-token matches the
|
|
185
|
-
* production, set the found-year flag and set the year-value to the
|
|
186
|
-
* denoted by the date-token. Skip the remaining sub-steps and
|
|
187
|
-
* the next date-token.
|
|
224
|
+
/* 2.4. If the found-year flag is not set and the date-token matches the
|
|
225
|
+
* year production, set the found-year flag and set the year-value to the
|
|
226
|
+
* number denoted by the date-token. Skip the remaining sub-steps and
|
|
227
|
+
* continue to the next date-token.
|
|
188
228
|
*/
|
|
189
229
|
if (year === null) {
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
230
|
+
// "year = 2*4DIGIT ( non-digit *OCTET )"
|
|
231
|
+
result = parseDigits(token, 2, 4, true);
|
|
232
|
+
if (result !== null) {
|
|
233
|
+
year = result;
|
|
193
234
|
/* From S5.1.1:
|
|
194
235
|
* 3. If the year-value is greater than or equal to 70 and less
|
|
195
236
|
* than or equal to 99, increment the year-value by 1900.
|
|
196
237
|
* 4. If the year-value is greater than or equal to 0 and less
|
|
197
238
|
* than or equal to 69, increment the year-value by 2000.
|
|
198
239
|
*/
|
|
199
|
-
if (
|
|
240
|
+
if (year >= 70 && year <= 99) {
|
|
200
241
|
year += 1900;
|
|
201
|
-
} else if (
|
|
242
|
+
} else if (year >= 0 && year <= 69) {
|
|
202
243
|
year += 2000;
|
|
203
244
|
}
|
|
204
|
-
|
|
205
|
-
if (year < 1601) {
|
|
206
|
-
return; // 5. ... the year-value is less than 1601
|
|
207
|
-
}
|
|
208
245
|
}
|
|
209
246
|
}
|
|
210
247
|
}
|
|
211
248
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
249
|
+
/* RFC 6265 S5.1.1
|
|
250
|
+
* "5. Abort these steps and fail to parse the cookie-date if:
|
|
251
|
+
* * at least one of the found-day-of-month, found-month, found-
|
|
252
|
+
* year, or found-time flags is not set,
|
|
253
|
+
* * the day-of-month-value is less than 1 or greater than 31,
|
|
254
|
+
* * the year-value is less than 1601,
|
|
255
|
+
* * the hour-value is greater than 23,
|
|
256
|
+
* * the minute-value is greater than 59, or
|
|
257
|
+
* * the second-value is greater than 59.
|
|
258
|
+
* (Note that leap seconds cannot be represented in this syntax.)"
|
|
259
|
+
*
|
|
260
|
+
* So, in order as above:
|
|
261
|
+
*/
|
|
262
|
+
if (
|
|
263
|
+
dayOfMonth === null || month === null || year === null || second === null ||
|
|
264
|
+
dayOfMonth < 1 || dayOfMonth > 31 ||
|
|
265
|
+
year < 1601 ||
|
|
266
|
+
hour > 23 ||
|
|
267
|
+
minute > 59 ||
|
|
268
|
+
second > 59
|
|
269
|
+
) {
|
|
270
|
+
return;
|
|
215
271
|
}
|
|
216
272
|
|
|
217
|
-
return new Date(Date.UTC(year, month,
|
|
273
|
+
return new Date(Date.UTC(year, month, dayOfMonth, hour, minute, second));
|
|
218
274
|
}
|
|
219
275
|
|
|
220
276
|
function formatDate(date) {
|
|
@@ -321,32 +377,62 @@ function defaultPath(path) {
|
|
|
321
377
|
return path.slice(0, rightSlash);
|
|
322
378
|
}
|
|
323
379
|
|
|
380
|
+
function trimTerminator(str) {
|
|
381
|
+
for (var t = 0; t < TERMINATORS.length; t++) {
|
|
382
|
+
var terminatorIdx = str.indexOf(TERMINATORS[t]);
|
|
383
|
+
if (terminatorIdx !== -1) {
|
|
384
|
+
str = str.substr(0,terminatorIdx);
|
|
385
|
+
}
|
|
386
|
+
}
|
|
324
387
|
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
388
|
+
return str;
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
function parseCookiePair(cookiePair, looseMode) {
|
|
392
|
+
cookiePair = trimTerminator(cookiePair);
|
|
393
|
+
|
|
394
|
+
var firstEq = cookiePair.indexOf('=');
|
|
395
|
+
if (looseMode) {
|
|
396
|
+
if (firstEq === 0) { // '=' is immediately at start
|
|
397
|
+
cookiePair = cookiePair.substr(1);
|
|
398
|
+
firstEq = cookiePair.indexOf('='); // might still need to split on '='
|
|
399
|
+
}
|
|
400
|
+
} else { // non-loose mode
|
|
401
|
+
if (firstEq <= 0) { // no '=' or is at start
|
|
402
|
+
return; // needs to have non-empty "cookie-name"
|
|
403
|
+
}
|
|
328
404
|
}
|
|
329
|
-
str = str.trim();
|
|
330
405
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
406
|
+
var cookieName, cookieValue;
|
|
407
|
+
if (firstEq <= 0) {
|
|
408
|
+
cookieName = "";
|
|
409
|
+
cookieValue = cookiePair.trim();
|
|
410
|
+
} else {
|
|
411
|
+
cookieName = cookiePair.substr(0, firstEq).trim();
|
|
412
|
+
cookieValue = cookiePair.substr(firstEq+1).trim();
|
|
413
|
+
}
|
|
335
414
|
|
|
336
|
-
|
|
337
|
-
// constraints as well as trimming any whitespace.
|
|
338
|
-
if (!result) {
|
|
415
|
+
if (CONTROL_CHARS.test(cookieName) || CONTROL_CHARS.test(cookieValue)) {
|
|
339
416
|
return;
|
|
340
417
|
}
|
|
341
418
|
|
|
342
419
|
var c = new Cookie();
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
420
|
+
c.key = cookieName;
|
|
421
|
+
c.value = cookieValue;
|
|
422
|
+
return c;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
function parse(str, options) {
|
|
426
|
+
if (!options || typeof options !== 'object') {
|
|
427
|
+
options = {};
|
|
347
428
|
}
|
|
348
|
-
|
|
349
|
-
|
|
429
|
+
str = str.trim();
|
|
430
|
+
|
|
431
|
+
// We use a regex to parse the "name-value-pair" part of S5.2
|
|
432
|
+
var firstSemi = str.indexOf(';'); // S5.2 step 1
|
|
433
|
+
var cookiePair = (firstSemi === -1) ? str : str.substr(0, firstSemi);
|
|
434
|
+
var c = parseCookiePair(cookiePair, !!options.loose);
|
|
435
|
+
if (!c) {
|
|
350
436
|
return;
|
|
351
437
|
}
|
|
352
438
|
|
|
@@ -671,6 +757,12 @@ Cookie.prototype.inspect = function inspect() {
|
|
|
671
757
|
'"';
|
|
672
758
|
};
|
|
673
759
|
|
|
760
|
+
// Use the new custom inspection symbol to add the custom inspect function if
|
|
761
|
+
// available.
|
|
762
|
+
if (util.inspect.custom) {
|
|
763
|
+
Cookie.prototype[util.inspect.custom] = Cookie.prototype.inspect;
|
|
764
|
+
}
|
|
765
|
+
|
|
674
766
|
Cookie.prototype.toJSON = function() {
|
|
675
767
|
var obj = {};
|
|
676
768
|
|
|
@@ -1279,7 +1371,6 @@ CookieJar.deserializeSync = function(strOrObj, store) {
|
|
|
1279
1371
|
};
|
|
1280
1372
|
CookieJar.fromJSON = CookieJar.deserializeSync;
|
|
1281
1373
|
|
|
1282
|
-
CAN_BE_SYNC.push('clone');
|
|
1283
1374
|
CookieJar.prototype.clone = function(newStore, cb) {
|
|
1284
1375
|
if (arguments.length === 1) {
|
|
1285
1376
|
cb = newStore;
|
|
@@ -1290,10 +1381,61 @@ CookieJar.prototype.clone = function(newStore, cb) {
|
|
|
1290
1381
|
if (err) {
|
|
1291
1382
|
return cb(err);
|
|
1292
1383
|
}
|
|
1293
|
-
CookieJar.deserialize(
|
|
1384
|
+
CookieJar.deserialize(serialized, newStore, cb);
|
|
1294
1385
|
});
|
|
1295
1386
|
};
|
|
1296
1387
|
|
|
1388
|
+
CAN_BE_SYNC.push('removeAllCookies');
|
|
1389
|
+
CookieJar.prototype.removeAllCookies = function(cb) {
|
|
1390
|
+
var store = this.store;
|
|
1391
|
+
|
|
1392
|
+
// Check that the store implements its own removeAllCookies(). The default
|
|
1393
|
+
// implementation in Store will immediately call the callback with a "not
|
|
1394
|
+
// implemented" Error.
|
|
1395
|
+
if (store.removeAllCookies instanceof Function &&
|
|
1396
|
+
store.removeAllCookies !== Store.prototype.removeAllCookies)
|
|
1397
|
+
{
|
|
1398
|
+
return store.removeAllCookies(cb);
|
|
1399
|
+
}
|
|
1400
|
+
|
|
1401
|
+
store.getAllCookies(function(err, cookies) {
|
|
1402
|
+
if (err) {
|
|
1403
|
+
return cb(err);
|
|
1404
|
+
}
|
|
1405
|
+
|
|
1406
|
+
if (cookies.length === 0) {
|
|
1407
|
+
return cb(null);
|
|
1408
|
+
}
|
|
1409
|
+
|
|
1410
|
+
var completedCount = 0;
|
|
1411
|
+
var removeErrors = [];
|
|
1412
|
+
|
|
1413
|
+
function removeCookieCb(removeErr) {
|
|
1414
|
+
if (removeErr) {
|
|
1415
|
+
removeErrors.push(removeErr);
|
|
1416
|
+
}
|
|
1417
|
+
|
|
1418
|
+
completedCount++;
|
|
1419
|
+
|
|
1420
|
+
if (completedCount === cookies.length) {
|
|
1421
|
+
return cb(removeErrors.length ? removeErrors[0] : null);
|
|
1422
|
+
}
|
|
1423
|
+
}
|
|
1424
|
+
|
|
1425
|
+
cookies.forEach(function(cookie) {
|
|
1426
|
+
store.removeCookie(cookie.domain, cookie.path, cookie.key, removeCookieCb);
|
|
1427
|
+
});
|
|
1428
|
+
});
|
|
1429
|
+
};
|
|
1430
|
+
|
|
1431
|
+
CookieJar.prototype._cloneSync = syncWrap('clone');
|
|
1432
|
+
CookieJar.prototype.cloneSync = function(newStore) {
|
|
1433
|
+
if (!newStore.synchronous) {
|
|
1434
|
+
throw new Error('CookieJar clone destination store is not synchronous; use async API instead.');
|
|
1435
|
+
}
|
|
1436
|
+
return this._cloneSync(newStore);
|
|
1437
|
+
};
|
|
1438
|
+
|
|
1297
1439
|
// Use a closure to provide a true imperative API for synchronous stores.
|
|
1298
1440
|
function syncWrap(method) {
|
|
1299
1441
|
return function() {
|
|
@@ -1321,21 +1463,20 @@ CAN_BE_SYNC.forEach(function(method) {
|
|
|
1321
1463
|
CookieJar.prototype[method+'Sync'] = syncWrap(method);
|
|
1322
1464
|
});
|
|
1323
1465
|
|
|
1324
|
-
|
|
1325
|
-
|
|
1326
|
-
|
|
1327
|
-
|
|
1328
|
-
|
|
1329
|
-
|
|
1330
|
-
|
|
1331
|
-
|
|
1332
|
-
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
|
|
1340
|
-
|
|
1341
|
-
};
|
|
1466
|
+
exports.version = VERSION;
|
|
1467
|
+
exports.CookieJar = CookieJar;
|
|
1468
|
+
exports.Cookie = Cookie;
|
|
1469
|
+
exports.Store = Store;
|
|
1470
|
+
exports.MemoryCookieStore = MemoryCookieStore;
|
|
1471
|
+
exports.parseDate = parseDate;
|
|
1472
|
+
exports.formatDate = formatDate;
|
|
1473
|
+
exports.parse = parse;
|
|
1474
|
+
exports.fromJSON = fromJSON;
|
|
1475
|
+
exports.domainMatch = domainMatch;
|
|
1476
|
+
exports.defaultPath = defaultPath;
|
|
1477
|
+
exports.pathMatch = pathMatch;
|
|
1478
|
+
exports.getPublicSuffix = pubsuffix.getPublicSuffix;
|
|
1479
|
+
exports.cookieCompare = cookieCompare;
|
|
1480
|
+
exports.permuteDomain = require('./permuteDomain').permuteDomain;
|
|
1481
|
+
exports.permutePath = permutePath;
|
|
1482
|
+
exports.canonicalDomain = canonicalDomain;
|
package/lib/memstore.js
CHANGED
|
@@ -50,6 +50,12 @@ MemoryCookieStore.prototype.inspect = function() {
|
|
|
50
50
|
return "{ idx: "+util.inspect(this.idx, false, 2)+' }';
|
|
51
51
|
};
|
|
52
52
|
|
|
53
|
+
// Use the new custom inspection symbol to add the custom inspect function if
|
|
54
|
+
// available.
|
|
55
|
+
if (util.inspect.custom) {
|
|
56
|
+
MemoryCookieStore.prototype[util.inspect.custom] = MemoryCookieStore.prototype.inspect;
|
|
57
|
+
}
|
|
58
|
+
|
|
53
59
|
MemoryCookieStore.prototype.findCookie = function(domain, path, key, cb) {
|
|
54
60
|
if (!this.idx[domain]) {
|
|
55
61
|
return cb(null,undefined);
|
|
@@ -143,6 +149,11 @@ MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) {
|
|
|
143
149
|
return cb(null);
|
|
144
150
|
};
|
|
145
151
|
|
|
152
|
+
MemoryCookieStore.prototype.removeAllCookies = function(cb) {
|
|
153
|
+
this.idx = {};
|
|
154
|
+
return cb(null);
|
|
155
|
+
}
|
|
156
|
+
|
|
146
157
|
MemoryCookieStore.prototype.getAllCookies = function(cb) {
|
|
147
158
|
var cookies = [];
|
|
148
159
|
var idx = this.idx;
|
package/lib/permuteDomain.js
CHANGED
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
30
30
|
*/
|
|
31
31
|
"use strict";
|
|
32
|
-
var pubsuffix = require('./pubsuffix');
|
|
32
|
+
var pubsuffix = require('./pubsuffix-psl');
|
|
33
33
|
|
|
34
34
|
// Gives the permutation of all possible domainMatch()es of a given domain. The
|
|
35
35
|
// array is in shortest-to-longest order. Handy for indexing.
|