Bug 1481252 - Part 1: Report FastBlock status to docshell; r=valentin

Differential Revision: https://phabricator.services.mozilla.com/D3024

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Liang-Heng Chen 2018-08-16 15:29:22 +00:00
parent 411a3a427b
commit 6c9d7c21d6
7 changed files with 124 additions and 5 deletions

View file

@ -630,6 +630,8 @@ LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
if (!aLoadInfo) { if (!aLoadInfo) {
*aForwarderArgsOut = ParentLoadInfoForwarderArgs(false, void_t(), *aForwarderArgsOut = ParentLoadInfoForwarderArgs(false, void_t(),
nsILoadInfo::TAINTING_BASIC, nsILoadInfo::TAINTING_BASIC,
false,
false,
false); false);
return; return;
} }
@ -643,11 +645,18 @@ LoadInfoToParentLoadInfoForwarder(nsILoadInfo* aLoadInfo,
uint32_t tainting = nsILoadInfo::TAINTING_BASIC; uint32_t tainting = nsILoadInfo::TAINTING_BASIC;
Unused << aLoadInfo->GetTainting(&tainting); Unused << aLoadInfo->GetTainting(&tainting);
bool isTracker;
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->GetIsTracker(&isTracker));
bool isTrackerBlocked;
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked));
*aForwarderArgsOut = ParentLoadInfoForwarderArgs( *aForwarderArgsOut = ParentLoadInfoForwarderArgs(
aLoadInfo->GetAllowInsecureRedirectToDataURI(), aLoadInfo->GetAllowInsecureRedirectToDataURI(),
ipcController, ipcController,
tainting, tainting,
aLoadInfo->GetServiceWorkerTaintingSynthesized() aLoadInfo->GetServiceWorkerTaintingSynthesized(),
isTracker,
isTrackerBlocked
); );
} }
@ -679,6 +688,9 @@ MergeParentLoadInfoForwarder(ParentLoadInfoForwarderArgs const& aForwarderArgs,
aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting()); aLoadInfo->MaybeIncreaseTainting(aForwarderArgs.tainting());
} }
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTracker(aForwarderArgs.isTracker()));
MOZ_ALWAYS_SUCCEEDS(aLoadInfo->SetIsTrackerBlocked(aForwarderArgs.isTrackerBlocked()));
return NS_OK; return NS_OK;
} }

View file

@ -87,6 +87,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mIsPreflight(false) , mIsPreflight(false)
, mLoadTriggeredFromExternal(false) , mLoadTriggeredFromExternal(false)
, mServiceWorkerTaintingSynthesized(false) , mServiceWorkerTaintingSynthesized(false)
, mIsTracker(false)
, mIsTrackerBlocked(false)
{ {
MOZ_ASSERT(mLoadingPrincipal); MOZ_ASSERT(mLoadingPrincipal);
MOZ_ASSERT(mTriggeringPrincipal); MOZ_ASSERT(mTriggeringPrincipal);
@ -322,6 +324,8 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
, mIsPreflight(false) , mIsPreflight(false)
, mLoadTriggeredFromExternal(false) , mLoadTriggeredFromExternal(false)
, mServiceWorkerTaintingSynthesized(false) , mServiceWorkerTaintingSynthesized(false)
, mIsTracker(false)
, mIsTrackerBlocked(false)
{ {
// Top-level loads are never third-party // Top-level loads are never third-party
// Grab the information we can out of the window. // Grab the information we can out of the window.
@ -419,6 +423,8 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal) , mLoadTriggeredFromExternal(rhs.mLoadTriggeredFromExternal)
// mServiceWorkerTaintingSynthesized must be handled specially during redirect // mServiceWorkerTaintingSynthesized must be handled specially during redirect
, mServiceWorkerTaintingSynthesized(false) , mServiceWorkerTaintingSynthesized(false)
, mIsTracker(rhs.mIsTracker)
, mIsTrackerBlocked(rhs.mIsTrackerBlocked)
{ {
} }
@ -506,6 +512,8 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mIsPreflight(aIsPreflight) , mIsPreflight(aIsPreflight)
, mLoadTriggeredFromExternal(aLoadTriggeredFromExternal) , mLoadTriggeredFromExternal(aLoadTriggeredFromExternal)
, mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized) , mServiceWorkerTaintingSynthesized(aServiceWorkerTaintingSynthesized)
, mIsTracker(false)
, mIsTrackerBlocked(false)
{ {
// Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal // Only top level TYPE_DOCUMENT loads can have a null loadingPrincipal
MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT); MOZ_ASSERT(mLoadingPrincipal || aContentPolicyType == nsIContentPolicy::TYPE_DOCUMENT);
@ -1328,6 +1336,36 @@ LoadInfo::SynthesizeServiceWorkerTainting(LoadTainting aTainting)
mServiceWorkerTaintingSynthesized = true; mServiceWorkerTaintingSynthesized = true;
} }
NS_IMETHODIMP
LoadInfo::GetIsTracker(bool *aIsTracker)
{
MOZ_ASSERT(aIsTracker);
*aIsTracker = mIsTracker;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetIsTracker(bool aIsTracker)
{
mIsTracker = aIsTracker;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetIsTrackerBlocked(bool *aIsTrackerBlocked)
{
MOZ_ASSERT(aIsTrackerBlocked);
*aIsTrackerBlocked = mIsTrackerBlocked;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetIsTrackerBlocked(bool aIsTrackerBlocked)
{
mIsTrackerBlocked = aIsTrackerBlocked;
return NS_OK;
}
NS_IMETHODIMP NS_IMETHODIMP
LoadInfo::GetIsTopLevelLoad(bool *aResult) LoadInfo::GetIsTopLevelLoad(bool *aResult)
{ {

View file

@ -208,6 +208,9 @@ private:
bool mIsPreflight; bool mIsPreflight;
bool mLoadTriggeredFromExternal; bool mLoadTriggeredFromExternal;
bool mServiceWorkerTaintingSynthesized; bool mServiceWorkerTaintingSynthesized;
bool mIsTracker;
bool mIsTrackerBlocked;
}; };
} // namespace net } // namespace net

View file

@ -1051,4 +1051,11 @@ interface nsILoadInfo : nsISupports
*/ */
[noscript, nostdcall, notxpcom] [noscript, nostdcall, notxpcom]
void SynthesizeServiceWorkerTainting(in LoadTainting aTainting); void SynthesizeServiceWorkerTainting(in LoadTainting aTainting);
/**
* These flags are used for FastBlock statistics to see if a resource is a
* tracker and whether it was blocked by the FastBlock mechanism or not.
*/
[infallible] attribute boolean isTracker;
[infallible] attribute boolean isTrackerBlocked;
}; };

View file

@ -143,6 +143,10 @@ struct ParentLoadInfoForwarderArgs
// by the service worker. // by the service worker.
bool serviceWorkerTaintingSynthesized; bool serviceWorkerTaintingSynthesized;
// Tracker information, currently used by FastBlock
bool isTracker;
bool isTrackerBlocked;
// IMPORTANT: when you add new properites here you must also update // IMPORTANT: when you add new properites here you must also update
// LoadInfoToParentLoadInfoForwarder and MergeParentLoadInfoForwarder // LoadInfoToParentLoadInfoForwarder and MergeParentLoadInfoForwarder
// in BackgroundUtils.cpp/.h! // in BackgroundUtils.cpp/.h!

View file

@ -696,6 +696,38 @@ public:
NS_IMPL_ISUPPORTS(SyntheticDiversionListener, nsIStreamListener); NS_IMPL_ISUPPORTS(SyntheticDiversionListener, nsIStreamListener);
static nsresult
GetTopDocument(nsIChannel* aChannel, nsIDocument** aResult)
{
nsresult rv;
nsCOMPtr<mozIThirdPartyUtil> thirdPartyUtil = services::GetThirdPartyUtil();
if (NS_WARN_IF(!thirdPartyUtil)) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<mozIDOMWindowProxy> win;
rv = thirdPartyUtil->GetTopWindowForChannel(aChannel,
getter_AddRefs(win));
if (NS_WARN_IF(NS_FAILED(rv))) {
return rv;
}
auto* pwin = nsPIDOMWindowOuter::From(win);
nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
if (!docShell) {
return NS_ERROR_FAILURE;
}
nsCOMPtr<nsIDocument> doc = docShell->GetDocument();
if (!doc) {
return NS_ERROR_FAILURE;
}
doc.forget(aResult);
return NS_OK;
}
void void
HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext) HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
{ {
@ -713,6 +745,23 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
static_cast<nsIChannel*>(this)); static_cast<nsIChannel*>(this));
} }
bool isTracker;
if (NS_SUCCEEDED(mLoadInfo->GetIsTracker(&isTracker)) && isTracker) {
bool isTrackerBlocked;
Unused << mLoadInfo->GetIsTrackerBlocked(&isTrackerBlocked);
LOG(("HttpChannelChild::DoOnStartRequest FastBlock %d [this=%p]\n",
isTrackerBlocked,
this));
nsCOMPtr<nsIDocument> doc;
if (!NS_WARN_IF(NS_FAILED(GetTopDocument(this,
getter_AddRefs(doc))))) {
doc->IncrementTrackerCount(isTrackerBlocked);
}
}
nsresult rv = mListener->OnStartRequest(aRequest, aContext); nsresult rv = mListener->OnStartRequest(aRequest, aContext);
if (NS_FAILED(rv)) { if (NS_FAILED(rv)) {
Cancel(rv); Cancel(rv);

View file

@ -701,12 +701,18 @@ nsHttpChannel::CheckFastBlocked()
} }
TimeDuration duration = TimeStamp::NowLoRes() - timestamp; TimeDuration duration = TimeStamp::NowLoRes() - timestamp;
if (duration.ToMilliseconds() < sFastBlockTimeout) { bool isFastBlocking = duration.ToMilliseconds() >= sFastBlockTimeout;
return false;
if (mLoadInfo) {
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTracker(true));
MOZ_ALWAYS_SUCCEEDS(mLoadInfo->SetIsTrackerBlocked(isFastBlocking));
} }
LOG(("FastBlock timeout (%lf) [this=%p]\n", duration.ToMilliseconds(), this)); LOG(("FastBlock %s (%lf) [this=%p]\n",
return true; isFastBlocking ? "timeout" : "passed",
duration.ToMilliseconds(),
this));
return isFastBlocking;
} }
bool bool