Bug 384944 - Use nsICookieManager2::Add instead of nsICookieService::SetCookieString for cookie restoration. Patch by Simon Bünzli <zeniko@gmail.com>. r=dwitte

This commit is contained in:
sdwilsh@shawnwilsher.com 2007-06-26 17:01:56 -07:00
parent 296d89a513
commit bb53da40e9

View File

@ -1010,6 +1010,9 @@ SessionStoreService.prototype = {
}
hosts[host] = true;
}
else if (/^file:\/\/([^\/]*)/.test(aEntry.url)) {
hosts[RegExp.$1] = true;
}
if (aEntry.children) {
aEntry.children.forEach(extractHosts);
}
@ -1027,45 +1030,37 @@ SessionStoreService.prototype = {
var cookiesEnum = Cc["@mozilla.org/cookiemanager;1"].
getService(Ci.nsICookieManager).enumerator;
// collect the cookies per window
for (var i = 0; i < aWindows.length; i++) {
aWindows[i].cookies = { count: 0 };
}
for (var i = 0; i < aWindows.length; i++)
aWindows[i].cookies = [];
var _this = this;
// MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
var MAX_EXPIRY = Math.pow(2, 62);
while (cookiesEnum.hasMoreElements()) {
var cookie = cookiesEnum.getNext().QueryInterface(Ci.nsICookie2);
if (cookie.isSession && cookie.host) {
var url = "", value = "";
if (cookie.isSession && this._checkPrivacyLevel(cookie.isSecure)) {
var jscookie = null;
aWindows.forEach(function(aWindow) {
if (aWindow._hosts && aWindow._hosts[cookie.rawHost]) {
// make sure to construct URL and value only once per cookie
if (!url) {
var url = "http" + (cookie.isSecure ? "s" : "") + "://" + cookie.host + (cookie.path || "").replace(/^(?!\/)/, "/");
if (_this._checkPrivacyLevel(cookie.isSecure)) {
value = (cookie.name || "name") + "=" + (cookie.value || "") + ";";
value += cookie.isDomain ? "domain=" + cookie.rawHost + ";" : "";
value += cookie.path ? "path=" + cookie.path + ";" : "";
value += cookie.isSecure ? "secure;" : "";
}
}
if (value) {
// in order to not unnecessarily bloat the session file,
// all window cookies are saved into one JS object
var cookies = aWindow.cookies;
cookies["domain" + ++cookies.count] = url;
cookies["value" + cookies.count] = value;
// serialize the cookie when it's first needed
if (!jscookie) {
jscookie = { host: cookie.host, value: cookie.value };
// only add attributes with non-default values (saving a few bits)
if (cookie.path) jscookie.path = cookie.path;
if (cookie.name) jscookie.name = cookie.name;
if (cookie.isSecure) jscookie.secure = true;
if (cookie.isHttpOnly) jscookie.httponly = true;
if (cookie.expiry < MAX_EXPIRY) jscookie.expiry = cookie.expiry;
}
aWindow.cookies.push(jscookie);
}
});
}
}
// don't include empty cookie sections
for (i = 0; i < aWindows.length; i++) {
if (aWindows[i].cookies.count == 0) {
for (i = 0; i < aWindows.length; i++)
if (aWindows[i].cookies.length == 0)
delete aWindows[i].cookies;
}
}
},
/**
@ -1571,21 +1566,36 @@ SessionStoreService.prototype = {
},
/**
* Restores cookies to cookie service
* Restores cookies (accepting both Firefox 2.0 and current format)
* @param aCookies
* Array of cookie data
* Array of cookie objects
*/
restoreCookies: function sss_restoreCookies(aCookies) {
var cookieService = Cc["@mozilla.org/cookieService;1"].
getService(Ci.nsICookieService);
var ioService = Cc["@mozilla.org/network/io-service;1"].
getService(Ci.nsIIOService);
for (var i = 1; i <= aCookies.count; i++) {
try {
cookieService.setCookieString(ioService.newURI(aCookies["domain" + i], null, null), null, aCookies["value" + i] + "expires=0;", null);
if (aCookies.count && aCookies.domain1) {
// convert to the new cookie serialization format
var converted = [];
for (var i = 1; i <= aCookies.count; i++) {
// for simplicity we only accept the format we produced ourselves
var parsed = aCookies["value" + i].match(/^([^=;]+)=([^;]*);(?:domain=[^;]+;)?(?:path=([^;]*);)?(secure;)?(httponly;)?/);
if (parsed && /^https?:\/\/([^\/]+)/.test(aCookies["domain" + i]))
converted.push({
host: RegExp.$1, path: parsed[3], name: parsed[1], value: parsed[2],
secure: parsed[4], httponly: parsed[5]
});
}
catch (ex) { debug(ex); } // don't let a single cookie stop recovering (might happen if a user tried to edit the session file)
aCookies = converted;
}
var cookieManager = Cc["@mozilla.org/cookiemanager;1"].
getService(Ci.nsICookieManager2);
// MAX_EXPIRY should be 2^63-1, but JavaScript can't handle that precision
var MAX_EXPIRY = Math.pow(2, 62);
for (i = 0; i < aCookies.length; i++) {
var cookie = aCookies[i];
try {
cookieManager.add(cookie.host, cookie.path || "", cookie.name || "", cookie.value, !!cookie.secure, !!cookie.httponly, true, "expiry" in cookie ? cookie.expiry : MAX_EXPIRY);
}
catch (ex) { Components.utils.reportError(ex); } // don't let a single cookie stop recovering
}
},