tough-cookie
Advanced tools
Comparing version 0.9.6 to 0.9.7
@@ -53,2 +53,5 @@ /* | ||
// Used for checking whether or not there is a trailing semi-colon | ||
var TRAILING_SEMICOLON = /;+$/; | ||
/* RFC6265 S5.1.1.5: | ||
@@ -301,2 +304,10 @@ * [fail if] the day-of-month-value is less than 1 or greater than 31 | ||
str = str.trim(); | ||
// S4.1.1 Trailing semi-colons are not part of the specification. | ||
// If we are not in strict mode we remove the trailing semi-colons. | ||
var semiColonCheck = TRAILING_SEMICOLON.exec(str); | ||
if (semiColonCheck) { | ||
if (strict) return; | ||
str = str.slice(0, semiColonCheck.index); | ||
} | ||
@@ -763,8 +774,21 @@ // We use a regex to parse the "name-value-pair" part of S5.2 | ||
// S5.3 step 11 - "If the cookie store contains a cookie with the same name, | ||
// domain, and path as the newly created cookie:" | ||
var store = this.store; | ||
if (!store.updateCookie) { | ||
store.updateCookie = function stubUpdateCookie(oldCookie, newCookie, cb) { | ||
this.putCookie(newCookie, cb); | ||
}; | ||
} | ||
store.findCookie(cookie.domain, cookie.path, cookie.key, function(err,oldCookie) { | ||
if (err) return cb(err); | ||
var next = function(err) { | ||
if (err) return cb(err); | ||
else cb(null, cookie); | ||
}; | ||
if (oldCookie) { | ||
// S5.3 step 11 - "If the cookie store contains a cookie with the same name, | ||
// domain, and path as the newly created cookie:" | ||
if (options.http === false && oldCookie.httpOnly) { // step 11.2 | ||
@@ -776,7 +800,9 @@ var err = new Error("old Cookie is HttpOnly and this isn't an HTTP API"); | ||
cookie.lastAccessed = now; | ||
// Step 11.4 (delete cookie) is implied by just setting the new one: | ||
store.updateCookie(oldCookie, cookie, next); // step 12 | ||
} else { | ||
cookie.creation = cookie.lastAccessed = now; | ||
store.putCookie(cookie, next); // step 12 | ||
} | ||
// Step 11.4 (delete cookie) is implied by just setting the new one: | ||
store.putCookie(cookie, function(err){cb(err,cookie)}); // step 12 | ||
}); | ||
@@ -783,0 +809,0 @@ }; |
@@ -53,2 +53,9 @@ var tough = require('./cookie'); | ||
MemoryCookieStore.prototype.updateCookie = function updateCookie(oldCookie, newCookie, cb) { | ||
// updateCookie() may avoid updating cookies that are identical. For example, | ||
// lastAccessed may not be important to some stores and an equality | ||
// comparison could exclude that field. | ||
this.putCookie(newCookie,cb); | ||
}; | ||
MemoryCookieStore.prototype.removeCookie = function removeCookie(domain, path, key, cb) { | ||
@@ -55,0 +62,0 @@ if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) { |
@@ -6,3 +6,3 @@ { | ||
"keywords": "HTTP cookie cookies set-cookie cookiejar jar RFC6265 RFC2965", | ||
"version": "0.9.6", | ||
"version": "0.9.7", | ||
"homepage": "https://github.com/goinstant/node-cookie", | ||
@@ -27,5 +27,5 @@ "repository": { | ||
"devDependencies": { | ||
"vows": ">=0.5.11", | ||
"vows": ">=0.6.0", | ||
"async": ">=0.1.12" | ||
} | ||
} |
@@ -309,6 +309,21 @@ [RFC6265](http://tools.ietf.org/html/rfc6265) Cookies and CookieJar for Node.js | ||
Adds a cookie to the store. The implementation MUST replace any existing cookie with the same `.domain`, `.path`, and `.key` properties. The cookie MUST not be modified; the caller will have already updated the `.creation` and `.lastAccessed` properties. | ||
Adds a new cookie to the store. The implementation SHOULD replace any existing cookie with the same `.domain`, `.path`, and `.key` properties -- depending on the nature of the implementation, it's possible that between the call to `fetchCookie` and `putCookie` that a duplicate `putCookie` can occur. | ||
The `cookie` object MUST NOT be modified; the caller will have already updated the `.creation` and `.lastAccessed` properties. | ||
Pass an error if the cookie cannot be stored. | ||
store.updateCookie(oldCookie, newCookie, cb(err)) | ||
------------------------------------------------- | ||
Update an existing cookie. The implementation MUST update the `.value` for a cookie with the same `domain`, `.path` and `.key`. The implementation SHOULD check that the old value in the store is equivalent to `oldCookie` - how the conflict is resolved is up to the store. | ||
The `.lastAccessed` property will always be different between the two objects and `.created` will always be the same. Stores MAY ignore or defer the `.lastAccessed` change at the cost of affecting how cookies are sorted (or selected for deletion). | ||
Stores may wish to optimize changing the `.value` of the cookie in the store versus storing a new cookie. If the implementation doesn't define this method a stub that calls `putCookie(newCookie,cb)` will be added to the store object. | ||
The `newCookie` and `oldCookie` objects MUST NOT be modified. | ||
Pass an error if the newCookie cannot be stored. | ||
store.removeCookie(domain, path, key, cb(err)) | ||
@@ -315,0 +330,0 @@ ---------------------------------------------- |
84
test.js
@@ -399,2 +399,21 @@ /* | ||
}, | ||
"trailing semi-colons after path": { | ||
topic: function () { | ||
return [ | ||
"a=b; path=/;", | ||
"c=d;;;;" | ||
]; | ||
}, | ||
"strict": function (t) { | ||
assert.ok(!Cookie.parse(t[0], true)); | ||
assert.ok(!Cookie.parse(t[1], true)); | ||
}, | ||
"non-strict": function (t) { | ||
var c1 = Cookie.parse(t[0]); | ||
var c2 = Cookie.parse(t[1]); | ||
assert.ok(c1); | ||
assert.ok(c2); | ||
assert.equal(c1.path, '/'); | ||
} | ||
}, | ||
"secure-with-value": { | ||
@@ -518,3 +537,3 @@ "strict": function() { assert.ok(!Cookie.parse("a=b; Secure=xyzzy", true)) }, | ||
"got": function(cookies) { | ||
assert.length(cookies, 6); | ||
assert.lengthOf(cookies, 6); | ||
var names = cookies.map(function(c) {return c.key}); | ||
@@ -675,3 +694,3 @@ assert.deepEqual(names, ['e','f','c','d','a','b']); | ||
"get a nodejs cookie": function(cookies) { | ||
assert.length(cookies, 1); | ||
assert.lengthOf(cookies, 1); | ||
var cookie = cookies[0]; | ||
@@ -748,3 +767,3 @@ assert.equal(cookie.domain, 'nodejs.org'); | ||
"get a single string": function(cookieHeaders) { | ||
assert.length(cookieHeaders, 3); | ||
assert.lengthOf(cookieHeaders, 3); | ||
assert.equal(cookieHeaders[0], "a=1; Domain=example.com; Path=/"); | ||
@@ -783,3 +802,3 @@ assert.equal(cookieHeaders[1], "b=2; Domain=example.com; Path=/; HttpOnly"); | ||
"all got set": function(err,t) { | ||
assert.length(t.cookies,4); | ||
assert.lengthOf(t.cookies,4); | ||
}, | ||
@@ -848,3 +867,3 @@ "then getting 'em back": { | ||
assert.equal(err,null); | ||
assert.length(cookies, 1); | ||
assert.lengthOf(cookies, 1); | ||
assert.equal(cookies[0].value,11); | ||
@@ -1062,3 +1081,3 @@ }, | ||
"got one cookie": function(t) { | ||
assert.length(t.cookies, 1); | ||
assert.lengthOf(t.cookies, 1); | ||
}, | ||
@@ -1097,3 +1116,3 @@ "it's the right one": function(t) { | ||
"got the cookie": function(t) { | ||
assert.length(t.cookies, 1); | ||
assert.lengthOf(t.cookies, 1); | ||
assert.equal(t.cookies[0].key, 'near'); | ||
@@ -1103,2 +1122,53 @@ }, | ||
} | ||
}).addBatch({ | ||
"trailing semi-colon set into cj": { | ||
topic: function () { | ||
var cb = this.callback; | ||
var cj = new CookieJar(); | ||
var ex = 'http://www.example.com'; | ||
tasks = [] | ||
tasks.push(function(next) { | ||
cj.setCookie('broken_path=testme; path=/;',ex,at(-1),next); | ||
}); | ||
tasks.push(function(next) { | ||
cj.setCookie('b=2; Path=/;;;;',ex,at(-1),next); | ||
}); | ||
async.parallel(tasks, function (err, cookies) { | ||
cb(null, { | ||
cj: cj, | ||
cookies: cookies | ||
}); | ||
}); | ||
}, | ||
"check number of cookies": function (t) { | ||
assert.lengthOf(t.cookies, 2, "didn't set"); | ||
}, | ||
"check *broken_path* was set properly": function (t) { | ||
assert.equal(t.cookies[0].key, "broken_path"); | ||
assert.equal(t.cookies[0].value, "testme"); | ||
assert.equal(t.cookies[0].path, "/"); | ||
}, | ||
"check *b* was set properly": function (t) { | ||
assert.equal(t.cookies[1].key, "b"); | ||
assert.equal(t.cookies[1].value, "2"); | ||
assert.equal(t.cookies[1].path, "/"); | ||
}, | ||
"retrieve the cookie": { | ||
topic: function (t) { | ||
var cb = this.callback; | ||
t.cj.getCookies('http://www.example.com', {}, function (err, cookies) { | ||
t.cookies = cookies; | ||
cb(err, t); | ||
}); | ||
}, | ||
"get the cookie": function(t) { | ||
assert.lengthOf(t.cookies, 2); | ||
assert.equal(t.cookies[0].key, 'broken_path'); | ||
assert.equal(t.cookies[0].value, 'testme'); | ||
assert.equal(t.cookies[1].key, "b"); | ||
assert.equal(t.cookies[1].value, "2"); | ||
assert.equal(t.cookies[1].path, "/"); | ||
}, | ||
}, | ||
} | ||
}).export(module); |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
253437
2553
373