/* -*- 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/. */
class LocalStorage; class LocalStorageCacheChild; class LocalStorageManager; class StorageUsage; class StorageDBBridge;
// Interface class on which only the database or IPC may call. // Used to populate the cache with DB data. class LocalStorageCacheBridge { public:
NS_IMETHOD_(MozExternalRefCountType) AddRef(void);
NS_IMETHOD_(void) Release(void);
// The origin of the cache, result is concatenation of OriginNoSuffix() and // OriginSuffix(), see below. virtualconst nsCString Origin() const = 0;
// The origin attributes suffix alone, this is usually passed as an // |aOriginSuffix| argument to various methods virtualconst nsCString& OriginSuffix() const = 0;
// The origin in the database usage format (reversed) and without the suffix virtualconst nsCString& OriginNoSuffix() const = 0;
// Whether the cache is already fully loaded virtualbool Loaded() = 0;
// How many items has so far been loaded into the cache, used // for optimization purposes virtual uint32_t LoadedCount() = 0;
// Called by the database to load a key and its value to the cache virtualbool LoadItem(const nsAString& aKey, const nsAString& aValue) = 0;
// Called by the database after all keys and values has been loaded // to this cache virtualvoid LoadDone(nsresult aRv) = 0;
// Use to synchronously wait until the cache gets fully loaded with data, // this method exits after LoadDone has been called virtualvoid LoadWait() = 0;
// Implementation of scope cache that is responsible for preloading data // for persistent storage (localStorage) and hold data for non-private, // private and session-only cookie modes. It is also responsible for // persisting data changes using the database, works as a write-back cache. class LocalStorageCache : public LocalStorageCacheBridge { public: void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LocalStorage); }
void SetActor(LocalStorageCacheChild* aActor);
void ClearActor() {
AssertIsOnOwningThread();
mActor = nullptr;
}
NS_IMETHOD_(void) Release(void) override;
enum MutationSource { // The mutation is a result of an explicit JS mutation in this process. // The mutation should be sent to the sDatabase. Quota will be checked and // QuotaExceededError may be returned without the mutation being applied.
ContentMutation, // The mutation initially was triggered in a different process and is being // propagated to this cache via LocalStorage::ApplyEvent. The mutation // should // not be sent to the sDatabase because the originating process is already // doing that. (In addition to the redundant writes being wasteful, there // is the potential for other processes to see inconsistent state from the // database while preloading.) Quota will be updated but not checked // because it's assumed it was checked in another process and data-coherency // is more important than slightly exceeding quota.
E10sPropagated
};
// Note: We pass aOriginNoSuffix through the ctor here, because // LocalStorageCacheHashKey's ctor is creating this class and // accepts reversed-origin-no-suffix as an argument - the hashing key. explicit LocalStorageCache(const nsACString* aOriginNoSuffix);
// Cache keeps 3 sets of data: regular, private and session-only. // This class keeps keys and values for a set and also caches // size of the data for quick per-origin quota checking. class Data { public:
Data() : mOriginQuotaUsage(0) {}
int64_t mOriginQuotaUsage;
nsTHashMap<nsStringHashKey, nsString> mKeys;
};
public: // Number of data sets we keep: default, session staticconst uint32_t kDataSetCount = 2;
private: // API to clear the cache data, this is invoked by chrome operations // like cookie deletion. friendclass LocalStorageManager;
private: // Synchronously blocks until the cache is fully loaded from the database void WaitForPreload();
// Helper to get one of the 3 data sets (regular, private, session)
Data& DataSet(const LocalStorage* aStorage);
// Used for firing storage events and synchronization of caches in other // content processes. void NotifyObservers(const LocalStorage* aStorage, const nsAString& aKey, const nsAString& aOldValue, const nsAString& aNewValue);
// Whether the storage change is about to persist bool Persist(const LocalStorage* aStorage) const;
// Changes the quota usage on the given data set if it fits the quota. // If not, then false is returned and no change to the set must be done. // A special case is if aSource==E10sPropagated, then we will return true even // if the change would put us over quota. This is done to ensure coherency of // caches between processes in the face of races. It does allow an attacker // to potentially use N multiples of the quota storage limit if they can // arrange for their origin to execute code in N processes. However, this is // not considered a particularly concerning threat model because it's already // very possible for a rogue page to attempt to intentionally fill up the // user's storage through the use of multiple domains. bool ProcessUsageDelta(uint32_t aGetDataSetIndex, const int64_t aDelta, const MutationSource aSource = ContentMutation); bool ProcessUsageDelta(const LocalStorage* aStorage, const int64_t aDelta, const MutationSource aSource = ContentMutation);
private: // When a cache is reponsible for its life time (in case of localStorage data // cache) we need to refer our manager since removal of the cache from the // hash table is handled in the destructor by call to the manager. Cache // could potentially overlive the manager, hence the hard ref.
RefPtr<LocalStorageManager> mManager;
// Reference to the usage counter object we check on for eTLD+1 quota limit. // Obtained from the manager during initialization (Init method).
RefPtr<StorageUsage> mUsage;
// The LocalStorageCacheChild is created at the same time of this class. // In normal operation, the actor will be synchronously cleared in our // destructor when we tell it to delete itself. In a shutdown-related edge // case in the parent process for JSM's, it is possible for the actor to be // destroyed while this class remains alive, in which case it will be nulled // out.
LocalStorageCacheChild* mActor;
// The origin this cache belongs to in the "DB format", i.e. reversed
nsCString mOriginNoSuffix;
// The origin attributes suffix
nsCString mOriginSuffix;
// The eTLD+1 scope used to count quota usage. It is in the reversed format // and contains the origin attributes suffix.
nsCString mQuotaOriginScope;
// Non-private Browsing, Private Browsing and Session Only sets.
Data mData[kDataSetCount];
// This monitor is used to wait for full load of data.
mozilla::Monitor mMonitor MOZ_UNANNOTATED;
// Flag that is initially false. When the cache is about to work with // the database (i.e. it is persistent) this flags is set to true after // all keys and coresponding values are loaded from the database. // This flag never goes from true back to false. Since this flag is // critical for mData hashtable synchronization, it's made atomic.
Atomic<bool, ReleaseAcquire> mLoaded;
// Result of load from the database. Valid after mLoaded flag has been set.
nsresult mLoadResult;
// Expected to be only 0 or 1.
uint32_t mPrivateBrowsingId;
// Init() method has been called bool mInitialized : 1;
// This cache is about to be bound with the database (i.e. it has // to load from the DB first and has to persist when modifying the // default data set.) bool mPersistent : 1;
// Whether we have already captured state of the cache preload on our first // access. bool mPreloadTelemetryRecorded : 1;
};
// StorageUsage // Infrastructure to manage and check eTLD+1 quota class StorageUsageBridge { public:
NS_INLINE_DECL_THREADSAFE_VIRTUAL_REFCOUNTING(StorageUsageBridge)
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung ist noch experimentell.