Bug 1165217 - Use nsIPrincipal instead of nsIURI/appId/inBrowser for nsIQuotaManager, r=janv

This commit is contained in:
Michael Layzell 2015-07-03 17:36:28 -04:00
parent aa26047103
commit 5dd6c9804e
11 changed files with 76 additions and 132 deletions

View File

@ -188,8 +188,11 @@ function initIndexedDBRow()
var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"] var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(nsIQuotaManager); .getService(nsIQuotaManager);
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.createCodebasePrincipal(gPermURI, {});
gUsageRequest = gUsageRequest =
quotaManager.getUsageForURI(gPermURI, onIndexedDBUsageCallback); quotaManager.getUsageForPrincipal(principal, onIndexedDBUsageCallback);
var status = document.getElementById("indexedDBStatus"); var status = document.getElementById("indexedDBStatus");
var button = document.getElementById("indexedDBClear"); var button = document.getElementById("indexedDBClear");
@ -201,9 +204,13 @@ function initIndexedDBRow()
function onIndexedDBClear() function onIndexedDBClear()
{ {
let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.createCodebasePrincipal(gPermURI, {});
Components.classes["@mozilla.org/dom/quota/manager;1"] Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(nsIQuotaManager) .getService(nsIQuotaManager)
.clearStoragesForURI(gPermURI); .clearStoragesForPrincipal(principal);
Components.classes["@mozilla.org/serviceworkers/manager;1"] Components.classes["@mozilla.org/serviceworkers/manager;1"]
.getService(Components.interfaces.nsIServiceWorkerManager) .getService(Components.interfaces.nsIServiceWorkerManager)
@ -213,8 +220,9 @@ function onIndexedDBClear()
initIndexedDBRow(); initIndexedDBRow();
} }
function onIndexedDBUsageCallback(uri, usage, fileUsage) function onIndexedDBUsageCallback(principal, usage, fileUsage)
{ {
let uri = principal.URI;
if (!uri.equals(gPermURI)) { if (!uri.equals(gPermURI)) {
throw new Error("Callback received for bad URI: " + uri); throw new Error("Callback received for bad URI: " + uri);
} }

View File

@ -6,13 +6,16 @@ const nsIQuotaManager = Components.interfaces.nsIQuotaManager;
let gURI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI("http://localhost", null, null); let gURI = Components.classes["@mozilla.org/network/io-service;1"].getService(Components.interfaces.nsIIOService).newURI("http://localhost", null, null);
function onUsageCallback(uri, usage, fileUsage) {} function onUsageCallback(principal, usage, fileUsage) {}
function onLoad() function onLoad()
{ {
var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"] var quotaManager = Components.classes["@mozilla.org/dom/quota/manager;1"]
.getService(nsIQuotaManager); .getService(nsIQuotaManager);
var quotaRequest = quotaManager.getUsageForURI(gURI, onUsageCallback); let principal = Components.classes["@mozilla.org/scriptsecuritymanager;1"]
.getService(Components.interfaces.nsIScriptSecurityManager)
.createCodebasePrincipal(gURI, {});
var quotaRequest = quotaManager.getUsageForPrincipal(principal, onUsageCallback);
quotaRequest.cancel(); quotaRequest.cancel();
Components.classes["@mozilla.org/observer-service;1"] Components.classes["@mozilla.org/observer-service;1"]
.getService(Components.interfaces.nsIObserverService) .getService(Components.interfaces.nsIObserverService)

View File

@ -92,7 +92,7 @@ function testSteps()
let usageBeforeMaintenance; let usageBeforeMaintenance;
quotaManager.getUsageForURI(uri, (url, usage) => { quotaManager.getUsageForPrincipal(principal, (principal, usage) => {
ok(usage > 0, "Usage is non-zero"); ok(usage > 0, "Usage is non-zero");
usageBeforeMaintenance = usage; usageBeforeMaintenance = usage;
continueToNextStep(); continueToNextStep();
@ -118,7 +118,7 @@ function testSteps()
let usageAfterMaintenance; let usageAfterMaintenance;
quotaManager.getUsageForURI(uri, (url, usage) => { quotaManager.getUsageForPrincipal(principal, (principal, usage) => {
ok(usage > 0, "Usage is non-zero"); ok(usage > 0, "Usage is non-zero");
usageAfterMaintenance = usage; usageAfterMaintenance = usage;
continueToNextStep(); continueToNextStep();

View File

@ -259,7 +259,10 @@ function resetOrClearAllDatabases(callback, clear) {
let uri = Cc["@mozilla.org/network/io-service;1"] let uri = Cc["@mozilla.org/network/io-service;1"]
.getService(Ci.nsIIOService) .getService(Ci.nsIIOService)
.newURI("http://foo.com", null, null); .newURI("http://foo.com", null, null);
quotaManager.getUsageForURI(uri, function(usage, fileUsage) { let principal = Cc["@mozilla.org/scriptsecuritymanager;1"]
.getService(Ci.nsIScriptSecurityManager)
.createCodebasePrincipal(uri, {});
quotaManager.getUsageForPrincipal(principal, function(principal, usage, fileUsage) {
callback(); callback();
}); });
} }

View File

@ -27,6 +27,7 @@
#include <algorithm> #include <algorithm>
#include "GeckoProfiler.h" #include "GeckoProfiler.h"
#include "mozilla/Atomics.h" #include "mozilla/Atomics.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/CondVar.h" #include "mozilla/CondVar.h"
#include "mozilla/dom/PContent.h" #include "mozilla/dom/PContent.h"
#include "mozilla/dom/asmjscache/AsmJSCache.h" #include "mozilla/dom/asmjscache/AsmJSCache.h"
@ -669,20 +670,16 @@ class GetUsageOp
UsageInfo mUsageInfo; UsageInfo mUsageInfo;
const nsCString mGroup; const nsCString mGroup;
nsCOMPtr<nsIURI> mURI; nsCOMPtr<nsIPrincipal> mPrincipal;
nsCOMPtr<nsIUsageCallback> mCallback; nsCOMPtr<nsIUsageCallback> mCallback;
const uint32_t mAppId;
const bool mIsApp; const bool mIsApp;
const bool mInMozBrowserOnly;
public: public:
GetUsageOp(const nsACString& aGroup, GetUsageOp(const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
bool aIsApp, bool aIsApp,
nsIURI* aURI, nsIPrincipal* aPrincipal,
nsIUsageCallback* aCallback, nsIUsageCallback* aCallback);
uint32_t aAppId,
bool aInMozBrowserOnly);
private: private:
~GetUsageOp() ~GetUsageOp()
@ -3404,32 +3401,6 @@ QuotaManager::GetStorageId(PersistenceType aPersistenceType,
aDatabaseId = str; aDatabaseId = str;
} }
// static
nsresult
QuotaManager::GetInfoFromURI(nsIURI* aURI,
uint32_t aAppId,
bool aInMozBrowser,
nsACString* aGroup,
nsACString* aOrigin,
bool* aIsApp)
{
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(aURI);
nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
NS_ENSURE_TRUE(secMan, NS_ERROR_FAILURE);
nsCOMPtr<nsIPrincipal> principal;
nsresult rv = secMan->GetAppCodebasePrincipal(aURI, aAppId, aInMozBrowser,
getter_AddRefs(principal));
NS_ENSURE_SUCCESS(rv, rv);
rv = GetInfoFromPrincipal(principal, aGroup, aOrigin, aIsApp);
NS_ENSURE_SUCCESS(rv, rv);
return NS_OK;
}
static nsresult static nsresult
TryGetInfoForAboutURI(nsIPrincipal* aPrincipal, TryGetInfoForAboutURI(nsIPrincipal* aPrincipal,
nsACString& aGroup, nsACString& aGroup,
@ -3709,36 +3680,27 @@ QuotaManager::GetDirectoryMetadata(nsIFile* aDirectory,
NS_IMPL_ISUPPORTS(QuotaManager, nsIQuotaManager, nsIObserver) NS_IMPL_ISUPPORTS(QuotaManager, nsIQuotaManager, nsIObserver)
NS_IMETHODIMP NS_IMETHODIMP
QuotaManager::GetUsageForURI(nsIURI* aURI, QuotaManager::GetUsageForPrincipal(nsIPrincipal* aPrincipal,
nsIUsageCallback* aCallback, nsIUsageCallback* aCallback,
uint32_t aAppId, nsIQuotaRequest** _retval)
bool aInMozBrowserOnly,
uint8_t aOptionalArgCount,
nsIQuotaRequest** _retval)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ENSURE_ARG_POINTER(aURI); NS_ENSURE_ARG_POINTER(aPrincipal);
NS_ENSURE_ARG_POINTER(aCallback); NS_ENSURE_ARG_POINTER(aCallback);
// This only works from the main process. // This only works from the main process.
NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
if (!aOptionalArgCount) {
aAppId = nsIScriptSecurityManager::NO_APP_ID;
}
// Figure out which origin we're dealing with. // Figure out which origin we're dealing with.
nsCString group; nsCString group;
nsCString origin; nsCString origin;
bool isApp; bool isApp;
nsresult rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, &group, &origin, nsresult rv = GetInfoFromPrincipal(aPrincipal, &group, &origin, &isApp);
&isApp);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
nsRefPtr<GetUsageOp> op = nsRefPtr<GetUsageOp> op =
new GetUsageOp(group, origin, isApp, aURI, aCallback, aAppId, new GetUsageOp(group, origin, isApp, aPrincipal, aCallback);
aInMozBrowserOnly);
op->RunImmediately(); op->RunImmediately();
@ -3764,15 +3726,12 @@ QuotaManager::Clear()
} }
NS_IMETHODIMP NS_IMETHODIMP
QuotaManager::ClearStoragesForURI(nsIURI* aURI, QuotaManager::ClearStoragesForPrincipal(nsIPrincipal* aPrincipal,
uint32_t aAppId, const nsACString& aPersistenceType)
bool aInMozBrowserOnly,
const nsACString& aPersistenceType,
uint8_t aOptionalArgCount)
{ {
NS_ASSERTION(NS_IsMainThread(), "Wrong thread!"); NS_ASSERTION(NS_IsMainThread(), "Wrong thread!");
NS_ENSURE_ARG_POINTER(aURI); NS_ENSURE_ARG_POINTER(aPrincipal);
Nullable<PersistenceType> persistenceType; Nullable<PersistenceType> persistenceType;
nsresult rv = nsresult rv =
@ -3784,18 +3743,16 @@ QuotaManager::ClearStoragesForURI(nsIURI* aURI,
// This only works from the main process. // This only works from the main process.
NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE); NS_ENSURE_TRUE(XRE_IsParentProcess(), NS_ERROR_NOT_AVAILABLE);
if (!aOptionalArgCount) {
aAppId = nsIScriptSecurityManager::NO_APP_ID;
}
// Figure out which origin we're dealing with. // Figure out which origin we're dealing with.
nsCString origin; nsCString origin;
rv = GetInfoFromURI(aURI, aAppId, aInMozBrowserOnly, nullptr, &origin, rv = GetInfoFromPrincipal(aPrincipal, nullptr, &origin, nullptr);
nullptr);
NS_ENSURE_SUCCESS(rv, rv); NS_ENSURE_SUCCESS(rv, rv);
const mozilla::OriginAttributes& attrs =
mozilla::BasePrincipal::Cast(aPrincipal)->OriginAttributesRef();
nsAutoCString pattern; nsAutoCString pattern;
GetOriginPatternString(aAppId, aInMozBrowserOnly, origin, pattern); GetOriginPatternString(attrs.mAppId, attrs.mInBrowser, origin, pattern);
nsRefPtr<OriginClearOp> op = nsRefPtr<OriginClearOp> op =
new OriginClearOp(persistenceType, OriginScope::FromPattern(pattern)); new OriginClearOp(persistenceType, OriginScope::FromPattern(pattern));
@ -4625,24 +4582,20 @@ SaveOriginAccessTimeOp::DoDirectoryWork(QuotaManager* aQuotaManager)
GetUsageOp::GetUsageOp(const nsACString& aGroup, GetUsageOp::GetUsageOp(const nsACString& aGroup,
const nsACString& aOrigin, const nsACString& aOrigin,
bool aIsApp, bool aIsApp,
nsIURI* aURI, nsIPrincipal* aPrincipal,
nsIUsageCallback* aCallback, nsIUsageCallback* aCallback)
uint32_t aAppId,
bool aInMozBrowserOnly)
: NormalOriginOperationBase(Nullable<PersistenceType>(), : NormalOriginOperationBase(Nullable<PersistenceType>(),
OriginScope::FromOrigin(aOrigin), OriginScope::FromOrigin(aOrigin),
/* aExclusive */ false) /* aExclusive */ false)
, mGroup(aGroup) , mGroup(aGroup)
, mURI(aURI) , mPrincipal(aPrincipal)
, mCallback(aCallback) , mCallback(aCallback)
, mAppId(aAppId)
, mIsApp(aIsApp) , mIsApp(aIsApp)
, mInMozBrowserOnly(aInMozBrowserOnly)
{ {
MOZ_ASSERT(NS_IsMainThread()); MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(!aGroup.IsEmpty()); MOZ_ASSERT(!aGroup.IsEmpty());
MOZ_ASSERT(!aOrigin.IsEmpty()); MOZ_ASSERT(!aOrigin.IsEmpty());
MOZ_ASSERT(aURI); MOZ_ASSERT(aPrincipal);
MOZ_ASSERT(aCallback); MOZ_ASSERT(aCallback);
} }
@ -4777,12 +4730,11 @@ GetUsageOp::SendResults()
mUsageInfo.ResetUsage(); mUsageInfo.ResetUsage();
} }
mCallback->OnUsageResult(mURI, mUsageInfo.TotalUsage(), mUsageInfo.FileUsage(), mAppId, mCallback->OnUsageResult(mPrincipal, mUsageInfo.TotalUsage(), mUsageInfo.FileUsage());
mInMozBrowserOnly);
} }
// Clean up. // Clean up.
mURI = nullptr; mPrincipal = nullptr;
mCallback = nullptr; mCallback = nullptr;
} }

View File

@ -306,14 +306,6 @@ public:
Client::Type aClientType, Client::Type aClientType,
nsACString& aDatabaseId); nsACString& aDatabaseId);
static nsresult
GetInfoFromURI(nsIURI* aURI,
uint32_t aAppId,
bool aInMozBrowser,
nsACString* aGroup,
nsACString* aOrigin,
bool* aIsApp);
static nsresult static nsresult
GetInfoFromPrincipal(nsIPrincipal* aPrincipal, GetInfoFromPrincipal(nsIPrincipal* aPrincipal,
nsACString* aGroup, nsACString* aGroup,

View File

@ -7,27 +7,24 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsIQuotaRequest; interface nsIQuotaRequest;
interface nsIURI; interface nsIPrincipal;
interface nsIUsageCallback; interface nsIUsageCallback;
[scriptable, builtinclass, uuid(2968fcd5-1872-4ddc-8c16-62b27e357f31)] [scriptable, builtinclass, uuid(101cf53c-e7f3-4723-9f43-a23a85c8eda0)]
interface nsIQuotaManager : nsISupports interface nsIQuotaManager : nsISupports
{ {
/** /**
* Schedules an asynchronous callback that will return the total amount of * Schedules an asynchronous callback that will return the total amount of
* disk space being used by storages for the given origin. * disk space being used by storages for the given origin.
* *
* @param aURI * @param aPrincipal
* The URI whose usage is being queried. * A principal for the origin whose usage is being queried.
* @param aCallback * @param aCallback
* The callback that will be called when the usage is available. * The callback that will be called when the usage is available.
*/ */
[optional_argc]
nsIQuotaRequest nsIQuotaRequest
getUsageForURI(in nsIURI aURI, getUsageForPrincipal(in nsIPrincipal aPrincipal,
in nsIUsageCallback aCallback, in nsIUsageCallback aCallback);
[optional] in unsigned long aAppId,
[optional] in boolean aInMozBrowserOnly);
/** /**
* Removes all storages. The files may not be deleted immediately depending * Removes all storages. The files may not be deleted immediately depending
@ -44,15 +41,12 @@ interface nsIQuotaManager : nsISupports
* Removes all storages stored for the given URI. The files may not be * Removes all storages stored for the given URI. The files may not be
* deleted immediately depending on prohibitive concurrent operations. * deleted immediately depending on prohibitive concurrent operations.
* *
* @param aURI * @param aPrincipal
* The URI whose storages are to be cleared. * A principal for the origin whose storages are to be cleared.
*/ */
[optional_argc]
void void
clearStoragesForURI(in nsIURI aURI, clearStoragesForPrincipal(in nsIPrincipal aPrincipal,
[optional] in unsigned long aAppId, [optional] in ACString aPersistenceType);
[optional] in boolean aInMozBrowserOnly,
[optional] in ACString aPersistenceType);
/** /**
* Resets quota and storage management. This can be used to force * Resets quota and storage management. This can be used to force

View File

@ -6,15 +6,12 @@
#include "nsISupports.idl" #include "nsISupports.idl"
interface nsIURI; interface nsIPrincipal;
[scriptable, function, uuid(7b0f9928-0ddc-42c7-b9f2-6b2308b90b18)] [scriptable, function, uuid(54b9f44f-533f-41ee-8fa8-86cc978125f0)]
interface nsIUsageCallback : nsISupports interface nsIUsageCallback : nsISupports
{ {
void void onUsageResult(in nsIPrincipal aPrincipal,
onUsageResult(in nsIURI aURI, in unsigned long long aUsage,
in unsigned long long aUsage, in unsigned long long aFileUsage);
in unsigned long long aFileUsage,
in unsigned long aAppId,
in boolean aInMozBrowserOnly);
}; };

View File

@ -34,6 +34,7 @@ skip-if = true
[test_ril_worker_voiceprivacy.js] [test_ril_worker_voiceprivacy.js]
[test_ril_worker_ecm.js] [test_ril_worker_ecm.js]
[test_ril_worker_stk.js] [test_ril_worker_stk.js]
requesttimeoutfactor = 2
[test_ril_worker_barring_password.js] [test_ril_worker_barring_password.js]
[test_ril_worker_cdma_info_rec.js] [test_ril_worker_cdma_info_rec.js]
[test_ril_system_messenger.js] [test_ril_system_messenger.js]

View File

@ -505,24 +505,22 @@ SpecialPowersObserverAPI.prototype = {
throw new SpecialPowersError('Invalid operation for SPQuotaManager'); throw new SpecialPowersError('Invalid operation for SPQuotaManager');
} }
let uri = this._getURI(msg.uri); let secMan = Services.scriptSecurityManager;
let principal = secMan.createCodebasePrincipal(this._getURI(msg.uri), {
appId: msg.appId,
inBrowser: msg.inBrowser,
});
if (op == 'clear') { if (op == 'clear') {
if (('inBrowser' in msg) && msg.inBrowser !== undefined) { qm.clearStoragesForPrincipal(principal);
qm.clearStoragesForURI(uri, msg.appId, msg.inBrowser);
} else if (('appId' in msg) && msg.appId !== undefined) {
qm.clearStoragesForURI(uri, msg.appId);
} else {
qm.clearStoragesForURI(uri);
}
} else if (op == 'reset') { } else if (op == 'reset') {
qm.reset(); qm.reset();
} }
// We always use the getUsageForURI callback even if we're clearing // We always use the getUsageForPrincipal callback even if we're clearing
// since we know that clear and getUsageForURI are synchronized by the // since we know that clear and getUsageForPrincipal are synchronized by the
// QuotaManager. // QuotaManager.
let callback = function(uri, usage, fileUsage) { let callback = function(principal, usage, fileUsage) {
let reply = { id: msg.id }; let reply = { id: msg.id };
if (op == 'getUsage') { if (op == 'getUsage') {
reply.usage = usage; reply.usage = usage;
@ -531,13 +529,7 @@ SpecialPowersObserverAPI.prototype = {
mm.sendAsyncMessage(aMessage.name, reply); mm.sendAsyncMessage(aMessage.name, reply);
}; };
if (('inBrowser' in msg) && msg.inBrowser !== undefined) { qm.getUsageForPrincipal(principal, callback);
qm.getUsageForURI(uri, callback, msg.appId, msg.inBrowser);
} else if (('appId' in msg) && msg.appId !== undefined) {
qm.getUsageForURI(uri, callback, msg.appId);
} else {
qm.getUsageForURI(uri, callback);
}
return undefined; // See comment at the beginning of this function. return undefined; // See comment at the beginning of this function.
} }

View File

@ -160,8 +160,10 @@ this.ForgetAboutSite = {
caUtils); caUtils);
let httpURI = caUtils.makeURI("http://" + aDomain); let httpURI = caUtils.makeURI("http://" + aDomain);
let httpsURI = caUtils.makeURI("https://" + aDomain); let httpsURI = caUtils.makeURI("https://" + aDomain);
qm.clearStoragesForURI(httpURI); let httpPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpURI, {});
qm.clearStoragesForURI(httpsURI); let httpsPrincipal = Services.scriptSecurityManager.createCodebasePrincipal(httpsURI, {});
qm.clearStoragesForPrincipal(httpPrincipal);
qm.clearStoragesForPrincipal(httpsPrincipal);
function onContentPrefsRemovalFinished() { function onContentPrefsRemovalFinished() {
// Everybody else (including extensions) // Everybody else (including extensions)