Bug 722857 - Determine private browsing status for DOMStorage from owning docshell if available, and receive updates if its privacy status changes. r=mayhemer

This commit is contained in:
Josh Matthews 2012-05-26 09:37:58 +01:00
parent b7d9295e8e
commit a913bc7bf5
14 changed files with 211 additions and 124 deletions

View File

@ -2400,7 +2400,7 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
if (!pistorage)
return NS_ERROR_FAILURE;
rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI, mInPrivateBrowsing);
if (NS_FAILED(rv))
return rv;

View File

@ -104,6 +104,7 @@
#include "nsIHttpProtocolHandler.h"
#include "nsIJSContextStack.h"
#include "nsIJSRuntimeService.h"
#include "nsILoadContext.h"
#include "nsIMarkupDocumentViewer.h"
#include "nsIPresShell.h"
#include "nsIPrivateDOMEvent.h"
@ -2243,6 +2244,19 @@ nsGlobalWindow::SetDocShell(nsIDocShell* aDocShell)
bool docShellActive;
mDocShell->GetIsActive(&docShellActive);
mIsBackground = !docShellActive;
if (mLocalStorage) {
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_GetInterface(mLocalStorage);
if (obs) {
mDocShell->AddWeakPrivacyTransitionObserver(obs);
}
}
if (mSessionStorage) {
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_GetInterface(mSessionStorage);
if (obs) {
mDocShell->AddWeakPrivacyTransitionObserver(obs);
}
}
}
}
@ -8084,6 +8098,11 @@ nsGlobalWindow::GetSessionStorage(nsIDOMStorage ** aSessionStorage)
if (!mSessionStorage) {
return NS_ERROR_DOM_NOT_SUPPORTED_ERR;
}
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_GetInterface(mSessionStorage);
if (obs) {
docShell->AddWeakPrivacyTransitionObserver(obs);
}
}
#ifdef PR_LOGGING
@ -8113,8 +8132,7 @@ nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
nsresult rv;
bool unused;
if (!nsDOMStorage::CanUseStorage(&unused))
if (!nsDOMStorage::CanUseStorage())
return NS_ERROR_DOM_SECURITY_ERR;
nsIPrincipal *principal = GetPrincipal();
@ -8130,10 +8148,19 @@ nsGlobalWindow::GetLocalStorage(nsIDOMStorage ** aLocalStorage)
mDocument->GetDocumentURI(documentURI);
}
nsIDocShell* docShell = GetDocShell();
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(docShell);
rv = storageManager->GetLocalStorageForPrincipal(principal,
documentURI,
loadContext && loadContext->UsePrivateBrowsing(),
getter_AddRefs(mLocalStorage));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPrivacyTransitionObserver> obs = do_GetInterface(mLocalStorage);
if (obs && docShell) {
docShell->AddWeakPrivacyTransitionObserver(obs);
}
}
NS_ADDREF(*aLocalStorage = mLocalStorage);

View File

@ -7,6 +7,8 @@
#include "CheckPermissionsHelper.h"
#include "nsIDOMWindow.h"
#include "nsILoadContext.h"
#include "nsIWebNavigation.h"
#include "nsIObserverService.h"
#include "nsIPermissionManager.h"
#include "nsIPrincipal.h"
@ -56,7 +58,9 @@ GetIndexedDBPermissions(const nsACString& aASCIIOrigin,
return nsIPermissionManager::ALLOW_ACTION;
}
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode()) {
nsCOMPtr<nsIWebNavigation> webNav = do_GetInterface(aWindow);
nsCOMPtr<nsILoadContext> loadContext = do_QueryInterface(webNav);
if (loadContext && loadContext->UsePrivateBrowsing()) {
// TODO Support private browsing indexedDB?
return nsIPermissionManager::DENY_ACTION;
}

View File

@ -8,7 +8,7 @@
interface nsIDOMStorage;
interface nsIPrincipal;
[scriptable, uuid(fd91ec36-7da8-43bb-b8f2-4b57a862a467)]
[scriptable, uuid(1541da6c-a9fb-4a8f-af9d-4493c981491d)]
interface nsIDOMStorageManager : nsISupports
{
/**
@ -33,5 +33,6 @@ interface nsIDOMStorageManager : nsISupports
* for a single origin.
*/
nsIDOMStorage getLocalStorageForPrincipal(in nsIPrincipal aPrincipal,
in DOMString aDocumentURI);
in DOMString aDocumentURI,
[optional] in bool aPrivate);
};

View File

@ -29,8 +29,10 @@ public:
SessionStorage = 2
} nsDOMStorageType;
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI) = 0;
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI) = 0;
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate) = 0;
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate) = 0;
virtual already_AddRefed<nsIDOMStorage> Clone() = 0;
virtual already_AddRefed<nsIDOMStorage> Fork(const nsSubstring &aDocumentURI) = 0;

View File

@ -35,8 +35,8 @@ sync protocol PStorage
parent:
__delete__();
Init(bool useDB, bool canUseChromePersist, bool sessionOnly, nsCString domain,
nsCString scopeDBKey, nsCString quotaDomainDBKey,
Init(bool useDB, bool canUseChromePersist, bool sessionOnly, bool isPrivate,
nsCString domain, nsCString scopeDBKey, nsCString quotaDomainDBKey,
nsCString quotaETLDplus1DomainDBKey, PRUint32 storageType);
sync GetKeys(bool callerSecure)
@ -60,6 +60,8 @@ parent:
returns (nsresult rv);
sync SetSecure(nsString key, bool secure)
returns (nsresult rv);
UpdatePrivateState(bool enabled);
};
}

View File

@ -15,7 +15,9 @@ NS_IMPL_CYCLE_COLLECTION_1(StorageChild, mStorage)
NS_IMPL_CYCLE_COLLECTING_ADDREF(StorageChild)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(StorageChild)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIPrivacyTransitionObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrivacyTransitionObserver)
NS_INTERFACE_MAP_END
NS_IMETHODIMP_(nsrefcnt) StorageChild::Release(void)
@ -79,21 +81,21 @@ StorageChild::InitRemote()
ContentChild* child = ContentChild::GetSingleton();
AddIPDLReference();
child->SendPStorageConstructor(this, null_t());
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mDomain, mScopeDBKey,
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mInPrivateBrowsing, mDomain, mScopeDBKey,
mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
}
void
StorageChild::InitAsSessionStorage(nsIURI* aDomainURI)
StorageChild::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI);
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
InitRemote();
}
void
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist)
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
InitRemote();
}
@ -234,8 +236,16 @@ StorageChild::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
StorageClone clone(nsnull, other, aCallerSecure);
AddIPDLReference();
child->SendPStorageConstructor(this, clone);
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mDomain, mScopeDBKey,
mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mInPrivateBrowsing, mDomain,
mScopeDBKey, mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
return NS_OK;
}
NS_IMETHODIMP
StorageChild::PrivateModeChanged(bool enabled)
{
mInPrivateBrowsing = enabled;
SendUpdatePrivateState(enabled);
return NS_OK;
}

View File

@ -16,16 +16,18 @@ namespace dom {
class StorageChild : public PStorageChild
, public DOMStorageBase
, public nsSupportsWeakReference
{
public:
NS_DECL_CYCLE_COLLECTION_CLASS(StorageChild)
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(StorageChild, nsIPrivacyTransitionObserver)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIPRIVACYTRANSITIONOBSERVER
StorageChild(nsDOMStorage* aOwner);
StorageChild(nsDOMStorage* aOwner, StorageChild& aOther);
virtual void InitAsSessionStorage(nsIURI* aDomainURI);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
virtual bool CacheStoragePermissions();

View File

@ -30,18 +30,26 @@ bool
StorageParent::RecvInit(const bool& aUseDB,
const bool& aCanUseChromePersist,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDomainDBKey,
const nsCString& aQuotaETLDplus1DomainDBKey,
const PRUint32& aStorageType)
{
mStorage->InitFromChild(aUseDB, aCanUseChromePersist, aSessionOnly, aDomain,
mStorage->InitFromChild(aUseDB, aCanUseChromePersist, aSessionOnly, aPrivate, aDomain,
aScopeDBKey, aQuotaDomainDBKey, aQuotaETLDplus1DomainDBKey,
aStorageType);
return true;
}
bool
StorageParent::RecvUpdatePrivateState(const bool& aEnabled)
{
mStorage->PrivateModeChanged(aEnabled);
return true;
}
bool
StorageParent::RecvGetKeys(const bool& aCallerSecure, InfallibleTArray<nsString>* aKeys)
{

View File

@ -45,12 +45,15 @@ private:
bool RecvInit(const bool& aUseDB,
const bool& aCanUseChromePersist,
const bool& aSessionOnly,
const bool& aPrivate,
const nsCString& aDomain,
const nsCString& aScopeDBKey,
const nsCString& aQuotaDomainDBKey,
const nsCString& aQuotaETLDplus1DomainDBKey,
const PRUint32& aStorageType);
bool RecvUpdatePrivateState(const bool& aEnabled);
nsRefPtr<DOMStorageImpl> mStorage;
};

View File

@ -5,8 +5,10 @@
#include "StorageChild.h"
#include "StorageParent.h"
#include "mozilla/dom/ContentChild.h"
#include "nsXULAppAPI.h"
using mozilla::dom::StorageChild;
using mozilla::dom::ContentChild;
#include "prnetdb.h"
#include "nsCOMPtr.h"
@ -219,7 +221,6 @@ nsSessionStorageEntry::~nsSessionStorageEntry()
nsDOMStorageManager* nsDOMStorageManager::gStorageManager;
nsDOMStorageManager::nsDOMStorageManager()
: mInPrivateBrowsing(false)
{
}
@ -252,8 +253,6 @@ nsDOMStorageManager::Initialize()
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, "offline-app-removed", true);
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, NS_PRIVATE_BROWSING_SWITCH_TOPIC, true);
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, "profile-after-change", true);
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, "perm-changed", true);
@ -265,6 +264,8 @@ nsDOMStorageManager::Initialize()
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, NS_DOMSTORAGE_FLUSH_TIMER_TOPIC, true);
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, "last-pb-context-exited", true);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
@ -361,10 +362,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
const PRUnichar *aData)
{
if (!strcmp(aTopic, "profile-after-change")) {
nsCOMPtr<nsIPrivateBrowsingService> pbs =
do_GetService(NS_PRIVATE_BROWSING_SERVICE_CONTRACTID);
if (pbs)
pbs->GetPrivateBrowsingEnabled(&gStorageManager->mInPrivateBrowsing);
}
else if (!strcmp(aTopic, "offline-app-removed")) {
nsresult rv = DOMStorageImpl::InitDB();
@ -383,16 +380,6 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
rv = GetOfflineDomains(domains);
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->RemoveOwners(domains, true, false);
} else if (!strcmp(aTopic, NS_PRIVATE_BROWSING_SWITCH_TOPIC)) {
mStorages.EnumerateEntries(ClearStorage, nsnull);
if (!nsCRT::strcmp(aData, NS_LITERAL_STRING(NS_PRIVATE_BROWSING_ENTER).get()))
mInPrivateBrowsing = true;
else if (!nsCRT::strcmp(aData, NS_LITERAL_STRING(NS_PRIVATE_BROWSING_LEAVE).get()))
mInPrivateBrowsing = false;
nsresult rv = DOMStorageImpl::InitDB();
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->DropPrivateBrowsingStorages();
} else if (!strcmp(aTopic, "perm-changed")) {
// Check for cookie permission change
nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject));
@ -471,6 +458,10 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
NS_WARN_IF_FALSE(NS_SUCCEEDED(rv),
"DOMStorage: temporary table commit failed");
}
} else if (!strcmp(aTopic, "last-pb-context-exited")) {
if (DOMStorageImpl::gStorageDB) {
return DOMStorageImpl::gStorageDB->DropPrivateBrowsingStorages();
}
}
return NS_OK;
@ -484,7 +475,7 @@ nsDOMStorageManager::GetUsage(const nsAString& aDomain,
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->GetUsage(NS_ConvertUTF16toUTF8(aDomain),
false, aUsage);
false, aUsage, false);
}
NS_IMETHODIMP
@ -502,6 +493,7 @@ nsDOMStorageManager::ClearOfflineApps()
NS_IMETHODIMP
nsDOMStorageManager::GetLocalStorageForPrincipal(nsIPrincipal *aPrincipal,
const nsSubstring &aDocumentURI,
bool aPrivate,
nsIDOMStorage **aResult)
{
NS_ENSURE_ARG_POINTER(aPrincipal);
@ -513,7 +505,7 @@ nsDOMStorageManager::GetLocalStorageForPrincipal(nsIPrincipal *aPrincipal,
if (!storage)
return NS_ERROR_OUT_OF_MEMORY;
rv = storage->InitAsLocalStorage(aPrincipal, aDocumentURI);
rv = storage->InitAsLocalStorage(aPrincipal, aDocumentURI, aPrivate);
if (NS_FAILED(rv))
return rv;
@ -570,9 +562,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStorage)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMStorageObsolete)
NS_INTERFACE_MAP_ENTRY(nsIDOMStorageObsolete)
NS_INTERFACE_MAP_ENTRY(nsPIDOMStorage)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(StorageObsolete)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsDOMStorage::GetInterface(const nsIID & aIID, void **result)
{
nsresult rv = mStorageImpl->QueryInterface(aIID, result);
if (NS_SUCCEEDED(rv))
return rv;
return QueryInterface(aIID, result);;
}
nsresult
NS_NewDOMStorage2(nsISupports* aOuter, REFNSIID aIID, void** aResult)
{
@ -585,6 +587,7 @@ DOMStorageBase::DOMStorageBase()
, mUseDB(false)
, mSessionOnly(true)
, mCanUseChromePersist(false)
, mInPrivateBrowsing(false)
{
}
@ -597,11 +600,12 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
, mQuotaETLDplus1DomainDBKey(aThat.mQuotaETLDplus1DomainDBKey)
, mQuotaDomainDBKey(aThat.mQuotaDomainDBKey)
, mCanUseChromePersist(aThat.mCanUseChromePersist)
, mInPrivateBrowsing(aThat.mInPrivateBrowsing)
{
}
void
DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI)
DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
@ -614,11 +618,13 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI)
mScopeDBKey.Truncate();
mQuotaDomainDBKey.Truncate();
mStorageType = nsPIDOMStorage::SessionStorage;
mInPrivateBrowsing = aPrivate;
}
void
DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
bool aCanUseChromePersist)
bool aCanUseChromePersist,
bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
// here as we call GetPrincipalURIAndHost (nsDOMStorage.cpp:88) from
@ -642,6 +648,7 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
true, true, mQuotaETLDplus1DomainDBKey);
mCanUseChromePersist = aCanUseChromePersist;
mStorageType = nsPIDOMStorage::LocalStorage;
mInPrivateBrowsing = aPrivate;
}
PLDHashOperator
@ -667,7 +674,9 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
NS_IMPL_CYCLE_COLLECTING_ADDREF(DOMStorageImpl)
NS_IMPL_CYCLE_COLLECTING_RELEASE(DOMStorageImpl)
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(DOMStorageImpl)
NS_INTERFACE_MAP_ENTRY(nsISupports)
NS_INTERFACE_MAP_ENTRY(nsIPrivacyTransitionObserver)
NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrivacyTransitionObserver)
NS_INTERFACE_MAP_END
DOMStorageImpl::DOMStorageImpl(nsDOMStorage* aStorage)
@ -723,7 +732,8 @@ DOMStorageImpl::InitDB()
void
DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
bool aSessionOnly, const nsACString& aDomain,
bool aSessionOnly, bool aPrivate,
const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDomainDBKey,
const nsACString& aQuotaETLDplus1DomainDBKey,
@ -732,6 +742,7 @@ DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
mUseDB = aUseDB;
mCanUseChromePersist = aCanUseChromePersist;
mSessionOnly = aSessionOnly;
mInPrivateBrowsing = aPrivate;
mDomain = aDomain;
mScopeDBKey = aScopeDBKey;
mQuotaDomainDBKey = aQuotaDomainDBKey;
@ -746,16 +757,17 @@ DOMStorageImpl::SetSessionOnly(bool aSessionOnly)
}
void
DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI)
DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
{
DOMStorageBase::InitAsSessionStorage(aDomainURI);
DOMStorageBase::InitAsSessionStorage(aDomainURI, aPrivate);
}
void
DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
bool aCanUseChromePersist)
bool aCanUseChromePersist,
bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist);
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
}
bool
@ -765,7 +777,7 @@ DOMStorageImpl::CacheStoragePermissions()
// All the correct checks have been done on the child, so we just need to
// make sure that our session-only status is correctly updated.
if (!mOwner)
return nsDOMStorage::CanUseStorage(&mSessionOnly);
return CanUseStorage();
return mOwner->CacheStoragePermissions();
}
@ -1255,6 +1267,16 @@ DOMStorageImpl::Clear(bool aCallerSecure, PRInt32* aOldCount)
return NS_OK;
}
NS_IMETHODIMP
DOMStorageImpl::PrivateModeChanged(bool enabled)
{
mInPrivateBrowsing = enabled;
CanUseStorage(); // cause mSessionOnly to update as well
mItems.Clear();
mItemsCachedVersion = 0;
return NS_OK;
}
nsDOMStorage::nsDOMStorage()
: mStorageType(nsPIDOMStorage::Unknown)
, mEventBroadcaster(nsnull)
@ -1313,7 +1335,8 @@ GetDomainURI(nsIPrincipal *aPrincipal, bool aIncludeDomain, nsIURI **_domain)
}
nsresult
nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI)
nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, true, getter_AddRefs(domainURI));
@ -1324,12 +1347,13 @@ nsDOMStorage::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &
mStorageType = SessionStorage;
mStorageImpl->InitAsSessionStorage(domainURI);
mStorageImpl->InitAsSessionStorage(domainURI, aPrivate);
return NS_OK;
}
nsresult
nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI)
nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
nsCOMPtr<nsIURI> domainURI;
nsresult rv = GetDomainURI(aPrincipal, false, getter_AddRefs(domainURI));
@ -1346,18 +1370,25 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
canUseChromePersist = URICanUseChromePersist(URI);
}
mStorageImpl->InitAsLocalStorage(domainURI, canUseChromePersist);
mStorageImpl->InitAsLocalStorage(domainURI, canUseChromePersist, aPrivate);
return NS_OK;
}
bool
DOMStorageBase::CanUseStorage()
{
return nsDOMStorage::CanUseStorage(this);
}
//static
bool
nsDOMStorage::CanUseStorage(bool* aSessionOnly)
nsDOMStorage::CanUseStorage(DOMStorageBase* aStorage /* = NULL */)
{
// check if the calling domain can use storage. Downgrade to session
// only if only session storage may be used.
NS_ASSERTION(aSessionOnly, "null session flag");
*aSessionOnly = false;
if (aStorage) {
// check if the calling domain can use storage. Downgrade to session
// only if only session storage may be used.
aStorage->mSessionOnly = false;
}
if (!Preferences::GetBool(kStorageEnabled)) {
return false;
@ -1398,8 +1429,9 @@ nsDOMStorage::CanUseStorage(bool* aSessionOnly)
// mode to prevent detection of being in private browsing mode and ensuring
// that there will be no traces left.
if (perm == nsICookiePermission::ACCESS_SESSION ||
nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode()) {
*aSessionOnly = true;
(aStorage && aStorage->IsPrivate())) {
if (aStorage)
aStorage->mSessionOnly = true;
}
else if (perm != nsIPermissionManager::ALLOW_ACTION) {
PRUint32 cookieBehavior = Preferences::GetUint(kCookiesBehavior);
@ -1411,8 +1443,8 @@ nsDOMStorage::CanUseStorage(bool* aSessionOnly)
!URICanUseChromePersist(subjectURI))
return false;
if (lifetimePolicy == ACCEPT_SESSION)
*aSessionOnly = true;
if (lifetimePolicy == ACCEPT_SESSION && aStorage)
aStorage->mSessionOnly = true;
}
return true;
@ -1424,7 +1456,7 @@ nsDOMStorage::CacheStoragePermissions()
// Bug 488446, disallowing storage use when in session only mode.
// This is temporary fix before we find complete solution for storage
// behavior in private browsing mode or session-only cookies mode.
if (!CanUseStorage(&mStorageImpl->mSessionOnly))
if (!mStorageImpl->CanUseStorage())
return false;
nsIScriptSecurityManager* ssm = nsContentUtils::GetSecurityManager();
@ -1701,9 +1733,19 @@ NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(nsDOMStorage2)
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIDOMStorage)
NS_INTERFACE_MAP_ENTRY(nsIDOMStorage)
NS_INTERFACE_MAP_ENTRY(nsPIDOMStorage)
NS_INTERFACE_MAP_ENTRY(nsIInterfaceRequestor)
NS_DOM_INTERFACE_MAP_ENTRY_CLASSINFO(Storage)
NS_INTERFACE_MAP_END
NS_IMETHODIMP
nsDOMStorage2::GetInterface(const nsIID & aIID, void **result)
{
nsresult rv = mStorage->GetInterface(aIID, result);
if (NS_SUCCEEDED(rv))
return rv;
return QueryInterface(aIID, result);;
}
nsDOMStorage2::nsDOMStorage2()
{
}
@ -1715,7 +1757,8 @@ nsDOMStorage2::nsDOMStorage2(nsDOMStorage2& aThat)
}
nsresult
nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI)
nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
mStorage = new nsDOMStorage();
if (!mStorage)
@ -1724,11 +1767,12 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
return mStorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
return mStorage->InitAsSessionStorage(aPrincipal, aDocumentURI, aPrivate);
}
nsresult
nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI)
nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate)
{
mStorage = new nsDOMStorage();
if (!mStorage)
@ -1737,7 +1781,7 @@ nsDOMStorage2::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &a
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
return mStorage->InitAsLocalStorage(aPrincipal, aDocumentURI);
return mStorage->InitAsLocalStorage(aPrincipal, aDocumentURI, aPrivate);
}
already_AddRefed<nsIDOMStorage>
@ -1907,7 +1951,7 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN(nsDOMStorageItem)
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN(nsDOMStorageItem)
{
cb.NoteXPCOMChild((nsISupports*) tmp->mStorage);
cb.NoteXPCOMChild(tmp->mStorage);
}
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END

View File

@ -12,6 +12,7 @@
#include "nsIDOMStorage.h"
#include "nsIDOMStorageItem.h"
#include "nsIPermissionManager.h"
#include "nsIPrivacyTransitionObserver.h"
#include "nsInterfaceHashtable.h"
#include "nsVoidArray.h"
#include "nsTArray.h"
@ -24,6 +25,7 @@
#include "nsIObserver.h"
#include "nsITimer.h"
#include "nsWeakReference.h"
#include "nsIInterfaceRequestor.h"
#include "nsDOMStorageDBWrapper.h"
@ -87,8 +89,6 @@ public:
nsresult ClearAllStorages();
bool InPrivateBrowsingMode() { return mInPrivateBrowsing; }
static nsresult Initialize();
static nsDOMStorageManager* GetInstance();
static void Shutdown();
@ -104,17 +104,16 @@ public:
protected:
nsTHashtable<nsDOMStorageEntry> mStorages;
bool mInPrivateBrowsing;
};
class DOMStorageBase : public nsISupports
class DOMStorageBase : public nsIPrivacyTransitionObserver
{
public:
DOMStorageBase();
DOMStorageBase(DOMStorageBase&);
virtual void InitAsSessionStorage(nsIURI* aDomainURI);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
virtual nsTArray<nsString>* GetKeys(bool aCallerSecure) = 0;
virtual nsresult GetLength(bool aCallerSecure, PRUint32* aLength) = 0;
@ -126,7 +125,10 @@ public:
virtual nsresult RemoveValue(bool aCallerSecure, const nsAString& aKey,
nsAString& aOldValue) = 0;
virtual nsresult Clear(bool aCallerSecure, PRInt32* aOldCount) = 0;
// Call nsDOMStorage::CanUseStorage with |this|
bool CanUseStorage();
// If true, the contents of the storage should be stored in the
// database, otherwise this storage should act like a session
// storage.
@ -137,6 +139,10 @@ public:
return mUseDB;
}
bool IsPrivate() {
return mInPrivateBrowsing;
}
// retrieve the value and secure state corresponding to a key out of storage.
virtual nsresult
GetDBValue(const nsAString& aKey,
@ -198,21 +204,23 @@ protected:
nsCString mQuotaDomainDBKey;
bool mCanUseChromePersist;
bool mInPrivateBrowsing;
};
class DOMStorageImpl : public DOMStorageBase
, public nsSupportsWeakReference
{
public:
NS_DECL_CYCLE_COLLECTION_CLASS(DOMStorageImpl)
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(DOMStorageImpl, nsIPrivacyTransitionObserver)
NS_DECL_CYCLE_COLLECTING_ISUPPORTS
NS_DECL_NSIPRIVACYTRANSITIONOBSERVER
DOMStorageImpl(nsDOMStorage*);
DOMStorageImpl(nsDOMStorage*, DOMStorageImpl&);
~DOMStorageImpl();
virtual void InitAsSessionStorage(nsIURI* aDomainURI);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
bool SessionOnly() {
return mSessionOnly;
@ -283,7 +291,7 @@ private:
// Cross-process storage implementations never have InitAs(Session|Local|Global)Storage
// called, so the appropriate initialization needs to happen from the child.
void InitFromChild(bool aUseDB, bool aCanUseChromePersist, bool aSessionOnly,
const nsACString& aDomain,
bool aPrivate, const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDomainDBKey,
const nsACString& aQuotaETLDplus1DomainDBKey,
@ -306,7 +314,8 @@ private:
class nsDOMStorage2;
class nsDOMStorage : public nsIDOMStorageObsolete,
public nsPIDOMStorage
public nsPIDOMStorage,
public nsIInterfaceRequestor
{
public:
nsDOMStorage();
@ -317,14 +326,17 @@ public:
NS_DECL_CYCLE_COLLECTION_CLASS_AMBIGUOUS(nsDOMStorage, nsIDOMStorageObsolete)
NS_DECL_NSIDOMSTORAGEOBSOLETE
NS_DECL_NSIINTERFACEREQUESTOR
// Helpers for implementing nsIDOMStorage
nsresult GetItem(const nsAString& key, nsAString& aData);
nsresult Clear();
// nsPIDOMStorage
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI);
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI);
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate);
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate);
virtual already_AddRefed<nsIDOMStorage> Clone();
virtual already_AddRefed<nsIDOMStorage> Fork(const nsSubstring &aDocumentURI);
virtual bool IsForkOf(nsIDOMStorage* aThat);
@ -336,7 +348,7 @@ public:
// Check whether storage may be used by the caller, and whether it
// is session only. Returns true if storage may be used.
static bool
CanUseStorage(bool* aSessionOnly);
CanUseStorage(DOMStorageBase* aStorage = nsnull);
// Check whether this URI can use chrome persist storage. This kind of
// storage can bypass cookies limits, private browsing and uses the offline
@ -381,7 +393,8 @@ public:
};
class nsDOMStorage2 : public nsIDOMStorage,
public nsPIDOMStorage
public nsPIDOMStorage,
public nsIInterfaceRequestor
{
public:
// nsISupports
@ -392,10 +405,13 @@ public:
nsDOMStorage2();
NS_DECL_NSIDOMSTORAGE
NS_DECL_NSIINTERFACEREQUESTOR
// nsPIDOMStorage
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI);
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI);
virtual nsresult InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate);
virtual nsresult InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aDocumentURI,
bool aPrivate);
virtual already_AddRefed<nsIDOMStorage> Clone();
virtual already_AddRefed<nsIDOMStorage> Fork(const nsSubstring &aDocumentURI);
virtual bool IsForkOf(nsIDOMStorage* aThat);

View File

@ -90,7 +90,7 @@ nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
PR_BEGIN_MACRO \
if (aStorage->CanUseChromePersist()) \
_return mChromePersistentDB._code; \
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode()) \
if (aStorage->IsPrivate()) \
_return mPrivateBrowsingDB._code; \
if (aStorage->SessionOnly()) \
_return mSessionOnlyDB._code; \
@ -188,9 +188,6 @@ nsDOMStorageDBWrapper::RemoveOwner(const nsACString& aOwner,
rv = mPrivateBrowsingDB.RemoveOwner(aOwner, aIncludeSubDomains);
NS_ENSURE_SUCCESS(rv, rv);
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
return NS_OK;
rv = mSessionOnlyDB.RemoveOwner(aOwner, aIncludeSubDomains);
NS_ENSURE_SUCCESS(rv, rv);
@ -210,9 +207,6 @@ nsDOMStorageDBWrapper::RemoveOwners(const nsTArray<nsString> &aOwners,
rv = mPrivateBrowsingDB.RemoveOwners(aOwners, aIncludeSubDomains, aMatch);
NS_ENSURE_SUCCESS(rv, rv);
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
return NS_OK;
rv = mSessionOnlyDB.RemoveOwners(aOwners, aIncludeSubDomains, aMatch);
NS_ENSURE_SUCCESS(rv, rv);
@ -222,26 +216,6 @@ nsDOMStorageDBWrapper::RemoveOwners(const nsTArray<nsString> &aOwners,
return rv;
}
nsresult
nsDOMStorageDBWrapper::RemoveAll()
{
nsresult rv;
rv = mPrivateBrowsingDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
return NS_OK;
rv = mSessionOnlyDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
rv = mPersistentDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
nsresult
nsDOMStorageDBWrapper::GetUsage(DOMStorageImpl* aStorage,
bool aExcludeOfflineFromUsage, PRInt32 *aUsage)
@ -251,9 +225,9 @@ nsDOMStorageDBWrapper::GetUsage(DOMStorageImpl* aStorage,
nsresult
nsDOMStorageDBWrapper::GetUsage(const nsACString& aDomain,
bool aIncludeSubDomains, PRInt32 *aUsage)
bool aIncludeSubDomains, PRInt32 *aUsage, bool aPrivate)
{
if (nsDOMStorageManager::gStorageManager->InPrivateBrowsingMode())
if (aPrivate)
return mPrivateBrowsingDB.GetUsage(aDomain, aIncludeSubDomains, aUsage);
#if 0

View File

@ -144,12 +144,6 @@ public:
RemoveOwners(const nsTArray<nsString>& aOwners,
bool aIncludeSubDomains, bool aMatch);
/**
* Removes all keys from storage. Used when clearing storage.
*/
nsresult
RemoveAll();
/**
* Returns usage for a storage using its GetQuotaDomainDBKey() as a key.
*/
@ -160,7 +154,7 @@ public:
* Returns usage of the domain and optionaly by any subdomain.
*/
nsresult
GetUsage(const nsACString& aDomain, bool aIncludeSubDomains, PRInt32 *aUsage);
GetUsage(const nsACString& aDomain, bool aIncludeSubDomains, PRInt32 *aUsage, bool aPrivate);
/**
* Marks the storage as "cached" after the DOMStorageImpl object has loaded