1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=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/. */
#ifndef mozilla_dom_cache_BackgroundStorageKey_h
#define mozilla_dom_cache_BackgroundStorageKey_h
#include "BoundStorageKeyChild.h"
#include "ErrorList.h"
#include "mozilla/MozPromise.h"
#include "mozilla/dom/cache/CacheTypes.h"
#include "mozilla/dom/cache/TypeUtils.h"
namespace mozilla {
namespace ipc {
class PrincipalInfo;
class PBackgroundChild;
} // namespace ipc
namespace dom {
class Response;
namespace cache {
extern bool IsTrusted(const ::mozilla::ipc::PrincipalInfo& aPrincipalInfo,
bool aTestingPrefEnabled);
class CacheStorageChild;
class BoundStorageKeyCache;
using mozilla::ipc::PrincipalInfo;
/* BoundStorageKey ipdl would be used to work with all storage APIs
* between child and parent process. BoundStorageKey is a generic
* base class and represents all respective derived storage classes.
* BoundStorageKeyCacheStorage below is one such class which deals with
* cachestorage and like this, there could be more in the future like
* BoundStorageKeyIDB for IndexedDB, etc.
*
* TODO: it might be worth moving BoundStorageKey protocol definition,
* implementation into separate directory while more derived implementations
* could be under their respective storage directories like dom/cache for
* BoundStorageKeyCacheStorage.
*/
class BoundStorageKey : public nsISupports,
public BoundStorageKeyChildListener {
public:
using PBackgroundChild = ::mozilla::ipc::PBackgroundChild;
NS_DECL_ISUPPORTS
BoundStorageKey() : mActor(nullptr), mStatus(NS_OK) {}
// Overrides Listener methods and are called by
// BoundStorageKeyChild and CacheStorageChild
void OnActorDestroy(BoundStorageKeyChild* aActor) override;
protected:
virtual ~BoundStorageKey();
// Initialization is performed here i.e.
// 1. Child and parent actors are setup and connection is attempted.
// 2. EventTarget has been retargetted to aTarget
nsresult Init(Namespace aNamespace, const PrincipalInfo& aPrincipalInfo,
nsISerialEventTarget* aTarget = GetCurrentSerialEventTarget());
RefPtr<BoundStorageKeyChild> mActor;
nsresult mStatus;
};
using CacheStoragePromise = MozPromiseBase;
using OpenResultPromise =
mozilla::MozPromise<RefPtr<BoundStorageKeyCache>, ErrorResult,
true /*IsExclusive=*/>;
using DeleteResultPromise =
mozilla::MozPromise<bool, ErrorResult, true /* IsExclusive= */>;
using HasResultPromise =
mozilla::MozPromise<bool, ErrorResult, true /* IsExclusive= */>;
using KeysResultPromise =
mozilla::MozPromise<CopyableTArray<nsString>, ErrorResult,
true /* IsExclusive= */>;
using MatchResultPromise =
mozilla::MozPromise<RefPtr<Response>, ErrorResult, true /* IsExclusive= */>;
/* This class exposes Cache APIs to be used by internal clients and is currently
* used by service workers when performing a lookup for cache'd scripts. This is
* intended to be used by internal clients only and is in contrast with
* CacheStorage which is used by internal and JS clients; though comparatively,
* internal clients would find it easier to work with this class. There are two
* major differences between the two:
* 1. APIs in CacheStorage return JS promise whereas this class return
* MozPromise
* 2. Even though both classes uses same underlying actors but actor used here
* gets spun off of top-level actor, BoundStorageKeyChild which could be
* retargetted to any event target.
* TODO: Since we have two implementations now; this class and CacheStorage with
* almost similar responsibilities; it maybe worth exploring to consolidate
* both.
*/
class BoundStorageKeyCacheStorage final : public BoundStorageKey,
public TypeUtils,
public CacheStorageChildListener {
public:
static already_AddRefed<BoundStorageKeyCacheStorage> Create(
Namespace aNamespace, nsIGlobalObject* aGlobal,
WorkerPrivate* aWorkerPrivate, nsISerialEventTarget* aActorTarget,
ErrorResult& aRv);
#ifdef DEBUG
void AssertOwningThread() const override {
NS_ASSERT_OWNINGTHREAD(BoundStorageKey);
}
#else
inline void AssertOwningThread() const {}
#endif
nsresult Init(WorkerPrivate* aWorkerPrivate, Namespace aNamespace,
const PrincipalInfo& aPrincipalInfo,
nsISerialEventTarget* aTarget = GetCurrentSerialEventTarget());
// Below methods declares the APIs that this class exposes, which looks
// similar to CacheStorage but return type is different
already_AddRefed<CacheStoragePromise> Match(
JSContext* aCx, const RequestOrUTF8String& aRequest,
const MultiCacheQueryOptions& aOptions, ErrorResult& aRv);
already_AddRefed<CacheStoragePromise> Has(const nsAString& aKey,
ErrorResult& aRv);
already_AddRefed<CacheStoragePromise> Open(const nsAString& aKey,
ErrorResult& aRv);
already_AddRefed<CacheStoragePromise> Delete(const nsAString& aKey,
ErrorResult& aRv);
already_AddRefed<CacheStoragePromise> Keys(ErrorResult& aRv);
nsIGlobalObject* GetGlobalObject() const override { return mGlobal; }
// explicitly exposing below OnActorDestroy to avoid cpp name hidiing
using BoundStorageKey::OnActorDestroy;
// called by associated CacheStorageChild actor during destruction.
void OnActorDestroy(CacheStorageChild* aActor) override;
private:
template <typename PromiseType>
struct Entry;
BoundStorageKeyCacheStorage(
Namespace aNamespace, nsIGlobalObject* aGlobal,
const mozilla::ipc::PrincipalInfo& aPrincipalInfo);
already_AddRefed<CacheStorageChild> CreateCacheStorageChild(
WorkerPrivate* aWorkerPrivate);
~BoundStorageKeyCacheStorage() override;
template <typename EntryType>
void RunRequest(EntryType&& aEntry);
RefPtr<CacheStorageChild> mCacheStorageChild;
nsCOMPtr<nsIGlobalObject> mGlobal;
const UniquePtr<mozilla::ipc::PrincipalInfo> mPrincipalInfo;
const Namespace mNamespace;
};
} // namespace cache
template <dom::cache::CacheOpResult::Type OP_TYPE>
struct cachestorage_traits;
template <>
struct cachestorage_traits<
dom::cache::CacheOpResult::Type::TStorageMatchResult> {
using PromiseType = cache::MatchResultPromise::Private;
};
template <>
struct cachestorage_traits<dom::cache::CacheOpResult::Type::TStorageHasResult> {
using PromiseType = cache::HasResultPromise::Private;
};
template <>
struct cachestorage_traits<
dom::cache::CacheOpResult::Type::TStorageOpenResult> {
using PromiseType = cache::OpenResultPromise::Private;
};
template <>
struct cachestorage_traits<
dom::cache::CacheOpResult::Type::TStorageDeleteResult> {
using PromiseType = cache::DeleteResultPromise::Private;
};
template <>
struct cachestorage_traits<
dom::cache::CacheOpResult::Type::TStorageKeysResult> {
using PromiseType = cache::KeysResultPromise::Private;
};
template <>
struct cachestorage_traits<dom::cache::CacheOpResult::Type::Tvoid_t> {
// Tvoid_t is only used to report errors, Resolve value doesn't matter much
// here. Just using HasResultPromise has it has simple Resolve value
using PromiseType = cache::HasResultPromise::Private;
};
} // namespace dom
} // namespace mozilla
#endif // mozilla_dom_cache_BackgroundStorageKey_h
|