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