2018-11-29 23:47:20 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=2 et sw=2 tw=80: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
|
|
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "LocalStorageManager2.h"
|
|
|
|
|
|
|
|
#include "LSObject.h"
|
2018-11-29 23:48:15 +03:00
|
|
|
#include "mozilla/dom/Promise.h"
|
2018-11-29 23:47:20 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace dom {
|
|
|
|
|
2018-11-29 23:48:15 +03:00
|
|
|
namespace {
|
|
|
|
|
2018-11-29 23:48:25 +03:00
|
|
|
class RequestResolver final : public LSRequestChildCallback {
|
|
|
|
RefPtr<Promise> mPromise;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit RequestResolver(Promise* aPromise) : mPromise(aPromise) {}
|
|
|
|
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(mozilla::dom::RequestResolver, override);
|
|
|
|
|
|
|
|
private:
|
|
|
|
~RequestResolver() = default;
|
|
|
|
|
|
|
|
void HandleResponse(nsresult aResponse);
|
|
|
|
|
|
|
|
void HandleResponse(const NullableDatastoreId& aDatastoreId);
|
|
|
|
|
|
|
|
// LSRequestChildCallback
|
|
|
|
void OnResponse(const LSRequestResponse& aResponse) override;
|
|
|
|
};
|
|
|
|
|
2018-11-29 23:48:15 +03:00
|
|
|
class SimpleRequestResolver final : public LSSimpleRequestChildCallback {
|
|
|
|
RefPtr<Promise> mPromise;
|
|
|
|
|
|
|
|
public:
|
|
|
|
explicit SimpleRequestResolver(Promise* aPromise) : mPromise(aPromise) {}
|
|
|
|
|
|
|
|
NS_INLINE_DECL_REFCOUNTING(SimpleRequestResolver, override);
|
|
|
|
|
|
|
|
private:
|
|
|
|
~SimpleRequestResolver() = default;
|
|
|
|
|
|
|
|
void HandleResponse(nsresult aResponse);
|
|
|
|
|
|
|
|
void HandleResponse(bool aResponse);
|
|
|
|
|
|
|
|
// LSRequestChildCallback
|
|
|
|
void OnResponse(const LSSimpleRequestResponse& aResponse) override;
|
|
|
|
};
|
|
|
|
|
|
|
|
nsresult CreatePromise(JSContext* aContext, Promise** aPromise) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aContext);
|
|
|
|
|
|
|
|
nsIGlobalObject* global =
|
|
|
|
xpc::NativeGlobal(JS::CurrentGlobalOrNull(aContext));
|
|
|
|
if (NS_WARN_IF(!global)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
ErrorResult result;
|
|
|
|
RefPtr<Promise> promise = Promise::Create(global, result);
|
|
|
|
if (result.Failed()) {
|
|
|
|
return result.StealNSResult();
|
|
|
|
}
|
|
|
|
|
|
|
|
promise.forget(aPromise);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsresult CheckedPrincipalToPrincipalInfo(nsIPrincipal* aPrincipal,
|
|
|
|
PrincipalInfo& aPrincipalInfo) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
|
|
|
|
nsresult rv = PrincipalToPrincipalInfo(aPrincipal, &aPrincipalInfo);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (aPrincipalInfo.type() != PrincipalInfo::TContentPrincipalInfo &&
|
|
|
|
aPrincipalInfo.type() != PrincipalInfo::TSystemPrincipalInfo) {
|
|
|
|
return NS_ERROR_UNEXPECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
2018-11-29 23:47:20 +03:00
|
|
|
LocalStorageManager2::LocalStorageManager2() {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(NextGenLocalStorageEnabled());
|
|
|
|
}
|
|
|
|
|
|
|
|
LocalStorageManager2::~LocalStorageManager2() { MOZ_ASSERT(NS_IsMainThread()); }
|
|
|
|
|
2018-11-29 23:47:48 +03:00
|
|
|
NS_IMPL_ISUPPORTS(LocalStorageManager2, nsIDOMStorageManager,
|
|
|
|
nsILocalStorageManager)
|
2018-11-29 23:47:20 +03:00
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::PrecacheStorage(nsIPrincipal* aPrincipal,
|
|
|
|
Storage** _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
2018-11-05 22:04:39 +03:00
|
|
|
// This method was created as part of the e10s-ification of the old LS
|
|
|
|
// implementation to perform a preload in the content/current process. That's
|
|
|
|
// not how things work in LSNG. Instead everything happens in the parent
|
|
|
|
// process, triggered by the official preloading spot,
|
2019-02-28 04:09:48 +03:00
|
|
|
// ContentParent::AboutToLoadHttpFtpDocumentForChild.
|
2018-11-29 23:47:20 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::CreateStorage(mozIDOMWindow* aWindow,
|
|
|
|
nsIPrincipal* aPrincipal,
|
|
|
|
const nsAString& aDocumentURI,
|
|
|
|
bool aPrivate, Storage** _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
2018-11-29 23:48:05 +03:00
|
|
|
nsCOMPtr<nsPIDOMWindowInner> inner = nsPIDOMWindowInner::From(aWindow);
|
|
|
|
|
|
|
|
RefPtr<LSObject> object;
|
|
|
|
nsresult rv = LSObject::CreateForPrincipal(inner, aPrincipal, aDocumentURI,
|
|
|
|
aPrivate, getter_AddRefs(object));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
object.forget(_retval);
|
|
|
|
return NS_OK;
|
2018-11-29 23:47:20 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::GetStorage(mozIDOMWindow* aWindow,
|
|
|
|
nsIPrincipal* aPrincipal, bool aPrivate,
|
|
|
|
Storage** _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::CloneStorage(Storage* aStorageToCloneFrom) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aStorageToCloneFrom);
|
|
|
|
|
2018-11-05 22:04:39 +03:00
|
|
|
// Cloning is specific to sessionStorage; state is forked when a new tab is
|
|
|
|
// opened from an existing tab.
|
2018-11-29 23:47:20 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::CheckStorage(nsIPrincipal* aPrincipal, Storage* aStorage,
|
|
|
|
bool* _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(aStorage);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
2018-11-05 22:04:39 +03:00
|
|
|
// Only used by sessionStorage.
|
2018-11-29 23:47:20 +03:00
|
|
|
return NS_ERROR_NOT_IMPLEMENTED;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:47:48 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::GetNextGenLocalStorageEnabled(bool* aResult) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aResult);
|
|
|
|
|
|
|
|
*aResult = NextGenLocalStorageEnabled();
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:25 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::Preload(nsIPrincipal* aPrincipal, JSContext* aContext,
|
|
|
|
nsISupports** _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
|
|
|
nsresult rv;
|
|
|
|
|
|
|
|
RefPtr<Promise> promise;
|
|
|
|
|
|
|
|
if (aContext) {
|
|
|
|
rv = CreatePromise(aContext, getter_AddRefs(promise));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
LSRequestPrepareDatastoreParams params;
|
|
|
|
params.createIfNotExists() = false;
|
|
|
|
|
|
|
|
rv = CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = StartRequest(promise, params);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
promise.forget(_retval);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:15 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
LocalStorageManager2::IsPreloaded(nsIPrincipal* aPrincipal, JSContext* aContext,
|
|
|
|
nsISupports** _retval) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPrincipal);
|
|
|
|
MOZ_ASSERT(_retval);
|
|
|
|
|
|
|
|
RefPtr<Promise> promise;
|
|
|
|
nsresult rv = CreatePromise(aContext, getter_AddRefs(promise));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
LSSimpleRequestPreloadedParams params;
|
|
|
|
|
|
|
|
rv = CheckedPrincipalToPrincipalInfo(aPrincipal, params.principalInfo());
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = StartSimpleRequest(promise, params);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
|
|
|
promise.forget(_retval);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:25 +03:00
|
|
|
nsresult LocalStorageManager2::StartRequest(Promise* aPromise,
|
|
|
|
const LSRequestParams& aParams) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
PBackgroundChild* backgroundActor =
|
|
|
|
BackgroundChild::GetOrCreateForCurrentThread();
|
|
|
|
if (NS_WARN_IF(!backgroundActor)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<RequestResolver> resolver = new RequestResolver(aPromise);
|
|
|
|
|
|
|
|
auto actor = new LSRequestChild(resolver);
|
|
|
|
|
|
|
|
if (!backgroundActor->SendPBackgroundLSRequestConstructor(actor, aParams)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:15 +03:00
|
|
|
nsresult LocalStorageManager2::StartSimpleRequest(
|
|
|
|
Promise* aPromise, const LSSimpleRequestParams& aParams) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(aPromise);
|
|
|
|
|
|
|
|
PBackgroundChild* backgroundActor =
|
|
|
|
BackgroundChild::GetOrCreateForCurrentThread();
|
|
|
|
if (NS_WARN_IF(!backgroundActor)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
RefPtr<SimpleRequestResolver> resolver = new SimpleRequestResolver(aPromise);
|
|
|
|
|
|
|
|
auto actor = new LSSimpleRequestChild(resolver);
|
|
|
|
|
|
|
|
if (!backgroundActor->SendPBackgroundLSSimpleRequestConstructor(actor,
|
|
|
|
aParams)) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:25 +03:00
|
|
|
void RequestResolver::HandleResponse(nsresult aResponse) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
if (!mPromise) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
mPromise->MaybeReject(aResponse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void RequestResolver::HandleResponse(const NullableDatastoreId& aDatastoreId) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
if (!mPromise) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (aDatastoreId.type()) {
|
|
|
|
case NullableDatastoreId::Tnull_t:
|
|
|
|
mPromise->MaybeResolve(JS::NullHandleValue);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case NullableDatastoreId::Tuint64_t:
|
|
|
|
mPromise->MaybeResolve(aDatastoreId.get_uint64_t());
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("Unknown datastore id type!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void RequestResolver::OnResponse(const LSRequestResponse& aResponse) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
switch (aResponse.type()) {
|
|
|
|
case LSRequestResponse::Tnsresult:
|
|
|
|
HandleResponse(aResponse.get_nsresult());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LSRequestResponse::TLSRequestPrepareDatastoreResponse:
|
|
|
|
HandleResponse(
|
|
|
|
aResponse.get_LSRequestPrepareDatastoreResponse().datastoreId());
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("Unknown response type!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:48:15 +03:00
|
|
|
void SimpleRequestResolver::HandleResponse(nsresult aResponse) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(mPromise);
|
|
|
|
|
|
|
|
mPromise->MaybeReject(aResponse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleRequestResolver::HandleResponse(bool aResponse) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
MOZ_ASSERT(mPromise);
|
|
|
|
|
|
|
|
mPromise->MaybeResolve(aResponse);
|
|
|
|
}
|
|
|
|
|
|
|
|
void SimpleRequestResolver::OnResponse(
|
|
|
|
const LSSimpleRequestResponse& aResponse) {
|
|
|
|
MOZ_ASSERT(NS_IsMainThread());
|
|
|
|
|
|
|
|
switch (aResponse.type()) {
|
|
|
|
case LSSimpleRequestResponse::Tnsresult:
|
|
|
|
HandleResponse(aResponse.get_nsresult());
|
|
|
|
break;
|
|
|
|
|
|
|
|
case LSSimpleRequestResponse::TLSSimpleRequestPreloadedResponse:
|
|
|
|
HandleResponse(
|
|
|
|
aResponse.get_LSSimpleRequestPreloadedResponse().preloaded());
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
MOZ_CRASH("Unknown response type!");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-11-29 23:47:20 +03:00
|
|
|
} // namespace dom
|
|
|
|
} // namespace mozilla
|