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