Bug 1619592 - Add initializePersistentOrigin and initializeTemporaryOrigin to nsIQuotaManagerService; r=dom-workers-and-storage-reviewers,sg

Differential Revision: https://phabricator.services.mozilla.com/D97255
This commit is contained in:
Jan Varga 2020-11-19 14:38:17 +00:00
Родитель 0ef77ed7df
Коммит c67cbb0b15
8 изменённых файлов: 330 добавлений и 3 удалений

Просмотреть файл

@ -352,6 +352,16 @@ mozilla::ipc::IPCResult QuotaRequestChild::Recv__delete__(
HandleResponse();
break;
case RequestResponse::TInitializePersistentOriginResponse:
HandleResponse(
aResponse.get_InitializePersistentOriginResponse().created());
break;
case RequestResponse::TInitializeTemporaryOriginResponse:
HandleResponse(
aResponse.get_InitializeTemporaryOriginResponse().created());
break;
case RequestResponse::TInitStorageAndOriginResponse:
HandleResponse(aResponse.get_InitStorageAndOriginResponse().created());
break;

Просмотреть файл

@ -1657,6 +1657,44 @@ class InitTemporaryStorageOp final : public QuotaRequestBase {
void GetResponse(RequestResponse& aResponse) override;
};
class InitializeOriginRequestBase : public QuotaRequestBase {
protected:
nsCString mSuffix;
nsCString mGroup;
bool mCreated;
public:
void Init(Quota& aQuota) override;
protected:
InitializeOriginRequestBase(PersistenceType aPersistenceType,
const PrincipalInfo& aPrincipalInfo);
};
class InitializePersistentOriginOp final : public InitializeOriginRequestBase {
public:
explicit InitializePersistentOriginOp(const RequestParams& aParams);
private:
~InitializePersistentOriginOp() = default;
nsresult DoDirectoryWork(QuotaManager& aQuotaManager) override;
void GetResponse(RequestResponse& aResponse) override;
};
class InitializeTemporaryOriginOp final : public InitializeOriginRequestBase {
public:
explicit InitializeTemporaryOriginOp(const RequestParams& aParams);
private:
~InitializeTemporaryOriginOp() = default;
nsresult DoDirectoryWork(QuotaManager& aQuotaManager) override;
void GetResponse(RequestResponse& aResponse) override;
};
class InitStorageAndOriginOp final : public QuotaRequestBase {
nsCString mSuffix;
nsCString mGroup;
@ -8495,6 +8533,37 @@ bool Quota::VerifyRequestParams(const RequestParams& aParams) const {
case RequestParams::TInitTemporaryStorageParams:
break;
case RequestParams::TInitializePersistentOriginParams: {
const InitializePersistentOriginParams& params =
aParams.get_InitializePersistentOriginParams();
if (NS_WARN_IF(
!QuotaManager::IsPrincipalInfoValid(params.principalInfo()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
case RequestParams::TInitializeTemporaryOriginParams: {
const InitializeTemporaryOriginParams& params =
aParams.get_InitializeTemporaryOriginParams();
if (NS_WARN_IF(!IsBestEffortPersistenceType(params.persistenceType()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
if (NS_WARN_IF(
!QuotaManager::IsPrincipalInfoValid(params.principalInfo()))) {
ASSERT_UNLESS_FUZZING();
return false;
}
break;
}
case RequestParams::TInitStorageAndOriginParams: {
const InitStorageAndOriginParams& params =
aParams.get_InitStorageAndOriginParams();
@ -8737,6 +8806,12 @@ PQuotaRequestParent* Quota::AllocPQuotaRequestParent(
case RequestParams::TInitTemporaryStorageParams:
return MakeRefPtr<InitTemporaryStorageOp>();
case RequestParams::TInitializePersistentOriginParams:
return MakeRefPtr<InitializePersistentOriginOp>(aParams);
case RequestParams::TInitializeTemporaryOriginParams:
return MakeRefPtr<InitializeTemporaryOriginOp>(aParams);
case RequestParams::TInitStorageAndOriginParams:
return MakeRefPtr<InitStorageAndOriginOp>(aParams);
@ -9503,6 +9578,102 @@ void InitTemporaryStorageOp::GetResponse(RequestResponse& aResponse) {
aResponse = InitTemporaryStorageResponse();
}
InitializeOriginRequestBase::InitializeOriginRequestBase(
const PersistenceType aPersistenceType, const PrincipalInfo& aPrincipalInfo)
: QuotaRequestBase(/* aExclusive */ false), mCreated(false) {
AssertIsOnOwningThread();
auto quotaInfo =
QuotaManager::GetInfoFromValidatedPrincipalInfo(aPrincipalInfo);
// Overwrite OriginOperationBase default values.
mNeedsQuotaManagerInit = true;
mNeedsStorageInit = false;
// Overwrite NormalOriginOperationBase default values.
mPersistenceType.SetValue(aPersistenceType);
mOriginScope.SetFromOrigin(quotaInfo.mOrigin);
// Overwrite InitializeOriginRequestBase default values.
mSuffix = std::move(quotaInfo.mSuffix);
mGroup = std::move(quotaInfo.mGroup);
}
void InitializeOriginRequestBase::Init(Quota& aQuota) {
AssertIsOnOwningThread();
}
InitializePersistentOriginOp::InitializePersistentOriginOp(
const RequestParams& aParams)
: InitializeOriginRequestBase(
PERSISTENCE_TYPE_PERSISTENT,
aParams.get_InitializePersistentOriginParams().principalInfo()) {
AssertIsOnOwningThread();
MOZ_ASSERT(aParams.type() ==
RequestParams::TInitializePersistentOriginParams);
}
nsresult InitializePersistentOriginOp::DoDirectoryWork(
QuotaManager& aQuotaManager) {
AssertIsOnIOThread();
MOZ_ASSERT(!mPersistenceType.IsNull());
AUTO_PROFILER_LABEL("InitializePersistentOriginOp::DoDirectoryWork", OTHER);
QM_TRY(OkIf(aQuotaManager.IsStorageInitialized()), NS_ERROR_FAILURE);
QM_TRY_UNWRAP(mCreated,
(aQuotaManager
.EnsurePersistentOriginIsInitialized(QuotaInfo{
mSuffix, mGroup, nsCString{mOriginScope.GetOrigin()}})
.map([](const auto& res) { return res.second; })));
return NS_OK;
}
void InitializePersistentOriginOp::GetResponse(RequestResponse& aResponse) {
AssertIsOnOwningThread();
aResponse = InitializePersistentOriginResponse(mCreated);
}
InitializeTemporaryOriginOp::InitializeTemporaryOriginOp(
const RequestParams& aParams)
: InitializeOriginRequestBase(
aParams.get_InitializeTemporaryOriginParams().persistenceType(),
aParams.get_InitializeTemporaryOriginParams().principalInfo()) {
AssertIsOnOwningThread();
MOZ_ASSERT(aParams.type() == RequestParams::TInitializeTemporaryOriginParams);
}
nsresult InitializeTemporaryOriginOp::DoDirectoryWork(
QuotaManager& aQuotaManager) {
AssertIsOnIOThread();
MOZ_ASSERT(!mPersistenceType.IsNull());
AUTO_PROFILER_LABEL("InitializeTemporaryOriginOp::DoDirectoryWork", OTHER);
QM_TRY(OkIf(aQuotaManager.IsStorageInitialized()), NS_ERROR_FAILURE);
QM_TRY(OkIf(aQuotaManager.IsTemporaryStorageInitialized()), NS_ERROR_FAILURE);
QM_TRY_UNWRAP(
mCreated,
(aQuotaManager
.EnsureTemporaryOriginIsInitialized(
mPersistenceType.Value(),
QuotaInfo{mSuffix, mGroup, nsCString{mOriginScope.GetOrigin()}})
.map([](const auto& res) { return res.second; })));
return NS_OK;
}
void InitializeTemporaryOriginOp::GetResponse(RequestResponse& aResponse) {
AssertIsOnOwningThread();
aResponse = InitializeTemporaryOriginResponse(mCreated);
}
InitStorageAndOriginOp::InitStorageAndOriginOp(const RequestParams& aParams)
: QuotaRequestBase(/* aExclusive */ false), mCreated(false) {
AssertIsOnOwningThread();

Просмотреть файл

@ -46,6 +46,17 @@ struct InitTemporaryStorageParams
{
};
struct InitializePersistentOriginParams
{
PrincipalInfo principalInfo;
};
struct InitializeTemporaryOriginParams
{
PersistenceType persistenceType;
PrincipalInfo principalInfo;
};
struct InitStorageAndOriginParams
{
PrincipalInfo principalInfo;
@ -128,6 +139,8 @@ union RequestParams
TemporaryStorageInitializedParams;
InitParams;
InitTemporaryStorageParams;
InitializePersistentOriginParams;
InitializeTemporaryOriginParams;
InitStorageAndOriginParams;
ClearOriginParams;
ResetOriginParams;

Просмотреть файл

@ -31,6 +31,16 @@ struct InitTemporaryStorageResponse
{
};
struct InitializePersistentOriginResponse
{
bool created;
};
struct InitializeTemporaryOriginResponse
{
bool created;
};
struct InitStorageAndOriginResponse
{
bool created;
@ -84,6 +94,8 @@ union RequestResponse
TemporaryStorageInitializedResponse;
InitResponse;
InitTemporaryStorageResponse;
InitializePersistentOriginResponse;
InitializeTemporaryOriginResponse;
InitStorageAndOriginResponse;
ClearOriginResponse;
ResetOriginResponse;

Просмотреть файл

@ -160,6 +160,19 @@ bool IsValidPersistenceType(const PersistenceType aPersistenceType) {
}
}
bool IsBestEffortPersistenceType(const PersistenceType aPersistenceType) {
switch (aPersistenceType) {
case PERSISTENCE_TYPE_TEMPORARY:
case PERSISTENCE_TYPE_DEFAULT:
return true;
case PERSISTENCE_TYPE_PERSISTENT:
case PERSISTENCE_TYPE_INVALID:
default:
return false;
}
}
nsLiteralCString PersistenceTypeToString(
const PersistenceType aPersistenceType) {
const auto maybeString = TypeTo_impl<nsLiteralCString>(aPersistenceType);

Просмотреть файл

@ -26,15 +26,17 @@ enum PersistenceType {
PERSISTENCE_TYPE_INVALID
};
static const PersistenceType kBestEffortPersistenceTypes[] = {
PERSISTENCE_TYPE_TEMPORARY, PERSISTENCE_TYPE_DEFAULT};
static const PersistenceType kAllPersistenceTypes[] = {
PERSISTENCE_TYPE_PERSISTENT, PERSISTENCE_TYPE_TEMPORARY,
PERSISTENCE_TYPE_DEFAULT};
static const PersistenceType kBestEffortPersistenceTypes[] = {
PERSISTENCE_TYPE_TEMPORARY, PERSISTENCE_TYPE_DEFAULT};
bool IsValidPersistenceType(PersistenceType aPersistenceType);
bool IsBestEffortPersistenceType(const PersistenceType aPersistenceType);
nsLiteralCString PersistenceTypeToString(PersistenceType aPersistenceType);
Maybe<PersistenceType> PersistenceTypeFromString(const nsACString& aString,

Просмотреть файл

@ -527,6 +527,81 @@ QuotaManagerService::InitTemporaryStorage(nsIQuotaRequest** _retval) {
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::InitializePersistentOrigin(nsIPrincipal* aPrincipal,
nsIQuotaRequest** _retval) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
InitializePersistentOriginParams params;
nsresult rv =
CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
RequestInfo info(request, params);
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::InitializeTemporaryOrigin(
const nsACString& aPersistenceType, nsIPrincipal* aPrincipal,
nsIQuotaRequest** _retval) {
MOZ_ASSERT(NS_IsMainThread());
MOZ_ASSERT(nsContentUtils::IsCallerChrome());
if (NS_WARN_IF(!StaticPrefs::dom_quotaManager_testing())) {
return NS_ERROR_UNEXPECTED;
}
RefPtr<Request> request = new Request();
InitializeTemporaryOriginParams params;
const auto maybePersistenceType =
PersistenceTypeFromString(aPersistenceType, fallible);
if (NS_WARN_IF(maybePersistenceType.isNothing())) {
return NS_ERROR_INVALID_ARG;
}
if (NS_WARN_IF(!IsBestEffortPersistenceType(maybePersistenceType.value()))) {
return NS_ERROR_FAILURE;
}
params.persistenceType() = maybePersistenceType.value();
nsresult rv =
CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
RequestInfo info(request, params);
rv = InitiateRequest(info);
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
request.forget(_retval);
return NS_OK;
}
NS_IMETHODIMP
QuotaManagerService::InitStorageAndOrigin(nsIPrincipal* aPrincipal,
const nsACString& aPersistenceType,

Просмотреть файл

@ -62,6 +62,37 @@ interface nsIQuotaManagerService : nsISupports
[must_use] nsIQuotaRequest
initTemporaryStorage();
/**
* Initializes persistent origin directory for the given origin. This can be
* used in tests to verify origin initialization.
*
* If the dom.quotaManager.testing preference is not true the call will be
* a no-op.
*
* @param aPrincipal
* A principal for the origin whose directory is to be initialized.
*/
[must_use] nsIQuotaRequest
initializePersistentOrigin(in nsIPrincipal aPrincipal);
/**
* Initializes temporary origin directory for the given origin. This can be
* used in tests to verify origin initialization.
*
* If the dom.quotaManager.testing preference is not true the call will be
* a no-op.
*
* @param aPersistenceType
* A string that tells what persistence type of origin will be
* initialized (temporary or default).
*
* @param aPrincipal
* A principal for the origin whose directory is to be initialized.
*/
[must_use] nsIQuotaRequest
initializeTemporaryOrigin(in ACString aPersistenceType,
in nsIPrincipal aPrincipal);
/**
* Initializes storage directory, temporary storage (if persistence type is
* default or temporary) and directory for the given origin. This can be used