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