Line data Source code
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 "nsIHstsPrimingCallback.h"
33 : #include "nsIRaceCacheWithNetwork.h"
34 :
35 : class nsDNSPrefetch;
36 : class nsICancelable;
37 : class nsIHttpChannelAuthProvider;
38 : class nsInputStreamPump;
39 : class nsISSLStatus;
40 :
41 : namespace mozilla { namespace net {
42 :
43 : class nsChannelClassifier;
44 : class Http2PushedStream;
45 :
46 3 : class HttpChannelSecurityWarningReporter
47 : {
48 : public:
49 : virtual MOZ_MUST_USE nsresult
50 : ReportSecurityMessage(const nsAString& aMessageTag,
51 : const nsAString& aMessageCategory) = 0;
52 : };
53 :
54 : //-----------------------------------------------------------------------------
55 : // nsHttpChannel
56 : //-----------------------------------------------------------------------------
57 :
58 : // Use to support QI nsIChannel to nsHttpChannel
59 : #define NS_HTTPCHANNEL_IID \
60 : { \
61 : 0x301bf95b, \
62 : 0x7bb3, \
63 : 0x4ae1, \
64 : {0xa9, 0x71, 0x40, 0xbc, 0xfa, 0x81, 0xde, 0x12} \
65 : }
66 :
67 : class nsHttpChannel final : public HttpBaseChannel
68 : , public HttpAsyncAborter<nsHttpChannel>
69 : , public nsIStreamListener
70 : , public nsICachingChannel
71 : , public nsICacheEntryOpenCallback
72 : , public nsITransportEventSink
73 : , public nsIProtocolProxyCallback
74 : , public nsIInputAvailableCallback
75 : , public nsIHttpAuthenticableChannel
76 : , public nsIApplicationCacheChannel
77 : , public nsIAsyncVerifyRedirectCallback
78 : , public nsIThreadRetargetableRequest
79 : , public nsIThreadRetargetableStreamListener
80 : , public nsIDNSListener
81 : , public nsSupportsWeakReference
82 : , public nsICorsPreflightCallback
83 : , public nsIChannelWithDivertableParentListener
84 : , public nsIHstsPrimingCallback
85 : , public nsIRaceCacheWithNetwork
86 : , public nsITimerCallback
87 : {
88 : public:
89 : NS_DECL_ISUPPORTS_INHERITED
90 : NS_DECL_NSIREQUESTOBSERVER
91 : NS_DECL_NSISTREAMLISTENER
92 : NS_DECL_NSITHREADRETARGETABLESTREAMLISTENER
93 : NS_DECL_NSICACHEINFOCHANNEL
94 : NS_DECL_NSICACHINGCHANNEL
95 : NS_DECL_NSICACHEENTRYOPENCALLBACK
96 : NS_DECL_NSITRANSPORTEVENTSINK
97 : NS_DECL_NSIPROTOCOLPROXYCALLBACK
98 : NS_DECL_NSIINPUTAVAILABLECALLBACK
99 : NS_DECL_NSIPROXIEDCHANNEL
100 : NS_DECL_NSIAPPLICATIONCACHECONTAINER
101 : NS_DECL_NSIAPPLICATIONCACHECHANNEL
102 : NS_DECL_NSIASYNCVERIFYREDIRECTCALLBACK
103 : NS_DECL_NSIHSTSPRIMINGCALLBACK
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 :
111 : // nsIHttpAuthenticableChannel. We can't use
112 : // NS_DECL_NSIHTTPAUTHENTICABLECHANNEL because it duplicates cancel() and
113 : // others.
114 : NS_IMETHOD GetIsSSL(bool *aIsSSL) override;
115 : NS_IMETHOD GetProxyMethodIsConnect(bool *aProxyMethodIsConnect) override;
116 : NS_IMETHOD GetServerResponseHeader(nsACString & aServerResponseHeader) override;
117 : NS_IMETHOD GetProxyChallenges(nsACString & aChallenges) override;
118 : NS_IMETHOD GetWWWChallenges(nsACString & aChallenges) override;
119 : NS_IMETHOD SetProxyCredentials(const nsACString & aCredentials) override;
120 : NS_IMETHOD SetWWWCredentials(const nsACString & aCredentials) override;
121 : NS_IMETHOD OnAuthAvailable() override;
122 : NS_IMETHOD OnAuthCancelled(bool userCancel) override;
123 : NS_IMETHOD CloseStickyConnection() override;
124 : NS_IMETHOD ConnectionRestartable(bool) override;
125 : // Functions we implement from nsIHttpAuthenticableChannel but are
126 : // declared in HttpBaseChannel must be implemented in this class. We
127 : // just call the HttpBaseChannel:: impls.
128 : NS_IMETHOD GetLoadFlags(nsLoadFlags *aLoadFlags) override;
129 : NS_IMETHOD GetURI(nsIURI **aURI) override;
130 : NS_IMETHOD GetNotificationCallbacks(nsIInterfaceRequestor **aCallbacks) override;
131 : NS_IMETHOD GetLoadGroup(nsILoadGroup **aLoadGroup) override;
132 : NS_IMETHOD GetRequestMethod(nsACString& aMethod) override;
133 :
134 : nsHttpChannel();
135 :
136 : virtual MOZ_MUST_USE nsresult Init(nsIURI *aURI, uint32_t aCaps,
137 : nsProxyInfo *aProxyInfo,
138 : uint32_t aProxyResolveFlags,
139 : nsIURI *aProxyURI,
140 : uint64_t aChannelId) override;
141 :
142 : MOZ_MUST_USE nsresult OnPush(const nsACString &uri,
143 : Http2PushedStream *pushedStream);
144 :
145 : static bool IsRedirectStatus(uint32_t status);
146 : static bool WillRedirect(nsHttpResponseHead * response);
147 :
148 :
149 : // Methods HttpBaseChannel didn't implement for us or that we override.
150 : //
151 : // nsIRequest
152 : NS_IMETHOD Cancel(nsresult status) override;
153 : NS_IMETHOD Suspend() override;
154 : NS_IMETHOD Resume() override;
155 : // nsIChannel
156 : NS_IMETHOD GetSecurityInfo(nsISupports **aSecurityInfo) override;
157 : NS_IMETHOD AsyncOpen(nsIStreamListener *listener, nsISupports *aContext) override;
158 : NS_IMETHOD AsyncOpen2(nsIStreamListener *aListener) override;
159 : // nsIHttpChannel
160 : NS_IMETHOD GetEncodedBodySize(uint64_t *aEncodedBodySize) override;
161 : // nsIHttpChannelInternal
162 : NS_IMETHOD SetupFallbackChannel(const char *aFallbackKey) override;
163 : NS_IMETHOD ForceIntercepted(uint64_t aInterceptionID) override;
164 : NS_IMETHOD SetChannelIsForDownload(bool aChannelIsForDownload) override;
165 : // nsISupportsPriority
166 : NS_IMETHOD SetPriority(int32_t value) override;
167 : // nsIClassOfService
168 : NS_IMETHOD SetClassFlags(uint32_t inFlags) override;
169 : NS_IMETHOD AddClassFlags(uint32_t inFlags) override;
170 : NS_IMETHOD ClearClassFlags(uint32_t inFlags) override;
171 :
172 : // nsIResumableChannel
173 : NS_IMETHOD ResumeAt(uint64_t startPos, const nsACString& entityID) override;
174 :
175 : NS_IMETHOD SetNotificationCallbacks(nsIInterfaceRequestor *aCallbacks) override;
176 : NS_IMETHOD SetLoadGroup(nsILoadGroup *aLoadGroup) override;
177 : // nsITimedChannel
178 : NS_IMETHOD GetDomainLookupStart(mozilla::TimeStamp *aDomainLookupStart) override;
179 : NS_IMETHOD GetDomainLookupEnd(mozilla::TimeStamp *aDomainLookupEnd) override;
180 : NS_IMETHOD GetConnectStart(mozilla::TimeStamp *aConnectStart) override;
181 : NS_IMETHOD GetConnectEnd(mozilla::TimeStamp *aConnectEnd) override;
182 : NS_IMETHOD GetRequestStart(mozilla::TimeStamp *aRequestStart) override;
183 : NS_IMETHOD GetResponseStart(mozilla::TimeStamp *aResponseStart) override;
184 : NS_IMETHOD GetResponseEnd(mozilla::TimeStamp *aResponseEnd) override;
185 : // nsICorsPreflightCallback
186 : NS_IMETHOD OnPreflightSucceeded() override;
187 : NS_IMETHOD OnPreflightFailed(nsresult aError) override;
188 :
189 : MOZ_MUST_USE nsresult
190 : AddSecurityMessage(const nsAString& aMessageTag,
191 : const nsAString& aMessageCategory) override;
192 :
193 3 : void SetWarningReporter(HttpChannelSecurityWarningReporter* aReporter)
194 3 : { mWarningReporter = aReporter; }
195 :
196 : public: /* internal necko use only */
197 :
198 : using InitLocalBlockListCallback = std::function<void(bool)>;
199 :
200 0 : void InternalSetUploadStream(nsIInputStream *uploadStream)
201 0 : { mUploadStream = uploadStream; }
202 0 : void SetUploadStreamHasHeaders(bool hasHeaders)
203 0 : { mUploadStreamHasHeaders = hasHeaders; }
204 :
205 : MOZ_MUST_USE nsresult
206 2 : SetReferrerWithPolicyInternal(nsIURI *referrer, uint32_t referrerPolicy) {
207 4 : nsAutoCString spec;
208 2 : nsresult rv = referrer->GetAsciiSpec(spec);
209 2 : if (NS_FAILED(rv)) return rv;
210 2 : mReferrer = referrer;
211 2 : mReferrerPolicy = referrerPolicy;
212 2 : rv = mRequestHead.SetHeader(nsHttp::Referer, spec);
213 2 : return rv;
214 : }
215 :
216 2 : MOZ_MUST_USE nsresult SetTopWindowURI(nsIURI* aTopWindowURI) {
217 2 : mTopWindowURI = aTopWindowURI;
218 2 : return NS_OK;
219 : }
220 :
221 1 : uint32_t GetRequestTime() const
222 : {
223 1 : return mRequestTime;
224 : }
225 :
226 : MOZ_MUST_USE nsresult OpenCacheEntry(bool usingSSL);
227 : MOZ_MUST_USE nsresult ContinueConnect();
228 :
229 : // If the load is mixed-content, build and send an HSTS priming request.
230 : MOZ_MUST_USE nsresult TryHSTSPriming();
231 :
232 : MOZ_MUST_USE nsresult StartRedirectChannelToURI(nsIURI *, uint32_t);
233 :
234 : // This allows cache entry to be marked as foreign even after channel itself
235 : // is gone. Needed for e10s (see HttpChannelParent::RecvDocumentChannelCleanup)
236 0 : class OfflineCacheEntryAsForeignMarker {
237 : nsCOMPtr<nsIApplicationCache> mApplicationCache;
238 : nsCOMPtr<nsIURI> mCacheURI;
239 : public:
240 0 : OfflineCacheEntryAsForeignMarker(nsIApplicationCache* appCache,
241 : nsIURI* aURI)
242 0 : : mApplicationCache(appCache)
243 0 : , mCacheURI(aURI)
244 0 : {}
245 :
246 : nsresult MarkAsForeign();
247 : };
248 :
249 : OfflineCacheEntryAsForeignMarker* GetOfflineCacheEntryAsForeignMarker();
250 :
251 : // Helper to keep cache callbacks wait flags consistent
252 : class AutoCacheWaitFlags
253 : {
254 : public:
255 6 : explicit AutoCacheWaitFlags(nsHttpChannel* channel)
256 6 : : mChannel(channel)
257 6 : , mKeep(0)
258 : {
259 : // Flags must be set before entering any AsyncOpenCacheEntry call.
260 6 : mChannel->mCacheEntriesToWaitFor =
261 : nsHttpChannel::WAIT_FOR_CACHE_ENTRY |
262 : nsHttpChannel::WAIT_FOR_OFFLINE_CACHE_ENTRY;
263 6 : }
264 :
265 5 : void Keep(uint32_t flags)
266 : {
267 : // Called after successful call to appropriate AsyncOpenCacheEntry call.
268 5 : mKeep |= flags;
269 5 : }
270 :
271 6 : ~AutoCacheWaitFlags()
272 6 : {
273 : // Keep only flags those are left to be wait for.
274 6 : mChannel->mCacheEntriesToWaitFor &= mKeep;
275 6 : }
276 :
277 : private:
278 : nsHttpChannel* mChannel;
279 : uint32_t mKeep : 2;
280 : };
281 :
282 : void MarkIntercepted();
283 : NS_IMETHOD GetResponseSynthesized(bool* aSynthesized) override;
284 : bool AwaitingCacheCallbacks();
285 : void SetCouldBeSynthesized();
286 :
287 : // Return true if the latest ODA is invoked by mCachePump.
288 : // Should only be called on the same thread as ODA.
289 3 : bool IsReadingFromCache() const { return mIsReadingFromCache; }
290 :
291 : private: // used for alternate service validation
292 : RefPtr<TransactionObserver> mTransactionObserver;
293 : public:
294 : void SetConnectionInfo(nsHttpConnectionInfo *); // clones the argument
295 0 : void SetTransactionObserver(TransactionObserver *arg) { mTransactionObserver = arg; }
296 : TransactionObserver *GetTransactionObserver() { return mTransactionObserver; }
297 :
298 : protected:
299 : virtual ~nsHttpChannel();
300 :
301 : private:
302 : typedef nsresult (nsHttpChannel::*nsContinueRedirectionFunc)(nsresult result);
303 :
304 : bool RequestIsConditional();
305 :
306 : // Connections will only be established in this function.
307 : // (including DNS prefetch and speculative connection.)
308 : nsresult BeginConnectActual();
309 :
310 : // We might synchronously or asynchronously call BeginConnectActual,
311 : // which includes DNS prefetch and speculative connection, according to
312 : // whether an async tracker lookup is required. If the tracker lookup
313 : // is required, this funciton will just return NS_OK and BeginConnectActual()
314 : // will be called when callback. See Bug 1325054 for more information.
315 : nsresult BeginConnect();
316 : void HandleBeginConnectContinue();
317 : MOZ_MUST_USE nsresult BeginConnectContinue();
318 : MOZ_MUST_USE nsresult ContinueBeginConnectWithResult();
319 : void ContinueBeginConnect();
320 : MOZ_MUST_USE nsresult Connect();
321 : void SpeculativeConnect();
322 : MOZ_MUST_USE nsresult SetupTransaction();
323 : void SetupTransactionRequestContext();
324 : MOZ_MUST_USE nsresult CallOnStartRequest();
325 : MOZ_MUST_USE nsresult ProcessResponse();
326 : void AsyncContinueProcessResponse();
327 : MOZ_MUST_USE nsresult ContinueProcessResponse1();
328 : MOZ_MUST_USE nsresult ContinueProcessResponse2(nsresult);
329 : MOZ_MUST_USE nsresult ContinueProcessResponse3(nsresult);
330 : MOZ_MUST_USE nsresult ProcessNormal();
331 : MOZ_MUST_USE nsresult ContinueProcessNormal(nsresult);
332 : void ProcessAltService();
333 : bool ShouldBypassProcessNotModified();
334 : MOZ_MUST_USE nsresult ProcessNotModified();
335 : MOZ_MUST_USE nsresult AsyncProcessRedirection(uint32_t httpStatus);
336 : MOZ_MUST_USE nsresult ContinueProcessRedirection(nsresult);
337 : MOZ_MUST_USE nsresult ContinueProcessRedirectionAfterFallback(nsresult);
338 : MOZ_MUST_USE nsresult ProcessFailedProxyConnect(uint32_t httpStatus);
339 : MOZ_MUST_USE nsresult ProcessFallback(bool *waitingForRedirectCallback);
340 : MOZ_MUST_USE nsresult ContinueProcessFallback(nsresult);
341 : void HandleAsyncAbort();
342 : MOZ_MUST_USE nsresult EnsureAssocReq();
343 : void ProcessSSLInformation();
344 : bool IsHTTPS();
345 :
346 : MOZ_MUST_USE nsresult ContinueOnStartRequest1(nsresult);
347 : MOZ_MUST_USE nsresult ContinueOnStartRequest2(nsresult);
348 : MOZ_MUST_USE nsresult ContinueOnStartRequest3(nsresult);
349 :
350 : void OnClassOfServiceUpdated();
351 :
352 : bool InitLocalBlockList(const InitLocalBlockListCallback& aCallback);
353 :
354 : // redirection specific methods
355 : void HandleAsyncRedirect();
356 : void HandleAsyncAPIRedirect();
357 : MOZ_MUST_USE nsresult ContinueHandleAsyncRedirect(nsresult);
358 : void HandleAsyncNotModified();
359 : void HandleAsyncFallback();
360 : MOZ_MUST_USE nsresult ContinueHandleAsyncFallback(nsresult);
361 : MOZ_MUST_USE nsresult PromptTempRedirect();
362 : virtual MOZ_MUST_USE nsresult
363 : SetupReplacementChannel(nsIURI *, nsIChannel *, bool preserveMethod,
364 : uint32_t redirectFlags) override;
365 :
366 : // proxy specific methods
367 : MOZ_MUST_USE nsresult ProxyFailover();
368 : MOZ_MUST_USE nsresult AsyncDoReplaceWithProxy(nsIProxyInfo *);
369 : MOZ_MUST_USE nsresult ContinueDoReplaceWithProxy(nsresult);
370 : MOZ_MUST_USE nsresult ResolveProxy();
371 :
372 : // cache specific methods
373 : MOZ_MUST_USE nsresult
374 : OnOfflineCacheEntryAvailable(nsICacheEntry *aEntry, bool aNew,
375 : nsIApplicationCache* aAppCache,
376 : nsresult aResult);
377 : MOZ_MUST_USE nsresult OnNormalCacheEntryAvailable(nsICacheEntry *aEntry,
378 : bool aNew,
379 : nsresult aResult);
380 : MOZ_MUST_USE nsresult OpenOfflineCacheEntryForWriting();
381 : MOZ_MUST_USE nsresult
382 : OnOfflineCacheEntryForWritingAvailable(nsICacheEntry *aEntry,
383 : nsIApplicationCache* aAppCache,
384 : nsresult aResult);
385 : MOZ_MUST_USE nsresult
386 : OnCacheEntryAvailableInternal(nsICacheEntry *entry, bool aNew,
387 : nsIApplicationCache* aAppCache,
388 : nsresult status);
389 : MOZ_MUST_USE nsresult GenerateCacheKey(uint32_t postID, nsACString &key);
390 : MOZ_MUST_USE nsresult UpdateExpirationTime();
391 : MOZ_MUST_USE nsresult CheckPartial(nsICacheEntry* aEntry, int64_t *aSize, int64_t *aContentLength);
392 : bool ShouldUpdateOfflineCacheEntry();
393 : MOZ_MUST_USE nsresult ReadFromCache(bool alreadyMarkedValid);
394 : void CloseCacheEntry(bool doomOnFailure);
395 : void CloseOfflineCacheEntry();
396 : MOZ_MUST_USE nsresult InitCacheEntry();
397 : void UpdateInhibitPersistentCachingFlag();
398 : MOZ_MUST_USE nsresult InitOfflineCacheEntry();
399 : MOZ_MUST_USE nsresult AddCacheEntryHeaders(nsICacheEntry *entry);
400 : MOZ_MUST_USE nsresult FinalizeCacheEntry();
401 : MOZ_MUST_USE nsresult InstallCacheListener(int64_t offset = 0);
402 : MOZ_MUST_USE nsresult InstallOfflineCacheListener(int64_t offset = 0);
403 : void MaybeInvalidateCacheEntryForSubsequentGet();
404 : void AsyncOnExamineCachedResponse();
405 :
406 : // Handle the bogus Content-Encoding Apache sometimes sends
407 : void ClearBogusContentEncodingIfNeeded();
408 :
409 : // byte range request specific methods
410 : MOZ_MUST_USE nsresult ProcessPartialContent();
411 : MOZ_MUST_USE nsresult OnDoneReadingPartialCacheEntry(bool *streamDone);
412 :
413 : MOZ_MUST_USE nsresult DoAuthRetry(nsAHttpConnection *);
414 :
415 : void HandleAsyncRedirectChannelToHttps();
416 : MOZ_MUST_USE nsresult StartRedirectChannelToHttps();
417 : MOZ_MUST_USE nsresult ContinueAsyncRedirectChannelToURI(nsresult rv);
418 : MOZ_MUST_USE nsresult OpenRedirectChannel(nsresult rv);
419 :
420 : void DetermineContentLength();
421 :
422 : /**
423 : * A function that takes care of reading STS and PKP headers and enforcing
424 : * STS and PKP load rules. After a secure channel is erected, STS and PKP
425 : * requires the channel to be trusted or any STS or PKP header data on
426 : * the channel is ignored. This is called from ProcessResponse.
427 : */
428 : MOZ_MUST_USE nsresult ProcessSecurityHeaders();
429 :
430 : /**
431 : * Taking care of the Content-Signature header and fail the channel if
432 : * the signature verification fails or is required but the header is not
433 : * present.
434 : * This sets mListener to ContentVerifier, which buffers the entire response
435 : * before verifying the Content-Signature header. If the verification is
436 : * successful, the load proceeds as usual. If the verification fails, a
437 : * NS_ERROR_INVALID_SIGNATURE is thrown and a fallback loaded in nsDocShell
438 : */
439 : MOZ_MUST_USE nsresult
440 : ProcessContentSignatureHeader(nsHttpResponseHead *aResponseHead);
441 :
442 : /**
443 : * A function that will, if the feature is enabled, send security reports.
444 : */
445 : void ProcessSecurityReport(nsresult status);
446 :
447 : /**
448 : * A function to process a single security header (STS or PKP), assumes
449 : * some basic sanity checks have been applied to the channel. Called
450 : * from ProcessSecurityHeaders.
451 : */
452 : MOZ_MUST_USE nsresult ProcessSingleSecurityHeader(uint32_t aType,
453 : nsISSLStatus *aSSLStatus,
454 : uint32_t aFlags);
455 :
456 : void InvalidateCacheEntryForLocation(const char *location);
457 : void AssembleCacheKey(const char *spec, uint32_t postID, nsACString &key);
458 : MOZ_MUST_USE nsresult CreateNewURI(const char *loc, nsIURI **newURI);
459 : void DoInvalidateCacheEntry(nsIURI* aURI);
460 :
461 : // Ref RFC2616 13.10: "invalidation... MUST only be performed if
462 : // the host part is the same as in the Request-URI"
463 0 : inline bool HostPartIsTheSame(nsIURI *uri) {
464 0 : nsAutoCString tmpHost1, tmpHost2;
465 0 : return (NS_SUCCEEDED(mURI->GetAsciiHost(tmpHost1)) &&
466 0 : NS_SUCCEEDED(uri->GetAsciiHost(tmpHost2)) &&
467 0 : (tmpHost1 == tmpHost2));
468 : }
469 :
470 0 : inline static bool DoNotRender3xxBody(nsresult rv) {
471 0 : return rv == NS_ERROR_REDIRECT_LOOP ||
472 0 : rv == NS_ERROR_CORRUPTED_CONTENT ||
473 0 : rv == NS_ERROR_UNKNOWN_PROTOCOL ||
474 0 : rv == NS_ERROR_MALFORMED_URI;
475 : }
476 :
477 : // Report net vs cache time telemetry
478 : void ReportNetVSCacheTelemetry();
479 : int64_t ComputeTelemetryBucketNumber(int64_t difftime_ms);
480 :
481 : // Report telemetry and stats to about:networking
482 : void ReportRcwnStats(bool isFromNet);
483 :
484 : // Create a aggregate set of the current notification callbacks
485 : // and ensure the transaction is updated to use it.
486 : void UpdateAggregateCallbacks();
487 :
488 : static bool HasQueryString(nsHttpRequestHead::ParsedMethodType method, nsIURI * uri);
489 : bool ResponseWouldVary(nsICacheEntry* entry);
490 : bool IsResumable(int64_t partialLen, int64_t contentLength,
491 : bool ignoreMissingPartialLen = false) const;
492 : MOZ_MUST_USE nsresult
493 : MaybeSetupByteRangeRequest(int64_t partialLen, int64_t contentLength,
494 : bool ignoreMissingPartialLen = false);
495 : MOZ_MUST_USE nsresult SetupByteRangeRequest(int64_t partialLen);
496 : void UntieByteRangeRequest();
497 : void UntieValidationRequest();
498 : MOZ_MUST_USE nsresult OpenCacheInputStream(nsICacheEntry* cacheEntry,
499 : bool startBuffering,
500 : bool checkingAppCacheEntry);
501 :
502 : void SetPushedStream(Http2PushedStream *stream);
503 :
504 : void MaybeWarnAboutAppCache();
505 :
506 : void SetLoadGroupUserAgentOverride();
507 :
508 : void SetDoNotTrack();
509 :
510 : already_AddRefed<nsChannelClassifier> GetOrCreateChannelClassifier();
511 :
512 : private:
513 : // this section is for main-thread-only object
514 : // all the references need to be proxy released on main thread.
515 : nsCOMPtr<nsIApplicationCache> mApplicationCacheForWrite;
516 : // auth specific data
517 : nsCOMPtr<nsIHttpChannelAuthProvider> mAuthProvider;
518 : nsCOMPtr<nsIURI> mRedirectURI;
519 : nsCOMPtr<nsIChannel> mRedirectChannel;
520 : nsCOMPtr<nsIChannel> mPreflightChannel;
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 cnannel was suspended.
561 : mozilla::TimeStamp mSuspendTimestamp;
562 : mozilla::TimeStamp mOnCacheEntryCheckTimestamp;
563 : // Total time the channel spent suspended. This value is reported to
564 : // telemetry in nsHttpChannel::OnStartRequest().
565 : uint32_t mSuspendTotalTime;
566 :
567 : // States of channel interception
568 : enum {
569 : DO_NOT_INTERCEPT, // no interception will occur
570 : MAYBE_INTERCEPT, // interception in progress, but can be cancelled
571 : INTERCEPTED, // a synthesized response has been provided
572 : } mInterceptCache;
573 : // ID of this channel for the interception purposes. Unique unless this
574 : // channel is replacing an intercepted one via an redirection.
575 : uint64_t mInterceptionID;
576 :
577 28 : bool PossiblyIntercepted() {
578 28 : return mInterceptCache != DO_NOT_INTERCEPT;
579 : }
580 :
581 : // If the channel is associated with a cache, and the URI matched
582 : // a fallback namespace, this will hold the key for the fallback
583 : // cache entry.
584 : nsCString mFallbackKey;
585 :
586 : friend class AutoRedirectVetoNotifier;
587 : friend class HttpAsyncAborter<nsHttpChannel>;
588 :
589 : uint32_t mRedirectType;
590 :
591 : static const uint32_t WAIT_FOR_CACHE_ENTRY = 1;
592 : static const uint32_t WAIT_FOR_OFFLINE_CACHE_ENTRY = 2;
593 :
594 : bool mCacheOpenWithPriority;
595 : uint32_t mCacheQueueSizeWhenOpen;
596 :
597 : // state flags
598 : uint32_t mCachedContentIsValid : 1;
599 : uint32_t mCachedContentIsPartial : 1;
600 : uint32_t mCacheOnlyMetadata : 1;
601 : uint32_t mTransactionReplaced : 1;
602 : uint32_t mAuthRetryPending : 1;
603 : uint32_t mProxyAuthPending : 1;
604 : // Set if before the first authentication attempt a custom authorization
605 : // header has been set on the channel. This will make that custom header
606 : // go to the server instead of any cached credentials.
607 : uint32_t mCustomAuthHeader : 1;
608 : uint32_t mResuming : 1;
609 : uint32_t mInitedCacheEntry : 1;
610 : // True if we are loading a fallback cache entry from the
611 : // application cache.
612 : uint32_t mFallbackChannel : 1;
613 : // True if consumer added its own If-None-Match or If-Modified-Since
614 : // headers. In such a case we must not override them in the cache code
615 : // and also we want to pass possible 304 code response through.
616 : uint32_t mCustomConditionalRequest : 1;
617 : uint32_t mFallingBack : 1;
618 : uint32_t mWaitingForRedirectCallback : 1;
619 : // True if mRequestTime has been set. In such a case it is safe to update
620 : // the cache entry's expiration time. Otherwise, it is not(see bug 567360).
621 : uint32_t mRequestTimeInitialized : 1;
622 : uint32_t mCacheEntryIsReadOnly : 1;
623 : uint32_t mCacheEntryIsWriteOnly : 1;
624 : // see WAIT_FOR_* constants above
625 : uint32_t mCacheEntriesToWaitFor : 2;
626 : uint32_t mHasQueryString : 1;
627 : // whether cache entry data write was in progress during cache entry check
628 : // when true, after we finish read from cache we must check all data
629 : // had been loaded from cache. If not, then an error has to be propagated
630 : // to the consumer.
631 : uint32_t mConcurrentCacheAccess : 1;
632 : // whether the request is setup be byte-range
633 : uint32_t mIsPartialRequest : 1;
634 : // true iff there is AutoRedirectVetoNotifier on the stack
635 : uint32_t mHasAutoRedirectVetoNotifier : 1;
636 : // consumers set this to true to use cache pinning, this has effect
637 : // only when the channel is in an app context (load context has an appid)
638 : uint32_t mPinCacheContent : 1;
639 : // True if CORS preflight has been performed
640 : uint32_t mIsCorsPreflightDone : 1;
641 :
642 : // if the http transaction was performed (i.e. not cached) and
643 : // the result in OnStopRequest was known to be correctly delimited
644 : // by chunking, content-length, or h2 end-stream framing
645 : uint32_t mStronglyFramed : 1;
646 :
647 : // true if an HTTP transaction is created for the socket thread
648 : uint32_t mUsedNetwork : 1;
649 :
650 : // the next authentication request can be sent on a whole new connection
651 : uint32_t mAuthConnectionRestartable : 1;
652 :
653 : uint32_t mReqContentLengthDetermined : 1;
654 :
655 : uint64_t mReqContentLength;
656 :
657 : nsTArray<nsContinueRedirectionFunc> mRedirectFuncStack;
658 :
659 : // Needed for accurate DNS timing
660 : RefPtr<nsDNSPrefetch> mDNSPrefetch;
661 :
662 : Http2PushedStream *mPushedStream;
663 : // True if the channel's principal was found on a phishing, malware, or
664 : // tracking (if tracking protection is enabled) blocklist
665 : bool mLocalBlocklist;
666 :
667 : MOZ_MUST_USE nsresult WaitForRedirectCallback();
668 : void PushRedirectAsyncFunc(nsContinueRedirectionFunc func);
669 : void PopRedirectAsyncFunc(nsContinueRedirectionFunc func);
670 :
671 : nsCString mUsername;
672 :
673 : // If non-null, warnings should be reported to this object.
674 : HttpChannelSecurityWarningReporter* mWarningReporter;
675 :
676 : RefPtr<ADivertableParentChannel> mParentChannel;
677 :
678 : // True if the channel is reading from cache.
679 : Atomic<bool> mIsReadingFromCache;
680 :
681 : // These next members are only used in unit tests to delay the call to
682 : // cache->AsyncOpenURI in order to race the cache with the network.
683 : nsCOMPtr<nsITimer> mCacheOpenTimer;
684 : std::function<void(nsHttpChannel*)> mCacheOpenFunc;
685 : uint32_t mCacheOpenDelay = 0;
686 :
687 : // We need to remember which is the source of the response we are using.
688 : enum {
689 : RESPONSE_PENDING, // response is pending
690 : RESPONSE_FROM_CACHE, // response coming from cache. no network.
691 : RESPONSE_FROM_NETWORK, // response coming from the network
692 : } mFirstResponseSource = RESPONSE_PENDING;
693 :
694 : // Determines if it's possible and advisable to race the network request
695 : // with the cache fetch, and proceeds to do so.
696 : nsresult MaybeRaceCacheWithNetwork();
697 :
698 : nsresult TriggerNetwork(int32_t aTimeout);
699 : void CancelNetworkRequest(nsresult aStatus);
700 : // Timer used to delay the network request, or to trigger the network
701 : // request if retrieving the cache entry takes too long.
702 : nsCOMPtr<nsITimer> mNetworkTriggerTimer;
703 : // Is true if the network request has been triggered.
704 : bool mNetworkTriggered = false;
705 : bool mWaitingForProxy = false;
706 : // Is true if the onCacheEntryAvailable callback has been called.
707 : Atomic<bool> mOnCacheAvailableCalled;
708 : // Will be true if the onCacheEntryAvailable callback is not called by the
709 : // time we send the network request
710 : Atomic<bool> mRaceCacheWithNetwork;
711 : uint32_t mRaceDelay;
712 : bool mCacheAsyncOpenCalled;
713 :
714 : protected:
715 : virtual void DoNotifyListenerCleanup() override;
716 :
717 : // Override ReleaseListeners() because mChannelClassifier only exists
718 : // in nsHttpChannel and it will be released in ReleaseListeners().
719 : virtual void ReleaseListeners() override;
720 :
721 : private: // cache telemetry
722 : bool mDidReval;
723 : };
724 :
725 : NS_DEFINE_STATIC_IID_ACCESSOR(nsHttpChannel, NS_HTTPCHANNEL_IID)
726 : } // namespace net
727 : } // namespace mozilla
728 :
729 : #endif // nsHttpChannel_h__
|