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