tor-browser

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

ServiceWorkerOp.h (6855B)


      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_serviceworkerop_h__
      8 #define mozilla_dom_serviceworkerop_h__
      9 
     10 #include <functional>
     11 
     12 #include "ServiceWorkerEvents.h"
     13 #include "ServiceWorkerOpPromise.h"
     14 #include "mozilla/Maybe.h"
     15 #include "mozilla/RefPtr.h"
     16 #include "mozilla/TimeStamp.h"
     17 #include "mozilla/dom/PromiseNativeHandler.h"
     18 #include "mozilla/dom/RemoteWorkerChild.h"
     19 #include "mozilla/dom/RemoteWorkerOp.h"
     20 #include "mozilla/dom/ServiceWorkerOpArgs.h"
     21 #include "mozilla/dom/ServiceWorkerOpPromise.h"
     22 #include "mozilla/dom/WorkerRunnable.h"
     23 #include "nsISupportsImpl.h"
     24 
     25 namespace mozilla::dom {
     26 
     27 using remoteworker::RemoteWorkerState;
     28 
     29 class FetchEventOpProxyChild;
     30 
     31 class ServiceWorkerOp : public RemoteWorkerOp {
     32 public:
     33  // `aCallback` will be called when the operation completes or is canceled.
     34  static already_AddRefed<ServiceWorkerOp> Create(
     35      ServiceWorkerOpArgs&& aArgs,
     36      std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
     37 
     38  ServiceWorkerOp(
     39      ServiceWorkerOpArgs&& aArgs,
     40      std::function<void(const ServiceWorkerOpResult&)>&& aCallback);
     41 
     42  ServiceWorkerOp(const ServiceWorkerOp&) = delete;
     43 
     44  ServiceWorkerOp& operator=(const ServiceWorkerOp&) = delete;
     45 
     46  ServiceWorkerOp(ServiceWorkerOp&&) = default;
     47 
     48  ServiceWorkerOp& operator=(ServiceWorkerOp&&) = default;
     49 
     50  // Returns `true` if the operation has started and `false` otherwise.
     51  bool MaybeStart(RemoteWorkerChild* aOwner, RemoteWorkerState& aState) final;
     52 
     53  void StartOnMainThread(RefPtr<RemoteWorkerChild>& aOwner) final;
     54 
     55  void Start(RemoteWorkerNonLifeCycleOpControllerChild* aOwner,
     56             RemoteWorkerState& aState) final;
     57 
     58  void Cancel() final;
     59 
     60 protected:
     61  ~ServiceWorkerOp();
     62 
     63  bool Started() const;
     64 
     65  bool IsTerminationOp() const;
     66 
     67  // Override to provide a runnable that's not a `ServiceWorkerOpRunnable.`
     68  virtual RefPtr<WorkerThreadRunnable> GetRunnable(
     69      WorkerPrivate* aWorkerPrivate);
     70 
     71  // Overridden by ServiceWorkerOp subclasses, it should return true when
     72  // the ServiceWorkerOp was executed successfully (and false if it did fail).
     73  // Content throwing an exception during event dispatch is still considered
     74  // success.
     75  virtual bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) = 0;
     76 
     77  // Override to reject any additional MozPromises that subclasses may contain.
     78  virtual void RejectAll(nsresult aStatus);
     79 
     80  ServiceWorkerOpArgs mArgs;
     81 
     82  // Subclasses must settle this promise when appropriate.
     83  MozPromiseHolder<ServiceWorkerOpPromise> mPromiseHolder;
     84 
     85 private:
     86  class ServiceWorkerOpRunnable;
     87 
     88  bool mStarted = false;
     89 };
     90 
     91 class ExtendableEventOp : public ServiceWorkerOp,
     92                          public ExtendableEventCallback {
     93  using ServiceWorkerOp::ServiceWorkerOp;
     94 
     95 protected:
     96  ~ExtendableEventOp() = default;
     97 
     98  void FinishedWithResult(ExtendableEventResult aResult) override;
     99 };
    100 
    101 class FetchEventOp final : public ExtendableEventOp,
    102                           public PromiseNativeHandler {
    103  using ExtendableEventOp::ExtendableEventOp;
    104 
    105 public:
    106  NS_DECL_THREADSAFE_ISUPPORTS
    107 
    108  /**
    109   * This must be called once and only once before the first call to
    110   * `MaybeStart()`; `aActor` will be used for `AsyncLog()` and
    111   * `ReportCanceled().`
    112   */
    113  void SetActor(RefPtr<FetchEventOpProxyChild> aActor);
    114 
    115  void RevokeActor(FetchEventOpProxyChild* aActor);
    116 
    117  // This must be called at most once before the first call to `MaybeStart().`
    118  RefPtr<FetchEventRespondWithPromise> GetRespondWithPromise();
    119 
    120  // This must be called when `FetchEvent::RespondWith()` is called.
    121  void RespondWithCalledAt(const nsCString& aRespondWithScriptSpec,
    122                           uint32_t aRespondWithLineNumber,
    123                           uint32_t aRespondWithColumnNumber);
    124 
    125  void ReportCanceled(const nsCString& aPreventDefaultScriptSpec,
    126                      uint32_t aPreventDefaultLineNumber,
    127                      uint32_t aPreventDefaultColumnNumber);
    128 
    129 private:
    130  class AutoCancel;
    131 
    132  ~FetchEventOp();
    133 
    134  bool Exec(JSContext* aCx, WorkerPrivate* aWorkerPrivate) override;
    135 
    136  void RejectAll(nsresult aStatus) override;
    137 
    138  void FinishedWithResult(ExtendableEventResult aResult) override;
    139 
    140  /**
    141   * `{Resolved,Reject}Callback()` are use to handle the
    142   * `FetchEvent::RespondWith()` promise.
    143   */
    144  void ResolvedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    145                        ErrorResult& aRv) override;
    146 
    147  void RejectedCallback(JSContext* aCx, JS::Handle<JS::Value> aValue,
    148                        ErrorResult& aRv) override;
    149 
    150  void MaybeFinished();
    151 
    152  // Requires mRespondWithClosure to be non-empty.
    153  void AsyncLog(const nsCString& aMessageName, nsTArray<nsString> aParams);
    154 
    155  void AsyncLog(const nsCString& aScriptSpec, uint32_t aLineNumber,
    156                uint32_t aColumnNumber, const nsCString& aMessageName,
    157                nsTArray<nsString> aParams);
    158 
    159  void GetRequestURL(nsAString& aOutRequestURL);
    160 
    161  // A failure code means that the dispatch failed.
    162  nsresult DispatchFetchEvent(JSContext* aCx, WorkerPrivate* aWorkerPrivate);
    163 
    164  // Worker Launcher thread only. Used for `AsyncLog().`
    165  RefPtr<FetchEventOpProxyChild> mActor;
    166 
    167  /**
    168   * Created on the Worker Launcher thread and settled on the worker thread.
    169   * If this isn't settled before `mPromiseHolder` (which it should be),
    170   * `FetchEventOpChild` will cancel the intercepted network request.
    171   */
    172  MozPromiseHolder<FetchEventRespondWithPromise> mRespondWithPromiseHolder;
    173 
    174  // Worker thread only.
    175  Maybe<ExtendableEventResult> mResult;
    176  bool mPostDispatchChecksDone = false;
    177 
    178  // Worker thread only; set when `FetchEvent::RespondWith()` is called.
    179  Maybe<FetchEventRespondWithClosure> mRespondWithClosure;
    180 
    181  // Must be set to `nullptr` on the worker thread because `Promise`'s
    182  // destructor must be called on the worker thread.
    183  RefPtr<Promise> mHandled;
    184 
    185  // Must be set to `nullptr` on the worker thread because `Promise`'s
    186  // destructor must be called on the worker thread.
    187  RefPtr<Promise> mPreloadResponse;
    188 
    189  // Holds the callback that resolves mPreloadResponse.
    190  MozPromiseRequestHolder<FetchEventPreloadResponseAvailablePromise>
    191      mPreloadResponseAvailablePromiseRequestHolder;
    192  MozPromiseRequestHolder<FetchEventPreloadResponseTimingPromise>
    193      mPreloadResponseTimingPromiseRequestHolder;
    194  MozPromiseRequestHolder<FetchEventPreloadResponseEndPromise>
    195      mPreloadResponseEndPromiseRequestHolder;
    196 
    197  TimeStamp mFetchHandlerStart;
    198  TimeStamp mFetchHandlerFinish;
    199 };
    200 
    201 }  // namespace mozilla::dom
    202 
    203 #endif  // mozilla_dom_serviceworkerop_h__