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
;
29 class nsIOutputStream
;
39 class InternalRequest
;
40 class InternalResponse
;
41 class PerformanceStorage
;
42 class PerformanceTimingData
;
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
50 class FetchDriverObserver
{
53 : mReporter(new ConsoleReportCollector()), mGotResponseAvailable(false) {}
55 NS_INLINE_DECL_THREADSAFE_REFCOUNTING(FetchDriverObserver
);
56 void OnResponseAvailable(SafeRefPtr
<InternalResponse
> aResponse
);
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
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
) {}
84 virtual ~FetchDriverObserver() = default;
86 virtual void OnResponseAvailableInternal(
87 SafeRefPtr
<InternalResponse
> aResponse
) = 0;
89 nsCOMPtr
<nsIConsoleReportCollector
> mReporter
;
92 bool mGotResponseAvailable
;
95 class AlternativeDataStreamListener
;
97 class FetchDriver final
: public nsIChannelEventSink
,
98 public nsIInterfaceRequestor
,
99 public nsINetworkInterceptController
,
100 public nsIThreadRetargetableStreamListener
,
101 public AbortFollower
{
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
);
139 void RunAbortAlgorithm() override
;
140 void FetchDriverAbortActions(AbortSignalImpl
* aSignalImpl
);
142 void EnableNetworkInterceptControl();
144 void SetAssociatedBrowsingContextID(uint64_t aID
) {
145 mAssociatedBrowsingContextID
= aID
;
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;
196 bool mResponseAvailableCalled
;
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;
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
220 void FailWithNetworkError(nsresult rv
);
222 void SetRequestHeaders(nsIHttpChannel
* aChannel
, bool aStripRequestBodyHeader
,
223 bool aStripAuthHeader
) const;
225 void FinishOnStopRequest(AlternativeDataStreamListener
* aAltDataListener
);
229 } // namespace mozilla
231 #endif // mozilla_dom_FetchDriver_h