/src/mozilla-central/netwerk/protocol/http/nsHttpChannel.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | /* vim:set et cin ts=4 sw=4 sts=4: */ |
3 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
4 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
5 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
6 | | |
7 | | #ifndef nsHttpChannel_h__ |
8 | | #define nsHttpChannel_h__ |
9 | | |
10 | | #include "HttpBaseChannel.h" |
11 | | #include "nsTArray.h" |
12 | | #include "nsICachingChannel.h" |
13 | | #include "nsICacheEntry.h" |
14 | | #include "nsICacheEntryOpenCallback.h" |
15 | | #include "nsIDNSListener.h" |
16 | | #include "nsIApplicationCacheChannel.h" |
17 | | #include "nsIChannelWithDivertableParentListener.h" |
18 | | #include "nsIProtocolProxyCallback.h" |
19 | | #include "nsIStreamTransportService.h" |
20 | | #include "nsIHttpAuthenticableChannel.h" |
21 | | #include "nsIAsyncVerifyRedirectCallback.h" |
22 | | #include "nsIThreadRetargetableRequest.h" |
23 | | #include "nsIThreadRetargetableStreamListener.h" |
24 | | #include "nsWeakReference.h" |
25 | | #include "TimingStruct.h" |
26 | | #include "ADivertableParentChannel.h" |
27 | | #include "AutoClose.h" |
28 | | #include "nsIStreamListener.h" |
29 | | #include "nsISupportsPrimitives.h" |
30 | | #include "nsICorsPreflightCallback.h" |
31 | | #include "AlternateServices.h" |
32 | | #include "nsIRaceCacheWithNetwork.h" |
33 | | #include "mozilla/extensions/PStreamFilterParent.h" |
34 | | #include "mozilla/Mutex.h" |
35 | | #include "nsITabParent.h" |
36 | | |
37 | | class nsDNSPrefetch; |
38 | | class nsICancelable; |
39 | | class nsIHttpChannelAuthProvider; |
40 | | class nsInputStreamPump; |
41 | | class nsITransportSecurityInfo; |
42 | | |
43 | | namespace mozilla { namespace net { |
44 | | |
45 | | class nsChannelClassifier; |
46 | | class Http2PushedStream; |
47 | | |
48 | | class HttpChannelSecurityWarningReporter : public nsISupports |
49 | | { |
50 | | public: |
51 | | virtual MOZ_MUST_USE nsresult |
52 | | ReportSecurityMessage(const nsAString& aMessageTag, |
53 | | const nsAString& aMessageCategory) = 0; |
54 | | virtual nsresult LogBlockedCORSRequest(const nsAString& aMessage, const nsACString& aCategory) = 0; |
55 | | }; |
56 | | |
57 | | //----------------------------------------------------------------------------- |
58 | | // nsHttpChannel |
59 | | //----------------------------------------------------------------------------- |
60 | | |
61 | | // Use to support QI nsIChannel to nsHttpChannel |
62 | | #define NS_HTTPCHANNEL_IID \ |
63 | | { \ |
64 | | 0x301bf95b, \ |
65 | | 0x7bb3, \ |
66 | | 0x4ae1, \ |
67 | | {0xa9, 0x71, 0x40, 0xbc, 0xfa, 0x81, 0xde, 0x12} \ |
68 | | } |
69 | | |
70 | | class nsHttpChannel final : public HttpBaseChannel |
71 | | , public HttpAsyncAborter<nsHttpChannel> |
72 | | , public nsIStreamListener |
73 | | , public nsICachingChannel |
74 | | , public nsICacheEntryOpenCallback |
75 | | , public nsITransportEventSink |
76 | | , public nsIProtocolProxyCallback |
77 | | , public nsIHttpAuthenticableChannel |
78 | | , public nsIApplicationCacheChannel |
79 | | , public nsIAsyncVerifyRedirectCallback |
80 | | , public nsIThreadRetargetableRequest |
81 | | , public nsIThreadRetargetableStreamListener |
82 | | , public nsIDNSListener |
83 | | , public nsSupportsWeakReference |
84 | | , public nsICorsPreflightCallback |
85 | | , public nsIChannelWithDivertableParentListener |
86 | | , public nsIRaceCacheWithNetwork |
87 | | , public nsIRequestTailUnblockCallback |
88 | | , public nsITimerCallback |
89 | | { |
90 | | public: |
91 | | NS_DECL_ISUPPORTS_INHERITED |
92 | | NS_DECL_NSIREQUESTOBSERVER |
93 | | NS_DECL_NSISTREAMLISTENER |
94 | | NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER |
95 | | NS_DECL_NSICACHEINFOCHANNEL |
96 | | NS_DECL_NSICACHINGCHANNEL |
97 | | NS_DECL_NSICACHEENTRYOPENCALLBACK |
98 | | NS_DECL_NSITRANSPORTEVENTSINK |
99 | | NS_DECL_NSIPROTOCOLPROXYCALLBACK |
100 | | NS_DECL_NSIPROXIEDCHANNEL |
101 | | NS_DECL_NSIAPPLICATIONCACHECONTAINER |
102 | | NS_DECL_NSIAPPLICATIONCACHECHANNEL |
103 | | NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK |
104 | | NS_DECL_NSITHREADRETARGETABLEREQUEST |
105 | | NS_DECL_NSIDNSLISTENER |
106 | | NS_DECL_NSICHANNELWITHDIVERTABLEPARENTLISTENER |
107 | | NS_DECLARE_STATIC_IID_ACCESSOR(NS_HTTPCHANNEL_IID) |
108 | | NS_DECL_NSIRACECACHEWITHNETWORK |
109 | | NS_DECL_NSITIMERCALLBACK |
110 | | NS_DECL_NSIREQUESTTAILUNBLOCKCALLBACK |
111 | | |
112 | | // nsIHttpAuthenticableChannel. We can't use |
113 | | // NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and |
114 | | // others. |
115 | | NS_IMETHOD GetIsSSL(bool *aIsSSL) override; |
116 | | NS_IMETHOD GetProxyMethodIsConnect(bool *aProxyMethodIsConnect) override; |
117 | | NS_IMETHOD GetServerResponseHeader(nsACString & aServerResponseHeader) override; |
118 | | NS_IMETHOD GetProxyChallenges(nsACString & aChallenges) override; |
119 | | NS_IMETHOD GetWWWChallenges(nsACString & aChallenges) override; |
120 | | NS_IMETHOD SetProxyCredentials(const nsACString & aCredentials) override; |
121 | | NS_IMETHOD SetWWWCredentials(const nsACString & aCredentials) override; |
122 | | NS_IMETHOD OnAuthAvailable() override; |
123 | | NS_IMETHOD OnAuthCancelled(bool userCancel) override; |
124 | | NS_IMETHOD CloseStickyConnection() override; |
125 | | NS_IMETHOD ConnectionRestartable(bool) override; |
126 | | // Functions we implement from nsIHttpAuthenticableChannel but are |
127 | | // declared in HttpBaseChannel must be implemented in this class. We |
128 | | // just call the HttpBaseChannel:: impls. |
129 | | NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags) override; |
130 | | NS_IMETHOD GetURI(nsIURI **aURI) override; |
131 | | NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks) override; |
132 | | NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup) override; |
133 | | NS_IMETHOD GetRequestMethod(nsACString& aMethod) override; |
134 | | |
135 | | nsHttpChannel(); |
136 | | |
137 | | virtual MOZ_MUST_USE nsresult Init(nsIURI *aURI, uint32_t aCaps, |
138 | | nsProxyInfo *aProxyInfo, |
139 | | uint32_t aProxyResolveFlags, |
140 | | nsIURI *aProxyURI, |
141 | | uint64_t aChannelId) override; |
142 | | |
143 | | MOZ_MUST_USE nsresult OnPush(const nsACString &uri, |
144 | | Http2PushedStream *pushedStream); |
145 | | |
146 | | static bool IsRedirectStatus(uint32_t status); |
147 | | static bool WillRedirect(nsHttpResponseHead * response); |
148 | | |
149 | | |
150 | | // Methods HttpBaseChannel didn't implement for us or that we override. |
151 | | // |
152 | | // nsIRequest |
153 | | NS_IMETHOD Cancel(nsresult status) override; |
154 | | NS_IMETHOD Suspend() override; |
155 | | NS_IMETHOD Resume() override; |
156 | | // nsIChannel |
157 | | NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override; |
158 | | NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) override; |
159 | | NS_IMETHOD AsyncOpen2(nsIStreamListener *aListener) override; |
160 | | // nsIHttpChannel |
161 | | NS_IMETHOD GetEncodedBodySize(uint64_t *aEncodedBodySize) override; |
162 | | // nsIHttpChannelInternal |
163 | | NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey) override; |
164 | | NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override; |
165 | | NS_IMETHOD GetNavigationStartTimeStamp(TimeStamp* aTimeStamp) override; |
166 | | NS_IMETHOD SetNavigationStartTimeStamp(TimeStamp aTimeStamp) override; |
167 | | NS_IMETHOD CancelForTrackingProtection() override; |
168 | | // nsISupportsPriority |
169 | | NS_IMETHOD SetPriority(int32_t value) override; |
170 | | // nsIClassOfService |
171 | | NS_IMETHOD SetClassFlags(uint32_t inFlags) override; |
172 | | NS_IMETHOD AddClassFlags(uint32_t inFlags) override; |
173 | | NS_IMETHOD ClearClassFlags(uint32_t inFlags) override; |
174 | | |
175 | | // nsIResumableChannel |
176 | | NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override; |
177 | | |
178 | | NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) override; |
179 | | NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup) override; |
180 | | // nsITimedChannel |
181 | | NS_IMETHOD GetDomainLookupStart(mozilla::TimeStamp *aDomainLookupStart) override; |
182 | | NS_IMETHOD GetDomainLookupEnd(mozilla::TimeStamp *aDomainLookupEnd) override; |
183 | | NS_IMETHOD GetConnectStart(mozilla::TimeStamp *aConnectStart) override; |
184 | | NS_IMETHOD GetTcpConnectEnd(mozilla::TimeStamp *aTcpConnectEnd) override; |
185 | | NS_IMETHOD GetSecureConnectionStart(mozilla::TimeStamp *aSecureConnectionStart) override; |
186 | | NS_IMETHOD GetConnectEnd(mozilla::TimeStamp *aConnectEnd) override; |
187 | | NS_IMETHOD GetRequestStart(mozilla::TimeStamp *aRequestStart) override; |
188 | | NS_IMETHOD GetResponseStart(mozilla::TimeStamp *aResponseStart) override; |
189 | | NS_IMETHOD GetResponseEnd(mozilla::TimeStamp *aResponseEnd) override; |
190 | | // nsICorsPreflightCallback |
191 | | NS_IMETHOD OnPreflightSucceeded() override; |
192 | | NS_IMETHOD OnPreflightFailed(nsresult aError) override; |
193 | | |
194 | | MOZ_MUST_USE nsresult |
195 | | AddSecurityMessage(const nsAString& aMessageTag, |
196 | | const nsAString& aMessageCategory) override; |
197 | | NS_IMETHOD LogBlockedCORSRequest(const nsAString& aMessage, const nsACString& aCategory) override; |
198 | | |
199 | | void SetWarningReporter(HttpChannelSecurityWarningReporter *aReporter); |
200 | | HttpChannelSecurityWarningReporter* GetWarningReporter(); |
201 | | public: /* internal necko use only */ |
202 | | |
203 | | uint32_t GetRequestTime() const |
204 | 0 | { |
205 | 0 | return mRequestTime; |
206 | 0 | } |
207 | | |
208 | | MOZ_MUST_USE nsresult OpenCacheEntry(bool usingSSL); |
209 | | MOZ_MUST_USE nsresult OpenCacheEntryInternal(bool isHttps, |
210 | | nsIApplicationCache *applicationCache, |
211 | | bool noAppCache); |
212 | | MOZ_MUST_USE nsresult ContinueConnect(); |
213 | | |
214 | | MOZ_MUST_USE nsresult StartRedirectChannelToURI(nsIURI *, uint32_t); |
215 | | |
216 | | // This allows cache entry to be marked as foreign even after channel itself |
217 | | // is gone. Needed for e10s (see HttpChannelParent::RecvDocumentChannelCleanup) |
218 | | class OfflineCacheEntryAsForeignMarker { |
219 | | nsCOMPtr<nsIApplicationCache> mApplicationCache; |
220 | | nsCOMPtr<nsIURI> mCacheURI; |
221 | | public: |
222 | | OfflineCacheEntryAsForeignMarker(nsIApplicationCache* appCache, |
223 | | nsIURI* aURI) |
224 | | : mApplicationCache(appCache) |
225 | | , mCacheURI(aURI) |
226 | 0 | {} |
227 | | |
228 | | nsresult MarkAsForeign(); |
229 | | }; |
230 | | |
231 | | OfflineCacheEntryAsForeignMarker* GetOfflineCacheEntryAsForeignMarker(); |
232 | | |
233 | | // Helper to keep cache callbacks wait flags consistent |
234 | | class AutoCacheWaitFlags |
235 | | { |
236 | | public: |
237 | | explicit AutoCacheWaitFlags(nsHttpChannel* channel) |
238 | | : mChannel(channel) |
239 | | , mKeep(0) |
240 | 0 | { |
241 | 0 | // Flags must be set before entering any AsyncOpenCacheEntry call. |
242 | 0 | mChannel->mCacheEntriesToWaitFor = |
243 | 0 | nsHttpChannel::WAIT_FOR_CACHE_ENTRY | |
244 | 0 | nsHttpChannel::WAIT_FOR_OFFLINE_CACHE_ENTRY; |
245 | 0 | } |
246 | | |
247 | | void Keep(uint32_t flags) |
248 | 0 | { |
249 | 0 | // Called after successful call to appropriate AsyncOpenCacheEntry call. |
250 | 0 | mKeep |= flags; |
251 | 0 | } |
252 | | |
253 | | ~AutoCacheWaitFlags() |
254 | 0 | { |
255 | 0 | // Keep only flags those are left to be wait for. |
256 | 0 | mChannel->mCacheEntriesToWaitFor &= mKeep; |
257 | 0 | } |
258 | | |
259 | | private: |
260 | | nsHttpChannel* mChannel; |
261 | | uint32_t mKeep : 2; |
262 | | }; |
263 | | |
264 | | bool AwaitingCacheCallbacks(); |
265 | | void SetCouldBeSynthesized(); |
266 | | |
267 | | // Return true if the latest ODA is invoked by mCachePump. |
268 | | // Should only be called on the same thread as ODA. |
269 | 0 | bool IsReadingFromCache() const { return mIsReadingFromCache; } |
270 | | |
271 | | base::ProcessId ProcessId(); |
272 | | |
273 | | MOZ_MUST_USE bool AttachStreamFilter(ipc::Endpoint<extensions::PStreamFilterParent>&& aEndpoint); |
274 | | |
275 | | private: // used for alternate service validation |
276 | | RefPtr<TransactionObserver> mTransactionObserver; |
277 | | public: |
278 | | void SetConnectionInfo(nsHttpConnectionInfo *); // clones the argument |
279 | 0 | void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; } |
280 | 0 | TransactionObserver *GetTransactionObserver() { return mTransactionObserver; } |
281 | | |
282 | | typedef MozPromise<nsCOMPtr<nsITabParent>, nsresult, false> TabPromise; |
283 | 0 | already_AddRefed<TabPromise> TakeRedirectTabPromise() { return mRedirectTabPromise.forget(); } |
284 | 0 | uint64_t CrossProcessRedirectIdentifier() { return mCrossProcessRedirectIdentifier; } |
285 | | |
286 | | protected: |
287 | | virtual ~nsHttpChannel(); |
288 | | |
289 | | private: |
290 | | typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result); |
291 | | |
292 | | bool RequestIsConditional(); |
293 | | void HandleContinueCancelledByTrackingProtection(); |
294 | | nsresult CancelInternal(nsresult status); |
295 | | void ContinueCancelledByTrackingProtection(); |
296 | | |
297 | | // Connections will only be established in this function. |
298 | | // (including DNS prefetch and speculative connection.) |
299 | | nsresult BeginConnectActual(); |
300 | | |
301 | | // We might synchronously or asynchronously call BeginConnectActual, |
302 | | // which includes DNS prefetch and speculative connection, according to |
303 | | // whether an async tracker lookup is required. If the tracker lookup |
304 | | // is required, this funciton will just return NS_OK and BeginConnectActual() |
305 | | // will be called when callback. See Bug 1325054 for more information. |
306 | | nsresult BeginConnect(); |
307 | | MOZ_MUST_USE nsresult ContinueBeginConnectWithResult(); |
308 | | void ContinueBeginConnect(); |
309 | | MOZ_MUST_USE nsresult PrepareToConnect(); |
310 | | void HandleOnBeforeConnect(); |
311 | | MOZ_MUST_USE nsresult OnBeforeConnect(); |
312 | | void OnBeforeConnectContinue(); |
313 | | MOZ_MUST_USE nsresult Connect(); |
314 | | void SpeculativeConnect(); |
315 | | MOZ_MUST_USE nsresult SetupTransaction(); |
316 | | MOZ_MUST_USE nsresult CallOnStartRequest(); |
317 | | MOZ_MUST_USE nsresult ProcessResponse(); |
318 | | void AsyncContinueProcessResponse(); |
319 | | MOZ_MUST_USE nsresult ContinueProcessResponse1(); |
320 | | MOZ_MUST_USE nsresult ContinueProcessResponse2(nsresult); |
321 | | MOZ_MUST_USE nsresult ContinueProcessResponse3(nsresult); |
322 | | MOZ_MUST_USE nsresult ProcessNormal(); |
323 | | MOZ_MUST_USE nsresult ContinueProcessNormal(nsresult); |
324 | | void ProcessAltService(); |
325 | | bool ShouldBypassProcessNotModified(); |
326 | | MOZ_MUST_USE nsresult ProcessNotModified(); |
327 | | MOZ_MUST_USE nsresult AsyncProcessRedirection(uint32_t httpStatus); |
328 | | MOZ_MUST_USE nsresult ContinueProcessRedirection(nsresult); |
329 | | MOZ_MUST_USE nsresult ContinueProcessRedirectionAfterFallback(nsresult); |
330 | | MOZ_MUST_USE nsresult ProcessFailedProxyConnect(uint32_t httpStatus); |
331 | | MOZ_MUST_USE nsresult ProcessFallback(bool *waitingForRedirectCallback); |
332 | | MOZ_MUST_USE nsresult ContinueProcessFallback(nsresult); |
333 | | void HandleAsyncAbort(); |
334 | | MOZ_MUST_USE nsresult EnsureAssocReq(); |
335 | | void ProcessSSLInformation(); |
336 | | bool IsHTTPS(); |
337 | | |
338 | | MOZ_MUST_USE nsresult ContinueOnStartRequest1(nsresult); |
339 | | MOZ_MUST_USE nsresult ContinueOnStartRequest2(nsresult); |
340 | | MOZ_MUST_USE nsresult ContinueOnStartRequest3(nsresult); |
341 | | |
342 | | void OnClassOfServiceUpdated(); |
343 | | |
344 | | // redirection specific methods |
345 | | void HandleAsyncRedirect(); |
346 | | void HandleAsyncAPIRedirect(); |
347 | | MOZ_MUST_USE nsresult ContinueHandleAsyncRedirect(nsresult); |
348 | | void HandleAsyncNotModified(); |
349 | | void HandleAsyncFallback(); |
350 | | MOZ_MUST_USE nsresult ContinueHandleAsyncFallback(nsresult); |
351 | | MOZ_MUST_USE nsresult PromptTempRedirect(); |
352 | | virtual MOZ_MUST_USE nsresult |
353 | | SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod, |
354 | | uint32_t redirectFlags) override; |
355 | | nsresult StartCrossProcessRedirect(); |
356 | | |
357 | | // proxy specific methods |
358 | | MOZ_MUST_USE nsresult ProxyFailover(); |
359 | | MOZ_MUST_USE nsresult AsyncDoReplaceWithProxy(nsIProxyInfo *); |
360 | | MOZ_MUST_USE nsresult ContinueDoReplaceWithProxy(nsresult); |
361 | | MOZ_MUST_USE nsresult ResolveProxy(); |
362 | | |
363 | | // cache specific methods |
364 | | MOZ_MUST_USE nsresult |
365 | | OnOfflineCacheEntryAvailable(nsICacheEntry *aEntry, bool aNew, |
366 | | nsIApplicationCache* aAppCache, |
367 | | nsresult aResult); |
368 | | MOZ_MUST_USE nsresult OnNormalCacheEntryAvailable(nsICacheEntry *aEntry, |
369 | | bool aNew, |
370 | | nsresult aResult); |
371 | | MOZ_MUST_USE nsresult OpenOfflineCacheEntryForWriting(); |
372 | | MOZ_MUST_USE nsresult |
373 | | OnOfflineCacheEntryForWritingAvailable(nsICacheEntry *aEntry, |
374 | | nsIApplicationCache* aAppCache, |
375 | | nsresult aResult); |
376 | | MOZ_MUST_USE nsresult |
377 | | OnCacheEntryAvailableInternal(nsICacheEntry *entry, bool aNew, |
378 | | nsIApplicationCache* aAppCache, |
379 | | nsresult status); |
380 | | MOZ_MUST_USE nsresult GenerateCacheKey(uint32_t postID, nsACString &key); |
381 | | MOZ_MUST_USE nsresult UpdateExpirationTime(); |
382 | | MOZ_MUST_USE nsresult CheckPartial(nsICacheEntry* aEntry, int64_t *aSize, int64_t *aContentLength); |
383 | | bool ShouldUpdateOfflineCacheEntry(); |
384 | | MOZ_MUST_USE nsresult ReadFromCache(bool alreadyMarkedValid); |
385 | | void CloseCacheEntry(bool doomOnFailure); |
386 | | void CloseOfflineCacheEntry(); |
387 | | MOZ_MUST_USE nsresult InitCacheEntry(); |
388 | | void UpdateInhibitPersistentCachingFlag(); |
389 | | MOZ_MUST_USE nsresult InitOfflineCacheEntry(); |
390 | | MOZ_MUST_USE nsresult AddCacheEntryHeaders(nsICacheEntry *entry); |
391 | | MOZ_MUST_USE nsresult FinalizeCacheEntry(); |
392 | | MOZ_MUST_USE nsresult InstallCacheListener(int64_t offset = 0); |
393 | | MOZ_MUST_USE nsresult InstallOfflineCacheListener(int64_t offset = 0); |
394 | | void MaybeInvalidateCacheEntryForSubsequentGet(); |
395 | | void AsyncOnExamineCachedResponse(); |
396 | | |
397 | | // Handle the bogus Content-Encoding Apache sometimes sends |
398 | | void ClearBogusContentEncodingIfNeeded(); |
399 | | |
400 | | // byte range request specific methods |
401 | | MOZ_MUST_USE nsresult ProcessPartialContent(); |
402 | | MOZ_MUST_USE nsresult OnDoneReadingPartialCacheEntry(bool *streamDone); |
403 | | |
404 | | MOZ_MUST_USE nsresult DoAuthRetry(nsAHttpConnection *); |
405 | | |
406 | | void HandleAsyncRedirectChannelToHttps(); |
407 | | MOZ_MUST_USE nsresult StartRedirectChannelToHttps(); |
408 | | MOZ_MUST_USE nsresult ContinueAsyncRedirectChannelToURI(nsresult rv); |
409 | | MOZ_MUST_USE nsresult OpenRedirectChannel(nsresult rv); |
410 | | |
411 | | /** |
412 | | * A function that takes care of reading STS and PKP headers and enforcing |
413 | | * STS and PKP load rules. After a secure channel is erected, STS and PKP |
414 | | * requires the channel to be trusted or any STS or PKP header data on |
415 | | * the channel is ignored. This is called from ProcessResponse. |
416 | | */ |
417 | | MOZ_MUST_USE nsresult ProcessSecurityHeaders(); |
418 | | |
419 | | /** |
420 | | * Taking care of the Content-Signature header and fail the channel if |
421 | | * the signature verification fails or is required but the header is not |
422 | | * present. |
423 | | * This sets mListener to ContentVerifier, which buffers the entire response |
424 | | * before verifying the Content-Signature header. If the verification is |
425 | | * successful, the load proceeds as usual. If the verification fails, a |
426 | | * NS_ERROR_INVALID_SIGNATURE is thrown and a fallback loaded in nsDocShell |
427 | | */ |
428 | | MOZ_MUST_USE nsresult |
429 | | ProcessContentSignatureHeader(nsHttpResponseHead *aResponseHead); |
430 | | |
431 | | /** |
432 | | * A function that will, if the feature is enabled, send security reports. |
433 | | */ |
434 | | void ProcessSecurityReport(nsresult status); |
435 | | |
436 | | /** |
437 | | * A function to process a single security header (STS or PKP), assumes |
438 | | * some basic sanity checks have been applied to the channel. Called |
439 | | * from ProcessSecurityHeaders. |
440 | | */ |
441 | | MOZ_MUST_USE nsresult ProcessSingleSecurityHeader(uint32_t aType, |
442 | | nsITransportSecurityInfo* aSecInfo, |
443 | | uint32_t aFlags); |
444 | | |
445 | | void InvalidateCacheEntryForLocation(const char *location); |
446 | | void AssembleCacheKey(const char *spec, uint32_t postID, nsACString &key); |
447 | | MOZ_MUST_USE nsresult CreateNewURI(const char *loc, nsIURI **newURI); |
448 | | void DoInvalidateCacheEntry(nsIURI* aURI); |
449 | | |
450 | | // Ref RFC2616 13.10: "invalidation... MUST only be performed if |
451 | | // the host part is the same as in the Request-URI" |
452 | 0 | inline bool HostPartIsTheSame(nsIURI *uri) { |
453 | 0 | nsAutoCString tmpHost1, tmpHost2; |
454 | 0 | return (NS_SUCCEEDED(mURI->GetAsciiHost(tmpHost1)) && |
455 | 0 | NS_SUCCEEDED(uri->GetAsciiHost(tmpHost2)) && |
456 | 0 | (tmpHost1 == tmpHost2)); |
457 | 0 | } |
458 | | |
459 | 0 | inline static bool DoNotRender3xxBody(nsresult rv) { |
460 | 0 | return rv == NS_ERROR_REDIRECT_LOOP || |
461 | 0 | rv == NS_ERROR_CORRUPTED_CONTENT || |
462 | 0 | rv == NS_ERROR_UNKNOWN_PROTOCOL || |
463 | 0 | rv == NS_ERROR_MALFORMED_URI; |
464 | 0 | } |
465 | | |
466 | | // Report net vs cache time telemetry |
467 | | void ReportNetVSCacheTelemetry(); |
468 | | int64_t ComputeTelemetryBucketNumber(int64_t difftime_ms); |
469 | | |
470 | | // Report telemetry and stats to about:networking |
471 | | void ReportRcwnStats(bool isFromNet); |
472 | | |
473 | | // Create a aggregate set of the current notification callbacks |
474 | | // and ensure the transaction is updated to use it. |
475 | | void UpdateAggregateCallbacks(); |
476 | | |
477 | | static bool HasQueryString(nsHttpRequestHead::ParsedMethodType method, nsIURI * uri); |
478 | | bool ResponseWouldVary(nsICacheEntry* entry); |
479 | | bool IsResumable(int64_t partialLen, int64_t contentLength, |
480 | | bool ignoreMissingPartialLen = false) const; |
481 | | MOZ_MUST_USE nsresult |
482 | | MaybeSetupByteRangeRequest(int64_t partialLen, int64_t contentLength, |
483 | | bool ignoreMissingPartialLen = false); |
484 | | MOZ_MUST_USE nsresult SetupByteRangeRequest(int64_t partialLen); |
485 | | void UntieByteRangeRequest(); |
486 | | void UntieValidationRequest(); |
487 | | MOZ_MUST_USE nsresult OpenCacheInputStream(nsICacheEntry* cacheEntry, |
488 | | bool startBuffering, |
489 | | bool checkingAppCacheEntry); |
490 | | |
491 | | void SetPushedStream(Http2PushedStream *stream); |
492 | | |
493 | | void MaybeWarnAboutAppCache(); |
494 | | |
495 | | void SetLoadGroupUserAgentOverride(); |
496 | | |
497 | | void SetOriginHeader(); |
498 | | void SetDoNotTrack(); |
499 | | |
500 | | already_AddRefed<nsChannelClassifier> GetOrCreateChannelClassifier(); |
501 | | |
502 | | // Start an internal redirect to a new InterceptedHttpChannel which will |
503 | | // resolve in firing a ServiceWorker FetchEvent. |
504 | | MOZ_MUST_USE nsresult RedirectToInterceptedChannel(); |
505 | | |
506 | | private: |
507 | | // this section is for main-thread-only object |
508 | | // all the references need to be proxy released on main thread. |
509 | | nsCOMPtr<nsIApplicationCache> mApplicationCacheForWrite; |
510 | | // auth specific data |
511 | | nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider; |
512 | | nsCOMPtr<nsIURI> mRedirectURI; |
513 | | nsCOMPtr<nsIChannel> mRedirectChannel; |
514 | | nsCOMPtr<nsIChannel> mPreflightChannel; |
515 | | |
516 | | // The associated childChannel is getting relocated to another process. |
517 | | // This promise will be resolved when that process is set up. |
518 | | RefPtr<TabPromise> mRedirectTabPromise; |
519 | | // This identifier is passed to the childChannel in order to identify it. |
520 | | uint64_t mCrossProcessRedirectIdentifier = 0; |
521 | | |
522 | | // nsChannelClassifier checks this channel's URI against |
523 | | // the URI classifier service. |
524 | | // nsChannelClassifier will be invoked twice in InitLocalBlockList() and |
525 | | // BeginConnectActual(), so save the nsChannelClassifier here to keep the |
526 | | // state of whether tracking protection is enabled or not. |
527 | | RefPtr<nsChannelClassifier> mChannelClassifier; |
528 | | |
529 | | // Proxy release all members above on main thread. |
530 | | void ReleaseMainThreadOnlyReferences(); |
531 | | |
532 | | private: |
533 | | nsCOMPtr<nsICancelable> mProxyRequest; |
534 | | |
535 | | RefPtr<nsInputStreamPump> mTransactionPump; |
536 | | RefPtr<nsHttpTransaction> mTransaction; |
537 | | |
538 | | uint64_t mLogicalOffset; |
539 | | |
540 | | // cache specific data |
541 | | nsCOMPtr<nsICacheEntry> mCacheEntry; |
542 | | // This will be set during OnStopRequest() before calling CloseCacheEntry(), |
543 | | // but only if the listener wants to use alt-data (signaled by |
544 | | // HttpBaseChannel::mPreferredCachedAltDataType being not empty) |
545 | | // Needed because calling openAlternativeOutputStream needs a reference |
546 | | // to the cache entry. |
547 | | nsCOMPtr<nsICacheEntry> mAltDataCacheEntry; |
548 | | // We must close mCacheInputStream explicitly to avoid leaks. |
549 | | AutoClose<nsIInputStream> mCacheInputStream; |
550 | | RefPtr<nsInputStreamPump> mCachePump; |
551 | | nsAutoPtr<nsHttpResponseHead> mCachedResponseHead; |
552 | | nsCOMPtr<nsISupports> mCachedSecurityInfo; |
553 | | uint32_t mPostID; |
554 | | uint32_t mRequestTime; |
555 | | |
556 | | nsCOMPtr<nsICacheEntry> mOfflineCacheEntry; |
557 | | uint32_t mOfflineCacheLastModifiedTime; |
558 | | |
559 | | mozilla::TimeStamp mOnStartRequestTimestamp; |
560 | | // Timestamp of the time the channel was suspended. |
561 | | mozilla::TimeStamp mSuspendTimestamp; |
562 | | mozilla::TimeStamp mOnCacheEntryCheckTimestamp; |
563 | | #ifdef MOZ_GECKO_PROFILER |
564 | | // For the profiler markers |
565 | | mozilla::TimeStamp mLastStatusReported; |
566 | | #endif |
567 | | // Total time the channel spent suspended. This value is reported to |
568 | | // telemetry in nsHttpChannel::OnStartRequest(). |
569 | | uint32_t mSuspendTotalTime; |
570 | | |
571 | | // If the channel is associated with a cache, and the URI matched |
572 | | // a fallback namespace, this will hold the key for the fallback |
573 | | // cache entry. |
574 | | nsCString mFallbackKey; |
575 | | |
576 | | friend class AutoRedirectVetoNotifier; |
577 | | friend class HttpAsyncAborter<nsHttpChannel>; |
578 | | |
579 | | uint32_t mRedirectType; |
580 | | |
581 | | static const uint32_t WAIT_FOR_CACHE_ENTRY = 1; |
582 | | static const uint32_t WAIT_FOR_OFFLINE_CACHE_ENTRY = 2; |
583 | | |
584 | | bool mCacheOpenWithPriority; |
585 | | uint32_t mCacheQueueSizeWhenOpen; |
586 | | |
587 | | // state flags |
588 | | uint32_t mCachedContentIsValid : 1; |
589 | | uint32_t mCachedContentIsPartial : 1; |
590 | | uint32_t mCacheOnlyMetadata : 1; |
591 | | uint32_t mTransactionReplaced : 1; |
592 | | uint32_t mAuthRetryPending : 1; |
593 | | uint32_t mProxyAuthPending : 1; |
594 | | // Set if before the first authentication attempt a custom authorization |
595 | | // header has been set on the channel. This will make that custom header |
596 | | // go to the server instead of any cached credentials. |
597 | | uint32_t mCustomAuthHeader : 1; |
598 | | uint32_t mResuming : 1; |
599 | | uint32_t mInitedCacheEntry : 1; |
600 | | // True if we are loading a fallback cache entry from the |
601 | | // application cache. |
602 | | uint32_t mFallbackChannel : 1; |
603 | | // True if consumer added its own If-None-Match or If-Modified-Since |
604 | | // headers. In such a case we must not override them in the cache code |
605 | | // and also we want to pass possible 304 code response through. |
606 | | uint32_t mCustomConditionalRequest : 1; |
607 | | uint32_t mFallingBack : 1; |
608 | | uint32_t mWaitingForRedirectCallback : 1; |
609 | | // True if mRequestTime has been set. In such a case it is safe to update |
610 | | // the cache entry's expiration time. Otherwise, it is not(see bug 567360). |
611 | | uint32_t mRequestTimeInitialized : 1; |
612 | | uint32_t mCacheEntryIsReadOnly : 1; |
613 | | uint32_t mCacheEntryIsWriteOnly : 1; |
614 | | // see WAIT_FOR_* constants above |
615 | | uint32_t mCacheEntriesToWaitFor : 2; |
616 | | uint32_t mHasQueryString : 1; |
617 | | // whether cache entry data write was in progress during cache entry check |
618 | | // when true, after we finish read from cache we must check all data |
619 | | // had been loaded from cache. If not, then an error has to be propagated |
620 | | // to the consumer. |
621 | | uint32_t mConcurrentCacheAccess : 1; |
622 | | // whether the request is setup be byte-range |
623 | | uint32_t mIsPartialRequest : 1; |
624 | | // true iff there is AutoRedirectVetoNotifier on the stack |
625 | | uint32_t mHasAutoRedirectVetoNotifier : 1; |
626 | | // consumers set this to true to use cache pinning, this has effect |
627 | | // only when the channel is in an app context (load context has an appid) |
628 | | uint32_t mPinCacheContent : 1; |
629 | | // True if CORS preflight has been performed |
630 | | uint32_t mIsCorsPreflightDone : 1; |
631 | | |
632 | | // if the http transaction was performed (i.e. not cached) and |
633 | | // the result in OnStopRequest was known to be correctly delimited |
634 | | // by chunking, content-length, or h2 end-stream framing |
635 | | uint32_t mStronglyFramed : 1; |
636 | | |
637 | | // true if an HTTP transaction is created for the socket thread |
638 | | uint32_t mUsedNetwork : 1; |
639 | | |
640 | | // the next authentication request can be sent on a whole new connection |
641 | | uint32_t mAuthConnectionRestartable : 1; |
642 | | |
643 | | // True if the channel classifier has marked the channel to be cancelled |
644 | | // due to the tracking protection rules, but the asynchronous cancellation |
645 | | // process hasn't finished yet. |
646 | | uint32_t mTrackingProtectionCancellationPending : 1; |
647 | | |
648 | | nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack; |
649 | | |
650 | | // Needed for accurate DNS timing |
651 | | RefPtr<nsDNSPrefetch> mDNSPrefetch; |
652 | | |
653 | | Http2PushedStream *mPushedStream; |
654 | | // True if the channel's principal was found on a phishing, malware, or |
655 | | // tracking (if tracking protection is enabled) blocklist |
656 | | bool mLocalBlocklist; |
657 | | |
658 | | MOZ_MUST_USE nsresult WaitForRedirectCallback(); |
659 | | void PushRedirectAsyncFunc(nsContinueRedirectionFunc func); |
660 | | void PopRedirectAsyncFunc(nsContinueRedirectionFunc func); |
661 | | |
662 | | // If this resource is eligible for tailing based on class-of-service flags |
663 | | // and load flags. We don't tail Leaders/Unblocked/UrgentStart and top-level |
664 | | // loads. |
665 | | bool EligibleForTailing(); |
666 | | |
667 | | // Called exclusively only from AsyncOpen or after all classification callbacks. |
668 | | // If this channel is 1) Tail, 2) assigned a request context, 3) the context is |
669 | | // still in the tail-blocked phase, then the method will queue this channel. |
670 | | // OnTailUnblock will be called after the context is tail-unblocked or canceled. |
671 | | bool WaitingForTailUnblock(); |
672 | | |
673 | | // A function we trigger when untail callback is triggered by our request |
674 | | // context in case this channel was tail-blocked. |
675 | | nsresult (nsHttpChannel::*mOnTailUnblock)(); |
676 | | // Called on untail when tailed during AsyncOpen execution. |
677 | | nsresult AsyncOpenOnTailUnblock(); |
678 | | // Called on untail when tailed because of being a tracking resource. |
679 | | nsresult ConnectOnTailUnblock(); |
680 | | |
681 | | // Check if current channel should be canceled by FastBlock rules. |
682 | | bool CheckFastBlocked(); |
683 | | |
684 | | nsCString mUsername; |
685 | | |
686 | | // If non-null, warnings should be reported to this object. |
687 | | RefPtr<HttpChannelSecurityWarningReporter> mWarningReporter; |
688 | | |
689 | | RefPtr<ADivertableParentChannel> mParentChannel; |
690 | | |
691 | | // True if the channel is reading from cache. |
692 | | Atomic<bool> mIsReadingFromCache; |
693 | | |
694 | | // These next members are only used in unit tests to delay the call to |
695 | | // cache->AsyncOpenURI in order to race the cache with the network. |
696 | | nsCOMPtr<nsITimer> mCacheOpenTimer; |
697 | | std::function<void(nsHttpChannel*)> mCacheOpenFunc; |
698 | | uint32_t mCacheOpenDelay = 0; |
699 | | |
700 | | // We need to remember which is the source of the response we are using. |
701 | | enum ResponseSource { |
702 | | RESPONSE_PENDING = 0, // response is pending |
703 | | RESPONSE_FROM_CACHE = 1, // response coming from cache. no network. |
704 | | RESPONSE_FROM_NETWORK = 2 // response coming from the network |
705 | | }; |
706 | | Atomic<ResponseSource, Relaxed> mFirstResponseSource; |
707 | | |
708 | | // Determines if it's possible and advisable to race the network request |
709 | | // with the cache fetch, and proceeds to do so. |
710 | | nsresult MaybeRaceCacheWithNetwork(); |
711 | | |
712 | | nsresult TriggerNetworkWithDelay(uint32_t aDelay); |
713 | | nsresult TriggerNetwork(); |
714 | | void CancelNetworkRequest(nsresult aStatus); |
715 | | // Timer used to delay the network request, or to trigger the network |
716 | | // request if retrieving the cache entry takes too long. |
717 | | nsCOMPtr<nsITimer> mNetworkTriggerTimer; |
718 | | // Is true if the network request has been triggered. |
719 | | bool mNetworkTriggered = false; |
720 | | bool mWaitingForProxy = false; |
721 | | // Will be true if the onCacheEntryAvailable callback is not called by the |
722 | | // time we send the network request |
723 | | Atomic<bool> mRaceCacheWithNetwork; |
724 | | uint32_t mRaceDelay; |
725 | | // If true then OnCacheEntryAvailable should ignore the entry, because |
726 | | // SetupTransaction removed conditional headers and decisions made in |
727 | | // OnCacheEntryCheck are no longer valid. |
728 | | bool mIgnoreCacheEntry; |
729 | | // Lock preventing OnCacheEntryCheck and SetupTransaction being called at |
730 | | // the same time. |
731 | | mozilla::Mutex mRCWNLock; |
732 | | |
733 | | TimeStamp mNavigationStartTimeStamp; |
734 | | |
735 | | protected: |
736 | | virtual void DoNotifyListenerCleanup() override; |
737 | | |
738 | | // Override ReleaseListeners() because mChannelClassifier only exists |
739 | | // in nsHttpChannel and it will be released in ReleaseListeners(). |
740 | | virtual void ReleaseListeners() override; |
741 | | |
742 | | virtual void DoAsyncAbort(nsresult aStatus) override; |
743 | | |
744 | | private: // cache telemetry |
745 | | bool mDidReval; |
746 | | }; |
747 | | |
748 | | NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpChannel, NS_HTTPCHANNEL_IID) |
749 | | } // namespace net |
750 | | } // namespace mozilla |
751 | | |
752 | | #endif // nsHttpChannel_h__ |