tough-cookie 2.3.0 → 2.3.4
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/README.md +9 -3
- package/lib/cookie.js +175 -85
- package/lib/pubsuffix.js +1 -1
- package/package.json +9 -5
- package/lib/cookie.js.orig +0 -1336
package/README.md
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
[RFC6265](https://tools.ietf.org/html/rfc6265) Cookies and CookieJar for Node.js
|
|
2
2
|
|
|
3
|
-
[](https://nodei.co/npm/tough-cookie/)
|
|
4
4
|
|
|
5
|
-
[
|
|
5
|
+
[](https://travis-ci.org/salesforce/tough-cookie)
|
|
7
6
|
|
|
8
7
|
# Synopsis
|
|
9
8
|
|
|
@@ -30,6 +29,10 @@ It's _so_ easy!
|
|
|
30
29
|
|
|
31
30
|
Why the name? NPM modules `cookie`, `cookies` and `cookiejar` were already taken.
|
|
32
31
|
|
|
32
|
+
## Version Support
|
|
33
|
+
|
|
34
|
+
Support for versions of node.js will follow that of the [request](https://www.npmjs.com/package/request) module.
|
|
35
|
+
|
|
33
36
|
# API
|
|
34
37
|
|
|
35
38
|
## tough
|
|
@@ -131,6 +134,9 @@ else
|
|
|
131
134
|
cookies = [Cookie.parse(res.headers['set-cookie'])];
|
|
132
135
|
```
|
|
133
136
|
|
|
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
|
+
See [Issue 92](https://github.com/salesforce/tough-cookie/issues/92)
|
|
139
|
+
|
|
134
140
|
### Properties
|
|
135
141
|
|
|
136
142
|
Cookie object properties:
|
package/lib/cookie.js
CHANGED
|
@@ -44,33 +44,24 @@ try {
|
|
|
44
44
|
console.warn("cookie: can't load punycode; won't use punycode for domain normalization");
|
|
45
45
|
}
|
|
46
46
|
|
|
47
|
-
var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
|
|
48
|
-
|
|
49
47
|
// From RFC6265 S4.1.1
|
|
50
48
|
// note that it excludes \x3B ";"
|
|
51
|
-
var
|
|
52
|
-
var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'+$');
|
|
49
|
+
var COOKIE_OCTETS = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
|
|
53
50
|
|
|
54
51
|
var CONTROL_CHARS = /[\x00-\x1F]/;
|
|
55
52
|
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
//
|
|
59
|
-
|
|
60
|
-
// (see: https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L64)
|
|
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]*)/;
|
|
53
|
+
// From Chromium // '\r', '\n' and '\0' should be treated as a terminator in
|
|
54
|
+
// the "relaxed" mode, see:
|
|
55
|
+
// https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/parsed_cookie.cc#L60
|
|
56
|
+
var TERMINATORS = ['\n', '\r', '\0'];
|
|
66
57
|
|
|
67
58
|
// RFC6265 S4.1.1 defines path value as 'any CHAR except CTLs or ";"'
|
|
68
59
|
// Note ';' is \x3B
|
|
69
60
|
var PATH_VALUE = /[\x20-\x3A\x3C-\x7E]+/;
|
|
70
61
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
var
|
|
62
|
+
// date-time parsing constants (RFC6265 S5.1.1)
|
|
63
|
+
|
|
64
|
+
var DATE_DELIM = /[\x09\x20-\x2F\x3B-\x40\x5B-\x60\x7B-\x7E]/;
|
|
74
65
|
|
|
75
66
|
var MONTH_TO_NUM = {
|
|
76
67
|
jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
|
|
@@ -83,13 +74,80 @@ var NUM_TO_DAY = [
|
|
|
83
74
|
'Sun','Mon','Tue','Wed','Thu','Fri','Sat'
|
|
84
75
|
];
|
|
85
76
|
|
|
86
|
-
var YEAR = /^(\d{2}|\d{4})$/; // 2 to 4 digits
|
|
87
|
-
|
|
88
77
|
var MAX_TIME = 2147483647000; // 31-bit max
|
|
89
78
|
var MIN_TIME = 0; // 31-bit min
|
|
90
79
|
|
|
80
|
+
/*
|
|
81
|
+
* Parses a Natural number (i.e., non-negative integer) with either the
|
|
82
|
+
* <min>*<max>DIGIT ( non-digit *OCTET )
|
|
83
|
+
* or
|
|
84
|
+
* <min>*<max>DIGIT
|
|
85
|
+
* grammar (RFC6265 S5.1.1).
|
|
86
|
+
*
|
|
87
|
+
* The "trailingOK" boolean controls if the grammar accepts a
|
|
88
|
+
* "( non-digit *OCTET )" trailer.
|
|
89
|
+
*/
|
|
90
|
+
function parseDigits(token, minDigits, maxDigits, trailingOK) {
|
|
91
|
+
var count = 0;
|
|
92
|
+
while (count < token.length) {
|
|
93
|
+
var c = token.charCodeAt(count);
|
|
94
|
+
// "non-digit = %x00-2F / %x3A-FF"
|
|
95
|
+
if (c <= 0x2F || c >= 0x3A) {
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
count++;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// constrain to a minimum and maximum number of digits.
|
|
102
|
+
if (count < minDigits || count > maxDigits) {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (!trailingOK && count != token.length) {
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
return parseInt(token.substr(0,count), 10);
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
function parseTime(token) {
|
|
114
|
+
var parts = token.split(':');
|
|
115
|
+
var result = [0,0,0];
|
|
116
|
+
|
|
117
|
+
/* RF6256 S5.1.1:
|
|
118
|
+
* time = hms-time ( non-digit *OCTET )
|
|
119
|
+
* hms-time = time-field ":" time-field ":" time-field
|
|
120
|
+
* time-field = 1*2DIGIT
|
|
121
|
+
*/
|
|
122
|
+
|
|
123
|
+
if (parts.length !== 3) {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
91
126
|
|
|
92
|
-
|
|
127
|
+
for (var i = 0; i < 3; i++) {
|
|
128
|
+
// "time-field" must be strictly "1*2DIGIT", HOWEVER, "hms-time" can be
|
|
129
|
+
// followed by "( non-digit *OCTET )" so therefore the last time-field can
|
|
130
|
+
// have a trailer
|
|
131
|
+
var trailingOK = (i == 2);
|
|
132
|
+
var num = parseDigits(parts[i], 1, 2, trailingOK);
|
|
133
|
+
if (num === null) {
|
|
134
|
+
return null;
|
|
135
|
+
}
|
|
136
|
+
result[i] = num;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
return result;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
function parseMonth(token) {
|
|
143
|
+
token = String(token).substr(0,3).toLowerCase();
|
|
144
|
+
var num = MONTH_TO_NUM[token];
|
|
145
|
+
return num >= 0 ? num : null;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/*
|
|
149
|
+
* RFC6265 S5.1.1 date parser (see RFC for full grammar)
|
|
150
|
+
*/
|
|
93
151
|
function parseDate(str) {
|
|
94
152
|
if (!str) {
|
|
95
153
|
return;
|
|
@@ -105,9 +163,9 @@ function parseDate(str) {
|
|
|
105
163
|
}
|
|
106
164
|
|
|
107
165
|
var hour = null;
|
|
108
|
-
var
|
|
109
|
-
var
|
|
110
|
-
var
|
|
166
|
+
var minute = null;
|
|
167
|
+
var second = null;
|
|
168
|
+
var dayOfMonth = null;
|
|
111
169
|
var month = null;
|
|
112
170
|
var year = null;
|
|
113
171
|
|
|
@@ -125,22 +183,12 @@ function parseDate(str) {
|
|
|
125
183
|
* the date-token, respectively. Skip the remaining sub-steps and continue
|
|
126
184
|
* to the next date-token.
|
|
127
185
|
*/
|
|
128
|
-
if (
|
|
129
|
-
result =
|
|
186
|
+
if (second === null) {
|
|
187
|
+
result = parseTime(token);
|
|
130
188
|
if (result) {
|
|
131
|
-
hour =
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
/* RFC6265 S5.1.1.5:
|
|
135
|
-
* [fail if]
|
|
136
|
-
* * the hour-value is greater than 23,
|
|
137
|
-
* * the minute-value is greater than 59, or
|
|
138
|
-
* * the second-value is greater than 59.
|
|
139
|
-
*/
|
|
140
|
-
if(hour > 23 || minutes > 59 || seconds > 59) {
|
|
141
|
-
return;
|
|
142
|
-
}
|
|
143
|
-
|
|
189
|
+
hour = result[0];
|
|
190
|
+
minute = result[1];
|
|
191
|
+
second = result[2];
|
|
144
192
|
continue;
|
|
145
193
|
}
|
|
146
194
|
}
|
|
@@ -150,16 +198,11 @@ function parseDate(str) {
|
|
|
150
198
|
* the day-of-month-value to the number denoted by the date-token. Skip
|
|
151
199
|
* the remaining sub-steps and continue to the next date-token.
|
|
152
200
|
*/
|
|
153
|
-
if (
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
* [fail if] the day-of-month-value is less than 1 or greater than 31
|
|
159
|
-
*/
|
|
160
|
-
if(day < 1 || day > 31) {
|
|
161
|
-
return;
|
|
162
|
-
}
|
|
201
|
+
if (dayOfMonth === null) {
|
|
202
|
+
// "day-of-month = 1*2DIGIT ( non-digit *OCTET )"
|
|
203
|
+
result = parseDigits(token, 1, 2, true);
|
|
204
|
+
if (result !== null) {
|
|
205
|
+
dayOfMonth = result;
|
|
163
206
|
continue;
|
|
164
207
|
}
|
|
165
208
|
}
|
|
@@ -170,47 +213,63 @@ function parseDate(str) {
|
|
|
170
213
|
* continue to the next date-token.
|
|
171
214
|
*/
|
|
172
215
|
if (month === null) {
|
|
173
|
-
result =
|
|
174
|
-
if (result) {
|
|
175
|
-
month =
|
|
216
|
+
result = parseMonth(token);
|
|
217
|
+
if (result !== null) {
|
|
218
|
+
month = result;
|
|
176
219
|
continue;
|
|
177
220
|
}
|
|
178
221
|
}
|
|
179
222
|
|
|
180
|
-
/* 2.4. If the found-year flag is not set and the date-token matches the
|
|
181
|
-
* production, set the found-year flag and set the year-value to the
|
|
182
|
-
* denoted by the date-token. Skip the remaining sub-steps and
|
|
183
|
-
* the next date-token.
|
|
223
|
+
/* 2.4. If the found-year flag is not set and the date-token matches the
|
|
224
|
+
* year production, set the found-year flag and set the year-value to the
|
|
225
|
+
* number denoted by the date-token. Skip the remaining sub-steps and
|
|
226
|
+
* continue to the next date-token.
|
|
184
227
|
*/
|
|
185
228
|
if (year === null) {
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
229
|
+
// "year = 2*4DIGIT ( non-digit *OCTET )"
|
|
230
|
+
result = parseDigits(token, 2, 4, true);
|
|
231
|
+
if (result !== null) {
|
|
232
|
+
year = result;
|
|
189
233
|
/* From S5.1.1:
|
|
190
234
|
* 3. If the year-value is greater than or equal to 70 and less
|
|
191
235
|
* than or equal to 99, increment the year-value by 1900.
|
|
192
236
|
* 4. If the year-value is greater than or equal to 0 and less
|
|
193
237
|
* than or equal to 69, increment the year-value by 2000.
|
|
194
238
|
*/
|
|
195
|
-
if (
|
|
239
|
+
if (year >= 70 && year <= 99) {
|
|
196
240
|
year += 1900;
|
|
197
|
-
} else if (
|
|
241
|
+
} else if (year >= 0 && year <= 69) {
|
|
198
242
|
year += 2000;
|
|
199
243
|
}
|
|
200
|
-
|
|
201
|
-
if (year < 1601) {
|
|
202
|
-
return; // 5. ... the year-value is less than 1601
|
|
203
|
-
}
|
|
204
244
|
}
|
|
205
245
|
}
|
|
206
246
|
}
|
|
207
247
|
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
248
|
+
/* RFC 6265 S5.1.1
|
|
249
|
+
* "5. Abort these steps and fail to parse the cookie-date if:
|
|
250
|
+
* * at least one of the found-day-of-month, found-month, found-
|
|
251
|
+
* year, or found-time flags is not set,
|
|
252
|
+
* * the day-of-month-value is less than 1 or greater than 31,
|
|
253
|
+
* * the year-value is less than 1601,
|
|
254
|
+
* * the hour-value is greater than 23,
|
|
255
|
+
* * the minute-value is greater than 59, or
|
|
256
|
+
* * the second-value is greater than 59.
|
|
257
|
+
* (Note that leap seconds cannot be represented in this syntax.)"
|
|
258
|
+
*
|
|
259
|
+
* So, in order as above:
|
|
260
|
+
*/
|
|
261
|
+
if (
|
|
262
|
+
dayOfMonth === null || month === null || year === null || second === null ||
|
|
263
|
+
dayOfMonth < 1 || dayOfMonth > 31 ||
|
|
264
|
+
year < 1601 ||
|
|
265
|
+
hour > 23 ||
|
|
266
|
+
minute > 59 ||
|
|
267
|
+
second > 59
|
|
268
|
+
) {
|
|
269
|
+
return;
|
|
211
270
|
}
|
|
212
271
|
|
|
213
|
-
return new Date(Date.UTC(year, month,
|
|
272
|
+
return new Date(Date.UTC(year, month, dayOfMonth, hour, minute, second));
|
|
214
273
|
}
|
|
215
274
|
|
|
216
275
|
function formatDate(date) {
|
|
@@ -317,32 +376,62 @@ function defaultPath(path) {
|
|
|
317
376
|
return path.slice(0, rightSlash);
|
|
318
377
|
}
|
|
319
378
|
|
|
379
|
+
function trimTerminator(str) {
|
|
380
|
+
for (var t = 0; t < TERMINATORS.length; t++) {
|
|
381
|
+
var terminatorIdx = str.indexOf(TERMINATORS[t]);
|
|
382
|
+
if (terminatorIdx !== -1) {
|
|
383
|
+
str = str.substr(0,terminatorIdx);
|
|
384
|
+
}
|
|
385
|
+
}
|
|
320
386
|
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
387
|
+
return str;
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
function parseCookiePair(cookiePair, looseMode) {
|
|
391
|
+
cookiePair = trimTerminator(cookiePair);
|
|
392
|
+
|
|
393
|
+
var firstEq = cookiePair.indexOf('=');
|
|
394
|
+
if (looseMode) {
|
|
395
|
+
if (firstEq === 0) { // '=' is immediately at start
|
|
396
|
+
cookiePair = cookiePair.substr(1);
|
|
397
|
+
firstEq = cookiePair.indexOf('='); // might still need to split on '='
|
|
398
|
+
}
|
|
399
|
+
} else { // non-loose mode
|
|
400
|
+
if (firstEq <= 0) { // no '=' or is at start
|
|
401
|
+
return; // needs to have non-empty "cookie-name"
|
|
402
|
+
}
|
|
324
403
|
}
|
|
325
|
-
str = str.trim();
|
|
326
404
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
405
|
+
var cookieName, cookieValue;
|
|
406
|
+
if (firstEq <= 0) {
|
|
407
|
+
cookieName = "";
|
|
408
|
+
cookieValue = cookiePair.trim();
|
|
409
|
+
} else {
|
|
410
|
+
cookieName = cookiePair.substr(0, firstEq).trim();
|
|
411
|
+
cookieValue = cookiePair.substr(firstEq+1).trim();
|
|
412
|
+
}
|
|
331
413
|
|
|
332
|
-
|
|
333
|
-
// constraints as well as trimming any whitespace.
|
|
334
|
-
if (!result) {
|
|
414
|
+
if (CONTROL_CHARS.test(cookieName) || CONTROL_CHARS.test(cookieValue)) {
|
|
335
415
|
return;
|
|
336
416
|
}
|
|
337
417
|
|
|
338
418
|
var c = new Cookie();
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
419
|
+
c.key = cookieName;
|
|
420
|
+
c.value = cookieValue;
|
|
421
|
+
return c;
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
function parse(str, options) {
|
|
425
|
+
if (!options || typeof options !== 'object') {
|
|
426
|
+
options = {};
|
|
343
427
|
}
|
|
344
|
-
|
|
345
|
-
|
|
428
|
+
str = str.trim();
|
|
429
|
+
|
|
430
|
+
// We use a regex to parse the "name-value-pair" part of S5.2
|
|
431
|
+
var firstSemi = str.indexOf(';'); // S5.2 step 1
|
|
432
|
+
var cookiePair = (firstSemi === -1) ? str : str.substr(0, firstSemi);
|
|
433
|
+
var c = parseCookiePair(cookiePair, !!options.loose);
|
|
434
|
+
if (!c) {
|
|
346
435
|
return;
|
|
347
436
|
}
|
|
348
437
|
|
|
@@ -1206,6 +1295,7 @@ CookieJar.prototype._importCookies = function(serialized, cb) {
|
|
|
1206
1295
|
if (!cookies || !Array.isArray(cookies)) {
|
|
1207
1296
|
return cb(new Error('serialized jar has no cookies array'));
|
|
1208
1297
|
}
|
|
1298
|
+
cookies = cookies.slice(); // do not modify the original
|
|
1209
1299
|
|
|
1210
1300
|
function putNext(err) {
|
|
1211
1301
|
if (err) {
|