Bug 776416 - Remove exceptions to 5MB quota rule in localStorage. r=honzab

This commit is contained in:
Jonas Sicking 2012-09-13 20:46:50 +02:00
parent 304335b415
commit 088d6f8f6f
24 changed files with 151 additions and 1279 deletions

View File

@ -5687,13 +5687,11 @@ var OfflineApps = {
// OfflineApps Public Methods
init: function ()
{
Services.obs.addObserver(this, "dom-storage-warn-quota-exceeded", false);
Services.obs.addObserver(this, "offline-cache-update-completed", false);
},
uninit: function ()
{
Services.obs.removeObserver(this, "dom-storage-warn-quota-exceeded");
Services.obs.removeObserver(this, "offline-cache-update-completed");
},
@ -5935,19 +5933,7 @@ var OfflineApps = {
// nsIObserver
observe: function (aSubject, aTopic, aState)
{
if (aTopic == "dom-storage-warn-quota-exceeded") {
if (aSubject) {
var uri = makeURI(aSubject.location.href);
if (OfflineApps._checkUsage(uri)) {
var browserWindow =
this._getBrowserWindowForContentWindow(aSubject);
var browser = this._getBrowserForContentWindow(browserWindow,
aSubject);
OfflineApps._warnUsage(browser, uri);
}
}
} else if (aTopic == "offline-cache-update-completed") {
if (aTopic == "offline-cache-update-completed") {
var cacheUpdate = aSubject.QueryInterface(Ci.nsIOfflineCacheUpdate);
var uri = cacheUpdate.manifestURI;

View File

@ -8,7 +8,7 @@
interface nsIDOMStorage;
interface nsIPrincipal;
[scriptable, uuid(1541da6c-a9fb-4a8f-af9d-4493c981491d)]
[scriptable, uuid(b16b207c-d883-43f5-a27e-548e7f2f5c20)]
interface nsIDOMStorageManager : nsISupports
{
/**
@ -21,12 +21,6 @@ interface nsIDOMStorageManager : nsISupports
*/
long getUsage(in AString aOwnerDomain);
/**
* Clear keys owned by offline applications. All data owned by a domain
* with the "offline-app" permission will be removed from the database.
*/
void clearOfflineApps();
/**
* Returns instance of localStorage object for aURI's origin.
* This method ensures there is always only a single instance

View File

@ -35,8 +35,8 @@ sync protocol PStorage
parent:
__delete__();
Init(bool useDB, bool canUseChromePersist, bool sessionOnly, bool isPrivate,
nsCString domain, nsCString scopeDBKey, nsCString quotaDomainDBKey,
Init(bool useDB, bool sessionOnly, bool isPrivate,
nsCString domain, nsCString scopeDBKey,
nsCString quotaETLDplus1DomainDBKey, uint32_t storageType);
sync GetKeys(bool callerSecure)

View File

@ -83,8 +83,8 @@ StorageChild::InitRemote()
ContentChild* child = ContentChild::GetSingleton();
AddIPDLReference();
child->SendPStorageConstructor(this, null_t());
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mInPrivateBrowsing, mDomain, mScopeDBKey,
mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain, mScopeDBKey,
mQuotaETLDplus1DomainDBKey, mStorageType);
}
void
@ -95,9 +95,9 @@ StorageChild::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
}
void
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate)
StorageChild::InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
InitRemote();
}
@ -196,12 +196,6 @@ StorageChild::Clear(bool aCallerSecure, int32_t* aOldCount)
return NS_OK;
}
bool
StorageChild::CanUseChromePersist()
{
return mCanUseChromePersist;
}
nsresult
StorageChild::GetDBValue(const nsAString& aKey, nsAString& aValue,
bool* aSecure)
@ -239,8 +233,8 @@ StorageChild::CloneFrom(bool aCallerSecure, DOMStorageBase* aThat)
StorageClone clone(nullptr, other, aCallerSecure);
AddIPDLReference();
child->SendPStorageConstructor(this, clone);
SendInit(mUseDB, mCanUseChromePersist, mSessionOnly, mInPrivateBrowsing, mDomain,
mScopeDBKey, mQuotaDomainDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
SendInit(mUseDB, mSessionOnly, mInPrivateBrowsing, mDomain,
mScopeDBKey, mQuotaETLDplus1DomainDBKey, mStorageType);
return NS_OK;
}

View File

@ -27,7 +27,7 @@ public:
StorageChild(nsDOMStorage* aOwner, StorageChild& aOther);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual bool CacheStoragePermissions();
@ -42,8 +42,6 @@ public:
nsAString& aOldValue);
virtual nsresult Clear(bool aCallerSecure, int32_t* aOldCount);
virtual bool CanUseChromePersist();
virtual nsresult GetDBValue(const nsAString& aKey,
nsAString& aValue,
bool* aSecure);

View File

@ -28,17 +28,15 @@ StorageParent::StorageParent(const StorageConstructData& aData)
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 uint32_t& aStorageType)
{
mStorage->InitFromChild(aUseDB, aCanUseChromePersist, aSessionOnly, aPrivate, aDomain,
aScopeDBKey, aQuotaDomainDBKey, aQuotaETLDplus1DomainDBKey,
mStorage->InitFromChild(aUseDB, aSessionOnly, aPrivate, aDomain,
aScopeDBKey, aQuotaETLDplus1DomainDBKey,
aStorageType);
return true;
}

View File

@ -43,12 +43,10 @@ private:
bool RecvSetSecure(const nsString& aKey, const bool& aSecure, nsresult* rv);
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 uint32_t& aStorageType);

View File

@ -29,7 +29,6 @@ using mozilla::dom::ContentChild;
#include "nsIPermission.h"
#include "nsIPermissionManager.h"
#include "nsCycleCollectionParticipant.h"
#include "nsIOfflineCacheUpdate.h"
#include "nsIJSContextStack.h"
#include "nsIPrivateBrowsingService.h"
#include "nsDOMString.h"
@ -52,23 +51,14 @@ static const uint32_t ASK_BEFORE_ACCEPT = 1;
static const uint32_t ACCEPT_SESSION = 2;
static const uint32_t BEHAVIOR_REJECT = 2;
static const uint32_t DEFAULT_QUOTA = 5 * 1024;
// Be generous with offline apps by default...
static const uint32_t DEFAULT_OFFLINE_APP_QUOTA = 200 * 1024;
// ... but warn if it goes over this amount
static const uint32_t DEFAULT_OFFLINE_WARN_QUOTA = 50 * 1024;
// Intervals to flush the temporary table after in seconds
#define NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_INACTIVITY_TIME (5)
#define NS_DOMSTORAGE_MAXIMUM_TEMPTABLE_AGE (30)
static const char kPermissionType[] = "cookie";
static const char kStorageEnabled[] = "dom.storage.enabled";
static const char kDefaultQuota[] = "dom.storage.default_quota";
static const char kCookiesBehavior[] = "network.cookie.cookieBehavior";
static const char kCookiesLifetimePolicy[] = "network.cookie.lifetimePolicy";
static const char kOfflineAppWarnQuota[] = "offline-apps.quota.warn";
static const char kOfflineAppQuota[] = "offline-apps.quota.max";
// The URI returned is the innermost URI that should be used for
// security-check-like stuff. aHost is its hostname, correctly canonicalized.
@ -140,65 +130,6 @@ IsCallerSecure()
return NS_SUCCEEDED(rv) && isHttps;
}
uint32_t
GetOfflinePermission(const nsACString &aDomain)
{
// Fake a URI for the permission manager
nsCOMPtr<nsIURI> uri;
NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aDomain);
uint32_t perm;
if (uri) {
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (permissionManager &&
NS_SUCCEEDED(permissionManager->TestPermission(uri, "offline-app", &perm)))
return perm;
}
return nsIPermissionManager::UNKNOWN_ACTION;
}
bool
IsOfflineAllowed(const nsACString &aDomain)
{
int32_t perm = GetOfflinePermission(aDomain);
return IS_PERMISSION_ALLOWED(perm);
}
// Returns two quotas - A hard limit for which adding data will be an error,
// and a limit after which a warning event will be sent to the observer
// service. The warn limit may be -1, in which case there will be no warning.
// If aOverrideQuota is set, the larger offline apps quota is used and no
// warning is sent.
static uint32_t
GetQuota(const nsACString &aDomain, int32_t *aQuota, int32_t *aWarnQuota,
bool aOverrideQuota)
{
uint32_t perm = GetOfflinePermission(aDomain);
if (IS_PERMISSION_ALLOWED(perm) || aOverrideQuota) {
// This is an offline app, give more space by default.
*aQuota = Preferences::GetInt(kOfflineAppQuota,
DEFAULT_OFFLINE_APP_QUOTA) * 1024;
if (perm == nsIOfflineCacheUpdateService::ALLOW_NO_WARN ||
aOverrideQuota) {
*aWarnQuota = -1;
} else {
*aWarnQuota = Preferences::GetInt(kOfflineAppWarnQuota,
DEFAULT_OFFLINE_WARN_QUOTA) * 1024;
}
return perm;
}
// FIXME: per-domain quotas?
*aQuota = Preferences::GetInt(kDefaultQuota, DEFAULT_QUOTA) * 1024;
*aWarnQuota = -1;
return perm;
}
nsSessionStorageEntry::nsSessionStorageEntry(KeyTypePointer aStr)
: nsStringHashKey(aStr), mItem(nullptr)
{
@ -251,8 +182,6 @@ nsDOMStorageManager::Initialize()
nsresult rv;
rv = os->AddObserver(gStorageManager, "cookie-changed", true);
NS_ENSURE_SUCCESS(rv, rv);
rv = os->AddObserver(gStorageManager, "offline-app-removed", 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);
@ -315,59 +244,12 @@ ClearStorageIfDomainMatches(nsDOMStorageEntry* aEntry, void* userArg)
return PL_DHASH_REMOVE;
}
static nsresult
GetOfflineDomains(nsTArray<nsString>& aDomains)
{
nsCOMPtr<nsIPermissionManager> permissionManager =
do_GetService(NS_PERMISSIONMANAGER_CONTRACTID);
if (permissionManager) {
nsCOMPtr<nsISimpleEnumerator> enumerator;
nsresult rv = permissionManager->GetEnumerator(getter_AddRefs(enumerator));
NS_ENSURE_SUCCESS(rv, rv);
bool hasMore;
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMore)) && hasMore) {
nsCOMPtr<nsISupports> supp;
rv = enumerator->GetNext(getter_AddRefs(supp));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIPermission> perm(do_QueryInterface(supp, &rv));
NS_ENSURE_SUCCESS(rv, rv);
uint32_t capability;
rv = perm->GetCapability(&capability);
NS_ENSURE_SUCCESS(rv, rv);
if (capability != nsIPermissionManager::DENY_ACTION) {
nsAutoCString type;
rv = perm->GetType(type);
NS_ENSURE_SUCCESS(rv, rv);
if (type.EqualsLiteral("offline-app")) {
nsAutoCString host;
rv = perm->GetHost(host);
NS_ENSURE_SUCCESS(rv, rv);
aDomains.AppendElement(NS_ConvertUTF8toUTF16(host));
}
}
}
}
return NS_OK;
}
nsresult
nsDOMStorageManager::Observe(nsISupports *aSubject,
const char *aTopic,
const PRUnichar *aData)
{
if (!strcmp(aTopic, "profile-after-change")) {
}
else if (!strcmp(aTopic, "offline-app-removed")) {
nsresult rv = DOMStorageImpl::InitDB();
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->RemoveOwner(NS_ConvertUTF16toUTF8(aData),
true);
} else if (!strcmp(aTopic, "cookie-changed") &&
!nsCRT::strcmp(aData, NS_LITERAL_STRING("cleared").get())) {
mStorages.EnumerateEntries(ClearStorage, nullptr);
@ -375,11 +257,7 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
nsresult rv = DOMStorageImpl::InitDB();
NS_ENSURE_SUCCESS(rv, rv);
// Remove global storage for domains that aren't marked for offline use.
nsTArray<nsString> domains;
rv = GetOfflineDomains(domains);
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->RemoveOwners(domains, true, false);
return DOMStorageImpl::gStorageDB->RemoveAll();
} else if (!strcmp(aTopic, "perm-changed")) {
// Check for cookie permission change
nsCOMPtr<nsIPermission> perm(do_QueryInterface(aSubject));
@ -434,7 +312,7 @@ nsDOMStorageManager::Observe(nsISupports *aSubject,
rv = DOMStorageImpl::InitDB();
NS_ENSURE_SUCCESS(rv, rv);
DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain, true);
DOMStorageImpl::gStorageDB->RemoveOwner(aceDomain);
} else if (!strcmp(aTopic, "profile-before-change")) {
if (DOMStorageImpl::gStorageDB) {
DebugOnly<nsresult> rv =
@ -475,19 +353,7 @@ nsDOMStorageManager::GetUsage(const nsAString& aDomain,
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->GetUsage(NS_ConvertUTF16toUTF8(aDomain),
false, aUsage, false);
}
NS_IMETHODIMP
nsDOMStorageManager::ClearOfflineApps()
{
nsresult rv = DOMStorageImpl::InitDB();
NS_ENSURE_SUCCESS(rv, rv);
nsTArray<nsString> domains;
rv = GetOfflineDomains(domains);
NS_ENSURE_SUCCESS(rv, rv);
return DOMStorageImpl::gStorageDB->RemoveOwners(domains, true, true);
aUsage, false);
}
NS_IMETHODIMP
@ -586,7 +452,6 @@ DOMStorageBase::DOMStorageBase()
: mStorageType(nsPIDOMStorage::Unknown)
, mUseDB(false)
, mSessionOnly(true)
, mCanUseChromePersist(false)
, mInPrivateBrowsing(false)
{
}
@ -598,8 +463,6 @@ DOMStorageBase::DOMStorageBase(DOMStorageBase& aThat)
, mDomain(aThat.mDomain)
, mScopeDBKey(aThat.mScopeDBKey)
, mQuotaETLDplus1DomainDBKey(aThat.mQuotaETLDplus1DomainDBKey)
, mQuotaDomainDBKey(aThat.mQuotaDomainDBKey)
, mCanUseChromePersist(aThat.mCanUseChromePersist)
, mInPrivateBrowsing(aThat.mInPrivateBrowsing)
{
}
@ -616,14 +479,12 @@ DOMStorageBase::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
mUseDB = false;
mScopeDBKey.Truncate();
mQuotaDomainDBKey.Truncate();
mStorageType = nsPIDOMStorage::SessionStorage;
mInPrivateBrowsing = aPrivate;
}
void
DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
bool aCanUseChromePersist,
bool aPrivate)
{
// No need to check for a return value. If this would fail we would not get
@ -643,10 +504,7 @@ DOMStorageBase::InitAsLocalStorage(nsIURI* aDomainURI,
mUseDB = !mScopeDBKey.IsEmpty();
nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(mDomain,
true, false, mQuotaDomainDBKey);
nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(mDomain,
true, true, mQuotaETLDplus1DomainDBKey);
mCanUseChromePersist = aCanUseChromePersist;
mQuotaETLDplus1DomainDBKey);
mStorageType = nsPIDOMStorage::LocalStorage;
mInPrivateBrowsing = aPrivate;
}
@ -731,21 +589,18 @@ DOMStorageImpl::InitDB()
}
void
DOMStorageImpl::InitFromChild(bool aUseDB, bool aCanUseChromePersist,
DOMStorageImpl::InitFromChild(bool aUseDB,
bool aSessionOnly, bool aPrivate,
const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDomainDBKey,
const nsACString& aQuotaETLDplus1DomainDBKey,
uint32_t aStorageType)
{
mUseDB = aUseDB;
mCanUseChromePersist = aCanUseChromePersist;
mSessionOnly = aSessionOnly;
mInPrivateBrowsing = aPrivate;
mDomain = aDomain;
mScopeDBKey = aScopeDBKey;
mQuotaDomainDBKey = aQuotaDomainDBKey;
mQuotaETLDplus1DomainDBKey = aQuotaETLDplus1DomainDBKey;
mStorageType = static_cast<nsPIDOMStorage::nsDOMStorageType>(aStorageType);
}
@ -764,10 +619,9 @@ DOMStorageImpl::InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate)
void
DOMStorageImpl::InitAsLocalStorage(nsIURI* aDomainURI,
bool aCanUseChromePersist,
bool aPrivate)
{
DOMStorageBase::InitAsLocalStorage(aDomainURI, aCanUseChromePersist, aPrivate);
DOMStorageBase::InitAsLocalStorage(aDomainURI, aPrivate);
}
bool
@ -782,12 +636,6 @@ DOMStorageImpl::CacheStoragePermissions()
return mOwner->CacheStoragePermissions();
}
bool
DOMStorageImpl::CanUseChromePersist()
{
return mCanUseChromePersist;
}
nsresult
DOMStorageImpl::GetCachedValue(const nsAString& aKey, nsAString& aValue,
bool* aSecure)
@ -843,39 +691,11 @@ DOMStorageImpl::SetDBValue(const nsAString& aKey,
nsresult rv = InitDB();
NS_ENSURE_SUCCESS(rv, rv);
int32_t offlineAppPermission;
int32_t quota;
int32_t warnQuota;
offlineAppPermission = GetQuota(mDomain, &quota, &warnQuota,
CanUseChromePersist());
CacheKeysFromDB();
int32_t usage;
rv = gStorageDB->SetKey(this, aKey, aValue, aSecure, quota,
!IS_PERMISSION_ALLOWED(offlineAppPermission),
&usage);
rv = gStorageDB->SetKey(this, aKey, aValue, aSecure);
NS_ENSURE_SUCCESS(rv, rv);
if (warnQuota >= 0 && usage > warnQuota) {
// try to include the window that exceeded the warn quota
nsCOMPtr<nsIDOMWindow> window;
JSContext *cx;
nsCOMPtr<nsIJSContextStack> stack =
do_GetService("@mozilla.org/js/xpc/ContextStack;1");
if (stack && NS_SUCCEEDED(stack->Peek(&cx)) && cx) {
nsCOMPtr<nsIScriptContext> scriptContext;
scriptContext = GetScriptContextFromJSContext(cx);
if (scriptContext) {
window = do_QueryInterface(scriptContext->GetGlobalObject());
}
}
nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService();
os->NotifyObservers(window, "dom-storage-warn-quota-exceeded",
NS_ConvertUTF8toUTF16(mDomain).get());
}
return NS_OK;
}
@ -1210,8 +1030,7 @@ DOMStorageImpl::RemoveValue(bool aCallerSecure, const nsAString& aKey,
oldValue = value;
rv = gStorageDB->RemoveKey(this, aKey, !IsOfflineAllowed(mDomain),
aKey.Length() + value.Length());
rv = gStorageDB->RemoveKey(this, aKey);
NS_ENSURE_SUCCESS(rv, rv);
}
else if (entry) {
@ -1364,13 +1183,7 @@ nsDOMStorage::InitAsLocalStorage(nsIPrincipal *aPrincipal, const nsSubstring &aD
mStorageType = LocalStorage;
bool canUseChromePersist = false;
nsCOMPtr<nsIURI> URI;
if (NS_SUCCEEDED(aPrincipal->GetURI(getter_AddRefs(URI))) && URI) {
canUseChromePersist = URICanUseChromePersist(URI);
}
mStorageImpl->InitAsLocalStorage(domainURI, canUseChromePersist, aPrivate);
mStorageImpl->InitAsLocalStorage(domainURI, aPrivate);
return NS_OK;
}
@ -1438,9 +1251,7 @@ nsDOMStorage::CanUseStorage(DOMStorageBase* aStorage /* = NULL */)
uint32_t lifetimePolicy = Preferences::GetUint(kCookiesLifetimePolicy);
// Treat "ask every time" as "reject always".
// Chrome persistent pages can bypass this check.
if ((cookieBehavior == BEHAVIOR_REJECT || lifetimePolicy == ASK_BEFORE_ACCEPT) &&
!URICanUseChromePersist(subjectURI))
if ((cookieBehavior == BEHAVIOR_REJECT || lifetimePolicy == ASK_BEFORE_ACCEPT))
return false;
if (lifetimePolicy == ACCEPT_SESSION && aStorage)
@ -1470,15 +1281,6 @@ nsDOMStorage::CacheStoragePermissions()
return CanAccess(subjectPrincipal);
}
// static
bool
nsDOMStorage::URICanUseChromePersist(nsIURI* aURI) {
bool isAbout;
return
(NS_SUCCEEDED(aURI->SchemeIs("moz-safe-about", &isAbout)) && isAbout) ||
(NS_SUCCEEDED(aURI->SchemeIs("about", &isAbout)) && isAbout);
}
NS_IMETHODIMP
nsDOMStorage::GetLength(uint32_t *aLength)
{

View File

@ -30,10 +30,6 @@
#include "nsDOMStorageDBWrapper.h"
#define IS_PERMISSION_ALLOWED(perm) \
((perm) != nsIPermissionManager::UNKNOWN_ACTION && \
(perm) != nsIPermissionManager::DENY_ACTION)
class nsDOMStorage;
class nsIDOMStorage;
class nsDOMStorageItem;
@ -114,7 +110,7 @@ public:
DOMStorageBase(DOMStorageBase&);
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
virtual nsTArray<nsString>* GetKeys(bool aCallerSecure) = 0;
virtual nsresult GetLength(bool aCallerSecure, uint32_t* aLength) = 0;
@ -170,11 +166,10 @@ public:
// an origin (localStorage).
nsCString& GetScopeDBKey() {return mScopeDBKey;}
// e.g. "moc.rab.%" - reversed eTLD+1 subpart of the domain or
// reversed offline application allowed domain.
nsCString& GetQuotaDomainDBKey(bool aOfflineAllowed)
// e.g. "moc.rab.%" - reversed eTLD+1 subpart of the domain.
nsCString& GetQuotaDomainDBKey()
{
return aOfflineAllowed ? mQuotaDomainDBKey : mQuotaETLDplus1DomainDBKey;
return mQuotaETLDplus1DomainDBKey;
}
virtual bool CacheStoragePermissions() = 0;
@ -202,9 +197,7 @@ protected:
// see comments of the getters bellow.
nsCString mScopeDBKey;
nsCString mQuotaETLDplus1DomainDBKey;
nsCString mQuotaDomainDBKey;
bool mCanUseChromePersist;
bool mInPrivateBrowsing;
};
@ -221,7 +214,7 @@ public:
~DOMStorageImpl();
virtual void InitAsSessionStorage(nsIURI* aDomainURI, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aCanUseChromePersist, bool aPrivate);
virtual void InitAsLocalStorage(nsIURI* aDomainURI, bool aPrivate);
bool SessionOnly() {
return mSessionOnly;
@ -244,10 +237,6 @@ public:
uint64_t CachedVersion() { return mItemsCachedVersion; }
void SetCachedVersion(uint64_t version) { mItemsCachedVersion = version; }
// Some privileged internal pages can use a persistent storage even in
// session-only or private-browsing modes.
bool CanUseChromePersist();
// retrieve the value and secure state corresponding to a key out of storage
// that has been cached in mItems hash table.
nsresult
@ -291,10 +280,9 @@ 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,
void InitFromChild(bool aUseDB, bool aSessionOnly,
bool aPrivate, const nsACString& aDomain,
const nsACString& aScopeDBKey,
const nsACString& aQuotaDomainDBKey,
const nsACString& aQuotaETLDplus1DomainDBKey,
uint32_t aStorageType);
void SetSessionOnly(bool aSessionOnly);
@ -351,12 +339,6 @@ public:
static bool
CanUseStorage(DOMStorageBase* aStorage = nullptr);
// Check whether this URI can use chrome persist storage. This kind of
// storage can bypass cookies limits, private browsing and uses the offline
// apps quota.
static bool
URICanUseChromePersist(nsIURI* aURI);
// Check whether storage may be used. Updates mSessionOnly based on
// the result of CanUseStorage.
bool
@ -503,10 +485,4 @@ protected:
nsresult
NS_NewDOMStorage2(nsISupports* aOuter, REFNSIID aIID, void** aResult);
uint32_t
GetOfflinePermission(const nsACString &aDomain);
bool
IsOfflineAllowed(const nsACString &aDomain);
#endif /* nsDOMStorage_h___ */

View File

@ -5,8 +5,24 @@
#include "nsDOMStorageBaseDB.h"
#include "nsDOMStorage.h"
#include "mozilla/Preferences.h"
// Only allow relatively small amounts of data since performance of
// the synchronous IO is very bad.
#define DEFAULT_QUOTA_LIMIT (5 * 1024)
uint64_t nsDOMStorageBaseDB::sGlobalVersion = 1;
int32_t nsDOMStorageBaseDB::gQuotaLimit = DEFAULT_QUOTA_LIMIT * 1024;
using namespace mozilla;
/* static */
void
nsDOMStorageBaseDB::Init()
{
Preferences::AddIntVarCache(&gQuotaLimit, "dom.storage.default_quota",
DEFAULT_QUOTA_LIMIT);
}
nsDOMStorageBaseDB::nsDOMStorageBaseDB()
{

View File

@ -14,6 +14,8 @@ class DOMStorageImpl;
class nsDOMStorageBaseDB
{
public:
static void Init();
nsDOMStorageBaseDB();
virtual ~nsDOMStorageBaseDB() {}
@ -34,6 +36,10 @@ public:
*/
bool IsScopeDirty(DOMStorageImpl* aStorage);
int32_t GetQuota() {
return gQuotaLimit * 1024;
}
protected:
nsDataHashtable<nsCStringHashKey, uint64_t> mScopesVersion;
@ -45,6 +51,8 @@ protected:
private:
static uint64_t sGlobalVersion;
static int32_t gQuotaLimit;
};
#endif /* nsDOMStorageDB_h___ */

View File

@ -48,7 +48,6 @@ void
nsDOMStorageDBWrapper::Close()
{
mPersistentDB.Close();
mChromePersistentDB.Close();
}
nsresult
@ -59,9 +58,6 @@ nsDOMStorageDBWrapper::Init()
rv = mPersistentDB.Init(NS_LITERAL_STRING("webappsstore.sqlite"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mChromePersistentDB.Init(NS_LITERAL_STRING("chromeappsstore.sqlite"));
NS_ENSURE_SUCCESS(rv, rv);
rv = mSessionOnlyDB.Init(&mPersistentDB);
NS_ENSURE_SUCCESS(rv, rv);
@ -75,12 +71,10 @@ nsresult
nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
{
nsresult rv1, rv2;
rv1 = mChromePersistentDB.FlushTemporaryTables(force);
rv2 = mPersistentDB.FlushTemporaryTables(force);
// Everything flushed? Then no need for a timer.
if (!mChromePersistentDB.mTempTableLoads.Count() &&
!mPersistentDB.mTempTableLoads.Count())
if (!mPersistentDB.mTempTableLoads.Count())
StopTempTableFlushTimer();
return NS_FAILED(rv1) ? rv1 : rv2;
@ -88,8 +82,6 @@ nsDOMStorageDBWrapper::FlushAndDeleteTemporaryTables(bool force)
#define IMPL_FORWARDER_GUTS(_return, _code) \
PR_BEGIN_MACRO \
if (aStorage->CanUseChromePersist()) \
_return mChromePersistentDB._code; \
if (aStorage->IsPrivate()) \
_return mPrivateBrowsingDB._code; \
if (aStorage->SessionOnly()) \
@ -123,13 +115,9 @@ nsresult
nsDOMStorageDBWrapper::SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t *aNewUsage)
bool aSecure)
{
IMPL_FORWARDER(SetKey(aStorage, aKey, aValue, aSecure,
aQuota, aExcludeOfflineFromUsage, aNewUsage));
IMPL_FORWARDER(SetKey(aStorage, aKey, aValue, aSecure));
}
nsresult
@ -142,11 +130,9 @@ nsDOMStorageDBWrapper::SetSecure(DOMStorageImpl* aStorage,
nsresult
nsDOMStorageDBWrapper::RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage)
const nsAString& aKey)
{
IMPL_FORWARDER(RemoveKey(aStorage, aKey, aExcludeOfflineFromUsage, aKeyUsage));
IMPL_FORWARDER(RemoveKey(aStorage, aKey));
}
nsresult
@ -170,7 +156,7 @@ nsDOMStorageDBWrapper::IsScopeDirty(DOMStorageImpl* aStorage)
nsresult
nsDOMStorageDBWrapper::DropSessionOnlyStoragesForHost(const nsACString& aHostName)
{
return mSessionOnlyDB.RemoveOwner(aHostName, true);
return mSessionOnlyDB.RemoveOwner(aHostName);
}
nsresult
@ -180,18 +166,17 @@ nsDOMStorageDBWrapper::DropPrivateBrowsingStorages()
}
nsresult
nsDOMStorageDBWrapper::RemoveOwner(const nsACString& aOwner,
bool aIncludeSubDomains)
nsDOMStorageDBWrapper::RemoveOwner(const nsACString& aOwner)
{
nsresult rv;
rv = mPrivateBrowsingDB.RemoveOwner(aOwner, aIncludeSubDomains);
rv = mPrivateBrowsingDB.RemoveOwner(aOwner);
NS_ENSURE_SUCCESS(rv, rv);
rv = mSessionOnlyDB.RemoveOwner(aOwner, aIncludeSubDomains);
rv = mSessionOnlyDB.RemoveOwner(aOwner);
NS_ENSURE_SUCCESS(rv, rv);
rv = mPersistentDB.RemoveOwner(aOwner, aIncludeSubDomains);
rv = mPersistentDB.RemoveOwner(aOwner);
NS_ENSURE_SUCCESS(rv, rv);
return rv;
@ -199,47 +184,45 @@ nsDOMStorageDBWrapper::RemoveOwner(const nsACString& aOwner,
nsresult
nsDOMStorageDBWrapper::RemoveOwners(const nsTArray<nsString> &aOwners,
bool aIncludeSubDomains, bool aMatch)
nsDOMStorageDBWrapper::RemoveAll()
{
nsresult rv;
rv = mPrivateBrowsingDB.RemoveOwners(aOwners, aIncludeSubDomains, aMatch);
rv = mPrivateBrowsingDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
rv = mSessionOnlyDB.RemoveOwners(aOwners, aIncludeSubDomains, aMatch);
rv = mSessionOnlyDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
rv = mPersistentDB.RemoveOwners(aOwners, aIncludeSubDomains, aMatch);
rv = mPersistentDB.RemoveAll();
NS_ENSURE_SUCCESS(rv, rv);
return rv;
}
nsresult
nsDOMStorageDBWrapper::GetUsage(DOMStorageImpl* aStorage,
bool aExcludeOfflineFromUsage, int32_t *aUsage)
nsDOMStorageDBWrapper::GetUsage(DOMStorageImpl* aStorage, int32_t *aUsage)
{
IMPL_FORWARDER(GetUsage(aStorage, aExcludeOfflineFromUsage, aUsage));
IMPL_FORWARDER(GetUsage(aStorage, aUsage));
}
nsresult
nsDOMStorageDBWrapper::GetUsage(const nsACString& aDomain,
bool aIncludeSubDomains, int32_t *aUsage, bool aPrivate)
int32_t *aUsage, bool aPrivate)
{
if (aPrivate)
return mPrivateBrowsingDB.GetUsage(aDomain, aIncludeSubDomains, aUsage);
return mPrivateBrowsingDB.GetUsage(aDomain, aUsage);
#if 0
// XXX Check where from all this method gets called, not sure this should
// include any potential session-only data
nsresult rv;
rv = mSessionOnlyDB.GetUsage(aDomain, aIncludeSubDomains, aUsage);
rv = mSessionOnlyDB.GetUsage(aDomain, aUsage);
if (NS_SUECEEDED(rv))
return rv;
#endif
return mPersistentDB.GetUsage(aDomain, aIncludeSubDomains, aUsage);
return mPersistentDB.GetUsage(aDomain, aUsage);
}
nsresult
@ -318,38 +301,29 @@ nsDOMStorageDBWrapper::CreateDomainScopeDBKey(const nsACString& aAsciiDomain,
nsresult
nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
bool aIncludeSubDomains,
bool aEffectiveTLDplus1Only,
nsACString& aKey)
{
nsresult rv;
nsAutoCString subdomainsDBKey;
if (aEffectiveTLDplus1Only) {
nsCOMPtr<nsIEffectiveTLDService> eTLDService(do_GetService(
NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIEffectiveTLDService> eTLDService(do_GetService(
NS_EFFECTIVETLDSERVICE_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aAsciiDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIURI> uri;
rv = NS_NewURI(getter_AddRefs(uri), NS_LITERAL_CSTRING("http://") + aAsciiDomain);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString eTLDplusOne;
rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
if (NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS == rv) {
// XXX bug 357323 - what to do for localhost/file exactly?
eTLDplusOne = aAsciiDomain;
rv = NS_OK;
}
NS_ENSURE_SUCCESS(rv, rv);
CreateDomainScopeDBKey(eTLDplusOne, subdomainsDBKey);
nsAutoCString eTLDplusOne;
rv = eTLDService->GetBaseDomain(uri, 0, eTLDplusOne);
if (NS_ERROR_INSUFFICIENT_DOMAIN_LEVELS == rv) {
// XXX bug 357323 - what to do for localhost/file exactly?
eTLDplusOne = aAsciiDomain;
rv = NS_OK;
}
else
CreateDomainScopeDBKey(aAsciiDomain, subdomainsDBKey);
NS_ENSURE_SUCCESS(rv, rv);
if (!aIncludeSubDomains)
subdomainsDBKey.AppendLiteral(":");
CreateDomainScopeDBKey(eTLDplusOne, subdomainsDBKey);
aKey.Assign(subdomainsDBKey);
return NS_OK;
@ -357,7 +331,7 @@ nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
nsresult
nsDOMStorageDBWrapper::GetDomainFromScopeKey(const nsACString& aScope,
nsACString& aDomain)
nsACString& aDomain)
{
nsAutoCString reverseDomain, scope;
scope = aScope;

View File

@ -89,10 +89,7 @@ public:
SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t* aNewUsage);
bool aSecure);
/**
* Set the secure flag for a key in storage. Does nothing if the key was
@ -108,9 +105,7 @@ public:
*/
nsresult
RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage);
const nsAString& aKey);
/**
* Remove all keys belonging to this storage.
@ -134,27 +129,25 @@ public:
* Removes all keys added by a given domain.
*/
nsresult
RemoveOwner(const nsACString& aOwner, bool aIncludeSubDomains);
RemoveOwner(const nsACString& aOwner);
/**
* Removes keys owned by domains that either match or don't match the
* list.
* Removes all keys from storage. Used when clearing storage.
*/
nsresult
RemoveOwners(const nsTArray<nsString>& aOwners,
bool aIncludeSubDomains, bool aMatch);
RemoveAll();
/**
* Returns usage for a storage using its GetQuotaDomainDBKey() as a key.
*/
nsresult
GetUsage(DOMStorageImpl* aStorage, bool aExcludeOfflineFromUsage, int32_t *aUsage);
GetUsage(DOMStorageImpl* aStorage, int32_t *aUsage);
/**
* Returns usage of the domain and optionaly by any subdomain.
*/
nsresult
GetUsage(const nsACString& aDomain, bool aIncludeSubDomains, int32_t *aUsage, bool aPrivate);
GetUsage(const nsACString& aDomain, int32_t *aUsage, bool aPrivate);
/**
* Marks the storage as "cached" after the DOMStorageImpl object has loaded
@ -195,11 +188,10 @@ public:
* and appends a dot.
*/
static nsresult CreateQuotaDomainDBKey(const nsACString& aAsciiDomain,
bool aIncludeSubDomains, bool aETLDplus1Only,
nsACString& aKey);
static nsresult GetDomainFromScopeKey(const nsACString& aScope,
nsACString& aDomain);
nsACString& aDomain);
/**
* Ensures the temp table flush timer is running. This is called when we add
@ -221,7 +213,6 @@ public:
void StopTempTableFlushTimer();
protected:
nsDOMStoragePersistentDB mChromePersistentDB;
nsDOMStoragePersistentDB mPersistentDB;
nsDOMStorageMemoryDB mSessionOnlyDB;
nsDOMStorageMemoryDB mPrivateBrowsingDB;

View File

@ -148,10 +148,7 @@ nsresult
nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t *aNewUsage)
bool aSecure)
{
nsresult rv;
@ -160,8 +157,8 @@ nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
NS_ENSURE_SUCCESS(rv, rv);
int32_t usage = 0;
if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
rv = GetUsage(aStorage, aExcludeOfflineFromUsage, &usage);
if (!aStorage->GetQuotaDomainDBKey().IsEmpty()) {
rv = GetUsage(aStorage, &usage);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -169,7 +166,7 @@ nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
nsInMemoryItem* item;
if (!storage->mTable.Get(aKey, &item)) {
if (usage > aQuota) {
if (usage > GetQuota()) {
return NS_ERROR_DOM_QUOTA_REACHED;
}
@ -185,7 +182,7 @@ nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
if (!aSecure && item->mSecure)
return NS_ERROR_DOM_SECURITY_ERR;
usage -= aKey.Length() + item->mValue.Length();
if (usage > aQuota) {
if (usage > GetQuota()) {
return NS_ERROR_DOM_QUOTA_REACHED;
}
}
@ -195,8 +192,6 @@ nsDOMStorageMemoryDB::SetKey(DOMStorageImpl* aStorage,
item->mValue = aValue;
item->mSecure = aSecure;
*aNewUsage = usage;
MarkScopeDirty(aStorage);
return NS_OK;
@ -226,9 +221,7 @@ nsDOMStorageMemoryDB::SetSecure(DOMStorageImpl* aStorage,
nsresult
nsDOMStorageMemoryDB::RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage)
const nsAString& aKey)
{
nsresult rv;
@ -304,15 +297,11 @@ RemoveOwnersEnum(const nsACString& key,
}
nsresult
nsDOMStorageMemoryDB::RemoveOwner(const nsACString& aOwner,
bool aIncludeSubDomains)
nsDOMStorageMemoryDB::RemoveOwner(const nsACString& aOwner)
{
nsAutoCString subdomainsDBKey;
nsDOMStorageDBWrapper::CreateDomainScopeDBKey(aOwner, subdomainsDBKey);
if (!aIncludeSubDomains)
subdomainsDBKey.AppendLiteral(":");
RemoveOwnersStruc struc;
struc.mSubDomain = &subdomainsDBKey;
struc.mMatch = true;
@ -323,39 +312,6 @@ nsDOMStorageMemoryDB::RemoveOwner(const nsACString& aOwner,
return NS_OK;
}
nsresult
nsDOMStorageMemoryDB::RemoveOwners(const nsTArray<nsString> &aOwners,
bool aIncludeSubDomains,
bool aMatch)
{
if (aOwners.Length() == 0) {
if (aMatch) {
return NS_OK;
}
return RemoveAll();
}
for (uint32_t i = 0; i < aOwners.Length(); i++) {
nsAutoCString quotaKey;
nsDOMStorageDBWrapper::CreateDomainScopeDBKey(
NS_ConvertUTF16toUTF8(aOwners[i]), quotaKey);
if (!aIncludeSubDomains)
quotaKey.AppendLiteral(":");
RemoveOwnersStruc struc;
struc.mSubDomain = &quotaKey;
struc.mMatch = aMatch;
mData.Enumerate(RemoveOwnersEnum, &struc);
}
MarkAllScopesDirty();
return NS_OK;
}
nsresult
nsDOMStorageMemoryDB::RemoveAll()
{
@ -367,34 +323,28 @@ nsDOMStorageMemoryDB::RemoveAll()
}
nsresult
nsDOMStorageMemoryDB::GetUsage(DOMStorageImpl* aStorage,
bool aExcludeOfflineFromUsage, int32_t *aUsage)
nsDOMStorageMemoryDB::GetUsage(DOMStorageImpl* aStorage, int32_t *aUsage)
{
return GetUsageInternal(aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage),
aExcludeOfflineFromUsage, aUsage);
return GetUsageInternal(aStorage->GetQuotaDomainDBKey(), aUsage);
}
nsresult
nsDOMStorageMemoryDB::GetUsage(const nsACString& aDomain,
bool aIncludeSubDomains,
int32_t *aUsage)
{
nsresult rv;
nsAutoCString quotadomainDBKey;
rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
aIncludeSubDomains,
false,
quotadomainDBKey);
NS_ENSURE_SUCCESS(rv, rv);
return GetUsageInternal(quotadomainDBKey, false, aUsage);
return GetUsageInternal(quotadomainDBKey, aUsage);
}
struct GetUsageEnumStruc
{
int32_t mUsage;
int32_t mExcludeOfflineFromUsage;
nsCString mSubdomain;
};
@ -406,13 +356,6 @@ GetUsageEnum(const nsACString& key,
GetUsageEnumStruc* struc = (GetUsageEnumStruc*)closure;
if (StringBeginsWith(key, struc->mSubdomain)) {
if (struc->mExcludeOfflineFromUsage) {
nsAutoCString domain;
nsresult rv = nsDOMStorageDBWrapper::GetDomainFromScopeKey(key, domain);
if (NS_SUCCEEDED(rv) && IsOfflineAllowed(domain))
return PL_DHASH_NEXT;
}
struc->mUsage += storageData->mUsageDelta;
}
@ -421,19 +364,16 @@ GetUsageEnum(const nsACString& key,
nsresult
nsDOMStorageMemoryDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
bool aExcludeOfflineFromUsage,
int32_t *aUsage)
{
GetUsageEnumStruc struc;
struc.mUsage = 0;
struc.mExcludeOfflineFromUsage = aExcludeOfflineFromUsage;
struc.mSubdomain = aQuotaDomainDBKey;
if (mPreloadDB) {
nsresult rv;
rv = mPreloadDB->GetUsageInternal(aQuotaDomainDBKey,
aExcludeOfflineFromUsage, &struc.mUsage);
rv = mPreloadDB->GetUsageInternal(aQuotaDomainDBKey, &struc.mUsage);
NS_ENSURE_SUCCESS(rv, rv);
}

View File

@ -78,10 +78,7 @@ public:
SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t* aNewUsage);
bool aSecure);
/**
* Set the secure flag for a key in storage. Does nothing if the key was
@ -97,9 +94,7 @@ public:
*/
nsresult
RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage);
const nsAString& aKey);
/**
* Remove all keys belonging to this storage.
@ -117,15 +112,7 @@ public:
* Removes all keys added by a given domain.
*/
nsresult
RemoveOwner(const nsACString& aOwner, bool aIncludeSubDomains);
/**
* Removes keys owned by domains that either match or don't match the
* list.
*/
nsresult
RemoveOwners(const nsTArray<nsString>& aOwners,
bool aIncludeSubDomains, bool aMatch);
RemoveOwner(const nsACString& aOwner);
/**
* Removes all keys from storage. Used when clearing storage.
@ -137,13 +124,13 @@ public:
* Returns usage for a storage using its GetQuotaDomainDBKey() as a key.
*/
nsresult
GetUsage(DOMStorageImpl* aStorage, bool aExcludeOfflineFromUsage, int32_t *aUsage);
GetUsage(DOMStorageImpl* aStorage, int32_t *aUsage);
/**
* Returns usage of the domain and optionaly by any subdomain.
*/
nsresult
GetUsage(const nsACString& aDomain, bool aIncludeSubDomains, int32_t *aUsage);
GetUsage(const nsACString& aDomain, int32_t *aUsage);
protected:
@ -152,7 +139,7 @@ protected:
bool mPreloading;
nsresult
GetUsageInternal(const nsACString& aQuotaDomainDBKey, bool aExcludeOfflineFromUsage, int32_t *aUsage);
GetUsageInternal(const nsACString& aQuotaDomainDBKey, int32_t *aUsage);
};
#endif

View File

@ -63,49 +63,12 @@ nsReverseStringSQLFunction::OnFunctionCall(
return NS_OK;
}
class nsIsOfflineSQLFunction MOZ_FINAL : public mozIStorageFunction
{
NS_DECL_ISUPPORTS
NS_DECL_MOZISTORAGEFUNCTION
};
NS_IMPL_ISUPPORTS1(nsIsOfflineSQLFunction, mozIStorageFunction)
nsDOMStoragePersistentDB::nsDOMStoragePersistentDB()
: mStatements(mConnection)
{
mTempTableLoads.Init(16);
}
NS_IMETHODIMP
nsIsOfflineSQLFunction::OnFunctionCall(
mozIStorageValueArray *aFunctionArguments, nsIVariant **aResult)
{
nsresult rv;
nsAutoCString scope;
rv = aFunctionArguments->GetUTF8String(0, scope);
NS_ENSURE_SUCCESS(rv, rv);
nsAutoCString domain;
rv = nsDOMStorageDBWrapper::GetDomainFromScopeKey(scope, domain);
NS_ENSURE_SUCCESS(rv, rv);
bool hasOfflinePermission = IsOfflineAllowed(domain);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<nsIWritableVariant> outVar(do_CreateInstance(
NS_VARIANT_CONTRACTID, &rv));
NS_ENSURE_SUCCESS(rv, rv);
rv = outVar->SetAsBool(hasOfflinePermission);
NS_ENSURE_SUCCESS(rv, rv);
*aResult = outVar.get();
outVar.forget();
return NS_OK;
}
nsresult
nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
{
@ -196,12 +159,6 @@ nsDOMStoragePersistentDB::Init(const nsString& aDatabaseName)
rv = mConnection->CreateFunction(NS_LITERAL_CSTRING("REVERSESTRING"), 1, function1);
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIStorageFunction> function2(new nsIsOfflineSQLFunction());
NS_ENSURE_TRUE(function2, NS_ERROR_OUT_OF_MEMORY);
rv = mConnection->CreateFunction(NS_LITERAL_CSTRING("ISOFFLINE"), 1, function2);
NS_ENSURE_SUCCESS(rv, rv);
bool exists;
// Check if there is storage of Gecko 1.9.0 and if so, upgrade that storage
@ -476,10 +433,7 @@ nsresult
nsDOMStoragePersistentDB::SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t *aNewUsage)
bool aSecure)
{
nsresult rv;
@ -487,8 +441,8 @@ nsDOMStoragePersistentDB::SetKey(DOMStorageImpl* aStorage,
NS_ENSURE_SUCCESS(rv, rv);
int32_t usage = 0;
if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
rv = GetUsage(aStorage, aExcludeOfflineFromUsage, &usage);
if (!aStorage->GetQuotaDomainDBKey().IsEmpty()) {
rv = GetUsage(aStorage, &usage);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -503,7 +457,7 @@ nsDOMStoragePersistentDB::SetKey(DOMStorageImpl* aStorage,
usage -= aKey.Length() + previousValue.Length();
}
if (usage > aQuota) {
if (usage > GetQuota()) {
return NS_ERROR_DOM_QUOTA_REACHED;
}
@ -533,13 +487,11 @@ nsDOMStoragePersistentDB::SetKey(DOMStorageImpl* aStorage,
rv = stmt->Execute();
NS_ENSURE_SUCCESS(rv, rv);
if (!aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage).IsEmpty()) {
if (!aStorage->GetQuotaDomainDBKey().IsEmpty()) {
// No need to set mCachedOwner since it was set by GetUsage()
mCachedUsage = usage;
}
*aNewUsage = usage;
MarkScopeDirty(aStorage);
return NS_OK;
@ -587,9 +539,7 @@ nsDOMStoragePersistentDB::SetSecure(DOMStorageImpl* aStorage,
nsresult
nsDOMStoragePersistentDB::RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage)
const nsAString& aKey)
{
nsresult rv;
@ -605,7 +555,7 @@ nsDOMStoragePersistentDB::RemoveKey(DOMStorageImpl* aStorage,
mozStorageStatementScoper scope(stmt);
if (DomainMaybeCached(
aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage))) {
aStorage->GetQuotaDomainDBKey())) {
mCachedUsage = 0;
mCachedOwner.Truncate();
}
@ -656,8 +606,7 @@ nsDOMStoragePersistentDB::ClearStorage(DOMStorageImpl* aStorage)
}
nsresult
nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
bool aIncludeSubDomains)
nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner)
{
nsresult rv;
@ -679,8 +628,6 @@ nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
mCachedOwner.Truncate();
}
if (!aIncludeSubDomains)
subdomainsDBKey.AppendLiteral(":");
subdomainsDBKey.AppendLiteral("*");
rv = stmt->BindUTF8StringByName(NS_LITERAL_CSTRING("scope"),
@ -695,84 +642,6 @@ nsDOMStoragePersistentDB::RemoveOwner(const nsACString& aOwner,
return NS_OK;
}
nsresult
nsDOMStoragePersistentDB::RemoveOwners(const nsTArray<nsString> &aOwners,
bool aIncludeSubDomains,
bool aMatch)
{
if (aOwners.Length() == 0) {
if (aMatch) {
return NS_OK;
}
return RemoveAll();
}
// Using nsString here because it is going to be very long
nsCString expression;
if (aMatch) {
expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope IN (");
} else {
expression.AppendLiteral("DELETE FROM webappsstore2_view WHERE scope NOT IN (");
}
for (uint32_t i = 0; i < aOwners.Length(); i++) {
if (i)
expression.AppendLiteral(" UNION ");
expression.AppendLiteral(
"SELECT DISTINCT scope FROM webappsstore2_temp WHERE scope GLOB :scope");
expression.AppendInt(i);
expression.AppendLiteral(" UNION ");
expression.AppendLiteral(
"SELECT DISTINCT scope FROM webappsstore2 WHERE scope GLOB :scope");
expression.AppendInt(i);
}
expression.AppendLiteral(");");
nsCOMPtr<mozIStorageStatement> statement;
nsresult rv;
rv = MaybeCommitInsertTransaction();
NS_ENSURE_SUCCESS(rv, rv);
rv = mConnection->CreateStatement(expression,
getter_AddRefs(statement));
NS_ENSURE_SUCCESS(rv, rv);
for (uint32_t i = 0; i < aOwners.Length(); i++) {
nsAutoCString quotaKey;
rv = nsDOMStorageDBWrapper::CreateDomainScopeDBKey(
NS_ConvertUTF16toUTF8(aOwners[i]), quotaKey);
if (DomainMaybeCached(quotaKey)) {
mCachedUsage = 0;
mCachedOwner.Truncate();
}
if (!aIncludeSubDomains)
quotaKey.AppendLiteral(":");
quotaKey.AppendLiteral("*");
nsAutoCString paramName;
paramName.Assign("scope");
paramName.AppendInt(i);
rv = statement->BindUTF8StringByName(paramName, quotaKey);
NS_ENSURE_SUCCESS(rv, rv);
}
rv = statement->Execute();
NS_ENSURE_SUCCESS(rv, rv);
MarkAllScopesDirty();
return NS_OK;
}
nsresult
nsDOMStoragePersistentDB::RemoveAll()
{
@ -797,34 +666,27 @@ nsDOMStoragePersistentDB::RemoveAll()
nsresult
nsDOMStoragePersistentDB::GetUsage(DOMStorageImpl* aStorage,
bool aExcludeOfflineFromUsage,
int32_t *aUsage)
{
return GetUsageInternal(aStorage->GetQuotaDomainDBKey(!aExcludeOfflineFromUsage),
aExcludeOfflineFromUsage,
aUsage);
return GetUsageInternal(aStorage->GetQuotaDomainDBKey(), aUsage);
}
nsresult
nsDOMStoragePersistentDB::GetUsage(const nsACString& aDomain,
bool aIncludeSubDomains,
int32_t *aUsage)
{
nsresult rv;
nsAutoCString quotadomainDBKey;
rv = nsDOMStorageDBWrapper::CreateQuotaDomainDBKey(aDomain,
aIncludeSubDomains,
false,
quotadomainDBKey);
NS_ENSURE_SUCCESS(rv, rv);
return GetUsageInternal(quotadomainDBKey, false, aUsage);
return GetUsageInternal(quotadomainDBKey, aUsage);
}
nsresult
nsDOMStoragePersistentDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
bool aExcludeOfflineFromUsage,
int32_t *aUsage)
{
if (aQuotaDomainDBKey == mCachedOwner) {
@ -838,43 +700,22 @@ nsDOMStoragePersistentDB::GetUsageInternal(const nsACString& aQuotaDomainDBKey,
NS_ENSURE_SUCCESS(rv, rv);
nsCOMPtr<mozIStorageStatement> stmt;
if (aExcludeOfflineFromUsage) {
stmt = mStatements.GetCachedStatement(
"SELECT SUM(LENGTH(key) + LENGTH(value)) "
"FROM ( "
"SELECT key, value FROM webappsstore2_temp "
"WHERE scope GLOB :scope "
"AND NOT ISOFFLINE(scope) "
"UNION ALL "
"SELECT key, value FROM webappsstore2 "
"WHERE scope GLOB :scope "
"AND NOT ISOFFLINE(scope) "
"AND NOT EXISTS ( "
"SELECT scope, key "
"FROM webappsstore2_temp "
"WHERE scope = webappsstore2.scope "
"AND key = webappsstore2.key "
") "
") "
);
} else {
stmt = mStatements.GetCachedStatement(
"SELECT SUM(LENGTH(key) + LENGTH(value)) "
"FROM ( "
"SELECT key,value FROM webappsstore2_temp "
"WHERE scope GLOB :scope "
"UNION ALL "
"SELECT key,value FROM webappsstore2 "
"WHERE scope GLOB :scope "
"AND NOT EXISTS ( "
"SELECT scope, key "
"FROM webappsstore2_temp "
"WHERE scope = webappsstore2.scope "
"AND key = webappsstore2.key "
") "
") "
);
}
stmt = mStatements.GetCachedStatement(
"SELECT SUM(LENGTH(key) + LENGTH(value)) "
"FROM ( "
"SELECT key,value FROM webappsstore2_temp "
"WHERE scope GLOB :scope "
"UNION ALL "
"SELECT key,value FROM webappsstore2 "
"WHERE scope GLOB :scope "
"AND NOT EXISTS ( "
"SELECT scope, key "
"FROM webappsstore2_temp "
"WHERE scope = webappsstore2.scope "
"AND key = webappsstore2.key "
") "
") "
);
NS_ENSURE_STATE(stmt);
mozStorageStatementScoper scope(stmt);

View File

@ -63,10 +63,7 @@ public:
SetKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
const nsAString& aValue,
bool aSecure,
int32_t aQuota,
bool aExcludeOfflineFromUsage,
int32_t* aNewUsage);
bool aSecure);
/**
* Set the secure flag for a key in storage. Does nothing if the key was
@ -82,9 +79,7 @@ public:
*/
nsresult
RemoveKey(DOMStorageImpl* aStorage,
const nsAString& aKey,
bool aExcludeOfflineFromUsage,
int32_t aKeyUsage);
const nsAString& aKey);
/**
* Remove all keys belonging to this storage.
@ -95,15 +90,7 @@ public:
* Removes all keys added by a given domain.
*/
nsresult
RemoveOwner(const nsACString& aOwner, bool aIncludeSubDomains);
/**
* Removes keys owned by domains that either match or don't match the
* list.
*/
nsresult
RemoveOwners(const nsTArray<nsString>& aOwners,
bool aIncludeSubDomains, bool aMatch);
RemoveOwner(const nsACString& aOwner);
/**
* Removes all keys from storage. Used when clearing storage.
@ -115,13 +102,13 @@ public:
* Returns usage for a storage using its GetQuotaDomainDBKey() as a key.
*/
nsresult
GetUsage(DOMStorageImpl* aStorage, bool aExcludeOfflineFromUsage, int32_t *aUsage);
GetUsage(DOMStorageImpl* aStorage, int32_t *aUsage);
/**
* Returns usage of the domain and optionaly by any subdomain.
*/
nsresult
GetUsage(const nsACString& aDomain, bool aIncludeSubDomains, int32_t *aUsage);
GetUsage(const nsACString& aDomain, int32_t *aUsage);
/**
* Clears all in-memory data from private browsing mode
@ -174,7 +161,7 @@ protected:
friend class nsDOMStorageDBWrapper;
friend class nsDOMStorageMemoryDB;
nsresult
GetUsageInternal(const nsACString& aQuotaDomainDBKey, bool aExcludeOfflineFromUsage, int32_t *aUsage);
GetUsageInternal(const nsACString& aQuotaDomainDBKey, int32_t *aUsage);
// Compares aDomain with the mCachedOwner and returns false if changes
// in aDomain don't affect mCachedUsage.

View File

@ -52,8 +52,6 @@ MOCHITEST_FILES = \
test_localStorageQuotaSessionOnly.html \
test_localStorageQuotaSessionOnly2.html \
test_localStorageKeyOrder.html \
test_removeOwnersAPI.html \
test_removeOwnersAPISessionOnly.html \
test_storageConstructor.html \
$(NULL)

View File

@ -13,36 +13,7 @@ netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var currentTest = 1;
var prefs = Components.classes["@mozilla.org/preferences-service;1"]
.getService(Components.interfaces.nsIPrefBranch);
var quota, quotaOffline;
function addOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.addFromPrincipal(principal, "offline-app",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
}
function removeOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.removeFromPrincipal(principal, "offline-app");
}
var quota;
function doNextTest()
{
@ -61,12 +32,6 @@ function doNextTest()
quota = 5*1024;
}
prefs.setIntPref("dom.storage.default_quota", 1);
try {
quotaOffline = prefs.getIntPref("offline-apps.quota.max");
} catch (ex) {
quotaOffline = 200*1024;
}
prefs.setIntPref("offline-apps.quota.max", 2);
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
@ -133,74 +98,8 @@ function doNextTest()
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
case 11:
// test1.example.com is now using its own offline app quota
addOfflineApp("http://test1.example.com");
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 12:
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 13:
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
// Now we have 1503 bytes stored, this exceeds the default storage quota
break;
case 14:
// Now check that upper level domain that is not set as an offline app
// domain is allowed to store data and is using the default quota
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 15:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 16:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure";
break;
case 17:
slaveOrigin = "http://test2.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&failure";
break;
case 18:
// check an offline app domain may store some more data
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&success";
break;
case 19:
// check an offline app domain is using its own (larger) quota
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&E&failure";
break;
case 20:
// Do a clean up...
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
case 21:
// Do a clean up...
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
default: // end
removeOfflineApp("http://test1.example.com");
prefs.setIntPref("dom.storage.default_quota", quota);
prefs.setIntPref("offline-apps.quota.max", quotaOffline);
SimpleTest.finish();
}

View File

@ -21,36 +21,7 @@ var cp = Components.classes["@mozilla.org/cookie/permission;1"]
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_SESSION);
var quota, quotaOffline;
function addOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.addFromPrincipal(principal, "offline-app",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
}
function removeOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.removeFromPrincipal(principal, "offline-app");
}
var quota;
function doNextTest()
{
@ -69,12 +40,6 @@ function doNextTest()
quota = 5*1024;
}
prefs.setIntPref("dom.storage.default_quota", 1);
try {
quotaOffline = prefs.getIntPref("offline-apps.quota.max");
} catch (ex) {
quotaOffline = 200*1024;
}
prefs.setIntPref("offline-apps.quota.max", 2);
slaveOrigin = "http://example.com";
@ -142,74 +107,8 @@ function doNextTest()
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear";
break;
case 11:
// test1.example.com is now using its own offline app quota
addOfflineApp("http://test1.example.com");
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 12:
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 13:
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
// Now we have 1503 bytes stored, this exceeds the default storage quota
break;
case 14:
// Now check that upper level domain that is not set as an offline app
// domain is allowed to store data and is using the default quota
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 15:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 16:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure";
break;
case 17:
slaveOrigin = "http://test2.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&failure";
break;
case 18:
// check an offline app domain may store some more data
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&success";
break;
case 19:
// check an offline app domain is using its own (larger) quota
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&E&failure";
break;
case 20:
// Do a clean up...
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
case 21:
// Do a clean up...
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
default:
removeOfflineApp("http://test1.example.com");
prefs.setIntPref("dom.storage.default_quota", quota);
prefs.setIntPref("offline-apps.quota.max", quotaOffline);
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_DEFAULT);
SimpleTest.finish();
}

View File

@ -19,36 +19,7 @@ var uri = io.newURI(window.location, "", null);
var cp = Cc["@mozilla.org/cookie/permission;1"]
.getService(Components.interfaces.nsICookiePermission);
var quota, quotaOffline;
function addOfflineApp(url)
{
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.addFromPrincipal(principal, "offline-app",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
}
function removeOfflineApp(url)
{
var permissionManager = Cc["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.removeFromPrincipal(principal, "offline-app");
}
var quota;
function doNextTest()
{
@ -65,12 +36,6 @@ function doNextTest()
quota = 5*1024;
}
prefs.setIntPref("dom.storage.default_quota", 1);
try {
quotaOffline = prefs.getIntPref("offline-apps.quota.max");
} catch (ex) {
quotaOffline = 200*1024;
}
prefs.setIntPref("offline-apps.quota.max", 2);
slaveOrigin = "http://example.com";
@ -126,89 +91,8 @@ function doNextTest()
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_DEFAULT);
break;
case 9:
// test1.example.com is now using its own offline app quota
addOfflineApp("http://test1.example.com");
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 10:
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 11:
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_SESSION);
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
// Now we have 1503 bytes stored, this exceeds the default storage quota
break;
case 12:
// Now check that upper level domain that is not set as an offline app
// domain is allowed to store data and is using the default quota
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
case 13:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
case 14:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&failure";
break;
case 15:
slaveOrigin = "http://test2.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&failure";
break;
case 16:
// Check an offline app domain may store some more data
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&D&success";
break;
case 17:
// Check an offline app domain is using its own (larger) quota
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&E&failure";
break;
case 18:
// This test checks we correctly subtract A from the usage. A is inherited
// from the persistent database before we switch to session-only cookies
// mode
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?remove&A&success";
break;
case 19:
// now we shold have more space to store a new value
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&E&success";
break;
case 20:
// Do a clean up...
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
case 21:
// Do a clean up...
slaveOrigin = "http://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?clear";
break;
default:
removeOfflineApp("http://test1.example.com");
prefs.setIntPref("dom.storage.default_quota", quota);
prefs.setIntPref("offline-apps.quota.max", quotaOffline);
cp.setAccess(uri, Components.interfaces.nsICookiePermission.ACCESS_DEFAULT);
SimpleTest.finish();
}

View File

@ -1,143 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>localStorage and DOM quota test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="interOriginTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var currentTest = 1;
var currentStep = 1;
function addOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.addFromPrincipal(principal, "offline-app",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
}
function removeOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.removeFromPrincipal(principal, "offline-app");
}
function doNextTest()
{
slave = frame;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
currentStep = 1;
switch (currentTest)
{
// Add something to storage of example.com
case 1:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&A&success";
break;
// Add something to storage of test1.example.com, secure schema
case 2:
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&B&success";
break;
// Add something to storage of http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp, secure schema
case 3:
slaveOrigin = "http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp";
slave.location = slaveOrigin + slavePath + "frameQuota.html?add&C&success";
break;
// Call RemoveOwners API through storage manager.
// Classify the sites above as offline-app using
// the permission manager to let the storage manager
// know about them.
case 4:
addOfflineApp("http://example.com");
addOfflineApp("http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp");
var manager = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
try {
manager.clearOfflineApps();
}
catch (ex) {
ok(false, "Exception not thrown during clearOfflineApps()");
}
removeOfflineApp("http://example.com");
removeOfflineApp("http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp");
// Now check that those two sites' data disappeared
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?checkclean&A&success";
break;
case 5:
slaveOrigin = "http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp";
slave.location = slaveOrigin + slavePath + "frameQuota.html?checkclean&C&success";
break;
case 6:
// Also subdomains to example.com must be deleted
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?checkclean&B&success";
break;
case 7:
addOfflineApp("https://test1.example.com");
var manager = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
try {
manager.clearOfflineApps();
}
catch (ex) {
ok(false, "Exception not thrown during clearOfflineApps()");
}
removeOfflineApp("https://test1.example.com");
// Now check that those site's data disappeared
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuota.html?checkclean&B&success";
break;
case 8:
SimpleTest.finish();
}
++currentTest;
}
function doStep()
{
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="doNextTest();">
<iframe src="" name="frame"></iframe>
</body>
</html>

View File

@ -1,158 +0,0 @@
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>localStorage and DOM quota test</title>
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
<script type="text/javascript" src="interOriginTest.js"></script>
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
<script type="text/javascript">
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var currentTest = 1;
var currentStep = 1;
function addOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.addFromPrincipal(principal, "offline-app",
Components.interfaces.nsIPermissionManager.ALLOW_ACTION);
}
function removeOfflineApp(url)
{
var permissionManager = Components.classes["@mozilla.org/permissionmanager;1"]
.getService(Components.interfaces.nsIPermissionManager);
var uri = Components.classes["@mozilla.org/network/io-service;1"]
.getService(Components.interfaces.nsIIOService)
.newURI(url, null, null);
var principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.getNoAppCodebasePrincipal(uri);
permissionManager.removeFromPrincipal(principal, "offline-app");
}
function doNextTest()
{
slave = frame;
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
currentStep = 1;
switch (currentTest)
{
// Add something to storage of example.com
case 1:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&A&success";
break;
// Add something to storage of test1.example.com, secure schema
case 2:
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&B&success";
break;
// Add something to storage of http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp, secure schema
case 3:
slaveOrigin = "http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?add&C&success";
break;
// Call RemoveOwners API through storage manager.
// Classify the sites above as offline-app using
// the permission manager to let the storage manager
// know about them.
case 4:
addOfflineApp("http://example.com");
addOfflineApp("http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp");
var manager = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
try {
manager.clearOfflineApps();
}
catch (ex) {
ok(false, "Exception not thrown during clearOfflineApps()");
}
removeOfflineApp("http://example.com");
removeOfflineApp("http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp");
// Now check that those two sites' data disappeared
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?checkclean&A&success";
break;
case 5:
slaveOrigin = "http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?checkclean&C&success";
break;
case 6:
// Also subdomains to example.com must be deleted
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?checkclean&B&success";
break;
case 7:
addOfflineApp("https://test1.example.com");
var manager = Components.classes["@mozilla.org/dom/storagemanager;1"]
.getService(Components.interfaces.nsIDOMStorageManager);
try {
manager.clearOfflineApps();
}
catch (ex) {
ok(false, "Exception not thrown during clearOfflineApps()");
}
removeOfflineApp("https://test1.example.com");
// Now check that those site's data disappeared
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?checkclean&B&success";
break;
case 8:
slaveOrigin = "http://example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear";
break;
case 9:
slaveOrigin = "https://test1.example.com";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear";
break;
case 10:
slaveOrigin = "http://sub1.xn--hxajbheg2az3al.xn--jxalpdlp";
slave.location = slaveOrigin + slavePath + "frameQuotaSessionOnly.html?clear";
break;
case 11:
SimpleTest.finish();
}
++currentTest;
}
function doStep()
{
}
SimpleTest.waitForExplicitFinish();
</script>
</head>
<body onload="doNextTest();">
<iframe src="" name="frame"></iframe>
</body>
</html>

View File

@ -59,6 +59,7 @@
#include "nsMathMLAtoms.h"
#include "nsMathMLOperators.h"
#include "Navigator.h"
#include "nsDOMStorageBaseDB.h"
#ifdef MOZ_XUL
#include "nsXULPopupManager.h"
@ -255,6 +256,8 @@ nsLayoutStatics::Initialize()
nsPermissionManager::AppUninstallObserverInit();
nsDOMStorageBaseDB::Init();
return NS_OK;
}