HttpChannelParent.h (14344B)
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_HttpChannelParent_h 9 #define mozilla_net_HttpChannelParent_h 10 11 #include "HttpBaseChannel.h" 12 #include "nsHttp.h" 13 #include "mozilla/net/PHttpChannelParent.h" 14 #include "mozilla/net/NeckoCommon.h" 15 #include "mozilla/net/NeckoParent.h" 16 #include "mozilla/MozPromise.h" 17 #include "nsIParentRedirectingChannel.h" 18 #include "nsIProgressEventSink.h" 19 #include "nsIChannelEventSink.h" 20 #include "nsIRedirectResultListener.h" 21 #include "nsHttpChannel.h" 22 #include "mozilla/dom/ipc/IdType.h" 23 #include "nsIMultiPartChannel.h" 24 #include "nsIURI.h" 25 26 class nsICacheEntry; 27 28 #define HTTP_CHANNEL_PARENT_IID \ 29 {0x982b2372, 0x7aa5, 0x4e8a, {0xbd, 0x9f, 0x89, 0x74, 0xd7, 0xf0, 0x58, 0xeb}} 30 31 namespace mozilla { 32 33 namespace dom { 34 class BrowserParent; 35 } // namespace dom 36 37 namespace net { 38 39 class HttpBackgroundChannelParent; 40 class ParentChannelListener; 41 class ChannelEventQueue; 42 class CacheEntryWriteHandleParent; 43 44 class HttpChannelParent final : public nsIInterfaceRequestor, 45 public PHttpChannelParent, 46 public nsIParentRedirectingChannel, 47 public nsIProgressEventSink, 48 public HttpChannelSecurityWarningReporter, 49 public nsIAsyncVerifyRedirectReadyCallback, 50 public nsIChannelEventSink, 51 public nsIRedirectResultListener, 52 public nsIMultiPartChannelListener { 53 virtual ~HttpChannelParent(); 54 55 public: 56 NS_DECL_ISUPPORTS 57 NS_DECL_NSIREQUESTOBSERVER 58 NS_DECL_NSISTREAMLISTENER 59 NS_DECL_NSIPARENTCHANNEL 60 NS_DECL_NSIPARENTREDIRECTINGCHANNEL 61 NS_DECL_NSIPROGRESSEVENTSINK 62 NS_DECL_NSIINTERFACEREQUESTOR 63 NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK 64 NS_DECL_NSICHANNELEVENTSINK 65 NS_DECL_NSIREDIRECTRESULTLISTENER 66 NS_DECL_NSIMULTIPARTCHANNELLISTENER 67 68 NS_INLINE_DECL_STATIC_IID(HTTP_CHANNEL_PARENT_IID) 69 70 HttpChannelParent(dom::BrowserParent* iframeEmbedding, 71 nsILoadContext* aLoadContext, 72 PBOverrideStatus aOverrideStatus); 73 74 [[nodiscard]] bool Init(const HttpChannelCreationArgs& aArgs); 75 76 // Forwarded to nsHttpChannel::SetApplyConversion. 77 void SetApplyConversion(bool aApplyConversion) { 78 if (mChannel) { 79 mChannel->SetApplyConversion(aApplyConversion); 80 } 81 } 82 83 [[nodiscard]] nsresult OpenAlternativeOutputStream( 84 const nsACString& type, int64_t predictedSize, 85 nsIAsyncOutputStream** _retval); 86 87 [[nodiscard]] CacheEntryWriteHandleParent* AllocCacheEntryWriteHandle(); 88 89 // Callbacks for each asynchronous tasks required in AsyncOpen 90 // procedure, will call InvokeAsyncOpen when all the expected 91 // tasks is finished successfully or when any failure happened. 92 // @see mAsyncOpenBarrier. 93 void TryInvokeAsyncOpen(nsresult aRv); 94 95 void InvokeAsyncOpen(nsresult rv); 96 97 void InvokeEarlyHintPreloader(nsresult rv, uint64_t aEarlyHintPreloaderId); 98 99 // Calls SendSetPriority if mIPCClosed is false. 100 void DoSendSetPriority(int16_t aValue); 101 102 // Calls SendReportLNAToConsole if mIPCClosed is false. 103 void DoSendReportLNAToConsole(const NetAddr& aPeerAddr, 104 const nsACString& aMessageType, 105 const nsACString& aPromptAction, 106 const nsACString& aTopLevelSite); 107 108 // Callback while background channel is ready. 109 void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent); 110 // Callback while background channel is destroyed. 111 void OnBackgroundParentDestroyed(); 112 113 base::ProcessId OtherPid() const; 114 115 // Inform the child actor that our referrer info was modified late during 116 // BeginConnect. 117 void OverrideReferrerInfoDuringBeginConnect(nsIReferrerInfo* aReferrerInfo); 118 119 // Set the cookie changes triggered by the channel, which will be applied by 120 // the child actor during PHttpBackgroundChannel::OnStartRequest. Note that 121 // CookieService also sends the information to all actors via PContent, a main 122 // thread IPC, which could be slower than background IPC 123 // PHttpBackgroundChannel::OnStartRequest. 124 void SetCookieChanges(nsTArray<CookieChange>&& aCookieChanges); 125 126 using ChildEndpointPromise = 127 MozPromise<ipc::Endpoint<extensions::PStreamFilterChild>, bool, true>; 128 [[nodiscard]] RefPtr<ChildEndpointPromise> AttachStreamFilter( 129 Endpoint<extensions::PStreamFilterParent>&& aParentEndpoint, 130 Endpoint<extensions::PStreamFilterChild>&& aChildEndpoint); 131 [[nodiscard]] RefPtr<GenericPromise> DetachStreamFilters(); 132 133 // Should only be called from EarlyHintPreloader. mChannel should be null at 134 // the point of calling. Sets mChannel to aChannel. Used by the 135 // EarlyHintPreloader to redirect the channel to this parent as soon as the 136 // final channel becomes available after all http redirects. 137 void SetHttpChannelFromEarlyHintPreloader(HttpBaseChannel* aChannel); 138 139 protected: 140 // used to connect redirected-to channel in parent with just created 141 // ChildChannel. Used during redirects. 142 [[nodiscard]] bool ConnectChannel(const uint32_t& registrarId); 143 144 [[nodiscard]] bool DoAsyncOpen( 145 nsIURI* uri, nsIURI* originalUri, nsIURI* docUri, 146 nsIReferrerInfo* aReferrerInfo, nsIURI* aAPIRedirectToURI, 147 nsIURI* topWindowUri, const uint32_t& loadFlags, 148 const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, 149 const Maybe<IPCStream>& uploadStream, const bool& uploadStreamHasHeaders, 150 const int16_t& priority, const ClassOfService& classOfService, 151 const uint8_t& redirectionLimit, const bool& allowSTS, 152 const uint32_t& thirdPartyFlags, const bool& doResumeAt, 153 const uint64_t& startPos, const nsCString& entityID, 154 const bool& allowSpdy, const bool& allowHttp3, const bool& allowAltSvc, 155 const bool& beConservative, const bool& bypassProxy, 156 const uint32_t& tlsFlags, const LoadInfoArgs& aLoadInfoArgs, 157 const uint32_t& aCacheKey, const uint64_t& aRequestContextID, 158 const Maybe<CorsPreflightArgs>& aCorsPreflightArgs, 159 const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt, 160 const bool& aAllowStaleCacheContent, 161 const bool& aPreferCacheLoadOverBypass, const nsCString& aContentTypeHint, 162 const dom::RequestMode& aRequestMode, const uint32_t& aRedirectMode, 163 const uint64_t& aChannelId, const uint64_t& aContentWindowId, 164 const nsTArray<PreferredAlternativeDataTypeParams>& 165 aPreferredAlternativeTypes, 166 const uint64_t& aBrowserId, const TimeStamp& aLaunchServiceWorkerStart, 167 const TimeStamp& aLaunchServiceWorkerEnd, 168 const TimeStamp& aDispatchFetchEventStart, 169 const TimeStamp& aDispatchFetchEventEnd, 170 const TimeStamp& aHandleFetchEventStart, 171 const TimeStamp& aHandleFetchEventEnd, 172 const bool& aForceMainDocumentChannel, 173 const TimeStamp& aNavigationStartTimeStamp, 174 const uint64_t& aEarlyHintPreloaderId, 175 const nsAString& aClassicScriptHintCharset, 176 const nsAString& aDocumentCharacterSet, 177 const bool& aIsUserAgentHeaderModified, const nsString& aInitiatorType); 178 179 virtual mozilla::ipc::IPCResult RecvSetPriority( 180 const int16_t& priority) override; 181 virtual mozilla::ipc::IPCResult RecvSetClassOfService( 182 const ClassOfService& cos) override; 183 virtual mozilla::ipc::IPCResult RecvSuspend() override; 184 virtual mozilla::ipc::IPCResult RecvResume() override; 185 virtual mozilla::ipc::IPCResult RecvCancel( 186 const nsresult& status, const uint32_t& requestBlockingReason, 187 const nsACString& reason, 188 const mozilla::Maybe<nsCString>& logString) override; 189 virtual mozilla::ipc::IPCResult RecvRedirect2Verify( 190 const nsresult& result, const RequestHeaderTuples& changedHeaders, 191 const uint32_t& aSourceRequestBlockingReason, 192 const Maybe<ChildLoadInfoForwarderArgs>& aTargetLoadInfoForwarder, 193 const uint32_t& loadFlags, nsIReferrerInfo* aReferrerInfo, 194 nsIURI* apiRedirectUri, 195 const Maybe<CorsPreflightArgs>& aCorsPreflightArgs) override; 196 virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup( 197 const bool& clearCacheEntry) override; 198 virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry( 199 nsIURI* uri, const mozilla::ipc::PrincipalInfo& requestingPrincipal, 200 const OriginAttributes& originAttributes) override; 201 virtual mozilla::ipc::IPCResult RecvSetCookies( 202 const nsACString& aBaseDomain, const OriginAttributes& aOriginAttributes, 203 nsIURI* aHost, const bool& aFromHttp, const bool& aIsThirdParty, 204 nsTArray<CookieStruct>&& aCookies) override; 205 virtual mozilla::ipc::IPCResult RecvBytesRead(const int32_t& aCount) override; 206 virtual mozilla::ipc::IPCResult RecvOpenOriginalCacheInputStream() override; 207 virtual void ActorDestroy(ActorDestroyReason why) override; 208 209 friend class ParentChannelListener; 210 RefPtr<mozilla::dom::BrowserParent> mBrowserParent; 211 212 [[nodiscard]] nsresult ReportSecurityMessage( 213 const nsAString& aMessageTag, const nsAString& aMessageCategory) override; 214 nsresult LogBlockedCORSRequest(const nsAString& aMessage, 215 const nsACString& aCategory, 216 bool aIsWarning = false) override; 217 nsresult LogMimeTypeMismatch(const nsACString& aMessageName, bool aWarning, 218 const nsAString& aURL, 219 const nsAString& aContentType) override; 220 221 // Calls SendDeleteSelf and sets mIPCClosed to true because we should not 222 // send any more messages after that. Bug 1274886 223 [[nodiscard]] bool DoSendDeleteSelf(); 224 // Called to notify the parent channel to not send any more IPC messages. 225 virtual mozilla::ipc::IPCResult RecvDeletingChannel() override; 226 227 private: 228 already_AddRefed<nsITransportSecurityInfo> SecurityInfo(); 229 230 // final step for Redirect2Verify procedure, will be invoked while both 231 // redirecting and redirected channel are ready or any error happened. 232 // OnRedirectVerifyCallback will be invoked for finishing the async 233 // redirect verification procedure. 234 void ContinueRedirect2Verify(const nsresult& aResult); 235 236 void AsyncOpenFailed(nsresult aRv); 237 238 // Request to pair with a HttpBackgroundChannelParent with the same channel 239 // id, a promise will be returned so the caller can append callbacks on it. 240 // If called multiple times before mBgParent is available, the same promise 241 // will be returned and the callbacks will be invoked in order. 242 [[nodiscard]] RefPtr<GenericNonExclusivePromise> WaitForBgParent( 243 uint64_t aChannelId); 244 245 // Remove the association with background channel after main-thread IPC 246 // is about to be destroyed or no further event is going to be sent, i.e., 247 // DocumentChannelCleanup. 248 void CleanupBackgroundChannel(); 249 250 // Check if the channel needs to enable the flow control on the IPC channel. 251 // That is, we may suspend the channel if the ODA-s to child process are not 252 // consumed quickly enough. Otherwise, memory explosion could happen. 253 bool NeedFlowControl(); 254 255 // Get the appropriate event target for background parent operations based on 256 // channel's class of service flags: synchronous event target for urgent 257 // channels, queued for others to balance responsiveness and prevent 258 // head-of-line blocking. 259 nsCOMPtr<nsISerialEventTarget> GetEventTargetForBgParentWait(); 260 261 bool IsRedirectDueToAuthRetry(uint32_t redirectFlags); 262 263 int32_t mSendWindowSize; 264 265 friend class HttpBackgroundChannelParent; 266 267 uint64_t mEarlyHintPreloaderId{}; 268 269 RefPtr<HttpBaseChannel> mChannel; 270 nsCOMPtr<nsICacheEntry> mCacheEntry; 271 272 nsCOMPtr<nsIChannel> mRedirectChannel; 273 nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; 274 275 nsCOMPtr<nsILoadContext> mLoadContext; 276 RefPtr<nsHttpHandler> mHttpHandler; 277 278 RefPtr<ParentChannelListener> mParentListener; 279 280 RefPtr<ChannelEventQueue> mEventQ; 281 282 RefPtr<HttpBackgroundChannelParent> mBgParent; 283 284 MozPromiseHolder<GenericNonExclusivePromise> mPromise; 285 MozPromiseRequestHolder<GenericNonExclusivePromise> mRequest; 286 287 // To calculate the delay caused by the e10s back-pressure suspension 288 TimeStamp mResumedTimestamp; 289 290 Atomic<bool> mIPCClosed; // PHttpChannel actor has been Closed() 291 292 // Corresponding redirect channel registrar Id. 0 means redirection is not 293 // started. 294 uint64_t mRedirectChannelId = 0; 295 296 PBOverrideStatus mPBOverride; 297 298 // Set to the canceled status value if the main channel was canceled. 299 nsresult mStatus; 300 301 // The referrer info, set during nsHttpChannel::BeginConnect, to override the 302 // original one. This info will be sent in OnStartRequest. 303 nsCOMPtr<nsIReferrerInfo> mOverrideReferrerInfo; 304 305 // The cookie changes received while processing the Set-Cookie header. This 306 // info will be sent in OnStartRequest. 307 nsTArray<CookieChange> mCookieChanges; 308 309 // OnStatus is always called before OnProgress. 310 // Set true in OnStatus if next OnProgress can be ignored 311 // since the information can be recontructed from ODA. 312 uint8_t mIgnoreProgress : 1; 313 314 uint8_t mHasSuspendedByBackPressure : 1; 315 316 // Set if we get the result of and cache |mNeedFlowControl| 317 uint8_t mCacheNeedFlowControlInitialized : 1; 318 uint8_t mNeedFlowControl : 1; 319 uint8_t mSuspendedForFlowControl : 1; 320 321 // Defaults to false. Is set to true at the begining of OnStartRequest. 322 // Used to ensure methods can't be called before OnStartRequest. 323 uint8_t mAfterOnStartRequestBegun : 1; 324 325 // Number of events to wait before actually invoking AsyncOpen on the main 326 // channel. For each asynchronous step required before InvokeAsyncOpen, should 327 // increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after 328 // finished. This attribute is main thread only. 329 uint8_t mAsyncOpenBarrier = 0; 330 331 // When true, ODAs are sent from the socket process to the child process 332 // directly. 333 uint8_t mDataSentToChildProcess : 1; 334 }; 335 336 } // namespace net 337 } // namespace mozilla 338 339 #endif // mozilla_net_HttpChannelParent_h