1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set sw=2 ts=8 et tw=80 : */
3
4 /* This Source Code Form is subject to the terms of the Mozilla Public
5 * License, v. 2.0. If a copy of the MPL was not distributed with this
6 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7
8 #ifndef mozilla_net_HttpBaseChannel_h
9 #define mozilla_net_HttpBaseChannel_h
10
11 #include <utility>
12
13 #include "mozilla/AtomicBitfields.h"
14 #include "mozilla/Atomics.h"
15 #include "mozilla/dom/DOMTypes.h"
16 #include "mozilla/net/DNS.h"
17 #include "mozilla/net/NeckoCommon.h"
18 #include "mozilla/net/PrivateBrowsingChannel.h"
19 #include "nsCOMPtr.h"
20 #include "nsHashPropertyBag.h"
21 #include "nsHttp.h"
22 #include "nsHttpHandler.h"
23 #include "nsHttpRequestHead.h"
24 #include "nsIClassOfService.h"
25 #include "nsIClassifiedChannel.h"
26 #include "nsIConsoleReportCollector.h"
27 #include "nsIEncodedChannel.h"
28 #include "nsIForcePendingChannel.h"
29 #include "nsIFormPOSTActionChannel.h"
30 #include "nsIHttpChannel.h"
31 #include "nsIHttpChannelInternal.h"
32 #include "nsILoadInfo.h"
33 #include "nsIResumableChannel.h"
34 #include "nsIStringEnumerator.h"
35 #include "nsISupportsPriority.h"
36 #include "nsIThrottledInputChannel.h"
37 #include "nsITimedChannel.h"
38 #include "nsITraceableChannel.h"
39 #include "nsIURI.h"
40 #include "nsIUploadChannel2.h"
41 #include "nsStringEnumerator.h"
42 #include "nsTArray.h"
43 #include "nsThreadUtils.h"
44
45 #define HTTP_BASE_CHANNEL_IID \
46 { \
47 0x9d5cde03, 0xe6e9, 0x4612, { \
48 0xbf, 0xef, 0xbb, 0x66, 0xf3, 0xbb, 0x74, 0x46 \
49 } \
50 }
51
52 class nsIProgressEventSink;
53 class nsISecurityConsoleMessage;
54 class nsIPrincipal;
55
56 namespace mozilla {
57
58 namespace dom {
59 class PerformanceStorage;
60 class ContentParent;
61 } // namespace dom
62
63 class LogCollector;
64
65 namespace net {
66 extern mozilla::LazyLogModule gHttpLog;
67
68 class OpaqueResponseBlockingInfo;
69 class PreferredAlternativeDataTypeParams;
70
71 enum CacheDisposition : uint8_t {
72 kCacheUnresolved = 0,
73 kCacheHit = 1,
74 kCacheHitViaReval = 2,
75 kCacheMissedViaReval = 3,
76 kCacheMissed = 4,
77 kCacheUnknown = 5
78 };
79
80 /*
81 * This class is a partial implementation of nsIHttpChannel. It contains code
82 * shared by nsHttpChannel and HttpChannelChild.
83 * - Note that this class has nothing to do with nsBaseChannel, which is an
84 * earlier effort at a base class for channels that somehow never made it all
85 * the way to the HTTP channel.
86 */
87 class HttpBaseChannel : public nsHashPropertyBag,
88 public nsIEncodedChannel,
89 public nsIHttpChannel,
90 public nsIHttpChannelInternal,
91 public nsIFormPOSTActionChannel,
92 public nsIUploadChannel2,
93 public nsISupportsPriority,
94 public nsIClassOfService,
95 public nsIResumableChannel,
96 public nsITraceableChannel,
97 public PrivateBrowsingChannel<HttpBaseChannel>,
98 public nsITimedChannel,
99 public nsIForcePendingChannel,
100 public nsIConsoleReportCollector,
101 public nsIThrottledInputChannel,
102 public nsIClassifiedChannel {
103 protected:
104 virtual ~HttpBaseChannel();
105
106 public:
107 NS_DECL_ISUPPORTS_INHERITED
108 NS_DECL_NSIUPLOADCHANNEL
109 NS_DECL_NSIFORMPOSTACTIONCHANNEL
110 NS_DECL_NSIUPLOADCHANNEL2
111 NS_DECL_NSITRACEABLECHANNEL
112 NS_DECL_NSITIMEDCHANNEL
113 NS_DECL_NSITHROTTLEDINPUTCHANNEL
114 NS_DECL_NSICLASSIFIEDCHANNEL
115
116 NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_BASE_CHANNEL_IID)
117
118 HttpBaseChannel();
119
120 [[nodiscard]] virtual nsresult Init(nsIURI* aURI, uint32_t aCaps,
121 nsProxyInfo* aProxyInfo,
122 uint32_t aProxyResolveFlags,
123 nsIURI* aProxyURI, uint64_t aChannelId,
124 ExtContentPolicyType aContentPolicyType);
125
126 // nsIRequest
127 NS_IMETHOD GetName(nsACString& aName) override;
128 NS_IMETHOD IsPending(bool* aIsPending) override;
129 NS_IMETHOD GetStatus(nsresult* aStatus) override;
130 NS_IMETHOD GetLoadGroup(nsILoadGroup** aLoadGroup) override;
131 NS_IMETHOD SetLoadGroup(nsILoadGroup* aLoadGroup) override;
132 NS_IMETHOD GetLoadFlags(nsLoadFlags* aLoadFlags) override;
133 NS_IMETHOD SetLoadFlags(nsLoadFlags aLoadFlags) override;
134 NS_IMETHOD GetTRRMode(nsIRequest::TRRMode* aTRRMode) override;
135 NS_IMETHOD SetTRRMode(nsIRequest::TRRMode aTRRMode) override;
136 NS_IMETHOD SetDocshellUserAgentOverride();
137
138 // nsIChannel
139 NS_IMETHOD GetOriginalURI(nsIURI** aOriginalURI) override;
140 NS_IMETHOD SetOriginalURI(nsIURI* aOriginalURI) override;
141 NS_IMETHOD GetURI(nsIURI** aURI) override;
142 NS_IMETHOD GetOwner(nsISupports** aOwner) override;
143 NS_IMETHOD SetOwner(nsISupports* aOwner) override;
144 NS_IMETHOD GetLoadInfo(nsILoadInfo** aLoadInfo) override;
145 NS_IMETHOD SetLoadInfo(nsILoadInfo* aLoadInfo) override;
146 NS_IMETHOD GetIsDocument(bool* aIsDocument) override;
147 NS_IMETHOD GetNotificationCallbacks(
148 nsIInterfaceRequestor** aCallbacks) override;
149 NS_IMETHOD SetNotificationCallbacks(
150 nsIInterfaceRequestor* aCallbacks) override;
151 NS_IMETHOD GetContentType(nsACString& aContentType) override;
152 NS_IMETHOD SetContentType(const nsACString& aContentType) override;
153 NS_IMETHOD GetContentCharset(nsACString& aContentCharset) override;
154 NS_IMETHOD SetContentCharset(const nsACString& aContentCharset) override;
155 NS_IMETHOD GetContentDisposition(uint32_t* aContentDisposition) override;
156 NS_IMETHOD SetContentDisposition(uint32_t aContentDisposition) override;
157 NS_IMETHOD GetContentDispositionFilename(
158 nsAString& aContentDispositionFilename) override;
159 NS_IMETHOD SetContentDispositionFilename(
160 const nsAString& aContentDispositionFilename) override;
161 NS_IMETHOD GetContentDispositionHeader(
162 nsACString& aContentDispositionHeader) override;
163 NS_IMETHOD GetContentLength(int64_t* aContentLength) override;
164 NS_IMETHOD SetContentLength(int64_t aContentLength) override;
165 NS_IMETHOD Open(nsIInputStream** aResult) override;
166 NS_IMETHOD GetBlockAuthPrompt(bool* aValue) override;
167 NS_IMETHOD SetBlockAuthPrompt(bool aValue) override;
168 NS_IMETHOD GetCanceled(bool* aCanceled) override;
169
170 // nsIEncodedChannel
171 NS_IMETHOD GetApplyConversion(bool* value) override;
172 NS_IMETHOD SetApplyConversion(bool value) override;
173 NS_IMETHOD GetContentEncodings(nsIUTF8StringEnumerator** aEncodings) override;
174 NS_IMETHOD DoApplyContentConversions(nsIStreamListener* aNextListener,
175 nsIStreamListener** aNewNextListener,
176 nsISupports* aCtxt) override;
177
178 // HttpBaseChannel::nsIHttpChannel
179 NS_IMETHOD GetRequestMethod(nsACString& aMethod) override;
180 NS_IMETHOD SetRequestMethod(const nsACString& aMethod) override;
181 NS_IMETHOD GetReferrerInfo(nsIReferrerInfo** aReferrerInfo) override;
182 NS_IMETHOD SetReferrerInfo(nsIReferrerInfo* aReferrerInfo) override;
183 NS_IMETHOD SetReferrerInfoWithoutClone(
184 nsIReferrerInfo* aReferrerInfo) override;
185 NS_IMETHOD GetRequestHeader(const nsACString& aHeader,
186 nsACString& aValue) override;
187 NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
188 const nsACString& aValue, bool aMerge) override;
189 NS_IMETHOD SetNewReferrerInfo(const nsACString& aUrl,
190 nsIReferrerInfo::ReferrerPolicyIDL aPolicy,
191 bool aSendReferrer) override;
192 NS_IMETHOD SetEmptyRequestHeader(const nsACString& aHeader) override;
193 NS_IMETHOD VisitRequestHeaders(nsIHttpHeaderVisitor* visitor) override;
194 NS_IMETHOD VisitNonDefaultRequestHeaders(
195 nsIHttpHeaderVisitor* visitor) override;
196 NS_IMETHOD ShouldStripRequestBodyHeader(const nsACString& aMethod,
197 bool* aResult) override;
198 NS_IMETHOD GetResponseHeader(const nsACString& header,
199 nsACString& value) override;
200 NS_IMETHOD SetResponseHeader(const nsACString& header,
201 const nsACString& value, bool merge) override;
202 NS_IMETHOD VisitResponseHeaders(nsIHttpHeaderVisitor* visitor) override;
203 NS_IMETHOD GetOriginalResponseHeader(const nsACString& aHeader,
204 nsIHttpHeaderVisitor* aVisitor) override;
205 NS_IMETHOD VisitOriginalResponseHeaders(
206 nsIHttpHeaderVisitor* aVisitor) override;
207 NS_IMETHOD GetAllowPipelining(bool* value) override; // deprecated
208 NS_IMETHOD SetAllowPipelining(bool value) override; // deprecated
209 NS_IMETHOD GetAllowSTS(bool* value) override;
210 NS_IMETHOD SetAllowSTS(bool value) override;
211 NS_IMETHOD GetRedirectionLimit(uint32_t* value) override;
212 NS_IMETHOD SetRedirectionLimit(uint32_t value) override;
213 NS_IMETHOD IsNoStoreResponse(bool* value) override;
214 NS_IMETHOD IsNoCacheResponse(bool* value) override;
215 NS_IMETHOD IsPrivateResponse(bool* value) override;
216 NS_IMETHOD GetResponseStatus(uint32_t* aValue) override;
217 NS_IMETHOD GetResponseStatusText(nsACString& aValue) override;
218 NS_IMETHOD GetRequestSucceeded(bool* aValue) override;
219 NS_IMETHOD RedirectTo(nsIURI* newURI) override;
220 NS_IMETHOD UpgradeToSecure() override;
221 NS_IMETHOD GetRequestContextID(uint64_t* aRCID) override;
222 NS_IMETHOD GetTransferSize(uint64_t* aTransferSize) override;
223 NS_IMETHOD GetRequestSize(uint64_t* aRequestSize) override;
224 NS_IMETHOD GetDecodedBodySize(uint64_t* aDecodedBodySize) override;
225 NS_IMETHOD GetEncodedBodySize(uint64_t* aEncodedBodySize) override;
226 NS_IMETHOD GetSupportsHTTP3(bool* aSupportsHTTP3) override;
227 NS_IMETHOD GetHasHTTPSRR(bool* aHasHTTPSRR) override;
228 NS_IMETHOD SetRequestContextID(uint64_t aRCID) override;
229 NS_IMETHOD GetIsMainDocumentChannel(bool* aValue) override;
230 NS_IMETHOD SetIsMainDocumentChannel(bool aValue) override;
231 NS_IMETHOD GetProtocolVersion(nsACString& aProtocolVersion) override;
232 NS_IMETHOD GetChannelId(uint64_t* aChannelId) override;
233 NS_IMETHOD SetChannelId(uint64_t aChannelId) override;
234 NS_IMETHOD GetTopLevelContentWindowId(uint64_t* aContentWindowId) override;
235 NS_IMETHOD SetTopLevelContentWindowId(uint64_t aContentWindowId) override;
236 NS_IMETHOD GetTopBrowsingContextId(uint64_t* aId) override;
237 NS_IMETHOD SetTopBrowsingContextId(uint64_t aId) override;
238
239 NS_IMETHOD GetFlashPluginState(
240 nsIHttpChannel::FlashPluginState* aState) override;
241
242 using nsIClassifiedChannel::IsThirdPartyTrackingResource;
243
SetSource(UniquePtr<ProfileChunkedBuffer> aSource)244 virtual void SetSource(UniquePtr<ProfileChunkedBuffer> aSource) override {
245 mSource = std::move(aSource);
246 }
247
248 // nsIHttpChannelInternal
249 NS_IMETHOD GetDocumentURI(nsIURI** aDocumentURI) override;
250 NS_IMETHOD SetDocumentURI(nsIURI* aDocumentURI) override;
251 NS_IMETHOD GetRequestVersion(uint32_t* major, uint32_t* minor) override;
252 NS_IMETHOD GetResponseVersion(uint32_t* major, uint32_t* minor) override;
253 NS_IMETHOD SetCookie(const nsACString& aCookieHeader) override;
254 NS_IMETHOD GetThirdPartyFlags(uint32_t* aForce) override;
255 NS_IMETHOD SetThirdPartyFlags(uint32_t aForce) override;
256 NS_IMETHOD GetForceAllowThirdPartyCookie(bool* aForce) override;
257 NS_IMETHOD SetForceAllowThirdPartyCookie(bool aForce) override;
258 NS_IMETHOD GetChannelIsForDownload(bool* aChannelIsForDownload) override;
259 NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
260 NS_IMETHOD SetCacheKeysRedirectChain(nsTArray<nsCString>* cacheKeys) override;
261 NS_IMETHOD GetLocalAddress(nsACString& addr) override;
262 NS_IMETHOD GetLocalPort(int32_t* port) override;
263 NS_IMETHOD GetRemoteAddress(nsACString& addr) override;
264 NS_IMETHOD GetRemotePort(int32_t* port) override;
265 NS_IMETHOD GetOnlyConnect(bool* aOnlyConnect) override;
266 NS_IMETHOD SetConnectOnly() override;
267 NS_IMETHOD GetAllowSpdy(bool* aAllowSpdy) override;
268 NS_IMETHOD SetAllowSpdy(bool aAllowSpdy) override;
269 NS_IMETHOD GetAllowHttp3(bool* aAllowHttp3) override;
270 NS_IMETHOD SetAllowHttp3(bool aAllowHttp3) override;
271 NS_IMETHOD GetAllowAltSvc(bool* aAllowAltSvc) override;
272 NS_IMETHOD SetAllowAltSvc(bool aAllowAltSvc) override;
273 NS_IMETHOD GetBeConservative(bool* aBeConservative) override;
274 NS_IMETHOD SetBeConservative(bool aBeConservative) override;
275 NS_IMETHOD GetIsTRRServiceChannel(bool* aTRR) override;
276 NS_IMETHOD SetIsTRRServiceChannel(bool aTRR) override;
277 NS_IMETHOD GetIsResolvedByTRR(bool* aResolvedByTRR) override;
278 NS_IMETHOD GetIsOCSP(bool* value) override;
279 NS_IMETHOD SetIsOCSP(bool value) override;
280 NS_IMETHOD GetTlsFlags(uint32_t* aTlsFlags) override;
281 NS_IMETHOD SetTlsFlags(uint32_t aTlsFlags) override;
282 NS_IMETHOD GetApiRedirectToURI(nsIURI** aApiRedirectToURI) override;
283 [[nodiscard]] virtual nsresult AddSecurityMessage(
284 const nsAString& aMessageTag, const nsAString& aMessageCategory);
285 NS_IMETHOD TakeAllSecurityMessages(
286 nsCOMArray<nsISecurityConsoleMessage>& aMessages) override;
287 NS_IMETHOD GetResponseTimeoutEnabled(bool* aEnable) override;
288 NS_IMETHOD SetResponseTimeoutEnabled(bool aEnable) override;
289 NS_IMETHOD GetInitialRwin(uint32_t* aRwin) override;
290 NS_IMETHOD SetInitialRwin(uint32_t aRwin) override;
291 NS_IMETHOD ForcePending(bool aForcePending) override;
292 NS_IMETHOD GetLastModifiedTime(PRTime* lastModifiedTime) override;
293 NS_IMETHOD GetCorsIncludeCredentials(bool* aInclude) override;
294 NS_IMETHOD SetCorsIncludeCredentials(bool aInclude) override;
295 NS_IMETHOD GetCorsMode(uint32_t* aCorsMode) override;
296 NS_IMETHOD SetCorsMode(uint32_t aCorsMode) override;
297 NS_IMETHOD GetRedirectMode(uint32_t* aRedirectMode) override;
298 NS_IMETHOD SetRedirectMode(uint32_t aRedirectMode) override;
299 NS_IMETHOD GetFetchCacheMode(uint32_t* aFetchCacheMode) override;
300 NS_IMETHOD SetFetchCacheMode(uint32_t aFetchCacheMode) override;
301 NS_IMETHOD GetTopWindowURI(nsIURI** aTopWindowURI) override;
302 NS_IMETHOD SetTopWindowURIIfUnknown(nsIURI* aTopWindowURI) override;
303 NS_IMETHOD GetProxyURI(nsIURI** proxyURI) override;
304 virtual void SetCorsPreflightParameters(
305 const nsTArray<nsCString>& unsafeHeaders,
306 bool aShouldStripRequestBodyHeader) override;
307 virtual void SetAltDataForChild(bool aIsForChild) override;
DisableAltDataCache()308 virtual void DisableAltDataCache() override {
309 StoreDisableAltDataCache(true);
310 };
311
312 NS_IMETHOD GetConnectionInfoHashKey(
313 nsACString& aConnectionInfoHashKey) override;
314 NS_IMETHOD GetIntegrityMetadata(nsAString& aIntegrityMetadata) override;
315 NS_IMETHOD SetIntegrityMetadata(const nsAString& aIntegrityMetadata) override;
316 NS_IMETHOD GetLastRedirectFlags(uint32_t* aValue) override;
317 NS_IMETHOD SetLastRedirectFlags(uint32_t aValue) override;
318 NS_IMETHOD GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) override;
319 NS_IMETHOD SetNavigationStartTimeStamp(TimeStamp aTimeStamp) override;
320 NS_IMETHOD CancelByURLClassifier(nsresult aErrorCode) override;
321 virtual void SetIPv4Disabled(void) override;
322 virtual void SetIPv6Disabled(void) override;
323 NS_IMETHOD GetCrossOriginOpenerPolicy(
324 nsILoadInfo::CrossOriginOpenerPolicy* aCrossOriginOpenerPolicy) override;
325 NS_IMETHOD ComputeCrossOriginOpenerPolicy(
326 nsILoadInfo::CrossOriginOpenerPolicy aInitiatorPolicy,
327 nsILoadInfo::CrossOriginOpenerPolicy* aOutPolicy) override;
328 NS_IMETHOD HasCrossOriginOpenerPolicyMismatch(bool* aIsMismatch) override;
329 NS_IMETHOD GetResponseEmbedderPolicy(
330 nsILoadInfo::CrossOriginEmbedderPolicy* aOutPolicy) override;
331
CleanRedirectCacheChainIfNecessary()332 inline void CleanRedirectCacheChainIfNecessary() {
333 mRedirectedCachekeys = nullptr;
334 }
335 NS_IMETHOD HTTPUpgrade(const nsACString& aProtocolName,
336 nsIHttpUpgradeListener* aListener) override;
337 void DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() override;
338
339 NS_IMETHOD SetWaitForHTTPSSVCRecord() override;
340
341 // nsISupportsPriority
342 NS_IMETHOD GetPriority(int32_t* value) override;
343 NS_IMETHOD AdjustPriority(int32_t delta) override;
344
345 // nsIClassOfService
GetClassFlags(uint32_t * outFlags)346 NS_IMETHOD GetClassFlags(uint32_t* outFlags) override {
347 *outFlags = mClassOfService;
348 return NS_OK;
349 }
350
351 // nsIResumableChannel
352 NS_IMETHOD GetEntityID(nsACString& aEntityID) override;
353
354 // nsIConsoleReportCollector
355 void AddConsoleReport(uint32_t aErrorFlags, const nsACString& aCategory,
356 nsContentUtils::PropertiesFile aPropertiesFile,
357 const nsACString& aSourceFileURI, uint32_t aLineNumber,
358 uint32_t aColumnNumber, const nsACString& aMessageName,
359 const nsTArray<nsString>& aStringParams) override;
360
361 void FlushReportsToConsole(
362 uint64_t aInnerWindowID,
363 ReportAction aAction = ReportAction::Forget) override;
364
365 void FlushReportsToConsoleForServiceWorkerScope(
366 const nsACString& aScope,
367 ReportAction aAction = ReportAction::Forget) override;
368
369 void FlushConsoleReports(
370 dom::Document* aDocument,
371 ReportAction aAction = ReportAction::Forget) override;
372
373 void FlushConsoleReports(
374 nsILoadGroup* aLoadGroup,
375 ReportAction aAction = ReportAction::Forget) override;
376
377 void FlushConsoleReports(nsIConsoleReportCollector* aCollector) override;
378
379 void StealConsoleReports(
380 nsTArray<net::ConsoleReportCollected>& aReports) override;
381
382 void ClearConsoleReports() override;
383
384 class nsContentEncodings : public nsStringEnumeratorBase {
385 public:
386 NS_DECL_ISUPPORTS
387 NS_DECL_NSIUTF8STRINGENUMERATOR
388
389 using nsStringEnumeratorBase::GetNext;
390
391 nsContentEncodings(nsIHttpChannel* aChannel, const char* aEncodingHeader);
392
393 private:
394 virtual ~nsContentEncodings() = default;
395
396 [[nodiscard]] nsresult PrepareForNext(void);
397
398 // We do not own the buffer. The channel owns it.
399 const char* mEncodingHeader;
400 const char* mCurStart; // points to start of current header
401 const char* mCurEnd; // points to end of current header
402
403 // Hold a ref to our channel so that it can't go away and take the
404 // header with it.
405 nsCOMPtr<nsIHttpChannel> mChannel;
406
407 bool mReady;
408 };
409
GetResponseHead()410 nsHttpResponseHead* GetResponseHead() const { return mResponseHead.get(); }
GetRequestHead()411 nsHttpRequestHead* GetRequestHead() { return &mRequestHead; }
GetResponseTrailers()412 nsHttpHeaderArray* GetResponseTrailers() const {
413 return mResponseTrailers.get();
414 }
415
GetSelfAddr()416 const NetAddr& GetSelfAddr() { return mSelfAddr; }
GetPeerAddr()417 const NetAddr& GetPeerAddr() { return mPeerAddr; }
418
419 [[nodiscard]] nsresult OverrideSecurityInfo(nsISupports* aSecurityInfo);
420
421 public: /* Necko internal use only... */
GetAltDataLength()422 int64_t GetAltDataLength() { return mAltDataLength; }
423 bool IsNavigation();
424
IsDeliveringAltData()425 bool IsDeliveringAltData() const { return LoadDeliveringAltData(); }
426
427 static void PropagateReferenceIfNeeded(nsIURI* aURI,
428 nsCOMPtr<nsIURI>& aRedirectURI);
429
430 // Return whether upon a redirect code of httpStatus for method, the
431 // request method should be rewritten to GET.
432 static bool ShouldRewriteRedirectToGET(
433 uint32_t httpStatus, nsHttpRequestHead::ParsedMethodType method);
434
435 // Like nsIEncodedChannel::DoApplyConversions except context is set to
436 // mListenerContext.
437 [[nodiscard]] nsresult DoApplyContentConversions(
438 nsIStreamListener* aNextListener, nsIStreamListener** aNewNextListener);
439
440 // Callback on STS thread called by CopyComplete when NS_AsyncCopy()
441 // is finished. This function works as a proxy function to dispatch
442 // |EnsureUploadStreamIsCloneableComplete| to main thread.
443 virtual void OnCopyComplete(nsresult aStatus);
444
445 void AddClassificationFlags(uint32_t aClassificationFlags,
446 bool aIsThirdParty);
447
448 void SetFlashPluginState(nsIHttpChannel::FlashPluginState aState);
449
ChannelId()450 const uint64_t& ChannelId() const { return mChannelId; }
451
InternalSetUploadStream(nsIInputStream * uploadStream)452 void InternalSetUploadStream(nsIInputStream* uploadStream) {
453 mUploadStream = uploadStream;
454 }
455
InternalSetUploadStreamLength(uint64_t aLength)456 void InternalSetUploadStreamLength(uint64_t aLength) {
457 mReqContentLength = aLength;
458 }
459
SetUploadStreamHasHeaders(bool hasHeaders)460 void SetUploadStreamHasHeaders(bool hasHeaders) {
461 StoreUploadStreamHasHeaders(hasHeaders);
462 }
463
464 virtual nsresult SetReferrerHeader(const nsACString& aReferrer,
465 bool aRespectBeforeConnect = true) {
466 if (aRespectBeforeConnect) {
467 ENSURE_CALLED_BEFORE_CONNECT();
468 }
469 return mRequestHead.SetHeader(nsHttp::Referer, aReferrer);
470 }
471
ClearReferrerHeader()472 nsresult ClearReferrerHeader() {
473 ENSURE_CALLED_BEFORE_CONNECT();
474 return mRequestHead.ClearHeader(nsHttp::Referer);
475 }
476
SetTopWindowURI(nsIURI * aTopWindowURI)477 void SetTopWindowURI(nsIURI* aTopWindowURI) { mTopWindowURI = aTopWindowURI; }
478
479 // Set referrerInfo and compute the referrer header if neccessary.
480 // Pass true for aSetOriginal if this is a new referrer and should
481 // overwrite the 'original' value, false if this is a mutation (like
482 // stripping the path).
483 nsresult SetReferrerInfoInternal(nsIReferrerInfo* aReferrerInfo, bool aClone,
484 bool aCompute, bool aRespectBeforeConnect);
485
486 struct ReplacementChannelConfig {
487 ReplacementChannelConfig() = default;
488 explicit ReplacementChannelConfig(
489 const dom::ReplacementChannelConfigInit& aInit);
490
491 uint32_t redirectFlags = 0;
492 uint32_t classOfService = 0;
493 Maybe<bool> privateBrowsing = Nothing();
494 Maybe<nsCString> method;
495 nsCOMPtr<nsIReferrerInfo> referrerInfo;
496 Maybe<dom::TimedChannelInfo> timedChannel;
497 nsCOMPtr<nsIInputStream> uploadStream;
498 uint64_t uploadStreamLength = 0;
499 bool uploadStreamHasHeaders = false;
500 Maybe<nsCString> contentType;
501 Maybe<nsCString> contentLength;
502
503 dom::ReplacementChannelConfigInit Serialize(dom::ContentParent* aParent);
504 };
505
506 enum class ReplacementReason {
507 Redirect,
508 InternalRedirect,
509 DocumentChannel,
510 };
511
512 // Create a ReplacementChannelConfig object that can be used to duplicate the
513 // current channel.
514 ReplacementChannelConfig CloneReplacementChannelConfig(
515 bool aPreserveMethod, uint32_t aRedirectFlags, ReplacementReason aReason);
516
517 static void ConfigureReplacementChannel(nsIChannel*,
518 const ReplacementChannelConfig&,
519 ReplacementReason);
520
521 // Called before we create the redirect target channel.
522 already_AddRefed<nsILoadInfo> CloneLoadInfoForRedirect(
523 nsIURI* aNewURI, uint32_t aRedirectFlags);
524
525 // True if we've already applied content conversion to the data
526 // passed to mListener.
HasAppliedConversion()527 bool HasAppliedConversion() { return LoadHasAppliedConversion(); }
528
529 protected:
530 nsresult GetTopWindowURI(nsIURI* aURIBeingLoaded, nsIURI** aTopWindowURI);
531
532 // Handle notifying listener, removing from loadgroup if request failed.
533 void DoNotifyListener();
534 virtual void DoNotifyListenerCleanup() = 0;
535
536 // drop reference to listener, its callbacks, and the progress sink
537 virtual void ReleaseListeners();
538
539 // Call AsyncAbort().
540 virtual void DoAsyncAbort(nsresult aStatus) = 0;
541
542 // This is fired only when a cookie is created due to the presence of
543 // Set-Cookie header in the response header of any network request.
544 // This notification will come only after the "http-on-examine-response"
545 // was fired.
546 void NotifySetCookie(const nsACString& aCookie);
547
548 mozilla::dom::PerformanceStorage* GetPerformanceStorage();
549 void MaybeReportTimingData();
550 nsIURI* GetReferringPage();
551 nsPIDOMWindowInner* GetInnerDOMWindow();
552
553 void AddCookiesToRequest();
554 [[nodiscard]] virtual nsresult SetupReplacementChannel(
555 nsIURI*, nsIChannel*, bool preserveMethod, uint32_t redirectFlags);
556
557 // bundle calling OMR observers and marking flag into one function
CallOnModifyRequestObservers()558 inline void CallOnModifyRequestObservers() {
559 gHttpHandler->OnModifyRequest(this);
560 MOZ_ASSERT(!LoadRequestObserversCalled());
561 StoreRequestObserversCalled(true);
562 }
563
564 // Helper function to simplify getting notification callbacks.
565 template <class T>
GetCallback(nsCOMPtr<T> & aResult)566 void GetCallback(nsCOMPtr<T>& aResult) {
567 NS_QueryNotificationCallbacks(mCallbacks, mLoadGroup,
568 NS_GET_TEMPLATE_IID(T),
569 getter_AddRefs(aResult));
570 }
571
572 // Redirect tracking
573 // Checks whether or not aURI and mOriginalURI share the same domain.
574 virtual bool SameOriginWithOriginalUri(nsIURI* aURI);
575
576 // GetPrincipal Returns the channel's URI principal.
577 nsIPrincipal* GetURIPrincipal();
578
579 [[nodiscard]] bool BypassServiceWorker() const;
580
581 // Returns true if this channel should intercept the network request and
582 // prepare for a possible synthesized response instead.
583 bool ShouldIntercept(nsIURI* aURI = nullptr);
584
585 // Callback on main thread when NS_AsyncCopy() is finished populating
586 // the new mUploadStream.
587 void EnsureUploadStreamIsCloneableComplete(nsresult aStatus);
588
589 #ifdef DEBUG
590 // Check if mPrivateBrowsingId matches between LoadInfo and LoadContext.
591 void AssertPrivateBrowsingId();
592 #endif
593
594 static void CallTypeSniffers(void* aClosure, const uint8_t* aData,
595 uint32_t aCount);
596
597 nsresult CheckRedirectLimit(uint32_t aRedirectFlags) const;
598
599 bool MaybeWaitForUploadStreamLength(nsIStreamListener* aListener,
600 nsISupports* aContext);
601
602 void MaybeFlushConsoleReports();
603
604 bool IsBrowsingContextDiscarded() const;
605
606 nsresult ProcessCrossOriginEmbedderPolicyHeader();
607
608 nsresult ProcessCrossOriginResourcePolicyHeader();
609
610 nsresult ComputeCrossOriginOpenerPolicyMismatch();
611
612 nsresult ValidateMIMEType();
613
614 bool EnsureOpaqueResponseIsAllowed();
615
616 Result<bool, nsresult> EnsureOpaqueResponseIsAllowedAfterSniff();
617
618 friend class PrivateBrowsingChannel<HttpBaseChannel>;
619 friend class InterceptFailedOnStop;
620
621 protected:
622 // this section is for main-thread-only object
623 // all the references need to be proxy released on main thread.
624 nsCOMPtr<nsIURI> mURI;
625 nsCOMPtr<nsIURI> mOriginalURI;
626 nsCOMPtr<nsIURI> mDocumentURI;
627 nsCOMPtr<nsILoadGroup> mLoadGroup;
628 nsCOMPtr<nsILoadInfo> mLoadInfo;
629 nsCOMPtr<nsIInterfaceRequestor> mCallbacks;
630 nsCOMPtr<nsIProgressEventSink> mProgressSink;
631 nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
632 nsCOMPtr<nsIURI> mAPIRedirectToURI;
633 nsCOMPtr<nsIURI> mProxyURI;
634 nsCOMPtr<nsIPrincipal> mPrincipal;
635 nsCOMPtr<nsIURI> mTopWindowURI;
636 nsCOMPtr<nsIStreamListener> mListener;
637 // An instance of nsHTTPCompressConv
638 nsCOMPtr<nsIStreamListener> mCompressListener;
639 nsCOMPtr<nsIEventTarget> mCurrentThread;
640
641 private:
642 // WHATWG Fetch Standard 4.4. HTTP-redirect fetch, step 10
643 bool ShouldTaintReplacementChannelOrigin(nsIURI* aNewURI);
644
645 // Proxy release all members above on main thread.
646 void ReleaseMainThreadOnlyReferences();
647
648 void ExplicitSetUploadStreamLength(uint64_t aContentLength,
649 bool aStreamHasHeaders);
650
651 void MaybeResumeAsyncOpen();
652
653 protected:
654 nsCString mSpec; // ASCII encoded URL spec
655 nsCString mContentTypeHint;
656 nsCString mContentCharsetHint;
657 nsCString mUserSetCookieHeader;
658 // HTTP Upgrade Data
659 nsCString mUpgradeProtocol;
660 // Resumable channel specific data
661 nsCString mEntityID;
662 // The initiator type (for this resource) - how was the resource referenced in
663 // the HTML file.
664 nsString mInitiatorType;
665 // Holds the name of the preferred alt-data type for each contentType.
666 nsTArray<PreferredAlternativeDataTypeParams> mPreferredCachedAltDataTypes;
667 // Holds the name of the alternative data type the channel returned.
668 nsCString mAvailableCachedAltDataType;
669 nsString mIntegrityMetadata;
670
671 // Classified channel's matched information
672 nsCString mMatchedList;
673 nsCString mMatchedProvider;
674 nsCString mMatchedFullHash;
675
676 nsTArray<nsCString> mMatchedTrackingLists;
677 nsTArray<nsCString> mMatchedTrackingFullHashes;
678
679 nsCOMPtr<nsISupports> mOwner;
680
681 nsHttpRequestHead mRequestHead;
682 // Upload throttling.
683 nsCOMPtr<nsIInputChannelThrottleQueue> mThrottleQueue;
684 nsCOMPtr<nsIInputStream> mUploadStream;
685 nsCOMPtr<nsIRunnable> mUploadCloneableCallback;
686 UniquePtr<nsHttpResponseHead> mResponseHead;
687 UniquePtr<nsHttpHeaderArray> mResponseTrailers;
688 RefPtr<nsHttpConnectionInfo> mConnectionInfo;
689 nsCOMPtr<nsIProxyInfo> mProxyInfo;
690 nsCOMPtr<nsISupports> mSecurityInfo;
691 nsCOMPtr<nsIHttpUpgradeListener> mUpgradeProtocolCallback;
692 UniquePtr<nsString> mContentDispositionFilename;
693 nsCOMPtr<nsIConsoleReportCollector> mReportCollector;
694
695 RefPtr<nsHttpHandler> mHttpHandler; // keep gHttpHandler alive
696 UniquePtr<nsTArray<nsCString>> mRedirectedCachekeys;
697 nsCOMPtr<nsIRequestContext> mRequestContext;
698
699 RefPtr<OpaqueResponseBlockingInfo> mOpaqueResponseBlockingInfo;
700
701 NetAddr mSelfAddr;
702 NetAddr mPeerAddr;
703
704 nsTArray<std::pair<nsString, nsString>> mSecurityConsoleMessages;
705 nsTArray<nsCString> mUnsafeHeaders;
706
707 // A time value equal to the starting time of the fetch that initiates the
708 // redirect.
709 mozilla::TimeStamp mRedirectStartTimeStamp;
710 // A time value equal to the time immediately after receiving the last byte of
711 // the response of the last redirect.
712 mozilla::TimeStamp mRedirectEndTimeStamp;
713
714 PRTime mChannelCreationTime;
715 TimeStamp mChannelCreationTimestamp;
716 TimeStamp mAsyncOpenTime;
717 TimeStamp mCacheReadStart;
718 TimeStamp mCacheReadEnd;
719 TimeStamp mLaunchServiceWorkerStart;
720 TimeStamp mLaunchServiceWorkerEnd;
721 TimeStamp mDispatchFetchEventStart;
722 TimeStamp mDispatchFetchEventEnd;
723 TimeStamp mHandleFetchEventStart;
724 TimeStamp mHandleFetchEventEnd;
725 // copied from the transaction before we null out mTransaction
726 // so that the timing can still be queried from OnStopRequest
727 TimingStruct mTransactionTimings;
728
729 // Gets computed during ComputeCrossOriginOpenerPolicyMismatch so we have
730 // the channel's policy even if we don't know policy initiator.
731 nsILoadInfo::CrossOriginOpenerPolicy mComputedCrossOriginOpenerPolicy;
732
733 uint64_t mStartPos;
734 uint64_t mTransferSize;
735 uint64_t mRequestSize;
736 uint64_t mDecodedBodySize;
737 // True only when the channel supports any of the versions of HTTP3
738 bool mSupportsHTTP3;
739 uint64_t mEncodedBodySize;
740 uint64_t mRequestContextID;
741 // ID of the top-level document's inner window this channel is being
742 // originated from.
743 uint64_t mContentWindowId;
744 uint64_t mTopBrowsingContextId;
745 int64_t mAltDataLength;
746 uint64_t mChannelId;
747 uint64_t mReqContentLength;
748
749 Atomic<nsresult, ReleaseAcquire> mStatus;
750
751 // Use Release-Acquire ordering to ensure the OMT ODA is ignored while channel
752 // is canceled on main thread.
753 Atomic<bool, ReleaseAcquire> mCanceled;
754 Atomic<uint32_t, ReleaseAcquire> mFirstPartyClassificationFlags;
755 Atomic<uint32_t, ReleaseAcquire> mThirdPartyClassificationFlags;
756 Atomic<uint32_t, ReleaseAcquire> mFlashPluginState;
757
758 UniquePtr<ProfileChunkedBuffer> mSource;
759
760 uint32_t mLoadFlags;
761 uint32_t mCaps;
762 uint32_t mClassOfService;
763
764 // clang-format off
765 MOZ_ATOMIC_BITFIELDS(mAtomicBitfields1, 32, (
766 (uint32_t, UpgradeToSecure, 1),
767 (uint32_t, ApplyConversion, 1),
768 // Set to true if DoApplyContentConversions has been applied to
769 // our default mListener.
770 (uint32_t, HasAppliedConversion, 1),
771 (uint32_t, IsPending, 1),
772 (uint32_t, WasOpened, 1),
773 // if 1 all "http-on-{opening|modify|etc}-request" observers have been
774 // called.
775 (uint32_t, RequestObserversCalled, 1),
776 (uint32_t, ResponseHeadersModified, 1),
777 (uint32_t, AllowSTS, 1),
778 (uint32_t, ThirdPartyFlags, 3),
779 (uint32_t, UploadStreamHasHeaders, 1),
780 (uint32_t, ChannelIsForDownload, 1),
781 (uint32_t, TracingEnabled, 1),
782 // True if timing collection is enabled
783 (uint32_t, TimingEnabled, 1),
784 (uint32_t, ReportTiming, 1),
785 (uint32_t, AllowSpdy, 1),
786 (uint32_t, AllowHttp3, 1),
787 (uint32_t, AllowAltSvc, 1),
788 // !!! This is also used by the URL classifier to exempt channels from
789 // classification. If this is changed or removed, make sure we also update
790 // NS_ShouldClassifyChannel accordingly !!!
791 (uint32_t, BeConservative, 1),
792 // If the current channel is used to as a TRR connection.
793 (uint32_t, IsTRRServiceChannel, 1),
794 // If the request was performed to a TRR resolved IP address.
795 // Will be false if loading the resource does not create a connection
796 // (for example when it's loaded from the cache).
797 (uint32_t, ResolvedByTRR, 1),
798 (uint32_t, ResponseTimeoutEnabled, 1),
799 // A flag that should be false only if a cross-domain redirect occurred
800 (uint32_t, AllRedirectsSameOrigin, 1),
801
802 // Is 1 if no redirects have occured or if all redirects
803 // pass the Resource Timing timing-allow-check
804 (uint32_t, AllRedirectsPassTimingAllowCheck, 1),
805
806 // True if this channel was intercepted and could receive a synthesized
807 // response.
808 (uint32_t, ResponseCouldBeSynthesized, 1),
809
810 (uint32_t, BlockAuthPrompt, 1),
811
812 // If true, we behave as if the LOAD_FROM_CACHE flag has been set.
813 // Used to enforce that flag's behavior but not expose it externally.
814 (uint32_t, AllowStaleCacheContent, 1),
815
816 // If true, we prefer the LOAD_FROM_CACHE flag over LOAD_BYPASS_CACHE or
817 // LOAD_BYPASS_LOCAL_CACHE.
818 (uint32_t, PreferCacheLoadOverBypass, 1)
819 ))
820
821 // Broken up into two bitfields to avoid alignment requirements of uint64_t.
822 // (Too many bits used for one uint32_t.)
823 MOZ_ATOMIC_BITFIELDS(mAtomicBitfields2, 32, (
824 // True iff this request has been calculated in its request context as
825 // a non tail request. We must remove it again when this channel is done.
826 (uint32_t, AddedAsNonTailRequest, 1),
827
828 // True if AsyncOpen() is called when the stream length is still unknown.
829 // AsyncOpen() will be retriggered when InputStreamLengthHelper execs the
830 // callback, passing the stream length value.
831 (uint32_t, AsyncOpenWaitingForStreamLength, 1),
832
833 // Defaults to true. This is set to false when it is no longer possible
834 // to upgrade the request to a secure channel.
835 (uint32_t, UpgradableToSecure, 1),
836
837 // Tainted origin flag of a request, specified by
838 // WHATWG Fetch Standard 2.2.5.
839 (uint32_t, TaintedOriginFlag, 1),
840
841 // If the channel is being used to check OCSP
842 (uint32_t, IsOCSP, 1)
843 ))
844 // clang-format on
845
846 // An opaque flags for non-standard behavior of the TLS system.
847 // It is unlikely this will need to be set outside of telemetry studies
848 // relating to the TLS implementation.
849 uint32_t mTlsFlags;
850
851 // Current suspension depth for this channel object
852 uint32_t mSuspendCount;
853
854 // Per channel transport window override (0 means no override)
855 uint32_t mInitialRwin;
856
857 uint32_t mProxyResolveFlags;
858
859 uint32_t mContentDispositionHint;
860
861 uint32_t mCorsMode;
862 uint32_t mRedirectMode;
863
864 // If this channel was created as the result of a redirect, then this value
865 // will reflect the redirect flags passed to the SetupReplacementChannel()
866 // method.
867 uint32_t mLastRedirectFlags;
868
869 int16_t mPriority;
870 uint8_t mRedirectionLimit;
871
872 // Performance tracking
873 // Number of redirects that has occurred.
874 int8_t mRedirectCount;
875 // Number of internal redirects that has occurred.
876 int8_t mInternalRedirectCount;
877
878 enum class SnifferCategoryType {
879 NetContent = 0,
880 OpaqueResponseBlocking,
881 All
882 };
883 SnifferCategoryType mSnifferCategoryType = SnifferCategoryType::NetContent;
884 const bool mCachedOpaqueResponseBlockingPref;
885 bool mBlockOpaqueResponseAfterSniff;
886 bool mCheckIsOpaqueResponseAllowedAfterSniff;
887
888 // clang-format off
889 MOZ_ATOMIC_BITFIELDS(mAtomicBitfields3, 8, (
890 (bool, AsyncOpenTimeOverriden, 1),
891 (bool, ForcePending, 1),
892
893 // true if the channel is deliving alt-data.
894 (bool, DeliveringAltData, 1),
895
896 (bool, CorsIncludeCredentials, 1),
897
898 // These parameters are used to ensure that we do not call OnStartRequest
899 // and OnStopRequest more than once.
900 (bool, OnStartRequestCalled, 1),
901 (bool, OnStopRequestCalled, 1),
902
903 // Defaults to false. Is set to true at the begining of OnStartRequest.
904 // Used to ensure methods can't be called before OnStartRequest.
905 (bool, AfterOnStartRequestBegun, 1),
906
907 (bool, RequireCORSPreflight, 1)
908 ))
909
910 // Broken up into two bitfields to avoid alignment requirements of uint16_t.
911 // (Too many bits used for one uint8_t.)
912 MOZ_ATOMIC_BITFIELDS(mAtomicBitfields4, 8, (
913 // This flag will be true if the consumer is requesting alt-data AND the
914 // consumer is in the child process.
915 (bool, AltDataForChild, 1),
916 // This flag will be true if the consumer cannot process alt-data. This
917 // is used in the webextension StreamFilter handler. If true, we bypass
918 // using alt-data for the request.
919 (bool, DisableAltDataCache, 1),
920
921 (bool, ForceMainDocumentChannel, 1),
922 // This is set true if the channel is waiting for the
923 // InputStreamLengthHelper::GetAsyncLength callback.
924 (bool, PendingInputStreamLengthOperation, 1),
925
926 // Set to true if our listener has indicated that it requires
927 // content conversion to be done by us.
928 (bool, ListenerRequiresContentConversion, 1),
929
930 // True if this is a navigation to a page with a different cross origin
931 // opener policy ( see ComputeCrossOriginOpenerPolicyMismatch )
932 (uint32_t, HasCrossOriginOpenerPolicyMismatch, 1),
933
934 // True if HTTPS RR is used during the connection establishment of this
935 // channel.
936 (uint32_t, HasHTTPSRR, 1)
937 ))
938 // clang-format on
939
940 bool EnsureRequestContextID();
941 bool EnsureRequestContext();
942
943 // Adds/removes this channel as a non-tailed request in its request context
944 // these helpers ensure we add it only once and remove it only when added
945 // via AddedAsNonTailRequest member tracking.
946 void AddAsNonTailRequest();
947 void RemoveAsNonTailRequest();
948
949 void EnsureTopBrowsingContextId();
950
951 void InitiateORBTelemetry();
952
953 void ReportORBTelemetry(const nsCString& aKey);
954 void ReportORBTelemetry(int64_t aContentLength);
955 };
956
NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel,HTTP_BASE_CHANNEL_IID)957 NS_DEFINE_STATIC_IID_ACCESSOR(HttpBaseChannel, HTTP_BASE_CHANNEL_IID)
958
959 // Share some code while working around C++'s absurd inability to handle casting
960 // of member functions between base/derived types.
961 // - We want to store member function pointer to call at resume time, but one
962 // such function--HandleAsyncAbort--we want to share between the
963 // nsHttpChannel/HttpChannelChild. Can't define it in base class, because
964 // then we'd have to cast member function ptr between base/derived class
965 // types. Sigh...
966 template <class T>
967 class HttpAsyncAborter {
968 public:
969 explicit HttpAsyncAborter(T* derived)
970 : mThis(derived), mCallOnResume(nullptr) {}
971
972 // Aborts channel: calls OnStart/Stop with provided status, removes channel
973 // from loadGroup.
974 [[nodiscard]] nsresult AsyncAbort(nsresult status);
975
976 // Does most the actual work.
977 void HandleAsyncAbort();
978
979 // AsyncCall calls a member function asynchronously (via an event).
980 // retval isn't refcounted and is set only when event was successfully
981 // posted, the event is returned for the purpose of cancelling when needed
982 [[nodiscard]] virtual nsresult AsyncCall(
983 void (T::*funcPtr)(), nsRunnableMethod<T>** retval = nullptr);
984
985 private:
986 T* mThis;
987
988 protected:
989 // Function to be called at resume time
990 std::function<nsresult(T*)> mCallOnResume;
991 };
992
993 template <class T>
AsyncAbort(nsresult status)994 [[nodiscard]] nsresult HttpAsyncAborter<T>::AsyncAbort(nsresult status) {
995 MOZ_LOG(gHttpLog, LogLevel::Debug,
996 ("HttpAsyncAborter::AsyncAbort [this=%p status=%" PRIx32 "]\n", mThis,
997 static_cast<uint32_t>(status)));
998
999 mThis->mStatus = status;
1000
1001 // if this fails? Callers ignore our return value anyway....
1002 return AsyncCall(&T::HandleAsyncAbort);
1003 }
1004
1005 // Each subclass needs to define its own version of this (which just calls this
1006 // base version), else we wind up casting base/derived member function ptrs
1007 template <class T>
HandleAsyncAbort()1008 inline void HttpAsyncAborter<T>::HandleAsyncAbort() {
1009 MOZ_ASSERT(!mCallOnResume, "How did that happen?");
1010
1011 if (mThis->mSuspendCount) {
1012 MOZ_LOG(
1013 gHttpLog, LogLevel::Debug,
1014 ("Waiting until resume to do async notification [this=%p]\n", mThis));
1015 mCallOnResume = [](T* self) {
1016 self->HandleAsyncAbort();
1017 return NS_OK;
1018 };
1019 return;
1020 }
1021
1022 mThis->DoNotifyListener();
1023
1024 // finally remove ourselves from the load group.
1025 if (mThis->mLoadGroup) {
1026 mThis->mLoadGroup->RemoveRequest(mThis, nullptr, mThis->mStatus);
1027 }
1028 }
1029
1030 template <class T>
AsyncCall(void (T::* funcPtr)(),nsRunnableMethod<T> ** retval)1031 nsresult HttpAsyncAborter<T>::AsyncCall(void (T::*funcPtr)(),
1032 nsRunnableMethod<T>** retval) {
1033 nsresult rv;
1034
1035 RefPtr<nsRunnableMethod<T>> event =
1036 NewRunnableMethod("net::HttpAsyncAborter::AsyncCall", mThis, funcPtr);
1037 rv = NS_DispatchToCurrentThread(event);
1038 if (NS_SUCCEEDED(rv) && retval) {
1039 *retval = event;
1040 }
1041
1042 return rv;
1043 }
1044
1045 class ProxyReleaseRunnable final : public mozilla::Runnable {
1046 public:
ProxyReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>> && aDoomed)1047 explicit ProxyReleaseRunnable(nsTArray<nsCOMPtr<nsISupports>>&& aDoomed)
1048 : Runnable("ProxyReleaseRunnable"), mDoomed(std::move(aDoomed)) {}
1049
1050 NS_IMETHOD
Run()1051 Run() override {
1052 mDoomed.Clear();
1053 return NS_OK;
1054 }
1055
1056 private:
1057 virtual ~ProxyReleaseRunnable() = default;
1058
1059 nsTArray<nsCOMPtr<nsISupports>> mDoomed;
1060 };
1061
1062 } // namespace net
1063 } // namespace mozilla
1064
1065 #endif // mozilla_net_HttpBaseChannel_h
1066