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_HttpChannelChild_h
9 #define mozilla_net_HttpChannelChild_h
10 
11 #include "mozilla/Mutex.h"
12 #include "mozilla/Telemetry.h"
13 #include "mozilla/UniquePtr.h"
14 #include "mozilla/net/HttpBaseChannel.h"
15 #include "mozilla/net/NeckoTargetHolder.h"
16 #include "mozilla/net/PHttpChannelChild.h"
17 #include "mozilla/net/ChannelEventQueue.h"
18 
19 #include "nsIStreamListener.h"
20 #include "nsIInterfaceRequestor.h"
21 #include "nsIInterfaceRequestorUtils.h"
22 #include "nsIProgressEventSink.h"
23 #include "nsICacheInfoChannel.h"
24 #include "nsIApplicationCache.h"
25 #include "nsIApplicationCacheChannel.h"
26 #include "nsIResumableChannel.h"
27 #include "nsIProxiedChannel.h"
28 #include "nsIAsyncVerifyRedirectCallback.h"
29 #include "nsIChildChannel.h"
30 #include "nsIHttpChannelChild.h"
31 #include "nsIDivertableChannel.h"
32 #include "nsIMultiPartChannel.h"
33 #include "nsIThreadRetargetableRequest.h"
34 #include "mozilla/net/DNS.h"
35 
36 using mozilla::Telemetry::LABELS_HTTP_CHILD_OMT_STATS;
37 
38 class nsIEventTarget;
39 class nsInputStreamPump;
40 class nsIInterceptedBodyCallback;
41 
42 #define HTTP_CHANNEL_CHILD_IID                       \
43   {                                                  \
44     0x321bd99e, 0x2242, 0x4dc6, {                    \
45       0xbb, 0xec, 0xd5, 0x06, 0x29, 0x7c, 0x39, 0x83 \
46     }                                                \
47   }
48 
49 namespace mozilla {
50 namespace net {
51 
52 class HttpBackgroundChannelChild;
53 class InterceptedChannelContent;
54 class InterceptStreamListener;
55 class SyntheticDiversionListener;
56 
57 class HttpChannelChild final : public PHttpChannelChild,
58                                public HttpBaseChannel,
59                                public HttpAsyncAborter<HttpChannelChild>,
60                                public nsICacheInfoChannel,
61                                public nsIProxiedChannel,
62                                public nsIApplicationCacheChannel,
63                                public nsIAsyncVerifyRedirectCallback,
64                                public nsIChildChannel,
65                                public nsIHttpChannelChild,
66                                public nsIDivertableChannel,
67                                public nsIMultiPartChannel,
68                                public nsIThreadRetargetableRequest,
69                                public NeckoTargetHolder {
70   virtual ~HttpChannelChild();
71 
72  public:
73   NS_DECL_ISUPPORTS_INHERITED
74   NS_DECL_NSICACHEINFOCHANNEL
75   NS_DECL_NSIPROXIEDCHANNEL
76   NS_DECL_NSIAPPLICATIONCACHECONTAINER
77   NS_DECL_NSIAPPLICATIONCACHECHANNEL
78   NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
79   NS_DECL_NSICHILDCHANNEL
80   NS_DECL_NSIHTTPCHANNELCHILD
81   NS_DECL_NSIDIVERTABLECHANNEL
82   NS_DECL_NSIMULTIPARTCHANNEL
83   NS_DECL_NSITHREADRETARGETABLEREQUEST
84   NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_CHILD_IID)
85 
86   HttpChannelChild();
87 
88   // Methods HttpBaseChannel didn't implement for us or that we override.
89   //
90   // nsIRequest
91   NS_IMETHOD Cancel(nsresult status) override;
92   NS_IMETHOD Suspend() override;
93   NS_IMETHOD Resume() override;
94   // nsIChannel
95   NS_IMETHOD GetSecurityInfo(nsISupports** aSecurityInfo) override;
96   NS_IMETHOD AsyncOpen(nsIStreamListener* aListener) override;
97 
98   // HttpBaseChannel::nsIHttpChannel
99   NS_IMETHOD SetRequestHeader(const nsACString& aHeader,
100                               const nsACString& aValue, bool aMerge) override;
101   NS_IMETHOD SetEmptyRequestHeader(const nsACString& aHeader) override;
102   NS_IMETHOD RedirectTo(nsIURI* newURI) override;
103   NS_IMETHOD UpgradeToSecure() override;
104   NS_IMETHOD GetProtocolVersion(nsACString& aProtocolVersion) override;
105   void DoDiagnosticAssertWhenOnStopNotCalledOnDestroy() override;
106   // nsIHttpChannelInternal
107   NS_IMETHOD SetupFallbackChannel(const char* aFallbackKey) override;
108   // nsISupportsPriority
109   NS_IMETHOD SetPriority(int32_t value) override;
110   // nsIClassOfService
111   NS_IMETHOD SetClassFlags(uint32_t inFlags) override;
112   NS_IMETHOD AddClassFlags(uint32_t inFlags) override;
113   NS_IMETHOD ClearClassFlags(uint32_t inFlags) override;
114   // nsIResumableChannel
115   NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override;
116 
117   nsresult SetReferrerHeader(const nsACString& aReferrer,
118                              bool aRespectBeforeConnect) override;
119 
120   [[nodiscard]] bool IsSuspended();
121 
122   void FlushedForDiversion();
123 
124   void OnCopyComplete(nsresult aStatus) override;
125 
126   // Callback while background channel is ready.
127   void OnBackgroundChildReady(HttpBackgroundChannelChild* aBgChild);
128   // Callback while background channel is destroyed.
129   void OnBackgroundChildDestroyed(HttpBackgroundChannelChild* aBgChild);
130 
131   nsresult CrossProcessRedirectFinished(nsresult aStatus);
132 
133  protected:
134   mozilla::ipc::IPCResult RecvOnStartRequest(
135       const nsHttpResponseHead& aResponseHead, const bool& aUseResponseHead,
136       const nsHttpHeaderArray& aRequestHeaders,
137       const HttpChannelOnStartRequestArgs& aArgs) override;
138   mozilla::ipc::IPCResult RecvOnTransportAndData(
139       const nsresult& aChannelStatus, const nsresult& aTransportStatus,
140       const uint64_t& aOffset, const uint32_t& aCount,
141       const nsCString& aData) override;
142 
143   mozilla::ipc::IPCResult RecvOnStopRequest(
144       const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
145       const TimeStamp& aLastActiveTabOptHit,
146       const nsHttpHeaderArray& aResponseTrailers,
147       nsTArray<ConsoleReportCollected>&& aConsoleReports) override;
148   mozilla::ipc::IPCResult RecvFailedAsyncOpen(const nsresult& status) override;
149   mozilla::ipc::IPCResult RecvRedirect1Begin(
150       const uint32_t& registrarId, const URIParams& newURI,
151       const uint32_t& newLoadFlags, const uint32_t& redirectFlags,
152       const ParentLoadInfoForwarderArgs& loadInfoForwarder,
153       const nsHttpResponseHead& responseHead,
154       const nsCString& securityInfoSerialization, const uint64_t& channelId,
155       const NetAddr& oldPeerAddr,
156       const ResourceTimingStructArgs& aTiming) override;
157   mozilla::ipc::IPCResult RecvRedirect3Complete() override;
158   mozilla::ipc::IPCResult RecvAssociateApplicationCache(
159       const nsCString& groupID, const nsCString& clientID) override;
160   mozilla::ipc::IPCResult RecvDeleteSelf() override;
161   mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override;
162 
163   mozilla::ipc::IPCResult RecvReportSecurityMessage(
164       const nsString& messageTag, const nsString& messageCategory) override;
165 
166   mozilla::ipc::IPCResult RecvIssueDeprecationWarning(
167       const uint32_t& warning, const bool& asError) override;
168 
169   mozilla::ipc::IPCResult RecvSetPriority(const int16_t& aPriority) override;
170 
171   mozilla::ipc::IPCResult RecvAttachStreamFilter(
172       Endpoint<extensions::PStreamFilterParent>&& aEndpoint) override;
173 
174   mozilla::ipc::IPCResult RecvCancelDiversion() override;
175 
176   mozilla::ipc::IPCResult RecvCancelRedirected() override;
177 
178   mozilla::ipc::IPCResult RecvOriginalCacheInputStreamAvailable(
179       const Maybe<IPCStream>& aStream) override;
180 
181   mozilla::ipc::IPCResult RecvAltDataCacheInputStreamAvailable(
182       const Maybe<IPCStream>& aStream) override;
183 
184   mozilla::ipc::IPCResult RecvOverrideReferrerInfoDuringBeginConnect(
185       nsIReferrerInfo* aReferrerInfo) override;
186 
187   mozilla::ipc::IPCResult RecvNotifyClassificationFlags(
188       const uint32_t& aClassificationFlags, const bool& aIsThirdParty) override;
189 
190   mozilla::ipc::IPCResult RecvNotifyFlashPluginStateChanged(
191       const nsIHttpChannel::FlashPluginState& aState) override;
192 
193   mozilla::ipc::IPCResult RecvSetClassifierMatchedInfo(
194       const ClassifierInfo& info) override;
195 
196   mozilla::ipc::IPCResult RecvSetClassifierMatchedTrackingInfo(
197       const ClassifierInfo& info) override;
198 
199   mozilla::ipc::IPCResult RecvOnAfterLastPart(const nsresult& aStatus) override;
200 
201   virtual void ActorDestroy(ActorDestroyReason aWhy) override;
202 
203   virtual void DoNotifyListenerCleanup() override;
204 
205   virtual void DoAsyncAbort(nsresult aStatus) override;
206 
207   nsresult AsyncCall(
208       void (HttpChannelChild::*funcPtr)(),
209       nsRunnableMethod<HttpChannelChild>** retval = nullptr) override {
210     // Normally, this method would just be implemented directly, but clang
211     // miscompiles the corresponding non-virtual thunk on linux x86.
212     // It however doesn't when going though a non-virtual method.
213     // https://bugs.llvm.org/show_bug.cgi?id=38466
214     return AsyncCallImpl(funcPtr, retval);
215   };
216 
217   // Get event target for processing network events.
218   already_AddRefed<nsIEventTarget> GetNeckoTarget() override;
219 
220   virtual mozilla::ipc::IPCResult RecvLogBlockedCORSRequest(
221       const nsString& aMessage, const nsCString& aCategory) override;
222   NS_IMETHOD LogBlockedCORSRequest(const nsAString& aMessage,
223                                    const nsACString& aCategory) override;
224 
225   virtual mozilla::ipc::IPCResult RecvLogMimeTypeMismatch(
226       const nsCString& aMessageName, const bool& aWarning, const nsString& aURL,
227       const nsString& aContentType) override;
228   NS_IMETHOD LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning,
229                                  const nsAString& aURL,
230                                  const nsAString& aContentType) override;
231 
232   mozilla::ipc::IPCResult RecvOnProgress(const int64_t& aProgress,
233                                          const int64_t& aProgressMax) override;
234 
235   mozilla::ipc::IPCResult RecvOnStatus(const nsresult& aStatus) override;
236 
237  private:
238   // We want to handle failure result of AsyncOpen, hence AsyncOpen calls the
239   // Internal method
240   nsresult AsyncOpenInternal(nsIStreamListener* aListener);
241 
242   nsresult AsyncCallImpl(void (HttpChannelChild::*funcPtr)(),
243                          nsRunnableMethod<HttpChannelChild>** retval);
244 
245   class OverrideRunnable : public Runnable {
246    public:
247     OverrideRunnable(HttpChannelChild* aChannel, HttpChannelChild* aNewChannel,
248                      InterceptStreamListener* aListener, nsIInputStream* aInput,
249                      nsIInterceptedBodyCallback* aCallback,
250                      UniquePtr<nsHttpResponseHead>&& aHead,
251                      nsICacheInfoChannel* aCacheInfo);
252 
253     NS_IMETHOD Run() override;
254     void OverrideWithSynthesizedResponse();
255 
256    private:
257     RefPtr<HttpChannelChild> mChannel;
258     RefPtr<HttpChannelChild> mNewChannel;
259     RefPtr<InterceptStreamListener> mListener;
260     nsCOMPtr<nsIInputStream> mInput;
261     nsCOMPtr<nsIInterceptedBodyCallback> mCallback;
262     UniquePtr<nsHttpResponseHead> mHead;
263     nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
264   };
265 
266   // Sets the event target for future IPC messages. Messages will either be
267   // directed to the TabGroup or DocGroup, depending on the LoadInfo associated
268   // with the channel. Should be called when a new channel is being set up,
269   // before the constructor message is sent to the parent.
270   void SetEventTarget();
271 
272   // Get event target for ODA.
273   already_AddRefed<nsIEventTarget> GetODATarget();
274 
275   [[nodiscard]] nsresult ContinueAsyncOpen();
276 
277   // Callbacks while receiving OnTransportAndData/OnStopRequest/OnProgress/
278   // OnStatus/FlushedForDiversion/DivertMessages on background IPC channel.
279   void ProcessOnTransportAndData(const nsresult& aChannelStatus,
280                                  const nsresult& aStatus,
281                                  const uint64_t& aOffset,
282                                  const uint32_t& aCount,
283                                  const nsCString& aData);
284   void ProcessOnStopRequest(
285       const nsresult& aChannelStatus, const ResourceTimingStructArgs& aTiming,
286       const nsHttpHeaderArray& aResponseTrailers,
287       const nsTArray<ConsoleReportCollected>& aConsoleReports);
288   void ProcessFlushedForDiversion();
289   void ProcessDivertMessages();
290 
291   // Return true if we need to tell the parent the size of unreported received
292   // data
293   bool NeedToReportBytesRead();
294   int32_t mUnreportBytesRead = 0;
295 
296   void DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext);
297   void DoOnStatus(nsIRequest* aRequest, nsresult status);
298   void DoOnProgress(nsIRequest* aRequest, int64_t progress,
299                     int64_t progressMax);
300   void DoOnDataAvailable(nsIRequest* aRequest, nsISupports* aContext,
301                          nsIInputStream* aStream, uint64_t offset,
302                          uint32_t count);
303   void DoPreOnStopRequest(nsresult aStatus);
304   void DoOnStopRequest(nsIRequest* aRequest, nsresult aChannelStatus,
305                        nsISupports* aContext);
306 
307   bool ShouldInterceptURI(nsIURI* aURI, bool& aShouldUpgrade);
308 
309   // Discard the prior interception and continue with the original network
310   // request.
311   void ResetInterception();
312 
313   // Override this channel's pending response with a synthesized one. The
314   // content will be asynchronously read from the pump.
315   void OverrideWithSynthesizedResponse(
316       UniquePtr<nsHttpResponseHead>& aResponseHead,
317       nsIInputStream* aSynthesizedInput,
318       nsIInterceptedBodyCallback* aSynthesizedCallback,
319       InterceptStreamListener* aStreamListener,
320       nsICacheInfoChannel* aCacheInfoChannel);
321 
322   void ForceIntercepted(nsIInputStream* aSynthesizedInput,
323                         nsIInterceptedBodyCallback* aSynthesizedCallback,
324                         nsICacheInfoChannel* aCacheInfo);
325 
326   // Try send DeletingChannel message to parent side. Dispatch an async task to
327   // main thread if invoking on non-main thread.
328   void TrySendDeletingChannel();
329 
330   // Try invoke Cancel if on main thread, or prepend a CancelEvent in mEventQ to
331   // ensure Cacnel is processed before any other channel events.
332   void CancelOnMainThread(nsresult aRv);
333 
334   void MaybeCallSynthesizedCallback();
335 
336  private:
337   // this section is for main-thread-only object
338   // all the references need to be proxy released on main thread.
339   nsCOMPtr<nsIChildChannel> mRedirectChannelChild;
340   RefPtr<InterceptStreamListener> mInterceptListener;
341   // Needed to call AsyncOpen in FinishInterceptedRedirect
342   nsCOMPtr<nsIStreamListener> mInterceptedRedirectListener;
343 
344   // Proxy release all members above on main thread.
345   void ReleaseMainThreadOnlyReferences();
346 
347  private:
348   nsCString mCachedCharset;
349   nsCString mProtocolVersion;
350 
351   RequestHeaderTuples mClientSetRequestHeaders;
352   RefPtr<nsInputStreamPump> mSynthesizedResponsePump;
353   nsCOMPtr<nsIInputStream> mSynthesizedInput;
354   nsCOMPtr<nsIInterceptedBodyCallback> mSynthesizedCallback;
355   nsCOMPtr<nsICacheInfoChannel> mSynthesizedCacheInfo;
356   RefPtr<ChannelEventQueue> mEventQ;
357 
358   nsCOMPtr<nsIInputStreamReceiver> mOriginalInputStreamReceiver;
359   nsCOMPtr<nsIInputStreamReceiver> mAltDataInputStreamReceiver;
360 
361   // Used to ensure atomicity of mBgChild and mBgInitFailCallback
362   Mutex mBgChildMutex;
363 
364   // Associated HTTP background channel
365   RefPtr<HttpBackgroundChannelChild> mBgChild;
366 
367   // Error handling procedure if failed to establish PBackground IPC
368   nsCOMPtr<nsIRunnable> mBgInitFailCallback;
369 
370   // Remove the association with background channel after OnStopRequest
371   // or AsyncAbort.
372   void CleanupBackgroundChannel();
373 
374   // Needed to call CleanupRedirectingChannel in FinishInterceptedRedirect
375   RefPtr<HttpChannelChild> mInterceptingChannel;
376   // Used to call OverrideWithSynthesizedResponse in FinishInterceptedRedirect
377   RefPtr<OverrideRunnable> mOverrideRunnable;
378 
379   // Target thread for delivering ODA.
380   nsCOMPtr<nsIEventTarget> mODATarget;
381   // Used to ensure atomicity of mNeckoTarget / mODATarget;
382   Mutex mEventTargetMutex;
383 
384   // If nsUnknownDecoder is involved OnStartRequest call will be delayed and
385   // this queue keeps OnDataAvailable data until OnStartRequest is finally
386   // called.
387   nsTArray<UniquePtr<ChannelEvent>> mUnknownDecoderEventQ;
388 
389   TimeStamp mLastStatusReported;
390 
391   int64_t mSynthesizedStreamLength;
392   uint64_t mCacheEntryId;
393 
394   // The result of RetargetDeliveryTo for this channel.
395   // |notRequested| represents OMT is not requested by the channel owner.
396   LABELS_HTTP_CHILD_OMT_STATS mOMTResult =
397       LABELS_HTTP_CHILD_OMT_STATS::notRequested;
398 
399   uint32_t mCacheKey;
400   int32_t mCacheFetchCount;
401   uint32_t mCacheExpirationTime;
402 
403   // If we're handling a multi-part response, then this is set to the current
404   // part ID during OnStartRequest.
405   Maybe<uint32_t> mMultiPartID;
406 
407   // To ensure only one SendDeletingChannel is triggered.
408   Atomic<bool> mDeletingChannelSent;
409 
410   Atomic<bool, ReleaseAcquire> mUnknownDecoderInvolved;
411 
412   // Once set, OnData and possibly OnStop will be diverted to the parent.
413   Atomic<bool, ReleaseAcquire> mDivertingToParent;
414   // Once set, no OnStart/OnData/OnStop callbacks should be received from the
415   // parent channel, nor dequeued from the ChannelEventQueue.
416   Atomic<bool, ReleaseAcquire> mFlushedForDiversion;
417 
418   Atomic<bool, SequentiallyConsistent> mIsFromCache;
419   Atomic<bool, SequentiallyConsistent> mIsRacing;
420   // Set if we get the result and cache |mNeedToReportBytesRead|
421   Atomic<bool, SequentiallyConsistent> mCacheNeedToReportBytesReadInitialized;
422   // True if we need to tell the parent the size of unreported received data
423   Atomic<bool, SequentiallyConsistent> mNeedToReportBytesRead;
424 
425 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED
426   bool mDoDiagnosticAssertWhenOnStopNotCalledOnDestroy = false;
427   bool mAsyncOpenSucceeded = false;
428   bool mSuccesfullyRedirected = false;
429   Maybe<ActorDestroyReason> mActorDestroyReason;
430 #endif
431 
432   uint8_t mCacheEntryAvailable : 1;
433   uint8_t mAltDataCacheEntryAvailable : 1;
434 
435   // If ResumeAt is called before AsyncOpen, we need to send extra data upstream
436   uint8_t mSendResumeAt : 1;
437 
438   uint8_t mKeptAlive : 1;  // IPC kept open, but only for security info
439 
440   // Set when ActorDestroy(ActorDestroyReason::Deletion) is called
441   // The channel must ignore any following OnStart/Stop/DataAvailable messages
442   uint8_t mIPCActorDeleted : 1;
443 
444   // Set if SendSuspend is called. Determines if SendResume is needed when
445   // diverting callbacks to parent.
446   uint8_t mSuspendSent : 1;
447 
448   // Set if a response was synthesized, indicating that any forthcoming
449   // redirects should be intercepted.
450   uint8_t mSynthesizedResponse : 1;
451 
452   // Set if a synthesized response should cause us to explictly allows
453   // intercepting an expected forthcoming redirect.
454   uint8_t mShouldInterceptSubsequentRedirect : 1;
455   // Set if a redirection is being initiated to facilitate providing a
456   // synthesized response to a channel using a different principal than the
457   // current one.
458   uint8_t mRedirectingForSubsequentSynthesizedResponse : 1;
459 
460   // Set if a manual redirect mode channel needs to be intercepted in the
461   // parent.
462   uint8_t mPostRedirectChannelShouldIntercept : 1;
463   // Set if a manual redirect mode channel needs to be upgraded to a secure URI
464   // when it's being considered for interception.  Can only be true if
465   // mPostRedirectChannelShouldIntercept is true.
466   uint8_t mPostRedirectChannelShouldUpgrade : 1;
467 
468   // Set if the corresponding parent channel should force an interception to
469   // occur before the network transaction is initiated.
470   uint8_t mShouldParentIntercept : 1;
471 
472   // Set if the corresponding parent channel should suspend after a response
473   // is synthesized.
474   uint8_t mSuspendParentAfterSynthesizeResponse : 1;
475 
476   // True if this channel is a multi-part channel, and the last part
477   // is currently being processed.
478   uint8_t mIsLastPartOfMultiPart : 1;
479 
480   void FinishInterceptedRedirect();
481   void CleanupRedirectingChannel(nsresult rv);
482 
483   // true after successful AsyncOpen until OnStopRequest completes.
RemoteChannelExists()484   bool RemoteChannelExists() { return CanSend() && !mKeptAlive; }
485 
486   void AssociateApplicationCache(const nsCString& groupID,
487                                  const nsCString& clientID);
488   void OnStartRequest(const nsHttpResponseHead& aResponseHead,
489                       const bool& aUseResponseHead,
490                       const nsHttpHeaderArray& aRequestHeaders,
491                       const HttpChannelOnStartRequestArgs& aArgs);
492   void MaybeDivertOnData(const nsCString& data, const uint64_t& offset,
493                          const uint32_t& count);
494   void OnTransportAndData(const nsresult& channelStatus, const nsresult& status,
495                           const uint64_t& offset, const uint32_t& count,
496                           const nsCString& data);
497   void OnStopRequest(const nsresult& channelStatus,
498                      const ResourceTimingStructArgs& timing,
499                      const nsHttpHeaderArray& aResponseTrailers,
500                      const nsTArray<ConsoleReportCollected>& aConsoleReports);
501   void MaybeDivertOnStop(const nsresult& aChannelStatus);
502   void FailedAsyncOpen(const nsresult& status);
503   void HandleAsyncAbort();
504   void Redirect1Begin(const uint32_t& registrarId, const URIParams& newUri,
505                       const uint32_t& newLoadFlags,
506                       const uint32_t& redirectFlags,
507                       const ParentLoadInfoForwarderArgs& loadInfoForwarder,
508                       const nsHttpResponseHead& responseHead,
509                       const nsACString& securityInfoSerialization,
510                       const uint64_t& channelId,
511                       const ResourceTimingStructArgs& timing);
512   bool Redirect3Complete(OverrideRunnable* aRunnable);
513   void DeleteSelf();
514   void DoNotifyListener();
515   void ContinueDoNotifyListener();
516   void OnAfterLastPart(const nsresult& aStatus);
517   void MaybeConnectToSocketProcess();
518 
519   // Create a a new channel to be used in a redirection, based on the provided
520   // response headers.
521   [[nodiscard]] nsresult SetupRedirect(nsIURI* uri,
522                                        const nsHttpResponseHead* responseHead,
523                                        const uint32_t& redirectFlags,
524                                        nsIChannel** outChannel);
525 
526   // Perform a redirection without communicating with the parent process at all.
527   void BeginNonIPCRedirect(nsIURI* responseURI,
528                            const nsHttpResponseHead* responseHead,
529                            bool responseRedirected);
530 
531   // Override the default security info pointer during a non-IPC redirection.
532   void OverrideSecurityInfoForNonIPCRedirect(nsISupports* securityInfo);
533 
534   // Collect telemetry for the successful rate of OMT.
535   void CollectOMTTelemetry();
536 
537   friend class HttpAsyncAborter<HttpChannelChild>;
538   friend class InterceptStreamListener;
539   friend class InterceptedChannelContent;
540   friend class HttpBackgroundChannelChild;
541   friend class NeckoTargetChannelFunctionEvent;
542 };
543 
NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelChild,HTTP_CHANNEL_CHILD_IID)544 NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelChild, HTTP_CHANNEL_CHILD_IID)
545 
546 // A stream listener interposed between the nsInputStreamPump used for
547 // intercepted channels and this channel's original listener. This is only used
548 // to ensure the original listener sees the channel as the request object, and
549 // to synthesize OnStatus and OnProgress notifications.
550 class InterceptStreamListener : public nsIStreamListener,
551                                 public nsIProgressEventSink {
552   RefPtr<HttpChannelChild> mOwner;
553   nsCOMPtr<nsISupports> mContext;
554   virtual ~InterceptStreamListener() = default;
555 
556  public:
557   InterceptStreamListener(HttpChannelChild* aOwner, nsISupports* aContext)
558       : mOwner(aOwner), mContext(aContext) {}
559 
560   NS_DECL_ISUPPORTS
561   NS_DECL_NSIREQUESTOBSERVER
562   NS_DECL_NSISTREAMLISTENER
563   NS_DECL_NSIPROGRESSEVENTSINK
564 
565   void Cleanup();
566 };
567 
568 //-----------------------------------------------------------------------------
569 // inline functions
570 //-----------------------------------------------------------------------------
571 
IsSuspended()572 inline bool HttpChannelChild::IsSuspended() { return mSuspendCount != 0; }
573 
574 }  // namespace net
575 }  // namespace mozilla
576 
577 #endif  // mozilla_net_HttpChannelChild_h
578