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

View file

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

View file

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

View file

@ -1051,4 +1051,11 @@ interface nsILoadInfo : nsISupports
*/
[noscript, nostdcall, notxpcom]
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.
bool serviceWorkerTaintingSynthesized;
// Tracker information, currently used by FastBlock
bool isTracker;
bool isTrackerBlocked;
// IMPORTANT: when you add new properites here you must also update
// LoadInfoToParentLoadInfoForwarder and MergeParentLoadInfoForwarder
// in BackgroundUtils.cpp/.h!

View file

@ -696,6 +696,38 @@ public:
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
HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
{
@ -713,6 +745,23 @@ HttpChannelChild::DoOnStartRequest(nsIRequest* aRequest, nsISupports* aContext)
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);
if (NS_FAILED(rv)) {
Cancel(rv);

View file

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