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 "ADivertableParentChannel.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 "nsIObserver.h" 18 #include "nsIParentRedirectingChannel.h" 19 #include "nsIProgressEventSink.h" 20 #include "nsHttpChannel.h" 21 #include "nsIAuthPromptProvider.h" 22 #include "mozilla/dom/ipc/IdType.h" 23 #include "nsIDeprecationWarner.h" 24 25 class nsICacheEntry; 26 class nsIAssociatedContentSecurity; 27 28 #define HTTP_CHANNEL_PARENT_IID \ 29 { \ 30 0x982b2372, 0x7aa5, 0x4e8a, { \ 31 0xbd, 0x9f, 0x89, 0x74, 0xd7, 0xf0, 0x58, 0xeb \ 32 } \ 33 } 34 35 namespace mozilla { 36 37 namespace dom { 38 class TabParent; 39 class PBrowserOrId; 40 } // namespace dom 41 42 namespace net { 43 44 class HttpBackgroundChannelParent; 45 class HttpChannelParentListener; 46 class ChannelEventQueue; 47 48 // Note: nsIInterfaceRequestor must be the first base so that do_QueryObject() 49 // works correctly on this object, as it's needed to compute a void* pointing to 50 // the beginning of this object. 51 52 class HttpChannelParent final : public nsIInterfaceRequestor, 53 public PHttpChannelParent, 54 public nsIParentRedirectingChannel, 55 public nsIProgressEventSink, 56 public ADivertableParentChannel, 57 public nsIAuthPromptProvider, 58 public nsIDeprecationWarner, 59 public HttpChannelSecurityWarningReporter, 60 public nsIAsyncVerifyRedirectReadyCallback { 61 virtual ~HttpChannelParent(); 62 63 public: 64 NS_DECL_ISUPPORTS 65 NS_DECL_NSIREQUESTOBSERVER 66 NS_DECL_NSISTREAMLISTENER 67 NS_DECL_NSIPARENTCHANNEL 68 NS_DECL_NSIPARENTREDIRECTINGCHANNEL 69 NS_DECL_NSIPROGRESSEVENTSINK 70 NS_DECL_NSIINTERFACEREQUESTOR 71 NS_DECL_NSIAUTHPROMPTPROVIDER 72 NS_DECL_NSIDEPRECATIONWARNER 73 NS_DECL_NSIASYNCVERIFYREDIRECTREADYCALLBACK 74 75 NS_DECLARE_STATIC_IID_ACCESSOR(HTTP_CHANNEL_PARENT_IID) 76 77 HttpChannelParent(const dom::PBrowserOrId& iframeEmbedding, 78 nsILoadContext* aLoadContext, PBOverrideStatus aStatus); 79 80 MOZ_MUST_USE bool Init(const HttpChannelCreationArgs& aOpenArgs); 81 82 // ADivertableParentChannel functions. 83 void DivertTo(nsIStreamListener* aListener) override; 84 MOZ_MUST_USE nsresult SuspendForDiversion() override; 85 MOZ_MUST_USE nsresult SuspendMessageDiversion() override; 86 MOZ_MUST_USE nsresult ResumeMessageDiversion() override; 87 MOZ_MUST_USE nsresult CancelDiversion() override; 88 89 // Calls OnStartRequest for "DivertTo" listener, then notifies child channel 90 // that it should divert OnDataAvailable and OnStopRequest calls to this 91 // parent channel. 92 void StartDiversion(); 93 94 // Handles calling OnStart/Stop if there are errors during diversion. 95 // Called asynchronously from FailDiversion. 96 void NotifyDiversionFailed(nsresult aErrorCode); 97 98 // Forwarded to nsHttpChannel::SetApplyConversion. SetApplyConversion(bool aApplyConversion)99 void SetApplyConversion(bool aApplyConversion) { 100 if (mChannel) { 101 mChannel->SetApplyConversion(aApplyConversion); 102 } 103 } 104 105 MOZ_MUST_USE nsresult OpenAlternativeOutputStream(const nsACString& type, 106 nsIOutputStream** _retval); 107 108 // Callbacks for each asynchronous tasks required in AsyncOpen 109 // procedure, will call InvokeAsyncOpen when all the expected 110 // tasks is finished successfully or when any failure happened. 111 // @see mAsyncOpenBarrier. 112 void TryInvokeAsyncOpen(nsresult aRv); 113 114 void InvokeAsyncOpen(nsresult rv); 115 116 // Calls SendSetPriority if mIPCClosed is false. 117 void DoSendSetPriority(int16_t aValue); 118 119 // Callback while background channel is ready. 120 void OnBackgroundParentReady(HttpBackgroundChannelParent* aBgParent); 121 // Callback while background channel is destroyed. 122 void OnBackgroundParentDestroyed(); 123 124 base::ProcessId OtherPid() const override; 125 126 protected: 127 // used to connect redirected-to channel in parent with just created 128 // ChildChannel. Used during redirects. 129 MOZ_MUST_USE bool ConnectChannel(const uint32_t& channelId, 130 const bool& shouldIntercept); 131 132 MOZ_MUST_USE bool DoAsyncOpen( 133 const URIParams& uri, const OptionalURIParams& originalUri, 134 const OptionalURIParams& docUri, const OptionalURIParams& referrerUri, 135 const uint32_t& referrerPolicy, 136 const OptionalURIParams& internalRedirectUri, 137 const OptionalURIParams& topWindowUri, const uint32_t& loadFlags, 138 const RequestHeaderTuples& requestHeaders, const nsCString& requestMethod, 139 const OptionalIPCStream& uploadStream, const bool& uploadStreamHasHeaders, 140 const int16_t& priority, const uint32_t& classOfService, 141 const uint8_t& redirectionLimit, const bool& allowSTS, 142 const uint32_t& thirdPartyFlags, const bool& doResumeAt, 143 const uint64_t& startPos, const nsCString& entityID, 144 const bool& chooseApplicationCache, const nsCString& appCacheClientID, 145 const bool& allowSpdy, const bool& allowAltSvc, 146 const bool& beConservative, const uint32_t& tlsFlags, 147 const OptionalLoadInfoArgs& aLoadInfoArgs, 148 const OptionalHttpResponseHead& aSynthesizedResponseHead, 149 const nsCString& aSecurityInfoSerialization, const uint32_t& aCacheKey, 150 const uint64_t& aRequestContextID, 151 const OptionalCorsPreflightArgs& aCorsPreflightArgs, 152 const uint32_t& aInitialRwin, const bool& aBlockAuthPrompt, 153 const bool& aSuspendAfterSynthesizeResponse, 154 const bool& aAllowStaleCacheContent, const nsCString& aContentTypeHint, 155 const uint32_t& aCorsMode, const uint32_t& aRedirectMode, 156 const uint64_t& aChannelId, const uint64_t& aContentWindowId, 157 const nsCString& aPreferredAlternativeType, 158 const uint64_t& aTopLevelOuterContentWindowId, 159 const TimeStamp& aLaunchServiceWorkerStart, 160 const TimeStamp& aLaunchServiceWorkerEnd, 161 const TimeStamp& aDispatchFetchEventStart, 162 const TimeStamp& aDispatchFetchEventEnd, 163 const TimeStamp& aHandleFetchEventStart, 164 const TimeStamp& aHandleFetchEventEnd, 165 const bool& aForceMainDocumentChannel); 166 167 virtual mozilla::ipc::IPCResult RecvSetPriority( 168 const int16_t& priority) override; 169 virtual mozilla::ipc::IPCResult RecvSetClassOfService( 170 const uint32_t& cos) override; 171 virtual mozilla::ipc::IPCResult RecvSetCacheTokenCachedCharset( 172 const nsCString& charset) override; 173 virtual mozilla::ipc::IPCResult RecvSuspend() override; 174 virtual mozilla::ipc::IPCResult RecvResume() override; 175 virtual mozilla::ipc::IPCResult RecvCancel(const nsresult& status) override; 176 virtual mozilla::ipc::IPCResult RecvRedirect2Verify( 177 const nsresult& result, const RequestHeaderTuples& changedHeaders, 178 const uint32_t& loadFlags, const uint32_t& referrerPolicy, 179 const OptionalURIParams& aReferrerURI, 180 const OptionalURIParams& apiRedirectUri, 181 const OptionalCorsPreflightArgs& aCorsPreflightArgs, 182 const bool& aChooseAppcache) override; 183 virtual mozilla::ipc::IPCResult RecvUpdateAssociatedContentSecurity( 184 const int32_t& broken, const int32_t& no) override; 185 virtual mozilla::ipc::IPCResult RecvDocumentChannelCleanup( 186 const bool& clearCacheEntry) override; 187 virtual mozilla::ipc::IPCResult RecvMarkOfflineCacheEntryAsForeign() override; 188 virtual mozilla::ipc::IPCResult RecvDivertOnDataAvailable( 189 const nsCString& data, const uint64_t& offset, 190 const uint32_t& count) override; 191 virtual mozilla::ipc::IPCResult RecvDivertOnStopRequest( 192 const nsresult& statusCode) override; 193 virtual mozilla::ipc::IPCResult RecvDivertComplete() override; 194 virtual mozilla::ipc::IPCResult RecvRemoveCorsPreflightCacheEntry( 195 const URIParams& uri, 196 const mozilla::ipc::PrincipalInfo& requestingPrincipal) override; 197 virtual void ActorDestroy(ActorDestroyReason why) override; 198 199 // Supporting function for ADivertableParentChannel. 200 MOZ_MUST_USE nsresult ResumeForDiversion(); 201 202 // Asynchronously calls NotifyDiversionFailed. 203 void FailDiversion(nsresult aErrorCode); 204 205 friend class HttpChannelParentListener; 206 RefPtr<mozilla::dom::TabParent> mTabParent; 207 208 MOZ_MUST_USE nsresult ReportSecurityMessage( 209 const nsAString& aMessageTag, const nsAString& aMessageCategory) override; 210 nsresult LogBlockedCORSRequest(const nsAString& aMessage) override; 211 212 // Calls SendDeleteSelf and sets mIPCClosed to true because we should not 213 // send any more messages after that. Bug 1274886 214 MOZ_MUST_USE bool DoSendDeleteSelf(); 215 // Called to notify the parent channel to not send any more IPC messages. 216 virtual mozilla::ipc::IPCResult RecvDeletingChannel() override; 217 virtual mozilla::ipc::IPCResult RecvFinishInterceptedRedirect() override; 218 219 private: 220 void UpdateAndSerializeSecurityInfo(nsACString& aSerializedSecurityInfoOut); 221 222 void DivertOnDataAvailable(const nsCString& data, const uint64_t& offset, 223 const uint32_t& count); 224 void DivertOnStopRequest(const nsresult& statusCode); 225 void DivertComplete(); 226 void MaybeFlushPendingDiversion(); 227 void ResponseSynthesized(); 228 229 // final step for Redirect2Verify procedure, will be invoked while both 230 // redirecting and redirected channel are ready or any error happened. 231 // OnRedirectVerifyCallback will be invoked for finishing the async 232 // redirect verification procedure. 233 void ContinueRedirect2Verify(const nsresult& aResult); 234 235 void AsyncOpenFailed(nsresult aRv); 236 237 // Request to pair with a HttpBackgroundChannelParent with the same channel 238 // id, a promise will be returned so the caller can append callbacks on it. 239 // If called multiple times before mBgParent is available, the same promise 240 // will be returned and the callbacks will be invoked in order. 241 already_AddRefed<GenericPromise> WaitForBgParent(); 242 243 // Remove the association with background channel after main-thread IPC 244 // is about to be destroyed or no further event is going to be sent, i.e., 245 // DocumentChannelCleanup. 246 void CleanupBackgroundChannel(); 247 248 friend class HttpBackgroundChannelParent; 249 friend class DivertDataAvailableEvent; 250 friend class DivertStopRequestEvent; 251 friend class DivertCompleteEvent; 252 253 RefPtr<HttpBaseChannel> mChannel; 254 nsCOMPtr<nsICacheEntry> mCacheEntry; 255 nsCOMPtr<nsIAssociatedContentSecurity> mAssociatedContentSecurity; 256 Atomic<bool> mIPCClosed; // PHttpChannel actor has been Closed() 257 258 nsCOMPtr<nsIChannel> mRedirectChannel; 259 nsCOMPtr<nsIAsyncVerifyRedirectCallback> mRedirectCallback; 260 261 nsAutoPtr<class nsHttpChannel::OfflineCacheEntryAsForeignMarker> 262 mOfflineForeignMarker; 263 264 // OnStatus is always called before OnProgress. 265 // Set true in OnStatus if next OnProgress can be ignored 266 // since the information can be recontructed from ODA. 267 bool mIgnoreProgress : 1; 268 269 bool mSentRedirect1BeginFailed : 1; 270 bool mReceivedRedirect2Verify : 1; 271 272 PBOverrideStatus mPBOverride; 273 274 nsCOMPtr<nsILoadContext> mLoadContext; 275 RefPtr<nsHttpHandler> mHttpHandler; 276 277 RefPtr<HttpChannelParentListener> mParentListener; 278 // The listener we are diverting to or will divert to if mPendingDiversion 279 // is set. 280 nsCOMPtr<nsIStreamListener> mDivertListener; 281 // Set to the canceled status value if the main channel was canceled. 282 nsresult mStatus; 283 // Indicates that diversion has been requested, but we could not start it 284 // yet because the channel is still being opened with a synthesized response. 285 bool mPendingDiversion; 286 // Once set, no OnStart/OnData/OnStop calls should be accepted; conversely, it 287 // must be set when RecvDivertOnData/~DivertOnStop/~DivertComplete are 288 // received from the child channel. 289 bool mDivertingFromChild; 290 291 // Set if OnStart|StopRequest was called during a diversion from the child. 292 bool mDivertedOnStartRequest; 293 294 bool mSuspendedForDiversion; 295 296 // Set if this channel should be suspended after synthesizing a response. 297 bool mSuspendAfterSynthesizeResponse; 298 // Set if this channel will synthesize its response. 299 bool mWillSynthesizeResponse; 300 301 dom::TabId mNestedFrameId; 302 303 RefPtr<ChannelEventQueue> mEventQ; 304 305 RefPtr<HttpBackgroundChannelParent> mBgParent; 306 307 // Number of events to wait before actually invoking AsyncOpen on the main 308 // channel. For each asynchronous step required before InvokeAsyncOpen, should 309 // increase 1 to mAsyncOpenBarrier and invoke TryInvokeAsyncOpen after 310 // finished. This attribute is main thread only. 311 uint8_t mAsyncOpenBarrier = 0; 312 313 // Corresponding redirect channel registrar Id. 0 means redirection is not 314 // started. 315 uint32_t mRedirectRegistrarId = 0; 316 317 MozPromiseHolder<GenericPromise> mPromise; 318 MozPromiseRequestHolder<GenericPromise> mRequest; 319 }; 320 321 NS_DEFINE_STATIC_IID_ACCESSOR(HttpChannelParent, HTTP_CHANNEL_PARENT_IID) 322 323 } // namespace net 324 } // namespace mozilla 325 326 #endif // mozilla_net_HttpChannelParent_h 327