tor-browser

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

FetchDriver.h (8353B)


      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_FetchDriver_h
      8 #define mozilla_dom_FetchDriver_h
      9 
     10 #include "mozilla/ConsoleReportCollector.h"
     11 #include "mozilla/Mutex.h"
     12 #include "mozilla/RefPtr.h"
     13 #include "mozilla/UniquePtr.h"
     14 #include "mozilla/dom/AbortSignal.h"
     15 #include "mozilla/dom/SRIMetadata.h"
     16 #include "mozilla/dom/SafeRefPtr.h"
     17 #include "mozilla/dom/SerializedStackHolder.h"
     18 #include "nsIChannelEventSink.h"
     19 #include "nsIClassifiedChannel.h"
     20 #include "nsIInterfaceRequestor.h"
     21 #include "nsINetworkInterceptController.h"
     22 #include "nsIStreamListener.h"
     23 #include "nsIThreadRetargetableStreamListener.h"
     24 
     25 class nsIConsoleReportCollector;
     26 class nsICookieJarSettings;
     27 class nsICSPEventListener;
     28 class nsIEventTarget;
     29 class nsIOutputStream;
     30 class nsILoadGroup;
     31 class nsIPrincipal;
     32 
     33 namespace mozilla {
     34 class PreloaderBase;
     35 
     36 namespace dom {
     37 
     38 class Document;
     39 class InternalRequest;
     40 class InternalResponse;
     41 class PerformanceStorage;
     42 class PerformanceTimingData;
     43 
     44 /**
     45 * Provides callbacks to be called when response is available or on error.
     46 * Implemenations usually resolve or reject the promise returned from fetch().
     47 * The callbacks can be called synchronously or asynchronously from
     48 * FetchDriver::Fetch.
     49 */
     50 class FetchDriverObserver {
     51 public:
     52  FetchDriverObserver()
     53      : mReporter(new ConsoleReportCollector()), mGotResponseAvailable(false) {}
     54 
     55  NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchDriverObserver);
     56  void OnResponseAvailable(SafeRefPtr<InternalResponse> aResponse);
     57 
     58  enum EndReason {
     59    eAborted,
     60    eByNetworking,
     61  };
     62 
     63  virtual void OnResponseEnd(EndReason aReason,
     64                             JS::Handle<JS::Value> aReasonDetails) {};
     65 
     66  nsIConsoleReportCollector* GetReporter() const { return mReporter; }
     67 
     68  virtual void FlushConsoleReport() = 0;
     69 
     70  // Called in OnStartRequest() to determine if the OnDataAvailable() method
     71  // needs to be called.  Invoking that method may generate additional main
     72  // thread runnables.
     73  virtual bool NeedOnDataAvailable() = 0;
     74 
     75  // Called once when the first byte of data is received iff
     76  // NeedOnDataAvailable() returned true when called in OnStartRequest().
     77  virtual void OnDataAvailable() = 0;
     78 
     79  virtual void OnReportPerformanceTiming() {}
     80 
     81  virtual void OnNotifyNetworkMonitorAlternateStack(uint64_t aChannelID) {}
     82 
     83 protected:
     84  virtual ~FetchDriverObserver() = default;
     85 
     86  virtual void OnResponseAvailableInternal(
     87      SafeRefPtr<InternalResponse> aResponse) = 0;
     88 
     89  nsCOMPtr<nsIConsoleReportCollector> mReporter;
     90 
     91 private:
     92  bool mGotResponseAvailable;
     93 };
     94 
     95 class AlternativeDataStreamListener;
     96 
     97 class FetchDriver final : public nsIChannelEventSink,
     98                          public nsIInterfaceRequestor,
     99                          public nsINetworkInterceptController,
    100                          public nsIThreadRetargetableStreamListener,
    101                          public AbortFollower {
    102 public:
    103  NS_DECL_THREADSAFE_ISUPPORTS
    104  NS_DECL_NSIREQUESTOBSERVER
    105  NS_DECL_NSISTREAMLISTENER
    106  NS_DECL_NSICHANNELEVENTSINK
    107  NS_DECL_NSIINTERFACEREQUESTOR
    108  NS_DECL_NSINETWORKINTERCEPTCONTROLLER
    109  NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
    110 
    111  FetchDriver(SafeRefPtr<InternalRequest> aRequest, nsIPrincipal* aPrincipal,
    112              nsILoadGroup* aLoadGroup, nsIEventTarget* aMainThreadEventTarget,
    113              nsICookieJarSettings* aCookieJarSettings,
    114              PerformanceStorage* aPerformanceStorage,
    115              net::ClassificationFlags aTrackingFlags);
    116 
    117  nsresult Fetch(AbortSignalImpl* aSignalImpl, FetchDriverObserver* aObserver);
    118 
    119  void SetDocument(Document* aDocument);
    120 
    121  void SetCSPEventListener(nsICSPEventListener* aCSPEventListener);
    122 
    123  void SetClientInfo(const ClientInfo& aClientInfo);
    124 
    125  void SetController(const Maybe<ServiceWorkerDescriptor>& aController);
    126 
    127  void SetWorkerScript(const nsACString& aWorkerScript) {
    128    MOZ_ASSERT(!aWorkerScript.IsEmpty());
    129    mWorkerScript = aWorkerScript;
    130  }
    131 
    132  void SetOriginStack(UniquePtr<SerializedStackHolder>&& aOriginStack) {
    133    mOriginStack = std::move(aOriginStack);
    134  }
    135 
    136  PerformanceTimingData* GetPerformanceTimingData(nsAString& aInitiatorType,
    137                                                  nsAString& aEntryName);
    138 
    139  // AbortFollower
    140  void RunAbortAlgorithm() override;
    141  void FetchDriverAbortActions(AbortSignalImpl* aSignalImpl);
    142 
    143  void EnableNetworkInterceptControl();
    144 
    145  void SetAssociatedBrowsingContextID(uint64_t aID) {
    146    mAssociatedBrowsingContextID = aID;
    147  }
    148 
    149  void SetIsThirdPartyContext(const Maybe<bool> aIsThirdPartyWorker) {
    150    mIsThirdPartyContext = aIsThirdPartyWorker;
    151  }
    152 
    153  void SetIsOn3PCBExceptionList(bool aIsOn3PCBExceptionList) {
    154    mIsOn3PCBExceptionList = aIsOn3PCBExceptionList;
    155  }
    156 
    157 private:
    158  nsCOMPtr<nsIPrincipal> mPrincipal;
    159  nsCOMPtr<nsILoadGroup> mLoadGroup;
    160  SafeRefPtr<InternalRequest> mRequest;
    161  SafeRefPtr<InternalResponse> mResponse;
    162  nsCOMPtr<nsIOutputStream> mPipeOutputStream;
    163 
    164  // mutex to prevent race between OnDataAvailable (OMT) and main thread
    165  // functions
    166  Mutex mODAMutex;
    167  // access to mObserver can race between FetchDriverAbortActions (main thread)
    168  // and OnDataAvailable (OMT)
    169  // See Bug 1810805
    170  RefPtr<FetchDriverObserver> mObserver;
    171  RefPtr<Document> mDocument;
    172  nsCOMPtr<nsICSPEventListener> mCSPEventListener;
    173  Maybe<ClientInfo> mClientInfo;
    174  Maybe<ServiceWorkerDescriptor> mController;
    175  nsCOMPtr<nsIChannel> mChannel;
    176  UniquePtr<SRICheckDataVerifier> mSRIDataVerifier;
    177  nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
    178 
    179  nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
    180 
    181  // This is set only when Fetch is used in workers.
    182  RefPtr<PerformanceStorage> mPerformanceStorage;
    183 
    184  SRIMetadata mSRIMetadata;
    185  nsCString mWorkerScript;
    186  UniquePtr<SerializedStackHolder> mOriginStack;
    187 
    188  // This is written once in OnStartRequest on the main thread and then
    189  // written/read in OnDataAvailable() on any thread.  Necko guarantees
    190  // that these do not overlap.
    191  bool mNeedToObserveOnDataAvailable;
    192 
    193  bool mIsTrackingFetch;
    194  net::ClassificationFlags mTrackingFlags;
    195 
    196  // Indicates whether the fetch request is from a third-party context.
    197  Maybe<bool> mIsThirdPartyContext;
    198 
    199  // Indicates whether the fetch request is on the 3PCB exception list.
    200  bool mIsOn3PCBExceptionList;
    201 
    202  RefPtr<AlternativeDataStreamListener> mAltDataListener;
    203  bool mOnStopRequestCalled;
    204 
    205  // This flag is true when this fetch has found a matching preload and is being
    206  // satisfied by a its response.
    207  bool mFromPreload = false;
    208  // This flag is set in call to Abort() and spans the possible window this
    209  // fetch doesn't have mChannel (to be cancelled) between reuse of the matching
    210  // preload, that has already finished and dropped reference to its channel,
    211  // and OnStartRequest notification.  It let's us cancel the load when we get
    212  // the channel in OnStartRequest.
    213  bool mAborted = false;
    214 
    215 #ifdef DEBUG
    216  bool mResponseAvailableCalled;
    217  bool mFetchCalled;
    218 #endif
    219  nsCOMPtr<nsINetworkInterceptController> mInterceptController;
    220 
    221  uint64_t mAssociatedBrowsingContextID{0};
    222 
    223  friend class AlternativeDataStreamListener;
    224 
    225  FetchDriver() = delete;
    226  FetchDriver(const FetchDriver&) = delete;
    227  FetchDriver& operator=(const FetchDriver&) = delete;
    228  ~FetchDriver();
    229 
    230  already_AddRefed<PreloaderBase> FindPreload(nsIURI* aURI);
    231 
    232  void UpdateReferrerInfoFromNewChannel(nsIChannel* aChannel);
    233 
    234  nsresult HttpFetch(const nsACString& aPreferredAlternativeDataType = ""_ns);
    235  // Returns the filtered response sent to the observer.
    236  SafeRefPtr<InternalResponse> BeginAndGetFilteredResponse(
    237      SafeRefPtr<InternalResponse> aResponse, bool aFoundOpaqueRedirect);
    238  // Utility since not all cases need to do any post processing of the filtered
    239  // response.
    240  void FailWithNetworkError(nsresult rv);
    241 
    242  void SetRequestHeaders(nsIHttpChannel* aChannel, bool aStripRequestBodyHeader,
    243                         bool aStripAuthHeader) const;
    244 
    245  void FinishOnStopRequest(AlternativeDataStreamListener* aAltDataListener);
    246 };
    247 
    248 }  // namespace dom
    249 }  // namespace mozilla
    250 
    251 #endif  // mozilla_dom_FetchDriver_h