mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 742047 - Part 1 - Create SessionStorage.jsm and migrate existing code; r=zpao
This commit is contained in:
parent
27c5dbc4df
commit
99e2966f5a
109
browser/components/sessionstore/src/SessionStorage.jsm
Normal file
109
browser/components/sessionstore/src/SessionStorage.jsm
Normal file
@ -0,0 +1,109 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
let EXPORTED_SYMBOLS = ["SessionStorage"];
|
||||
|
||||
const Cu = Components.utils;
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStore",
|
||||
"resource:///modules/sessionstore/SessionStore.jsm");
|
||||
|
||||
let SessionStorage = {
|
||||
/**
|
||||
* Updates all sessionStorage "super cookies"
|
||||
* @param aTabData
|
||||
* The data object for a specific tab
|
||||
* @param aHistory
|
||||
* That tab's session history
|
||||
* @param aDocShell
|
||||
* That tab's docshell (containing the sessionStorage)
|
||||
* @param aFullData
|
||||
* always return privacy sensitive data (use with care)
|
||||
* @param aIsPinned
|
||||
* the tab is pinned and should be treated differently for privacy
|
||||
*/
|
||||
serialize: function ssto_serialize(aTabData, aHistory, aDocShell, aFullData,
|
||||
aIsPinned) {
|
||||
let storageData = {};
|
||||
let hasContent = false;
|
||||
|
||||
for (let i = 0; i < aHistory.count; i++) {
|
||||
let uri;
|
||||
try {
|
||||
uri = aHistory.getEntryAtIndex(i, false).URI;
|
||||
}
|
||||
catch (ex) {
|
||||
// Chances are that this is getEntryAtIndex throwing, as seen in bug 669196.
|
||||
// We've already asserted in _collectTabData, so we won't show that again.
|
||||
continue;
|
||||
}
|
||||
// sessionStorage is saved per origin (cf. nsDocShell::GetSessionStorageForURI)
|
||||
let domain = uri.spec;
|
||||
try {
|
||||
if (uri.host)
|
||||
domain = uri.prePath;
|
||||
}
|
||||
catch (ex) { /* this throws for host-less URIs (such as about: or jar:) */ }
|
||||
if (storageData[domain] ||
|
||||
!(aFullData || SessionStore.checkPrivacyLevel(uri.schemeIs("https"), aIsPinned)))
|
||||
continue;
|
||||
|
||||
let storage, storageItemCount = 0;
|
||||
try {
|
||||
var principal = Services.scriptSecurityManager.getCodebasePrincipal(uri);
|
||||
|
||||
// Using getSessionStorageForPrincipal instead of getSessionStorageForURI
|
||||
// just to be able to pass aCreate = false, that avoids creation of the
|
||||
// sessionStorage object for the page earlier than the page really
|
||||
// requires it. It was causing problems while accessing a storage when
|
||||
// a page later changed its domain.
|
||||
storage = aDocShell.getSessionStorageForPrincipal(principal, "", false);
|
||||
if (storage)
|
||||
storageItemCount = storage.length;
|
||||
}
|
||||
catch (ex) { /* sessionStorage might throw if it's turned off, see bug 458954 */ }
|
||||
if (storageItemCount == 0)
|
||||
continue;
|
||||
|
||||
let data = storageData[domain] = {};
|
||||
for (let j = 0; j < storageItemCount; j++) {
|
||||
try {
|
||||
let key = storage.key(j);
|
||||
let item = storage.getItem(key);
|
||||
data[key] = item;
|
||||
}
|
||||
catch (ex) { /* this currently throws for secured items (cf. bug 442048) */ }
|
||||
}
|
||||
hasContent = true;
|
||||
}
|
||||
|
||||
if (hasContent)
|
||||
aTabData.storage = storageData;
|
||||
},
|
||||
|
||||
/**
|
||||
* restores all sessionStorage "super cookies"
|
||||
* @param aStorageData
|
||||
* Storage data to be restored
|
||||
* @param aDocShell
|
||||
* A tab's docshell (containing the sessionStorage)
|
||||
*/
|
||||
deserialize: function ssto_deserialize(aStorageData, aDocShell) {
|
||||
for (let url in aStorageData) {
|
||||
let uri = Services.io.newURI(url, null, null);
|
||||
let storage = aDocShell.getSessionStorageForURI(uri, "");
|
||||
for (let key in aStorageData[url]) {
|
||||
try {
|
||||
storage.setItem(key, aStorageData[url][key]);
|
||||
}
|
||||
catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Object.freeze(SessionStorage);
|
@ -86,6 +86,8 @@ XPCOMUtils.defineLazyModuleGetter(this, "ScratchpadManager",
|
||||
"resource:///modules/devtools/scratchpad-manager.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "DocumentUtils",
|
||||
"resource:///modules/sessionstore/DocumentUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "SessionStorage",
|
||||
"resource:///modules/sessionstore/SessionStorage.jsm");
|
||||
|
||||
#ifdef MOZ_CRASHREPORTER
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "CrashReporter",
|
||||
@ -200,6 +202,10 @@ let SessionStore = {
|
||||
|
||||
restoreLastSession: function ss_restoreLastSession() {
|
||||
SessionStoreInternal.restoreLastSession();
|
||||
},
|
||||
|
||||
checkPrivacyLevel: function ss_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
|
||||
return SessionStoreInternal.checkPrivacyLevel(aIsHTTPS, aUseDefaultPref);
|
||||
}
|
||||
};
|
||||
|
||||
@ -1988,8 +1994,8 @@ let SessionStoreInternal = {
|
||||
delete tabData.extData;
|
||||
|
||||
if (history && browser.docShell instanceof Ci.nsIDocShell)
|
||||
this._serializeSessionStorage(tabData, history, browser.docShell, aFullData,
|
||||
aTab.pinned);
|
||||
SessionStorage.serialize(tabData, history, browser.docShell, aFullData,
|
||||
aTab.pinned);
|
||||
|
||||
return tabData;
|
||||
},
|
||||
@ -2054,7 +2060,7 @@ let SessionStoreInternal = {
|
||||
try {
|
||||
var prefPostdata = this._prefBranch.getIntPref("sessionstore.postdata");
|
||||
if (aEntry.postData && (aFullData || prefPostdata &&
|
||||
this._checkPrivacyLevel(aEntry.URI.schemeIs("https"), aIsPinned))) {
|
||||
this.checkPrivacyLevel(aEntry.URI.schemeIs("https"), aIsPinned))) {
|
||||
aEntry.postData.QueryInterface(Ci.nsISeekableStream).
|
||||
seek(Ci.nsISeekableStream.NS_SEEK_SET, 0);
|
||||
var stream = Cc["@mozilla.org/binaryinputstream;1"].
|
||||
@ -2135,78 +2141,6 @@ let SessionStoreInternal = {
|
||||
return entry;
|
||||
},
|
||||
|
||||
/**
|
||||
* Updates all sessionStorage "super cookies"
|
||||
* @param aTabData
|
||||
* The data object for a specific tab
|
||||
* @param aHistory
|
||||
* That tab's session history
|
||||
* @param aDocShell
|
||||
* That tab's docshell (containing the sessionStorage)
|
||||
* @param aFullData
|
||||
* always return privacy sensitive data (use with care)
|
||||
* @param aIsPinned
|
||||
* the tab is pinned and should be treated differently for privacy
|
||||
*/
|
||||
_serializeSessionStorage:
|
||||
function ssi_serializeSessionStorage(aTabData, aHistory, aDocShell, aFullData, aIsPinned) {
|
||||
let storageData = {};
|
||||
let hasContent = false;
|
||||
|
||||
for (let i = 0; i < aHistory.count; i++) {
|
||||
let uri;
|
||||
try {
|
||||
uri = aHistory.getEntryAtIndex(i, false).URI;
|
||||
}
|
||||
catch (ex) {
|
||||
// Chances are that this is getEntryAtIndex throwing, as seen in bug 669196.
|
||||
// We've already asserted in _collectTabData, so we won't show that again.
|
||||
continue;
|
||||
}
|
||||
// sessionStorage is saved per origin (cf. nsDocShell::GetSessionStorageForURI)
|
||||
let domain = uri.spec;
|
||||
try {
|
||||
if (uri.host)
|
||||
domain = uri.prePath;
|
||||
}
|
||||
catch (ex) { /* this throws for host-less URIs (such as about: or jar:) */ }
|
||||
if (storageData[domain] ||
|
||||
!(aFullData || this._checkPrivacyLevel(uri.schemeIs("https"), aIsPinned)))
|
||||
continue;
|
||||
|
||||
let storage, storageItemCount = 0;
|
||||
try {
|
||||
var principal = Services.scriptSecurityManager.getCodebasePrincipal(uri);
|
||||
|
||||
// Using getSessionStorageForPrincipal instead of getSessionStorageForURI
|
||||
// just to be able to pass aCreate = false, that avoids creation of the
|
||||
// sessionStorage object for the page earlier than the page really
|
||||
// requires it. It was causing problems while accessing a storage when
|
||||
// a page later changed its domain.
|
||||
storage = aDocShell.getSessionStorageForPrincipal(principal, "", false);
|
||||
if (storage)
|
||||
storageItemCount = storage.length;
|
||||
}
|
||||
catch (ex) { /* sessionStorage might throw if it's turned off, see bug 458954 */ }
|
||||
if (storageItemCount == 0)
|
||||
continue;
|
||||
|
||||
let data = storageData[domain] = {};
|
||||
for (let j = 0; j < storageItemCount; j++) {
|
||||
try {
|
||||
let key = storage.key(j);
|
||||
let item = storage.getItem(key);
|
||||
data[key] = item;
|
||||
}
|
||||
catch (ex) { /* XXXzeniko this currently throws for secured items (cf. bug 442048) */ }
|
||||
}
|
||||
hasContent = true;
|
||||
}
|
||||
|
||||
if (hasContent)
|
||||
aTabData.storage = storageData;
|
||||
},
|
||||
|
||||
/**
|
||||
* go through all tabs and store the current scroll positions
|
||||
* and innerHTML content of WYSIWYG editors
|
||||
@ -2295,7 +2229,7 @@ let SessionStoreInternal = {
|
||||
var isHTTPS = this._getURIFromString((aContent.parent || aContent).
|
||||
document.location.href).schemeIs("https");
|
||||
let isAboutSR = aContent.top.document.location.href == "about:sessionrestore";
|
||||
if (aFullData || this._checkPrivacyLevel(isHTTPS, aIsPinned) || isAboutSR) {
|
||||
if (aFullData || this.checkPrivacyLevel(isHTTPS, aIsPinned) || isAboutSR) {
|
||||
if (aFullData || aUpdateFormData) {
|
||||
let formData = DocumentUtils.getFormData(aContent.document);
|
||||
|
||||
@ -2417,7 +2351,7 @@ let SessionStoreInternal = {
|
||||
// case testing scheme will be sufficient.
|
||||
if (/https?/.test(aScheme) && !aHosts[aHost] &&
|
||||
(!aCheckPrivacy ||
|
||||
this._checkPrivacyLevel(aScheme == "https", aIsPinned))) {
|
||||
this.checkPrivacyLevel(aScheme == "https", aIsPinned))) {
|
||||
// By setting this to true or false, we can determine when looking at
|
||||
// the host in _updateCookies if we should check for privacy.
|
||||
aHosts[aHost] = aIsPinned;
|
||||
@ -2488,8 +2422,8 @@ let SessionStoreInternal = {
|
||||
var cookie = list.getNext().QueryInterface(Ci.nsICookie2);
|
||||
// window._hosts will only have hosts with the right privacy rules,
|
||||
// so there is no need to do anything special with this call to
|
||||
// _checkPrivacyLevel.
|
||||
if (cookie.isSession && _this._checkPrivacyLevel(cookie.isSecure, isPinned)) {
|
||||
// checkPrivacyLevel.
|
||||
if (cookie.isSession && _this.checkPrivacyLevel(cookie.isSecure, isPinned)) {
|
||||
// use the cookie's host, path, and name as keys into a hash,
|
||||
// to make sure we serialize each cookie only once
|
||||
if (!(cookie.host in jscookies &&
|
||||
@ -3127,7 +3061,7 @@ let SessionStoreInternal = {
|
||||
tab.setAttribute(name, tabData.attributes[name]);
|
||||
|
||||
if (tabData.storage && browser.docShell instanceof Ci.nsIDocShell)
|
||||
this._deserializeSessionStorage(tabData.storage, browser.docShell);
|
||||
SessionStorage.deserialize(tabData.storage, browser.docShell);
|
||||
|
||||
// notify the tabbrowser that the tab chrome has been restored
|
||||
var event = aWindow.document.createEvent("Events");
|
||||
@ -3426,26 +3360,6 @@ let SessionStoreInternal = {
|
||||
return shEntry;
|
||||
},
|
||||
|
||||
/**
|
||||
* restores all sessionStorage "super cookies"
|
||||
* @param aStorageData
|
||||
* Storage data to be restored
|
||||
* @param aDocShell
|
||||
* A tab's docshell (containing the sessionStorage)
|
||||
*/
|
||||
_deserializeSessionStorage: function ssi_deserializeSessionStorage(aStorageData, aDocShell) {
|
||||
for (let url in aStorageData) {
|
||||
let uri = this._getURIFromString(url);
|
||||
let storage = aDocShell.getSessionStorageForURI(uri, "");
|
||||
for (let key in aStorageData[url]) {
|
||||
try {
|
||||
storage.setItem(key, aStorageData[url][key]);
|
||||
}
|
||||
catch (ex) { Cu.reportError(ex); } // throws e.g. for URIs that can't have sessionStorage
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Restore properties to a loaded document
|
||||
*/
|
||||
@ -3929,7 +3843,7 @@ let SessionStoreInternal = {
|
||||
* don't do normal check for deferred
|
||||
* @returns bool
|
||||
*/
|
||||
_checkPrivacyLevel: function ssi_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
|
||||
checkPrivacyLevel: function ssi_checkPrivacyLevel(aIsHTTPS, aUseDefaultPref) {
|
||||
let pref = "sessionstore.privacy_level";
|
||||
// If we're in the process of quitting and we're not autoresuming the session
|
||||
// then we should treat it as a deferred session. We have a different privacy
|
||||
|
Loading…
Reference in New Issue
Block a user