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