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