You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.7 KiB
181 lines
5.7 KiB
/*! |
|
* Copyright (c) 2015, Salesforce.com, Inc. |
|
* All rights reserved. |
|
* |
|
* Redistribution and use in source and binary forms, with or without |
|
* modification, are permitted provided that the following conditions are met: |
|
* |
|
* 1. Redistributions of source code must retain the above copyright notice, |
|
* this list of conditions and the following disclaimer. |
|
* |
|
* 2. Redistributions in binary form must reproduce the above copyright notice, |
|
* this list of conditions and the following disclaimer in the documentation |
|
* and/or other materials provided with the distribution. |
|
* |
|
* 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. |
|
* |
|
* 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. |
|
*/ |
|
'use strict'; |
|
var Store = require('./store').Store; |
|
var permuteDomain = require('./permuteDomain').permuteDomain; |
|
var pathMatch = require('./pathMatch').pathMatch; |
|
var util = require('util'); |
|
|
|
function MemoryCookieStore() { |
|
Store.call(this); |
|
this.idx = {}; |
|
} |
|
util.inherits(MemoryCookieStore, Store); |
|
exports.MemoryCookieStore = MemoryCookieStore; |
|
MemoryCookieStore.prototype.idx = null; |
|
|
|
// Since it's just a struct in RAM, this Store is synchronous |
|
MemoryCookieStore.prototype.synchronous = true; |
|
|
|
// force a default depth: |
|
MemoryCookieStore.prototype.inspect = function() { |
|
return "{ idx: "+util.inspect(this.idx, false, 2)+' }'; |
|
}; |
|
|
|
// Use the new custom inspection symbol to add the custom inspect function if |
|
// available. |
|
if (util.inspect.custom) { |
|
MemoryCookieStore.prototype[util.inspect.custom] = MemoryCookieStore.prototype.inspect; |
|
} |
|
|
|
MemoryCookieStore.prototype.findCookie = function(domain, path, key, cb) { |
|
if (!this.idx[domain]) { |
|
return cb(null,undefined); |
|
} |
|
if (!this.idx[domain][path]) { |
|
return cb(null,undefined); |
|
} |
|
return cb(null,this.idx[domain][path][key]||null); |
|
}; |
|
|
|
MemoryCookieStore.prototype.findCookies = function(domain, path, cb) { |
|
var results = []; |
|
if (!domain) { |
|
return cb(null,[]); |
|
} |
|
|
|
var pathMatcher; |
|
if (!path) { |
|
// null means "all paths" |
|
pathMatcher = function matchAll(domainIndex) { |
|
for (var curPath in domainIndex) { |
|
var pathIndex = domainIndex[curPath]; |
|
for (var key in pathIndex) { |
|
results.push(pathIndex[key]); |
|
} |
|
} |
|
}; |
|
|
|
} else { |
|
pathMatcher = function matchRFC(domainIndex) { |
|
//NOTE: we should use path-match algorithm from S5.1.4 here |
|
//(see : https://github.com/ChromiumWebApps/chromium/blob/b3d3b4da8bb94c1b2e061600df106d590fda3620/net/cookies/canonical_cookie.cc#L299) |
|
Object.keys(domainIndex).forEach(function (cookiePath) { |
|
if (pathMatch(path, cookiePath)) { |
|
var pathIndex = domainIndex[cookiePath]; |
|
|
|
for (var key in pathIndex) { |
|
results.push(pathIndex[key]); |
|
} |
|
} |
|
}); |
|
}; |
|
} |
|
|
|
var domains = permuteDomain(domain) || [domain]; |
|
var idx = this.idx; |
|
domains.forEach(function(curDomain) { |
|
var domainIndex = idx[curDomain]; |
|
if (!domainIndex) { |
|
return; |
|
} |
|
pathMatcher(domainIndex); |
|
}); |
|
|
|
cb(null,results); |
|
}; |
|
|
|
MemoryCookieStore.prototype.putCookie = function(cookie, cb) { |
|
if (!this.idx[cookie.domain]) { |
|
this.idx[cookie.domain] = {}; |
|
} |
|
if (!this.idx[cookie.domain][cookie.path]) { |
|
this.idx[cookie.domain][cookie.path] = {}; |
|
} |
|
this.idx[cookie.domain][cookie.path][cookie.key] = cookie; |
|
cb(null); |
|
}; |
|
|
|
MemoryCookieStore.prototype.updateCookie = function(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(domain, path, key, cb) { |
|
if (this.idx[domain] && this.idx[domain][path] && this.idx[domain][path][key]) { |
|
delete this.idx[domain][path][key]; |
|
} |
|
cb(null); |
|
}; |
|
|
|
MemoryCookieStore.prototype.removeCookies = function(domain, path, cb) { |
|
if (this.idx[domain]) { |
|
if (path) { |
|
delete this.idx[domain][path]; |
|
} else { |
|
delete this.idx[domain]; |
|
} |
|
} |
|
return cb(null); |
|
}; |
|
|
|
MemoryCookieStore.prototype.removeAllCookies = function(cb) { |
|
this.idx = {}; |
|
return cb(null); |
|
} |
|
|
|
MemoryCookieStore.prototype.getAllCookies = function(cb) { |
|
var cookies = []; |
|
var idx = this.idx; |
|
|
|
var domains = Object.keys(idx); |
|
domains.forEach(function(domain) { |
|
var paths = Object.keys(idx[domain]); |
|
paths.forEach(function(path) { |
|
var keys = Object.keys(idx[domain][path]); |
|
keys.forEach(function(key) { |
|
if (key !== null) { |
|
cookies.push(idx[domain][path][key]); |
|
} |
|
}); |
|
}); |
|
}); |
|
|
|
// Sort by creationIndex so deserializing retains the creation order. |
|
// When implementing your own store, this SHOULD retain the order too |
|
cookies.sort(function(a,b) { |
|
return (a.creationIndex||0) - (b.creationIndex||0); |
|
}); |
|
|
|
cb(null, cookies); |
|
};
|
|
|