From 2f578529eadbe17fe1fa41107bbc3ad42fb75aef Mon Sep 17 00:00:00 2001 From: Mihai Alexandru Michis Date: Tue, 16 Jul 2019 00:15:17 +0300 Subject: [PATCH] Backed out changeset 91f2821b4bfa (bug 1563313) for xpcshell failures CLOSED TREE --- modules/libpref/init/StaticPrefList.h | 7 ++ netwerk/protocol/http/nsHttpChannel.cpp | 134 +++++++++++++++--------- netwerk/protocol/http/nsHttpChannel.h | 8 +- 3 files changed, 93 insertions(+), 56 deletions(-) diff --git a/modules/libpref/init/StaticPrefList.h b/modules/libpref/init/StaticPrefList.h index 67d9c9db08dc..c2b985265ae1 100644 --- a/modules/libpref/init/StaticPrefList.h +++ b/modules/libpref/init/StaticPrefList.h @@ -6989,6 +6989,13 @@ VARCACHE_PREF( RelaxedAtomicBool, false ) +VARCACHE_PREF( + Live, + "network.delay.tracking.load", + network_delay_tracking_load, + uint32_t, 0 +) + // Max time to shutdown the resolver threads VARCACHE_PREF( Live, diff --git a/netwerk/protocol/http/nsHttpChannel.cpp b/netwerk/protocol/http/nsHttpChannel.cpp index c65738bf0236..bf31dad56753 100644 --- a/netwerk/protocol/http/nsHttpChannel.cpp +++ b/netwerk/protocol/http/nsHttpChannel.cpp @@ -6495,6 +6495,8 @@ nsHttpChannel::AsyncOpen(nsIStreamListener* aListener) { nsresult nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp) { // Added due to PauseTask/DelayHttpChannel + nsresult rv; + if (mLoadGroup) mLoadGroup->AddRequest(this, nullptr); // record asyncopen time unconditionally and clear it if we @@ -6509,39 +6511,6 @@ nsresult nsHttpChannel::AsyncOpenFinal(TimeStamp aTimeStamp) { // just once and early, AsyncOpen is the best place. mCustomAuthHeader = mRequestHead.HasHeader(nsHttp::Authorization); - if (!NS_ShouldClassifyChannel(this)) { - return MaybeResolveProxyAndBeginConnect(); - } - - // We are about to do an async lookup to check if the URI is a tracker. If - // yes, this channel will be canceled by channel classifier. Chances are the - // lookup is not needed so CheckIsTrackerWithLocalTable() will return an - // error and then we can MaybeResolveProxyAndBeginConnect() right away. - RefPtr self = this; - bool willCallback = NS_SUCCEEDED( - AsyncUrlChannelClassifier::CheckChannel(this, [self]() -> void { - nsresult rv = self->MaybeResolveProxyAndBeginConnect(); - if (NS_FAILED(rv)) { - // Since this error is thrown asynchronously so that the caller - // of BeginConnect() will not do clean up for us. We have to do - // it on our own. - self->CloseCacheEntry(false); - Unused << self->AsyncAbort(rv); - } - })); - - if (!willCallback) { - // We can do MaybeResolveProxyAndBeginConnect immediately if - // CheckIsTrackerWithLocalTable is failed. Note that we don't need to - // handle the failure because BeginConnect() will return synchronously and - // the caller will be responsible for handling it. - return MaybeResolveProxyAndBeginConnect(); - } - - return NS_OK; -} - -nsresult nsHttpChannel::MaybeResolveProxyAndBeginConnect() { // The common case for HTTP channels is to begin proxy resolution and return // at this point. The only time we know mProxyInfo already is if we're // proxying a non-http protocol like ftp. We don't need to discover proxy @@ -6552,7 +6521,7 @@ nsresult nsHttpChannel::MaybeResolveProxyAndBeginConnect() { return NS_OK; } - nsresult rv = BeginConnect(); + rv = BeginConnect(); if (NS_FAILED(rv)) { CloseCacheEntry(false); Unused << AsyncAbort(rv); @@ -6770,30 +6739,57 @@ nsresult nsHttpChannel::BeginConnect() { return mStatus; } - if (mChannelClassifierCancellationPending) { - LOG( - ("Waiting for safe-browsing protection cancellation in BeginConnect " - "[this=%p]\n", - this)); - return NS_OK; + if (!NS_ShouldClassifyChannel(this)) { + MaybeStartDNSPrefetch(); + return ContinueBeginConnectWithResult(); } - ReEvaluateReferrerAfterTrackingStatusIsKnown(); + // We are about to do an async lookup to check if the URI is a + // tracker. If yes, this channel will be canceled by channel classifier. + // Chances are the lookup is not needed so CheckIsTrackerWithLocalTable() + // will return an error and then we can BeginConnectActual() right away. + RefPtr self = this; + bool willCallback = NS_SUCCEEDED( + AsyncUrlChannelClassifier::CheckChannel(this, [self]() -> void { + auto nextFunc = [self]() -> void { + nsresult rv = self->BeginConnectActual(); + if (NS_FAILED(rv)) { + // Since this error is thrown asynchronously so that the caller + // of BeginConnect() will not do clean up for us. We have to do + // it on our own. + self->CloseCacheEntry(false); + Unused << self->AsyncAbort(rv); + } + }; - MaybeStartDNSPrefetch(); + uint32_t delayMillisec = StaticPrefs::network_delay_tracking_load(); + if (self->IsThirdPartyTrackingResource() && delayMillisec) { + nsCOMPtr runnable = NS_NewRunnableFunction( + "nsHttpChannel::BeginConnect-delayed", nextFunc); + nsresult rv = NS_DelayedDispatchToCurrentThread(runnable.forget(), + delayMillisec); + if (NS_SUCCEEDED(rv)) { + LOG( + ("nsHttpChannel::BeginConnect delaying 3rd-party tracking " + "resource for %u ms [this=%p]", + delayMillisec, self.get())); + return; + } + LOG(("nsHttpChannel::BeginConnect unable to delay loading. [this=%p]", + self.get())); + } - rv = ContinueBeginConnectWithResult(); - if (NS_FAILED(rv)) { - return rv; + nextFunc(); + })); + + if (!willCallback) { + // We can do BeginConnectActual immediately if CheckIsTrackerWithLocalTable + // is failed. Note that we don't need to handle the failure because + // BeginConnect() will return synchronously and the caller will be + // responsible for handling it. + return BeginConnectActual(); } - // Start nsChannelClassifier to catch phishing and malware URIs. - RefPtr channelClassifier = - GetOrCreateChannelClassifier(); - LOG(("nsHttpChannel::Starting nsChannelClassifier %p [this=%p]", - channelClassifier.get(), this)); - channelClassifier->Start(); - return NS_OK; } @@ -6823,6 +6819,40 @@ void nsHttpChannel::MaybeStartDNSPrefetch() { } } +nsresult nsHttpChannel::BeginConnectActual() { + if (mCanceled) { + return mStatus; + } + + AUTO_PROFILER_LABEL("nsHttpChannel::BeginConnectActual", NETWORK); + + if (mChannelClassifierCancellationPending) { + LOG( + ("Waiting for safe-browsing protection cancellation in " + "BeginConnectActual [this=%p]\n", + this)); + return NS_OK; + } + + ReEvaluateReferrerAfterTrackingStatusIsKnown(); + + MaybeStartDNSPrefetch(); + + nsresult rv = ContinueBeginConnectWithResult(); + if (NS_FAILED(rv)) { + return rv; + } + + // Start nsChannelClassifier to catch phishing and malware URIs. + RefPtr channelClassifier = + GetOrCreateChannelClassifier(); + LOG(("nsHttpChannel::Starting nsChannelClassifier %p [this=%p]", + channelClassifier.get(), this)); + channelClassifier->Start(); + + return NS_OK; +} + NS_IMETHODIMP nsHttpChannel::GetEncodedBodySize(uint64_t* aEncodedBodySize) { if (mCacheEntry && !mCacheEntryIsWriteOnly) { diff --git a/netwerk/protocol/http/nsHttpChannel.h b/netwerk/protocol/http/nsHttpChannel.h index 3b0e876174af..035378e6516c 100644 --- a/netwerk/protocol/http/nsHttpChannel.h +++ b/netwerk/protocol/http/nsHttpChannel.h @@ -316,13 +316,13 @@ class nsHttpChannel final : public HttpBaseChannel, // Connections will only be established in this function. // (including DNS prefetch and speculative connection.) - nsresult MaybeResolveProxyAndBeginConnect(); + nsresult BeginConnectActual(); void MaybeStartDNSPrefetch(); - // We might synchronously or asynchronously call BeginConnect, + // We might synchronously or asynchronously call BeginConnectActual, // which includes DNS prefetch and speculative connection, according to // whether an async tracker lookup is required. If the tracker lookup - // is required, this funciton will just return NS_OK and BeginConnect() + // is required, this funciton will just return NS_OK and BeginConnectActual() // will be called when callback. See Bug 1325054 for more information. nsresult BeginConnect(); MOZ_MUST_USE nsresult ContinueBeginConnectWithResult(); @@ -587,7 +587,7 @@ class nsHttpChannel final : public HttpBaseChannel, // nsChannelClassifier checks this channel's URI against // the URI classifier service. // nsChannelClassifier will be invoked twice in InitLocalBlockList() and - // BeginConnect(), so save the nsChannelClassifier here to keep the + // BeginConnectActual(), so save the nsChannelClassifier here to keep the // state of whether tracking protection is enabled or not. RefPtr mChannelClassifier;