Bug 1890793: Assert CallArgs::newTarget is not gray. r=spidermonkey-reviewers,sfink...
[gecko.git] / dom / fetch / FetchDriver.h
blobde01c2a6be803e2722ee9e71ec173042c6fe04ee
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/. */
7 #ifndef mozilla_dom_FetchDriver_h
8 #define mozilla_dom_FetchDriver_h
10 #include "nsIChannelEventSink.h"
11 #include "nsIInterfaceRequestor.h"
12 #include "nsINetworkInterceptController.h"
13 #include "nsIStreamListener.h"
14 #include "nsIThreadRetargetableStreamListener.h"
15 #include "mozilla/ConsoleReportCollector.h"
16 #include "mozilla/dom/AbortSignal.h"
17 #include "mozilla/dom/SafeRefPtr.h"
18 #include "mozilla/dom/SerializedStackHolder.h"
19 #include "mozilla/dom/SRIMetadata.h"
20 #include "mozilla/RefPtr.h"
21 #include "mozilla/UniquePtr.h"
23 #include "mozilla/DebugOnly.h"
25 class nsIConsoleReportCollector;
26 class nsICookieJarSettings;
27 class nsICSPEventListener;
28 class nsIEventTarget;
29 class nsIOutputStream;
30 class nsILoadGroup;
31 class nsIPrincipal;
33 namespace mozilla {
34 class PreloaderBase;
36 namespace dom {
38 class Document;
39 class InternalRequest;
40 class InternalResponse;
41 class PerformanceStorage;
42 class PerformanceTimingData;
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.
50 class FetchDriverObserver {
51 public:
52 FetchDriverObserver()
53 : mReporter(new ConsoleReportCollector()), mGotResponseAvailable(false) {}
55 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchDriverObserver);
56 void OnResponseAvailable(SafeRefPtr<InternalResponse> aResponse);
58 enum EndReason {
59 eAborted,
60 eByNetworking,
63 virtual void OnResponseEnd(EndReason aReason,
64 JS::Handle<JS::Value> aReasonDetails){};
66 nsIConsoleReportCollector* GetReporter() const { return mReporter; }
68 virtual void FlushConsoleReport() = 0;
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;
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;
79 virtual void OnReportPerformanceTiming() {}
81 virtual void OnNotifyNetworkMonitorAlternateStack(uint64_t aChannelID) {}
83 protected:
84 virtual ~FetchDriverObserver() = default;
86 virtual void OnResponseAvailableInternal(
87 SafeRefPtr<InternalResponse> aResponse) = 0;
89 nsCOMPtr<nsIConsoleReportCollector> mReporter;
91 private:
92 bool mGotResponseAvailable;
95 class AlternativeDataStreamListener;
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
111 FetchDriver(SafeRefPtr<InternalRequest> aRequest, nsIPrincipal* aPrincipal,
112 nsILoadGroup* aLoadGroup, nsIEventTarget* aMainThreadEventTarget,
113 nsICookieJarSettings* aCookieJarSettings,
114 PerformanceStorage* aPerformanceStorage, bool aIsTrackingFetch);
116 nsresult Fetch(AbortSignalImpl* aSignalImpl, FetchDriverObserver* aObserver);
118 void SetDocument(Document* aDocument);
120 void SetCSPEventListener(nsICSPEventListener* aCSPEventListener);
122 void SetClientInfo(const ClientInfo& aClientInfo);
124 void SetController(const Maybe<ServiceWorkerDescriptor>& aController);
126 void SetWorkerScript(const nsACString& aWorkerScript) {
127 MOZ_ASSERT(!aWorkerScript.IsEmpty());
128 mWorkerScript = aWorkerScript;
131 void SetOriginStack(UniquePtr<SerializedStackHolder>&& aOriginStack) {
132 mOriginStack = std::move(aOriginStack);
135 PerformanceTimingData* GetPerformanceTimingData(nsAString& aInitiatorType,
136 nsAString& aEntryName);
138 // AbortFollower
139 void RunAbortAlgorithm() override;
140 void FetchDriverAbortActions(AbortSignalImpl* aSignalImpl);
142 void EnableNetworkInterceptControl();
144 void SetAssociatedBrowsingContextID(uint64_t aID) {
145 mAssociatedBrowsingContextID = aID;
148 private:
149 nsCOMPtr<nsIPrincipal> mPrincipal;
150 nsCOMPtr<nsILoadGroup> mLoadGroup;
151 SafeRefPtr<InternalRequest> mRequest;
152 SafeRefPtr<InternalResponse> mResponse;
153 nsCOMPtr<nsIOutputStream> mPipeOutputStream;
154 // Access to mObserver can be racy from OnDataAvailable and
155 // FetchAbortActions. This must not be modified
156 // in either of these functions.
157 RefPtr<FetchDriverObserver> mObserver;
158 RefPtr<Document> mDocument;
159 nsCOMPtr<nsICSPEventListener> mCSPEventListener;
160 Maybe<ClientInfo> mClientInfo;
161 Maybe<ServiceWorkerDescriptor> mController;
162 nsCOMPtr<nsIChannel> mChannel;
163 UniquePtr<SRICheckDataVerifier> mSRIDataVerifier;
164 nsCOMPtr<nsIEventTarget> mMainThreadEventTarget;
166 nsCOMPtr<nsICookieJarSettings> mCookieJarSettings;
168 // This is set only when Fetch is used in workers.
169 RefPtr<PerformanceStorage> mPerformanceStorage;
171 SRIMetadata mSRIMetadata;
172 nsCString mWorkerScript;
173 UniquePtr<SerializedStackHolder> mOriginStack;
175 // This is written once in OnStartRequest on the main thread and then
176 // written/read in OnDataAvailable() on any thread. Necko guarantees
177 // that these do not overlap.
178 bool mNeedToObserveOnDataAvailable;
180 bool mIsTrackingFetch;
182 RefPtr<AlternativeDataStreamListener> mAltDataListener;
183 bool mOnStopRequestCalled;
185 // This flag is true when this fetch has found a matching preload and is being
186 // satisfied by a its response.
187 bool mFromPreload = false;
188 // This flag is set in call to Abort() and spans the possible window this
189 // fetch doesn't have mChannel (to be cancelled) between reuse of the matching
190 // preload, that has already finished and dropped reference to its channel,
191 // and OnStartRequest notification. It let's us cancel the load when we get
192 // the channel in OnStartRequest.
193 bool mAborted = false;
195 #ifdef DEBUG
196 bool mResponseAvailableCalled;
197 bool mFetchCalled;
198 #endif
199 nsCOMPtr<nsINetworkInterceptController> mInterceptController;
201 uint64_t mAssociatedBrowsingContextID{0};
203 friend class AlternativeDataStreamListener;
205 FetchDriver() = delete;
206 FetchDriver(const FetchDriver&) = delete;
207 FetchDriver& operator=(const FetchDriver&) = delete;
208 ~FetchDriver();
210 already_AddRefed<PreloaderBase> FindPreload(nsIURI* aURI);
212 void UpdateReferrerInfoFromNewChannel(nsIChannel* aChannel);
214 nsresult HttpFetch(const nsACString& aPreferredAlternativeDataType = ""_ns);
215 // Returns the filtered response sent to the observer.
216 SafeRefPtr<InternalResponse> BeginAndGetFilteredResponse(
217 SafeRefPtr<InternalResponse> aResponse, bool aFoundOpaqueRedirect);
218 // Utility since not all cases need to do any post processing of the filtered
219 // response.
220 void FailWithNetworkError(nsresult rv);
222 void SetRequestHeaders(nsIHttpChannel* aChannel, bool aStripRequestBodyHeader,
223 bool aStripAuthHeader) const;
225 void FinishOnStopRequest(AlternativeDataStreamListener* aAltDataListener);
228 } // namespace dom
229 } // namespace mozilla
231 #endif // mozilla_dom_FetchDriver_h