summaryrefslogtreecommitdiff
path: root/deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js
diff options
context:
space:
mode:
Diffstat (limited to 'deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js')
-rw-r--r--deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js376
1 files changed, 268 insertions, 108 deletions
diff --git a/deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js b/deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js
index 1d8615b58..c93e927ae 100644
--- a/deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js
+++ b/deps/npm/node_modules/request/node_modules/tough-cookie/lib/cookie.js
@@ -19,10 +19,11 @@
* IN THE SOFTWARE.
*/
-/*jshint regexp:false */
+'use strict';
var net = require('net');
var urlParse = require('url').parse;
var pubsuffix = require('./pubsuffix');
+var Store = require('./store').Store;
var punycode;
try {
@@ -39,11 +40,11 @@ var TOKEN = /[\x21\x23-\x26\x2A\x2B\x2D\x2E\x30-\x39\x41-\x5A\x5E-\x7A\x7C\x7E]/
// From RFC6265 S4.1.1
// note that it excludes \x3B ";"
var COOKIE_OCTET = /[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]/;
-var COOKIE_OCTETS = /^[\x21\x23-\x2B\x2D-\x3A\x3C-\x5B\x5D-\x7E]+$/;
+var COOKIE_OCTETS = new RegExp('^'+COOKIE_OCTET.source+'$');
// The name/key cannot be empty but the value can (S5.2):
-var COOKIE_PAIR_STRICT = new RegExp('^('+TOKEN.source+'+)=("?)('+COOKIE_OCTET.source+'*)\\2');
-var COOKIE_PAIR = /^([^=\s]+)\s*=\s*("?)\s*(.*)\s*\2/;
+var COOKIE_PAIR_STRICT = new RegExp('^('+TOKEN.source+'+)=("?)('+COOKIE_OCTET.source+'*)\\2$');
+var COOKIE_PAIR = /^([^=\s]+)\s*=\s*("?)\s*(.*)\s*\2\s*$/;
// RFC6265 S4.1.1 defines extension-av as 'any CHAR except CTLs or ";"'
// Note ';' is \x3B
@@ -70,7 +71,8 @@ var STRICT_TIME = /^(0?[0-9]|1[0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/;
var MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)$/i;
var MONTH_TO_NUM = {
- jan:0, feb:1, mar:2, apr:3, may:4, jun:5, jul:6, aug:7, sep:8, oct:9, nov:10, dec:11
+ jan:0, feb:1, mar:2, apr:3, may:4, jun:5,
+ jul:6, aug:7, sep:8, oct:9, nov:10, dec:11
};
var NUM_TO_MONTH = [
'Jan','Feb','Mar','Apr','May','Jun','Jul','Aug','Sep','Oct','Nov','Dec'
@@ -79,17 +81,17 @@ var NUM_TO_DAY = [
'Sun','Mon','Tue','Wed','Thu','Fri','Sat'
];
-var YEAR = /^([1-9][0-9]{1,3})$/; // 2 to 4 digits (will check range when parsing)
+var YEAR = /^([1-9][0-9]{1,3})$/; // 2 to 4 digits
var MAX_TIME = 2147483647000; // 31-bit max
-var MAX_DATE = new Date(CookieJar.MAX_TIME); // 31-bit max
var MIN_TIME = 0; // 31-bit min
-var MIN_DATE = new Date(CookieJar.MIN_TIME); // 31-bit min
// RFC6265 S5.1.1 date parser:
function parseDate(str,strict) {
- if (!str) return;
+ if (!str) {
+ return;
+ }
var found_time, found_dom, found_month, found_year;
/* RFC6265 S5.1.1:
@@ -97,14 +99,18 @@ function parseDate(str,strict) {
* appear in the cookie-date
*/
var tokens = str.split(DATE_DELIM);
- if (!tokens) return;
+ if (!tokens) {
+ return;
+ }
var date = new Date();
date.setMilliseconds(0);
for (var i=0; i<tokens.length; i++) {
var token = tokens[i].trim();
- if (!token.length) continue;
+ if (!token.length) {
+ continue;
+ }
var result;
@@ -168,13 +174,15 @@ function parseDate(str,strict) {
* 4. If the year-value is greater than or equal to 0 and less
* than or equal to 69, increment the year-value by 2000.
*/
- if (70 <= year && year <= 99)
+ if (70 <= year && year <= 99) {
year += 1900;
- else if (0 <= year && year <= 69)
+ } else if (0 <= year && year <= 69) {
year += 2000;
+ }
- if (year < 1601)
+ if (year < 1601) {
return; // 5. ... the year-value is less than 1601
+ }
found_year = true;
date.setUTCFullYear(year);
@@ -203,19 +211,24 @@ function formatDate(date) {
// S5.1.2 Canonicalized Host Names
function canonicalDomain(str) {
- if (str == null) return null;
+ if (str == null) {
+ return null;
+ }
str = str.trim().replace(/^\./,''); // S4.1.2.3 & S5.2.3: ignore leading .
// convert to IDN if any non-ASCII characters
- if (punycode && /[^\u0001-\u007f]/.test(str))
+ if (punycode && /[^\u0001-\u007f]/.test(str)) {
str = punycode.toASCII(str);
+ }
return str.toLowerCase();
}
// S5.1.3 Domain Matching
function domainMatch(str, domStr, canonicalize) {
- if (str == null || domStr == null) return null;
+ if (str == null || domStr == null) {
+ return null;
+ }
if (canonicalize !== false) {
str = canonicalDomain(str);
domStr = canonicalDomain(domStr);
@@ -226,25 +239,35 @@ function domainMatch(str, domStr, canonicalize) {
* domain string and the string will have been canonicalized to lower case at
* this point)"
*/
- if (str == domStr) return true;
+ if (str == domStr) {
+ return true;
+ }
/* "All of the following [three] conditions hold:" (order adjusted from the RFC) */
/* "* The string is a host name (i.e., not an IP address)." */
- if (net.isIP(str)) return false;
+ if (net.isIP(str)) {
+ return false;
+ }
/* "* The domain string is a suffix of the string" */
var idx = str.indexOf(domStr);
- if (idx <= 0) return false; // it's a non-match (-1) or prefix (0)
+ if (idx <= 0) {
+ return false; // it's a non-match (-1) or prefix (0)
+ }
// e.g "a.b.c".indexOf("b.c") === 2
// 5 === 3+2
- if (str.length !== domStr.length + idx) // it's not a suffix
+ if (str.length !== domStr.length + idx) { // it's not a suffix
return false;
+ }
/* "* The last character of the string that is not included in the domain
* string is a %x2E (".") character." */
- if (str.substr(idx-1,1) !== '.') return false;
+ if (str.substr(idx-1,1) !== '.') {
+ return false;
+ }
+
return true;
}
@@ -260,14 +283,20 @@ function domainMatch(str, domStr, canonicalize) {
function defaultPath(path) {
// "2. If the uri-path is empty or if the first character of the uri-path is not
// a %x2F ("/") character, output %x2F ("/") and skip the remaining steps.
- if (!path || path.substr(0,1) !== "/") return "/";
+ if (!path || path.substr(0,1) !== "/") {
+ return "/";
+ }
// "3. If the uri-path contains no more than one %x2F ("/") character, output
// %x2F ("/") and skip the remaining step."
- if (path === "/") return path;
+ if (path === "/") {
+ return path;
+ }
var rightSlash = path.lastIndexOf("/");
- if (rightSlash === 0) return "/";
+ if (rightSlash === 0) {
+ return "/";
+ }
// "4. Output the characters of the uri-path from the first character up to,
// but not including, the right-most %x2F ("/")."
@@ -280,21 +309,24 @@ function defaultPath(path) {
*/
function pathMatch(reqPath,cookiePath) {
// "o The cookie-path and the request-path are identical."
- if (cookiePath === reqPath)
+ if (cookiePath === reqPath) {
return true;
+ }
var idx = reqPath.indexOf(cookiePath);
if (idx === 0) {
// "o The cookie-path is a prefix of the request-path, and the last
// character of the cookie-path is %x2F ("/")."
- if (cookiePath.substr(-1) === "/")
+ if (cookiePath.substr(-1) === "/") {
return true;
+ }
// " o The cookie-path is a prefix of the request-path, and the first
// character of the request-path that is not included in the cookie- path
// is a %x2F ("/") character."
- if (reqPath.substr(cookiePath.length,1) === "/")
+ if (reqPath.substr(cookiePath.length,1) === "/") {
return true;
+ }
}
return false;
@@ -307,7 +339,9 @@ function parse(str, strict) {
// If we are not in strict mode we remove the trailing semi-colons.
var semiColonCheck = TRAILING_SEMICOLON.exec(str);
if (semiColonCheck) {
- if (strict) return;
+ if (strict) {
+ return;
+ }
str = str.slice(0, semiColonCheck.index);
}
@@ -318,13 +352,17 @@ function parse(str, strict) {
// Rx satisfies the "the name string is empty" and "lacks a %x3D ("=")"
// constraints as well as trimming any whitespace.
- if (!result) return;
+ if (!result) {
+ return;
+ }
var c = new Cookie();
c.key = result[1]; // the regexp should trim() already
c.value = result[3]; // [2] is quotes or empty-string
- if (firstSemi === -1) return c;
+ if (firstSemi === -1) {
+ return c;
+ }
// S5.2.3 "unparsed-attributes consist of the remainder of the set-cookie-string
// (including the %x3B (";") in question)." plus later on in the same section
@@ -333,7 +371,9 @@ function parse(str, strict) {
// "If the unparsed-attributes string is empty, skip the rest of these
// steps."
- if (unparsed.length === 0) return c;
+ if (unparsed.length === 0) {
+ return c;
+ }
/*
* S5.2 says that when looping over the items "[p]rocess the attribute-name
@@ -347,7 +387,9 @@ function parse(str, strict) {
while (cookie_avs.length) {
var av = cookie_avs.shift();
- if (strict && !EXTENSION_AV.test(av)) return;
+ if (strict && !EXTENSION_AV.test(av)) {
+ return;
+ }
var av_sep = av.indexOf('=');
var av_key, av_value;
@@ -360,28 +402,32 @@ function parse(str, strict) {
}
av_key = av_key.trim().toLowerCase();
- if (av_value) av_value = av_value.trim();
+ if (av_value) {
+ av_value = av_value.trim();
+ }
switch(av_key) {
case 'expires': // S5.2.1
- if (!av_value) { if(strict){return}else{break;} }
+ if (!av_value) {if(strict){return;}else{break;} }
var exp = parseDate(av_value,strict);
// "If the attribute-value failed to parse as a cookie date, ignore the
// cookie-av."
- if (exp == null) { if(strict){return}else{break;} }
+ if (exp == null) { if(strict){return;}else{break;} }
c.expires = exp;
// over and underflow not realistically a concern: V8's getTime() seems to
// store something larger than a 32-bit time_t (even with 32-bit node)
break;
case 'max-age': // S5.2.2
- if (!av_value) { if(strict){return}else{break;} }
+ if (!av_value) { if(strict){return;}else{break;} }
// "If the first character of the attribute-value is not a DIGIT or a "-"
// character ...[or]... If the remainder of attribute-value contains a
// non-DIGIT character, ignore the cookie-av."
- if (!/^-?[0-9]+$/.test(av_value)) { if(strict){return}else{break;} }
+ if (!/^-?[0-9]+$/.test(av_value)) { if(strict){return;}else{break;} }
var delta = parseInt(av_value,10);
- if (strict && delta <= 0) return; // S4.1.1
+ if (strict && delta <= 0) {
+ return; // S4.1.1
+ }
// "If delta-seconds is less than or equal to zero (0), let expiry-time
// be the earliest representable date and time."
c.setMaxAge(delta);
@@ -390,11 +436,11 @@ function parse(str, strict) {
case 'domain': // S5.2.3
// "If the attribute-value is empty, the behavior is undefined. However,
// the user agent SHOULD ignore the cookie-av entirely."
- if (!av_value) { if(strict){return}else{break;} }
+ if (!av_value) { if(strict){return;}else{break;} }
// S5.2.3 "Let cookie-domain be the attribute-value without the leading %x2E
// (".") character."
var domain = av_value.trim().replace(/^\./,'');
- if (!domain) { if(strict){return}else{break;} } // see "is empty" above
+ if (!domain) { if(strict){return;}else{break;} } // see "is empty" above
// "Convert the cookie-domain to lower case."
c.domain = domain.toLowerCase();
break;
@@ -410,7 +456,9 @@ function parse(str, strict) {
* We'll represent the default-path as null since it depends on the
* context of the parsing.
*/
- if (!av_value || av_value.substr(0,1) != "/") { if(strict){return}else{break;} }
+ if (!av_value || av_value.substr(0,1) != "/") {
+ if(strict){return;}else{break;}
+ }
c.path = av_value;
break;
@@ -420,12 +468,12 @@ function parse(str, strict) {
* the user agent MUST append an attribute to the cookie-attribute-list
* with an attribute-name of Secure and an empty attribute-value."
*/
- if (av_value != null) { if(strict){return} }
+ if (av_value != null) { if(strict){return;} }
c.secure = true;
break;
case 'httponly': // S5.2.6 -- effectively the same as 'secure'
- if (av_value != null) { if(strict){return} }
+ if (av_value != null) { if(strict){return;} }
c.httpOnly = true;
break;
@@ -442,7 +490,9 @@ function parse(str, strict) {
}
function fromJSON(str) {
- if (!str) return null;
+ if (!str) {
+ return null;
+ }
var obj;
try {
@@ -454,7 +504,9 @@ function fromJSON(str) {
var c = new Cookie();
for (var i=0; i<numCookieProperties; i++) {
var prop = cookieProperties[i];
- if (obj[prop] == null) continue;
+ if (obj[prop] == null) {
+ continue;
+ }
if (prop === 'expires' ||
prop === 'creation' ||
prop === 'lastAccessed')
@@ -484,7 +536,9 @@ function fromJSON(str) {
function cookieCompare(a,b) {
// descending for length: b CMP a
var deltaLen = (b.path ? b.path.length : 0) - (a.path ? a.path.length : 0);
- if (deltaLen !== 0) return deltaLen;
+ if (deltaLen !== 0) {
+ return deltaLen;
+ }
// ascending for time: a CMP b
return (a.creation ? a.creation.getTime() : MAX_TIME) -
(b.creation ? b.creation.getTime() : MAX_TIME);
@@ -494,8 +548,12 @@ function cookieCompare(a,b) {
// array is in shortest-to-longest order. Handy for indexing.
function permuteDomain(domain) {
var pubSuf = pubsuffix.getPublicSuffix(domain);
- if (!pubSuf) return null;
- if (pubSuf == domain) return [domain];
+ if (!pubSuf) {
+ return null;
+ }
+ if (pubSuf == domain) {
+ return [domain];
+ }
var prefix = domain.slice(0,-(pubSuf.length+1)); // ".example.com"
var parts = prefix.split('.').reverse();
@@ -511,14 +569,18 @@ function permuteDomain(domain) {
// Gives the permutation of all possible pathMatch()es of a given path. The
// array is in longest-to-shortest order. Handy for indexing.
function permutePath(path) {
- var origPath = path;
- if (path === '/') return ['/'];
- if (path.lastIndexOf('/') === path.length-1)
+ if (path === '/') {
+ return ['/'];
+ }
+ if (path.lastIndexOf('/') === path.length-1) {
path = path.substr(0,path.length-1);
+ }
var permutations = [path];
while (path.length > 1) {
var lindex = path.lastIndexOf('/');
- if (lindex === 0) break;
+ if (lindex === 0) {
+ break;
+ }
path = path.substr(0,lindex);
permutations.push(path);
}
@@ -528,7 +590,9 @@ function permutePath(path) {
function Cookie (opts) {
- if (typeof opts !== "object") return;
+ if (typeof opts !== "object") {
+ return;
+ }
Object.keys(opts).forEach(function (key) {
if (Cookie.prototype.hasOwnProperty(key)) {
this[key] = opts[key] || Cookie.prototype[key];
@@ -558,7 +622,9 @@ Cookie.prototype.creation = null; // Date when set; defaulted by Cookie.parse
Cookie.prototype.lastAccessed = null; // Date when set
var cookieProperties = Object.freeze(Object.keys(Cookie.prototype).map(function(p) {
- if (p instanceof Function) return;
+ if (p instanceof Function) {
+ return;
+ }
return p;
}));
var numCookieProperties = cookieProperties.length;
@@ -573,46 +639,55 @@ Cookie.prototype.inspect = function inspect() {
};
Cookie.prototype.validate = function validate() {
- if (!COOKIE_OCTETS.test(this.value))
+ if (!COOKIE_OCTETS.test(this.value)) {
return false;
- if (this.expires != Infinity && !(this.expires instanceof Date) && !parseDate(this.expires,true))
+ }
+ if (this.expires != Infinity && !(this.expires instanceof Date) && !parseDate(this.expires,true)) {
return false;
- if (this.maxAge != null && this.maxAge <= 0)
+ }
+ if (this.maxAge != null && this.maxAge <= 0) {
return false; // "Max-Age=" non-zero-digit *DIGIT
- if (this.path != null && !PATH_VALUE.test(this.path))
+ }
+ if (this.path != null && !PATH_VALUE.test(this.path)) {
return false;
+ }
var cdomain = this.cdomain();
if (cdomain) {
- if (cdomain.match(/\.$/))
+ if (cdomain.match(/\.$/)) {
return false; // S4.1.2.3 suggests that this is bad. domainMatch() tests confirm this
+ }
var suffix = pubsuffix.getPublicSuffix(cdomain);
- if (suffix == null) // it's a public suffix
+ if (suffix == null) { // it's a public suffix
return false;
+ }
}
return true;
};
Cookie.prototype.setExpires = function setExpires(exp) {
- if (exp instanceof Date) this.expires = exp;
- else this.expires = parseDate(exp) || "Infinity";
+ if (exp instanceof Date) {
+ this.expires = exp;
+ } else {
+ this.expires = parseDate(exp) || "Infinity";
+ }
};
Cookie.prototype.setMaxAge = function setMaxAge(age) {
- if (age === Infinity || age === -Infinity)
+ if (age === Infinity || age === -Infinity) {
this.maxAge = age.toString(); // so JSON.stringify() works
- else
+ } else {
this.maxAge = age;
+ }
};
// gives Cookie header format
Cookie.prototype.cookieString = function cookieString() {
var val = this.value;
- if (val == null) val = '';
- if (!val.length || COOKIE_OCTETS.test(val))
- return this.key+'='+val;
- else
- return this.key+'="'+val+'"';
+ if (val == null) {
+ val = '';
+ }
+ return this.key+'='+val;
};
// gives Set-Cookie header format
@@ -620,22 +695,30 @@ Cookie.prototype.toString = function toString() {
var str = this.cookieString();
if (this.expires != Infinity) {
- if (this.expires instanceof Date)
+ if (this.expires instanceof Date) {
str += '; Expires='+formatDate(this.expires);
- else
+ } else {
str += '; Expires='+this.expires;
+ }
}
- if (this.maxAge != null && this.maxAge != Infinity)
+ if (this.maxAge != null && this.maxAge != Infinity) {
str += '; Max-Age='+this.maxAge;
+ }
- if (this.domain && !this.hostOnly)
+ if (this.domain && !this.hostOnly) {
str += '; Domain='+this.domain;
- if (this.path)
+ }
+ if (this.path) {
str += '; Path='+this.path;
+ }
- if (this.secure) str += '; Secure';
- if (this.httpOnly) str += '; HttpOnly';
+ if (this.secure) {
+ str += '; Secure';
+ }
+ if (this.httpOnly) {
+ str += '; HttpOnly';
+ }
if (this.extensions) {
this.extensions.forEach(function(ext) {
str += '; '+ext;
@@ -665,8 +748,9 @@ Cookie.prototype.TTL = function TTL(now) {
expires = parseDate(expires) || Infinity;
}
- if (expires == Infinity)
+ if (expires == Infinity) {
return Infinity;
+ }
return expires.getTime() - (now || Date.now());
}
@@ -683,7 +767,9 @@ Cookie.prototype.expiryTime = function expiryTime(now) {
return relativeTo.getTime() + age;
}
- if (this.expires == Infinity) return Infinity;
+ if (this.expires == Infinity) {
+ return Infinity;
+ }
return this.expires.getTime();
};
@@ -691,9 +777,13 @@ Cookie.prototype.expiryTime = function expiryTime(now) {
// elsewhere), except it returns a Date
Cookie.prototype.expiryDate = function expiryDate(now) {
var millisec = this.expiryTime(now);
- if (millisec == Infinity) return new Date(MAX_TIME);
- else if (millisec == -Infinity) return new Date(MIN_TIME);
- else return new Date(millisec);
+ if (millisec == Infinity) {
+ return new Date(MAX_TIME);
+ } else if (millisec == -Infinity) {
+ return new Date(MIN_TIME);
+ } else {
+ return new Date(millisec);
+ }
};
// This replaces the "persistent-flag" parts of S5.3 step 3
@@ -704,14 +794,19 @@ Cookie.prototype.isPersistent = function isPersistent() {
// Mostly S5.1.2 and S5.2.3:
Cookie.prototype.cdomain =
Cookie.prototype.canonicalizedDomain = function canonicalizedDomain() {
- if (this.domain == null) return null;
+ if (this.domain == null) {
+ return null;
+ }
return canonicalDomain(this.domain);
};
var memstore;
function CookieJar(store, rejectPublicSuffixes) {
- if (rejectPublicSuffixes != null) this.rejectPublicSuffixes = rejectPublicSuffixes;
+ if (rejectPublicSuffixes != null) {
+ this.rejectPublicSuffixes = rejectPublicSuffixes;
+ }
+
if (!store) {
memstore = memstore || require('./memstore');
store = new memstore.MemoryCookieStore();
@@ -720,8 +815,10 @@ function CookieJar(store, rejectPublicSuffixes) {
}
CookieJar.prototype.store = null;
CookieJar.prototype.rejectPublicSuffixes = true;
+var CAN_BE_SYNC = [];
-CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
+CAN_BE_SYNC.push('setCookie');
+CookieJar.prototype.setCookie = function(cookie, url, options, cb) {
var err;
var context = (url instanceof Object) ? url : urlParse(url);
if (options instanceof Function) {
@@ -732,8 +829,9 @@ CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
var host = canonicalDomain(context.hostname);
// S5.3 step 1
- if (!(cookie instanceof Cookie))
+ if (!(cookie instanceof Cookie)) {
cookie = Cookie.parse(cookie, options.strict === true);
+ }
if (!cookie) {
err = new Error("Cookie failed to parse");
return cb(options.ignoreError ? null : err);
@@ -762,8 +860,9 @@ CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
return cb(options.ignoreError ? null : err);
}
- if (cookie.hostOnly == null) // don't reset if already set
+ if (cookie.hostOnly == null) { // don't reset if already set
cookie.hostOnly = false;
+ }
} else {
cookie.hostOnly = true;
@@ -776,8 +875,9 @@ CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
cookie.path = defaultPath(context.pathname);
cookie.pathIsDefault = true;
} else {
- if (cookie.path.length > 1 && cookie.path.substr(-1) == '/')
+ if (cookie.path.length > 1 && cookie.path.substr(-1) == '/') {
cookie.path = cookie.path.slice(0,-1);
+ }
}
// S5.3 step 8: NOOP; secure attribute
@@ -792,17 +892,22 @@ CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
var store = this.store;
if (!store.updateCookie) {
- store.updateCookie = function stubUpdateCookie(oldCookie, newCookie, cb) {
+ store.updateCookie = function(oldCookie, newCookie, cb) {
this.putCookie(newCookie, cb);
};
}
- store.findCookie(cookie.domain, cookie.path, cookie.key, function(err,oldCookie) {
- if (err) return cb(err);
+ function withCookie(err, oldCookie) {
+ if (err) {
+ return cb(err);
+ }
var next = function(err) {
- if (err) return cb(err);
- else cb(null, cookie);
+ if (err) {
+ return cb(err);
+ } else {
+ cb(null, cookie);
+ }
};
if (oldCookie) {
@@ -821,11 +926,14 @@ CookieJar.prototype.setCookie = function setCookie(cookie, url, options, cb) {
cookie.creation = cookie.lastAccessed = now;
store.putCookie(cookie, next); // step 12
}
- });
+ }
+
+ store.findCookie(cookie.domain, cookie.path, cookie.key, withCookie);
};
// RFC6365 S5.4
-CookieJar.prototype.getCookies = function getCookies(url, options, cb) {
+CAN_BE_SYNC.push('getCookies');
+CookieJar.prototype.getCookies = function(url, options, cb) {
var context = (url instanceof Object) ? url : urlParse(url);
if (options instanceof Function) {
cb = options;
@@ -843,7 +951,9 @@ CookieJar.prototype.getCookies = function getCookies(url, options, cb) {
}
var http = options.http;
- if (http == null) http = true;
+ if (http == null) {
+ http = true;
+ }
var now = options.now || Date.now();
var expireCheck = options.expire !== false;
@@ -858,24 +968,31 @@ CookieJar.prototype.getCookies = function getCookies(url, options, cb) {
// The cookie's host-only-flag is false and the canonicalized
// request-host domain-matches the cookie's domain."
if (c.hostOnly) {
- if (c.domain != host) return false;
+ if (c.domain != host) {
+ return false;
+ }
} else {
- if (!domainMatch(host, c.domain, false)) return false;
+ if (!domainMatch(host, c.domain, false)) {
+ return false;
+ }
}
// "The request-uri's path path-matches the cookie's path."
- if (!allPaths && !pathMatch(path, c.path))
+ if (!allPaths && !pathMatch(path, c.path)) {
return false;
+ }
// "If the cookie's secure-only-flag is true, then the request-uri's
// scheme must denote a "secure" protocol"
- if (c.secure && !secure)
+ if (c.secure && !secure) {
return false;
+ }
// "If the cookie's http-only-flag is true, then exclude the cookie if the
// cookie-string is being generated for a "non-HTTP" API"
- if (c.httpOnly && !http)
+ if (c.httpOnly && !http) {
return false;
+ }
// deferred from S5.3
// non-RFC: allow retention of expired cookies by choice
@@ -888,50 +1005,93 @@ CookieJar.prototype.getCookies = function getCookies(url, options, cb) {
}
store.findCookies(host, allPaths ? null : path, function(err,cookies) {
- if (err) return cb(err);
+ if (err) {
+ return cb(err);
+ }
cookies = cookies.filter(matchingCookie);
// sorting of S5.4 part 2
- if (options.sort !== false)
+ if (options.sort !== false) {
cookies = cookies.sort(cookieCompare);
+ }
// S5.4 part 3
var now = new Date();
- cookies.forEach(function(c) { c.lastAccessed = now });
+ cookies.forEach(function(c) {
+ c.lastAccessed = now;
+ });
// TODO persist lastAccessed
cb(null,cookies);
});
};
+CAN_BE_SYNC.push('getCookieString');
CookieJar.prototype.getCookieString = function(/*..., cb*/) {
var args = Array.prototype.slice.call(arguments,0);
var cb = args.pop();
var next = function(err,cookies) {
- if (err) cb(err);
- else cb(null, cookies.map(function(c){return c.cookieString()}).join('; '));
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, cookies.map(function(c){
+ return c.cookieString();
+ }).join('; '));
+ }
};
args.push(next);
this.getCookies.apply(this,args);
};
+CAN_BE_SYNC.push('getSetCookieStrings');
CookieJar.prototype.getSetCookieStrings = function(/*..., cb*/) {
var args = Array.prototype.slice.call(arguments,0);
var cb = args.pop();
var next = function(err,cookies) {
- if (err) cb(err);
- else cb(null, cookies.map(function(c){return c.toString()}));
+ if (err) {
+ cb(err);
+ } else {
+ cb(null, cookies.map(function(c){
+ return c.toString();
+ }));
+ }
};
args.push(next);
this.getCookies.apply(this,args);
};
+// Use a closure to provide a true imperative API for synchronous stores.
+function syncWrap(method) {
+ return function() {
+ if (!this.store.synchronous) {
+ throw new Error('CookieJar store is not synchronous; use async API instead.');
+ }
+
+ var args = Array.prototype.slice.call(arguments);
+ var syncErr, syncResult;
+ args.push(function syncCb(err, result) {
+ syncErr = err;
+ syncResult = result;
+ });
+ this[method].apply(this, args);
+
+ if (syncErr) {
+ throw syncErr;
+ }
+ return syncResult;
+ };
+}
+// wrap all declared CAN_BE_SYNC methods in the sync wrapper
+CAN_BE_SYNC.forEach(function(method) {
+ CookieJar.prototype[method+'Sync'] = syncWrap(method);
+});
module.exports = {
CookieJar: CookieJar,
Cookie: Cookie,
+ Store: Store,
parseDate: parseDate,
formatDate: formatDate,
parse: parse,