tor-browser

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

ServiceWorkerEvents.h (9726B)


      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_serviceworkerevents_h__
      8 #define mozilla_dom_serviceworkerevents_h__
      9 
     10 #include "mozilla/Attributes.h"
     11 #include "mozilla/dom/Event.h"
     12 #include "mozilla/dom/ExtendableEventBinding.h"
     13 #include "mozilla/dom/ExtendableMessageEventBinding.h"
     14 #include "mozilla/dom/FetchEventBinding.h"
     15 #include "mozilla/dom/File.h"
     16 #include "mozilla/dom/Promise.h"
     17 #include "mozilla/dom/Response.h"
     18 #include "mozilla/dom/ServiceWorkerUtils.h"
     19 #include "mozilla/dom/WorkerCommon.h"
     20 #include "nsContentUtils.h"
     21 #include "nsProxyRelease.h"
     22 
     23 class nsIInterceptedChannel;
     24 
     25 namespace mozilla::dom {
     26 
     27 class Blob;
     28 class Client;
     29 class FetchEventOp;
     30 class MessagePort;
     31 struct PushEventInit;
     32 class Request;
     33 class ResponseOrPromise;
     34 class ServiceWorker;
     35 class ServiceWorkerRegistrationInfo;
     36 
     37 class CancelChannelRunnable final : public Runnable {
     38  nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
     39  nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
     40  const nsresult mStatus;
     41 
     42 public:
     43  CancelChannelRunnable(
     44      nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
     45      nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
     46      nsresult aStatus);
     47 
     48  NS_IMETHOD Run() override;
     49 };
     50 
     51 enum ExtendableEventResult { Rejected = 0, Resolved };
     52 
     53 class ExtendableEventCallback {
     54 public:
     55  virtual void FinishedWithResult(ExtendableEventResult aResult) = 0;
     56 
     57  NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
     58 };
     59 
     60 class ExtendableEvent : public Event {
     61 public:
     62  class ExtensionsHandler {
     63    friend class ExtendableEvent;
     64 
     65   public:
     66    virtual bool WaitOnPromise(Promise& aPromise) = 0;
     67 
     68    NS_INLINE_DECL_PURE_VIRTUAL_REFCOUNTING
     69 
     70   protected:
     71    virtual ~ExtensionsHandler();
     72 
     73    // Also returns false if the owning ExtendableEvent is destroyed.
     74    bool GetDispatchFlag() const;
     75 
     76   private:
     77    // Only the owning ExtendableEvent is allowed to set this data.
     78    void SetExtendableEvent(const ExtendableEvent* const aExtendableEvent);
     79 
     80    MOZ_NON_OWNING_REF const ExtendableEvent* mExtendableEvent = nullptr;
     81  };
     82 
     83 private:
     84  RefPtr<ExtensionsHandler> mExtensionsHandler;
     85 
     86 protected:
     87  bool GetDispatchFlag() const { return mEvent->mFlags.mIsBeingDispatched; }
     88 
     89  bool WaitOnPromise(Promise& aPromise);
     90 
     91  explicit ExtendableEvent(mozilla::dom::EventTarget* aOwner);
     92 
     93  ~ExtendableEvent() {
     94    if (mExtensionsHandler) {
     95      mExtensionsHandler->SetExtendableEvent(nullptr);
     96    }
     97  };
     98 
     99 public:
    100  NS_DECL_ISUPPORTS_INHERITED
    101 
    102  void SetKeepAliveHandler(ExtensionsHandler* aExtensionsHandler);
    103 
    104  virtual JSObject* WrapObjectInternal(
    105      JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override {
    106    return mozilla::dom::ExtendableEvent_Binding::Wrap(aCx, this, aGivenProto);
    107  }
    108 
    109  static already_AddRefed<ExtendableEvent> Constructor(
    110      mozilla::dom::EventTarget* aOwner, const nsAString& aType,
    111      const EventInit& aOptions) {
    112    RefPtr<ExtendableEvent> e = new ExtendableEvent(aOwner);
    113    bool trusted = e->Init(aOwner);
    114    e->InitEvent(aType, aOptions.mBubbles, aOptions.mCancelable);
    115    e->SetTrusted(trusted);
    116    e->SetComposed(aOptions.mComposed);
    117    return e.forget();
    118  }
    119 
    120  static already_AddRefed<ExtendableEvent> Constructor(
    121      const GlobalObject& aGlobal, const nsAString& aType,
    122      const EventInit& aOptions) {
    123    nsCOMPtr<EventTarget> target = do_QueryInterface(aGlobal.GetAsSupports());
    124    return Constructor(target, aType, aOptions);
    125  }
    126 
    127  void WaitUntil(JSContext* aCx, Promise& aPromise, ErrorResult& aRv);
    128 
    129  virtual ExtendableEvent* AsExtendableEvent() override { return this; }
    130 };
    131 
    132 class FetchEvent final : public ExtendableEvent {
    133  RefPtr<FetchEventOp> mRespondWithHandler;
    134  nsMainThreadPtrHandle<nsIInterceptedChannel> mChannel;
    135  nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo> mRegistration;
    136  RefPtr<Request> mRequest;
    137  RefPtr<Promise> mHandled;
    138  RefPtr<Promise> mPreloadResponse;
    139  nsCString mScriptSpec;
    140  nsString mClientId;
    141  nsString mResultingClientId;
    142  JSCallingLocation mPreventDefaultLocation;
    143  bool mWaitToRespond;
    144 
    145 protected:
    146  explicit FetchEvent(EventTarget* aOwner);
    147  ~FetchEvent();
    148 
    149 public:
    150  NS_DECL_ISUPPORTS_INHERITED
    151  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(FetchEvent, ExtendableEvent)
    152 
    153  virtual JSObject* WrapObjectInternal(
    154      JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override {
    155    return FetchEvent_Binding::Wrap(aCx, this, aGivenProto);
    156  }
    157 
    158  void PostInit(
    159      nsMainThreadPtrHandle<nsIInterceptedChannel>& aChannel,
    160      nsMainThreadPtrHandle<ServiceWorkerRegistrationInfo>& aRegistration,
    161      const nsACString& aScriptSpec);
    162 
    163  void PostInit(const nsACString& aScriptSpec,
    164                RefPtr<FetchEventOp> aRespondWithHandler);
    165 
    166  static already_AddRefed<FetchEvent> Constructor(
    167      const GlobalObject& aGlobal, const nsAString& aType,
    168      const FetchEventInit& aOptions);
    169 
    170  bool WaitToRespond() const { return mWaitToRespond; }
    171 
    172  Request* Request_() const {
    173    MOZ_ASSERT(mRequest);
    174    return mRequest;
    175  }
    176 
    177  void GetClientId(nsAString& aClientId) const { aClientId = mClientId; }
    178 
    179  void GetResultingClientId(nsAString& aResultingClientId) const {
    180    aResultingClientId = mResultingClientId;
    181  }
    182 
    183  Promise* Handled() const { return mHandled; }
    184 
    185  Promise* PreloadResponse() const { return mPreloadResponse; }
    186 
    187  void RespondWith(JSContext* aCx, Promise& aArg, ErrorResult& aRv);
    188 
    189  // Pull in the Event version of PreventDefault so we don't get
    190  // shadowing warnings.
    191  using Event::PreventDefault;
    192  void PreventDefault(JSContext* aCx, CallerType aCallerType) override;
    193 
    194  void ReportCanceled();
    195 };
    196 
    197 class PushMessageData final : public nsISupports, public nsWrapperCache {
    198 public:
    199  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
    200  NS_DECL_CYCLE_COLLECTION_WRAPPERCACHE_CLASS(PushMessageData)
    201 
    202  virtual JSObject* WrapObject(JSContext* aCx,
    203                               JS::Handle<JSObject*> aGivenProto) override;
    204 
    205  nsIGlobalObject* GetParentObject() const { return mOwner; }
    206 
    207  void Json(JSContext* cx, JS::MutableHandle<JS::Value> aRetval,
    208            ErrorResult& aRv);
    209  void Text(nsAString& aData);
    210  void ArrayBuffer(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
    211                   ErrorResult& aRv);
    212  already_AddRefed<mozilla::dom::Blob> Blob(ErrorResult& aRv);
    213  void Bytes(JSContext* cx, JS::MutableHandle<JSObject*> aRetval,
    214             ErrorResult& aRv);
    215 
    216  PushMessageData(nsIGlobalObject* aOwner, nsTArray<uint8_t>&& aBytes);
    217 
    218 private:
    219  nsCOMPtr<nsIGlobalObject> mOwner;
    220  nsTArray<uint8_t> mBytes;
    221  nsString mDecodedText;
    222  ~PushMessageData();
    223 
    224  nsresult EnsureDecodedText();
    225  uint8_t* GetContentsCopy();
    226  void SetUseCounterIfDeclarative(JSContext* aCx);
    227 };
    228 
    229 class PushEvent final : public ExtendableEvent {
    230  RefPtr<PushMessageData> mData;
    231 
    232 protected:
    233  explicit PushEvent(mozilla::dom::EventTarget* aOwner);
    234  ~PushEvent() = default;
    235 
    236 public:
    237  NS_DECL_ISUPPORTS_INHERITED
    238  NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(PushEvent, ExtendableEvent)
    239 
    240  virtual JSObject* WrapObjectInternal(
    241      JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override;
    242 
    243  static already_AddRefed<PushEvent> Constructor(
    244      mozilla::dom::EventTarget* aOwner, const nsAString& aType,
    245      const PushEventInit& aOptions, ErrorResult& aRv);
    246 
    247  static already_AddRefed<PushEvent> Constructor(const GlobalObject& aGlobal,
    248                                                 const nsAString& aType,
    249                                                 const PushEventInit& aOptions,
    250                                                 ErrorResult& aRv) {
    251    nsCOMPtr<EventTarget> owner = do_QueryInterface(aGlobal.GetAsSupports());
    252    return Constructor(owner, aType, aOptions, aRv);
    253  }
    254 
    255  PushMessageData* GetData() const { return mData; }
    256 };
    257 
    258 class ExtendableMessageEvent final : public ExtendableEvent {
    259  JS::Heap<JS::Value> mData;
    260  nsString mOrigin;
    261  nsString mLastEventId;
    262  RefPtr<Client> mClient;
    263  RefPtr<ServiceWorker> mServiceWorker;
    264  RefPtr<MessagePort> mMessagePort;
    265  nsTArray<RefPtr<MessagePort>> mPorts;
    266 
    267 protected:
    268  explicit ExtendableMessageEvent(EventTarget* aOwner);
    269  ~ExtendableMessageEvent();
    270 
    271 public:
    272  NS_DECL_ISUPPORTS_INHERITED
    273  NS_DECL_CYCLE_COLLECTION_SCRIPT_HOLDER_CLASS_INHERITED(ExtendableMessageEvent,
    274                                                         ExtendableEvent)
    275 
    276  virtual JSObject* WrapObjectInternal(
    277      JSContext* aCx, JS::Handle<JSObject*> aGivenProto) override {
    278    return mozilla::dom::ExtendableMessageEvent_Binding::Wrap(aCx, this,
    279                                                              aGivenProto);
    280  }
    281 
    282  static already_AddRefed<ExtendableMessageEvent> Constructor(
    283      mozilla::dom::EventTarget* aOwner, const nsAString& aType,
    284      const ExtendableMessageEventInit& aOptions);
    285 
    286  static already_AddRefed<ExtendableMessageEvent> Constructor(
    287      const GlobalObject& aGlobal, const nsAString& aType,
    288      const ExtendableMessageEventInit& aOptions);
    289 
    290  void GetData(JSContext* aCx, JS::MutableHandle<JS::Value> aData,
    291               ErrorResult& aRv);
    292 
    293  void GetSource(
    294      Nullable<OwningClientOrServiceWorkerOrMessagePort>& aValue) const;
    295 
    296  void GetOrigin(nsAString& aOrigin) const { aOrigin = mOrigin; }
    297 
    298  void GetLastEventId(nsAString& aLastEventId) const {
    299    aLastEventId = mLastEventId;
    300  }
    301 
    302  void GetPorts(nsTArray<RefPtr<MessagePort>>& aPorts);
    303 };
    304 
    305 }  // namespace mozilla::dom
    306 
    307 #endif /* mozilla_dom_serviceworkerevents_h__ */