2018-12-14 14:40:17 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim:set expandtab ts=4 sw=2 sts=2 cin: */
|
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
|
|
|
|
#include "mozilla/ErrorNames.h"
|
|
|
|
#include "mozilla/net/AsyncUrlChannelClassifier.h"
|
|
|
|
#include "mozilla/net/UrlClassifierCommon.h"
|
|
|
|
#include "mozilla/net/UrlClassifierFeatureFactory.h"
|
|
|
|
#include "mozilla/net/UrlClassifierFeatureResult.h"
|
|
|
|
#include "nsContentUtils.h"
|
|
|
|
#include "nsIChannel.h"
|
|
|
|
#include "nsIHttpChannel.h"
|
|
|
|
#include "nsIHttpChannelInternal.h"
|
|
|
|
#include "nsIURIClassifier.h"
|
|
|
|
#include "nsNetCID.h"
|
|
|
|
#include "nsPrintfCString.h"
|
|
|
|
#include "nsServiceManagerUtils.h"
|
2019-01-23 14:43:15 +03:00
|
|
|
#include "nsNetUtil.h"
|
2018-12-14 14:40:17 +03:00
|
|
|
|
|
|
|
namespace mozilla {
|
|
|
|
namespace net {
|
|
|
|
|
|
|
|
namespace {
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// When we do blacklist/whitelist classification, from a list of features, we
|
|
|
|
// need to aggregate them per URI, because not all the features work with the
|
|
|
|
// same channel's URI.
|
|
|
|
// This struct contains only the features able to deal with a particular URI.
|
|
|
|
// See more in GetFeatureTasks().
|
|
|
|
struct FeatureTask {
|
2019-01-04 16:45:42 +03:00
|
|
|
nsCOMPtr<nsIURI> mURI;
|
2019-01-23 14:43:15 +03:00
|
|
|
// Let's use RefPtr<> here, because this needs to be used with methods which
|
|
|
|
// require it.
|
|
|
|
nsTArray<RefPtr<nsIUrlClassifierFeature>> mFeatures;
|
2019-01-04 16:45:42 +03:00
|
|
|
};
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// Features are able to classify particular URIs from a channel. For instance,
|
|
|
|
// tracking-annotation feature uses the top-level URI to whitelist the current
|
|
|
|
// channel's URI; flash feature always uses the channel's URI. Because of
|
|
|
|
// this, this function aggregates feature per URI in an array of FeatureTask
|
|
|
|
// object.
|
|
|
|
nsresult GetFeatureTasks(
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
const nsTArray<nsCOMPtr<nsIUrlClassifierFeature>>& aFeatures,
|
|
|
|
nsIUrlClassifierFeature::listType aListType,
|
|
|
|
nsTArray<FeatureTask>& aTasks) {
|
|
|
|
MOZ_ASSERT(!aFeatures.IsEmpty());
|
|
|
|
|
|
|
|
// Let's unify features per nsIURI.
|
|
|
|
for (nsIUrlClassifierFeature* feature : aFeatures) {
|
|
|
|
nsCOMPtr<nsIURI> uri;
|
|
|
|
nsresult rv =
|
|
|
|
feature->GetURIByListType(aChannel, aListType, getter_AddRefs(uri));
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv)) || !uri) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
nsAutoCString errorName;
|
|
|
|
GetErrorName(rv, errorName);
|
|
|
|
UC_LOG(
|
|
|
|
("GetFeatureTasks got an unexpected error (rv=%s) while trying to "
|
|
|
|
"create a whitelist URI. Allowing tracker.",
|
|
|
|
errorName.get()));
|
|
|
|
}
|
|
|
|
return rv;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
MOZ_ASSERT(uri);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
bool found = false;
|
|
|
|
for (FeatureTask& task : aTasks) {
|
|
|
|
bool equal = false;
|
|
|
|
rv = task.mURI->Equals(uri, &equal);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return rv;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (equal) {
|
|
|
|
task.mFeatures.AppendElement(feature);
|
|
|
|
found = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (!found) {
|
|
|
|
FeatureTask* task = aTasks.AppendElement();
|
|
|
|
task->mURI = uri;
|
|
|
|
task->mFeatures.AppendElement(feature);
|
|
|
|
}
|
2019-01-23 03:08:39 +03:00
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return NS_OK;
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsresult TrackerFound(
|
|
|
|
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults,
|
|
|
|
nsIChannel* aChannel, const std::function<void()>& aCallback) {
|
|
|
|
// Let's ask the features to do the magic.
|
|
|
|
for (nsIUrlClassifierFeatureResult* result : aResults) {
|
|
|
|
UrlClassifierFeatureResult* r =
|
|
|
|
static_cast<UrlClassifierFeatureResult*>(result);
|
|
|
|
|
|
|
|
bool shouldContinue = false;
|
|
|
|
nsresult rv =
|
|
|
|
r->Feature()->ProcessChannel(aChannel, r->List(), &shouldContinue);
|
|
|
|
// Don't return here! We want to process all the channel and execute the
|
|
|
|
// callback.
|
2019-01-17 11:33:25 +03:00
|
|
|
Unused << NS_WARN_IF(NS_FAILED(rv));
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (!shouldContinue) {
|
|
|
|
break;
|
|
|
|
}
|
2019-01-23 03:08:39 +03:00
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
aCallback();
|
|
|
|
return NS_OK;
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// This class is designed to get the results of checking whitelist.
|
|
|
|
class WhitelistClassifierCallback final
|
|
|
|
: public nsIUrlClassifierFeatureCallback {
|
2019-01-17 11:33:25 +03:00
|
|
|
public:
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
WhitelistClassifierCallback(
|
|
|
|
nsIChannel* aChannel,
|
|
|
|
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aBlacklistResults,
|
|
|
|
std::function<void()>& aCallback)
|
|
|
|
: mChannel(aChannel),
|
|
|
|
mTaskCount(0),
|
|
|
|
mBlacklistResults(aBlacklistResults),
|
|
|
|
mChannelCallback(aCallback) {
|
|
|
|
MOZ_ASSERT(mChannel);
|
|
|
|
MOZ_ASSERT(!mBlacklistResults.IsEmpty());
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
void SetTaskCount(uint32_t aTaskCount) {
|
|
|
|
MOZ_ASSERT(aTaskCount > 0);
|
|
|
|
mTaskCount = aTaskCount;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2018-12-14 14:40:17 +03:00
|
|
|
private:
|
2019-01-23 14:43:15 +03:00
|
|
|
~WhitelistClassifierCallback() = default;
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsresult OnClassifyCompleteInternal();
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsCOMPtr<nsIChannel> mChannel;
|
|
|
|
nsCOMPtr<nsIURI> mURI;
|
|
|
|
uint32_t mTaskCount;
|
|
|
|
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mBlacklistResults;
|
|
|
|
std::function<void()> mChannelCallback;
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mWhitelistResults;
|
2018-12-14 14:40:17 +03:00
|
|
|
};
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_IMPL_ISUPPORTS(WhitelistClassifierCallback, nsIUrlClassifierFeatureCallback)
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
WhitelistClassifierCallback::OnClassifyComplete(
|
|
|
|
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aWhitelistResults) {
|
|
|
|
MOZ_ASSERT(mTaskCount > 0);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
UC_LOG(("WhitelistClassifierCallback[%p]:OnClassifyComplete channel=%p", this,
|
|
|
|
mChannel.get()));
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
mWhitelistResults.AppendElements(aWhitelistResults);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (--mTaskCount) {
|
|
|
|
// More callbacks will come.
|
|
|
|
return NS_OK;
|
2019-01-04 16:45:42 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return OnClassifyCompleteInternal();
|
2019-01-04 16:45:42 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsresult WhitelistClassifierCallback::OnClassifyCompleteInternal() {
|
|
|
|
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> remainingResults;
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
for (nsIUrlClassifierFeatureResult* blacklistResult : mBlacklistResults) {
|
|
|
|
UrlClassifierFeatureResult* result =
|
|
|
|
static_cast<UrlClassifierFeatureResult*>(blacklistResult);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsIUrlClassifierFeature* blacklistFeature = result->Feature();
|
|
|
|
MOZ_ASSERT(blacklistFeature);
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
bool found = false;
|
|
|
|
for (nsIUrlClassifierFeatureResult* whitelistResult : mWhitelistResults) {
|
|
|
|
// We can do pointer comparison because Features are singletons.
|
|
|
|
if (static_cast<UrlClassifierFeatureResult*>(whitelistResult)
|
|
|
|
->Feature() == blacklistFeature) {
|
|
|
|
found = true;
|
|
|
|
break;
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (found) {
|
|
|
|
continue;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// Maybe we have to skip this host
|
|
|
|
nsAutoCString skipList;
|
|
|
|
nsresult rv = blacklistFeature->GetSkipHostList(skipList);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
continue;
|
2019-01-23 03:08:39 +03:00
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (nsContentUtils::IsURIInList(result->URI(), skipList)) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
UC_LOG(
|
|
|
|
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri found in "
|
|
|
|
"skiplist",
|
|
|
|
this));
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
continue;
|
|
|
|
}
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
remainingResults.AppendElement(blacklistResult);
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// Whitelist lookup results
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (remainingResults.IsEmpty()) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
2019-01-17 11:33:25 +03:00
|
|
|
UC_LOG(
|
2019-01-23 14:43:15 +03:00
|
|
|
("WhitelistClassifierCallback[%p]::OnClassifyComplete uri fully "
|
|
|
|
"whitelisted",
|
2019-01-17 11:33:25 +03:00
|
|
|
this));
|
2019-01-23 14:43:15 +03:00
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
mChannelCallback();
|
|
|
|
return NS_OK;
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (UC_LOG_ENABLED()) {
|
2018-12-14 14:40:17 +03:00
|
|
|
UC_LOG(
|
2019-01-23 14:43:15 +03:00
|
|
|
("WhitelistClassifierCallback[%p]::OnClassifyComplete channel[%p] "
|
|
|
|
"should not be whitelisted",
|
|
|
|
this, mChannel.get()));
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return TrackerFound(remainingResults, mChannel, mChannelCallback);
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// This class is designed to get the results of checking blacklist.
|
|
|
|
class BlacklistClassifierCallback final
|
|
|
|
: public nsIUrlClassifierFeatureCallback {
|
2018-12-14 14:40:17 +03:00
|
|
|
public:
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_DECL_THREADSAFE_ISUPPORTS
|
|
|
|
NS_DECL_NSIURLCLASSIFIERFEATURECALLBACK
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
BlacklistClassifierCallback(nsIChannel* aChannel,
|
|
|
|
std::function<void()>&& aCallback)
|
|
|
|
: mChannel(aChannel),
|
|
|
|
mTaskCount(0),
|
|
|
|
mChannelCallback(std::move(aCallback)) {
|
|
|
|
MOZ_ASSERT(mChannel);
|
|
|
|
}
|
2019-01-23 03:08:39 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
void SetTaskCount(uint32_t aTaskCount) {
|
|
|
|
MOZ_ASSERT(aTaskCount > 0);
|
|
|
|
mTaskCount = aTaskCount;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
|
|
|
private:
|
2019-01-23 14:43:15 +03:00
|
|
|
~BlacklistClassifierCallback() = default;
|
|
|
|
|
|
|
|
nsresult OnClassifyCompleteInternal();
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2018-12-14 14:40:17 +03:00
|
|
|
nsCOMPtr<nsIChannel> mChannel;
|
2019-01-23 14:43:15 +03:00
|
|
|
uint32_t mTaskCount;
|
|
|
|
std::function<void()> mChannelCallback;
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsTArray<RefPtr<nsIUrlClassifierFeatureResult>> mResults;
|
2018-12-14 14:40:17 +03:00
|
|
|
};
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_IMPL_ISUPPORTS(BlacklistClassifierCallback, nsIUrlClassifierFeatureCallback)
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
BlacklistClassifierCallback::OnClassifyComplete(
|
|
|
|
const nsTArray<RefPtr<nsIUrlClassifierFeatureResult>>& aResults) {
|
|
|
|
MOZ_ASSERT(mTaskCount > 0);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
UC_LOG(("BlacklistClassifierCallback[%p]:OnClassifyComplete - remaining %d",
|
|
|
|
this, mTaskCount));
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
mResults.AppendElements(aResults);
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (--mTaskCount) {
|
|
|
|
// More callbacks will come.
|
|
|
|
return NS_OK;
|
2019-01-04 16:45:42 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return OnClassifyCompleteInternal();
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsresult BlacklistClassifierCallback::OnClassifyCompleteInternal() {
|
|
|
|
// All good! The URL has not been classified.
|
|
|
|
if (mResults.IsEmpty()) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
UC_LOG(
|
|
|
|
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri not found "
|
|
|
|
"in blacklist",
|
|
|
|
this));
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
mChannelCallback();
|
|
|
|
return NS_OK;
|
2019-01-04 16:45:42 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
UC_LOG(
|
|
|
|
("BlacklistClassifierCallback[%p]::OnClassifyComplete uri is in "
|
|
|
|
"blacklist. Start checking whitelist.",
|
|
|
|
this));
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>> features;
|
|
|
|
for (nsIUrlClassifierFeatureResult* result : mResults) {
|
|
|
|
features.AppendElement(
|
|
|
|
static_cast<UrlClassifierFeatureResult*>(result)->Feature());
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsTArray<FeatureTask> tasks;
|
|
|
|
nsresult rv = GetFeatureTasks(mChannel, features,
|
|
|
|
nsIUrlClassifierFeature::whitelist, tasks);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
return TrackerFound(mResults, mChannel, mChannelCallback);
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (tasks.IsEmpty()) {
|
|
|
|
UC_LOG(
|
|
|
|
("BlacklistClassifierCallback[%p]:OnClassifyComplete could not create "
|
|
|
|
"a whitelist URI. Ignoring whitelist.",
|
|
|
|
this));
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return TrackerFound(mResults, mChannel, mChannelCallback);
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
RefPtr<WhitelistClassifierCallback> callback =
|
|
|
|
new WhitelistClassifierCallback(mChannel, mResults, mChannelCallback);
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
|
|
|
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
|
|
|
NS_ENSURE_SUCCESS(rv, rv);
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
uint32_t pendingCallbacks = 0;
|
|
|
|
for (FeatureTask& task : tasks) {
|
|
|
|
rv = uriClassifier->AsyncClassifyLocalWithFeatures(
|
|
|
|
task.mURI, task.mFeatures, nsIUrlClassifierFeature::whitelist,
|
|
|
|
callback);
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
nsAutoCString errorName;
|
|
|
|
GetErrorName(rv, errorName);
|
|
|
|
UC_LOG((
|
|
|
|
"BlacklistClassifierCallback[%p]:OnClassifyComplete Failed "
|
|
|
|
"calling AsyncClassifyLocalWithFeatures with rv=%s. Let's move on.",
|
|
|
|
this, errorName.get()));
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
continue;
|
|
|
|
}
|
2019-01-17 11:33:25 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
++pendingCallbacks;
|
2019-01-17 11:33:25 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// All the AsyncClassifyLocalWithFeatures() calls return error. We do not
|
|
|
|
// expect callbacks.
|
|
|
|
if (pendingCallbacks == 0) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
UC_LOG(
|
|
|
|
("BlacklistClassifierCallback[%p]:OnClassifyComplete All "
|
|
|
|
"AsyncClassifyLocalWithFeatures() calls return errors. We cannot "
|
|
|
|
"continue.",
|
|
|
|
this));
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
return TrackerFound(mResults, mChannel, mChannelCallback);
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// Nothing else do here. Let's wait for the WhitelistClassifierCallback.
|
|
|
|
callback->SetTaskCount(pendingCallbacks);
|
2018-12-14 14:40:17 +03:00
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace
|
|
|
|
|
|
|
|
/* static */ nsresult AsyncUrlChannelClassifier::CheckChannel(
|
|
|
|
nsIChannel* aChannel, std::function<void()>&& aCallback) {
|
|
|
|
MOZ_ASSERT(XRE_IsParentProcess());
|
|
|
|
MOZ_ASSERT(aChannel);
|
|
|
|
|
|
|
|
if (!aCallback) {
|
|
|
|
return NS_ERROR_INVALID_ARG;
|
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// We need to obtain the list of nsIUrlClassifierFeature objects able to
|
|
|
|
// classify this channel. If the list is empty, we do an early return.
|
|
|
|
nsTArray<nsCOMPtr<nsIUrlClassifierFeature>> features;
|
|
|
|
UrlClassifierFeatureFactory::GetFeaturesFromChannel(aChannel, features);
|
|
|
|
if (features.IsEmpty()) {
|
|
|
|
UC_LOG(
|
|
|
|
("AsyncUrlChannelClassifier: Nothing to do for channel %p", aChannel));
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
nsTArray<FeatureTask> tasks;
|
|
|
|
nsresult rv = GetFeatureTasks(aChannel, features,
|
|
|
|
nsIUrlClassifierFeature::blacklist, tasks);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv)) || tasks.IsEmpty()) {
|
2019-01-04 16:45:42 +03:00
|
|
|
return rv;
|
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
MOZ_ASSERT(!tasks.IsEmpty());
|
|
|
|
|
|
|
|
nsCOMPtr<nsIURIClassifier> uriClassifier =
|
|
|
|
do_GetService(NS_URICLASSIFIERSERVICE_CONTRACTID, &rv);
|
|
|
|
if (NS_FAILED(rv)) {
|
|
|
|
return rv;
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
RefPtr<BlacklistClassifierCallback> callback =
|
|
|
|
new BlacklistClassifierCallback(aChannel, std::move(aCallback));
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
uint32_t pendingCallbacks = 0;
|
|
|
|
for (FeatureTask& task : tasks) {
|
|
|
|
if (UC_LOG_ENABLED()) {
|
|
|
|
nsCString spec = task.mURI->GetSpecOrDefault();
|
|
|
|
spec.Truncate(
|
|
|
|
std::min(spec.Length(), UrlClassifierCommon::sMaxSpecLength));
|
|
|
|
UC_LOG(("AsyncUrlChannelClassifier: Checking blacklist for uri=%s\n",
|
|
|
|
spec.get()));
|
|
|
|
}
|
2019-01-04 16:45:42 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
rv = uriClassifier->AsyncClassifyLocalWithFeatures(
|
|
|
|
task.mURI, task.mFeatures, nsIUrlClassifierFeature::blacklist,
|
|
|
|
callback);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
++pendingCallbacks;
|
|
|
|
}
|
2018-12-14 14:40:17 +03:00
|
|
|
|
2019-01-23 14:43:15 +03:00
|
|
|
// All the AsyncClassifyLocalWithFeatures() calls return error. We do not
|
|
|
|
// expect callbacks.
|
|
|
|
if (pendingCallbacks == 0) {
|
|
|
|
return NS_ERROR_FAILURE;
|
|
|
|
}
|
|
|
|
|
|
|
|
callback->SetTaskCount(pendingCallbacks);
|
|
|
|
return NS_OK;
|
2018-12-14 14:40:17 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace net
|
|
|
|
} // namespace mozilla
|