tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

LSObject.h (7701B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #ifndef mozilla_dom_localstorage_LSObject_h
      8 #define mozilla_dom_localstorage_LSObject_h
      9 
     10 #include <cstdint>
     11 
     12 #include "ErrorList.h"
     13 #include "mozilla/Maybe.h"
     14 #include "mozilla/RefPtr.h"
     15 #include "mozilla/UniquePtr.h"
     16 #include "mozilla/dom/Storage.h"
     17 #include "mozilla/ipc/PBackgroundSharedTypes.h"
     18 #include "nsCycleCollectionParticipant.h"
     19 #include "nsID.h"
     20 #include "nsISupports.h"
     21 #include "nsStringFwd.h"
     22 #include "nsTArrayForwardDeclare.h"
     23 
     24 class nsGlobalWindowInner;
     25 class nsIEventTarget;
     26 class nsIPrincipal;
     27 class nsISerialEventTarget;
     28 class nsPIDOMWindowInner;
     29 
     30 namespace mozilla {
     31 
     32 class ErrorResult;
     33 
     34 namespace dom {
     35 
     36 class LSDatabase;
     37 class LSObjectChild;
     38 class LSObserver;
     39 class LSRequestChild;
     40 class LSRequestChildCallback;
     41 class LSRequestParams;
     42 class LSRequestResponse;
     43 
     44 /**
     45 * Backs the WebIDL `Storage` binding; all content LocalStorage calls are
     46 * handled by this class.
     47 *
     48 * ## Semantics under e10s / multi-process ##
     49 *
     50 * A snapshot mechanism used in conjuction with stable points ensures that JS
     51 * run-to-completion semantics are experienced even if the same origin is
     52 * concurrently accessing LocalStorage across multiple content processes.
     53 *
     54 * ### Snapshot Consistency ###
     55 *
     56 * An LSSnapshot is created locally whenever the contents of LocalStorage are
     57 * about to be read or written (including length).  This synchronously
     58 * establishes a corresponding Snapshot in PBackground in the parent process.
     59 * An effort is made to send as much data from the parent process as possible,
     60 * so sites using a small/reasonable amount of LocalStorage data will have it
     61 * sent to the content process for immediate access.  Sites with greater
     62 * LocalStorage usage may only have some of the information relayed.  In that
     63 * case, the parent Snapshot will ensure that it retains the exact state of the
     64 * parent Datastore at the moment the Snapshot was created.
     65 */
     66 class LSObject final : public Storage {
     67  using PrincipalInfo = mozilla::ipc::PrincipalInfo;
     68 
     69  friend nsGlobalWindowInner;
     70 
     71  UniquePtr<PrincipalInfo> mPrincipalInfo;
     72  UniquePtr<PrincipalInfo> mStoragePrincipalInfo;
     73 
     74  RefPtr<LSDatabase> mDatabase;
     75  RefPtr<LSObserver> mObserver;
     76 
     77  uint32_t mPrivateBrowsingId;
     78  Maybe<nsID> mClientId;
     79  Maybe<PrincipalInfo> mClientPrincipalInfo;
     80  nsCString mOrigin;
     81  nsCString mOriginKey;
     82  nsString mDocumentURI;
     83 
     84  bool mInExplicitSnapshot;
     85 
     86 public:
     87  /**
     88   * The normal creation path invoked by nsGlobalWindowInner.
     89   */
     90  static nsresult CreateForWindow(nsPIDOMWindowInner* aWindow,
     91                                  Storage** aStorage);
     92 
     93  /**
     94   * nsIDOMStorageManager creation path for use in testing logic.  Supports the
     95   * system principal where CreateForWindow does not.  This is also why aPrivate
     96   * exists separate from the principal; because the system principal can never
     97   * be mutated to have a private browsing id even though it can be used in a
     98   * window/document marked as private browsing.  That's a legacy issue that is
     99   * being dealt with, but it's why it exists here.
    100   */
    101  static nsresult CreateForPrincipal(nsPIDOMWindowInner* aWindow,
    102                                     nsIPrincipal* aPrincipal,
    103                                     nsIPrincipal* aStoragePrincipal,
    104                                     const nsAString& aDocumentURI,
    105                                     bool aPrivate, LSObject** aObject);
    106 
    107  void AssertIsOnOwningThread() const { NS_ASSERT_OWNINGTHREAD(LSObject); }
    108 
    109  const RefPtr<LSDatabase>& DatabaseStrongRef() const { return mDatabase; }
    110 
    111  const nsString& DocumentURI() const { return mDocumentURI; }
    112 
    113  bool InExplicitSnapshot() const { return mInExplicitSnapshot; }
    114 
    115  LSRequestChild* StartRequest(const LSRequestParams& aParams,
    116                               LSRequestChildCallback* aCallback);
    117 
    118  // Storage overrides.
    119  StorageType Type() const override;
    120 
    121  bool IsForkOf(const Storage* aStorage) const override;
    122 
    123  int64_t GetOriginQuotaUsage() const override;
    124 
    125  void Disconnect() override;
    126 
    127  uint32_t GetLength(nsIPrincipal& aSubjectPrincipal,
    128                     ErrorResult& aError) override;
    129 
    130  void Key(uint32_t aIndex, nsAString& aResult, nsIPrincipal& aSubjectPrincipal,
    131           ErrorResult& aError) override;
    132 
    133  void GetItem(const nsAString& aKey, nsAString& aResult,
    134               nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
    135 
    136  void GetSupportedNames(nsTArray<nsString>& aNames) override;
    137 
    138  void SetItem(const nsAString& aKey, const nsAString& aValue,
    139               nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
    140 
    141  void RemoveItem(const nsAString& aKey, nsIPrincipal& aSubjectPrincipal,
    142                  ErrorResult& aError) override;
    143 
    144  void Clear(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
    145 
    146  //////////////////////////////////////////////////////////////////////////////
    147  // Testing Methods: See Storage.h
    148  void Open(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
    149 
    150  void Close(nsIPrincipal& aSubjectPrincipal, ErrorResult& aError) override;
    151 
    152  void BeginExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
    153                             ErrorResult& aError) override;
    154 
    155  void CheckpointExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
    156                                  ErrorResult& aError) override;
    157 
    158  void EndExplicitSnapshot(nsIPrincipal& aSubjectPrincipal,
    159                           ErrorResult& aError) override;
    160 
    161  bool GetHasSnapshot(nsIPrincipal& aSubjectPrincipal,
    162                      ErrorResult& aError) override;
    163 
    164  int64_t GetSnapshotUsage(nsIPrincipal& aSubjectPrincipal,
    165                           ErrorResult& aError) override;
    166 
    167  //////////////////////////////////////////////////////////////////////////////
    168 
    169  NS_DECL_ISUPPORTS_INHERITED
    170  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(LSObject, Storage)
    171 
    172 private:
    173  LSObject(nsPIDOMWindowInner* aWindow, nsIPrincipal* aPrincipal,
    174           nsIPrincipal* aStoragePrincipal);
    175 
    176  ~LSObject();
    177 
    178  nsresult DoRequestSynchronously(const LSRequestParams& aParams,
    179                                  LSRequestResponse& aResponse);
    180 
    181  nsresult EnsureDatabase();
    182 
    183  void DropDatabase();
    184 
    185  /**
    186   * Invoked by nsGlobalWindowInner whenever a new "storage" event listener is
    187   * added to the window in order to ensure that "storage" events are received
    188   * from other processes.  (`LSObject::OnChange` directly invokes
    189   * `Storage::NotifyChange` to notify in-process listeners.)
    190   *
    191   * If this is the first request in the process for an observer for this
    192   * origin, this will trigger a RequestHelper-mediated synchronous LSRequest
    193   * to prepare a new observer in the parent process and also construction of
    194   * corresponding actors, which will result in the observer being fully
    195   * registered in the parent process.
    196   */
    197  nsresult EnsureObserver();
    198 
    199  /**
    200   * Invoked by nsGlobalWindowInner whenever its last "storage" event listener
    201   * is removed.
    202   */
    203  void DropObserver();
    204 
    205  /**
    206   * Internal helper method used by mutation methods that wraps the call to
    207   * Storage::NotifyChange to generate same-process "storage" events.
    208   */
    209  void OnChange(const nsAString& aKey, const nsAString& aOldValue,
    210                const nsAString& aNewValue);
    211 
    212  // Storage overrides.
    213  void LastRelease() override;
    214 };
    215 
    216 }  // namespace dom
    217 }  // namespace mozilla
    218 
    219 #endif  // mozilla_dom_localstorage_LSObject_h