Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use new Rust based ad-block library #2569

Merged
merged 9 commits into from
Jun 24, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions DEPS
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
use_relative_paths = True

deps = {
"vendor/ad-block": "https://github.com/brave/ad-block.git@3aba8df268ed735b8b6a94961dbe0e4c1cb55767",
"vendor/autoplay-whitelist": "https://github.com/brave/autoplay-whitelist.git@a85d71af4e416cf8188dc297320b0d777aafa315",
"vendor/extension-whitelist": "https://github.com/brave/extension-whitelist.git@a3a9a768900909739db99d79541fc56c2984407d",
"vendor/tracking-protection": "https://github.com/brave/tracking-protection.git@29b1f86b11a8c7438fd7d57b446a77a84946712a",
"vendor/hashset-cpp": "https://github.com/brave/hashset-cpp.git@2536f1b242fc0388b39be5cd45bfbcd563db1154",
"vendor/bloom-filter-cpp": "https://github.com/brave/bloom-filter-cpp.git@000613c53a83bf0f20c8d19f0d47ea1e192e7854",
"vendor/adblock_rust_ffi": "https://github.com/brave/adblock-rust-ffi.git@97a85bb5968a7bc73bcf97d8a232ff538e8c58eb",
"vendor/autoplay-whitelist": "https://github.com/brave/autoplay-whitelist.git@f39d83788cd12b883bfe6561cc7166b176ab9d9d",
"vendor/extension-whitelist": "https://github.com/brave/extension-whitelist.git@aa74a1bc29ced176e50db9f54946f28d82dfc795",
"vendor/tracking-protection": "https://github.com/brave/tracking-protection.git@3de744d4698b2f8fac1f52579d39f9ad154d1ec2",
"vendor/hashset-cpp": "https://github.com/brave/hashset-cpp.git@4b55fe39bb25bb0d8b11a43d547d75f00c6c46fb",
"vendor/bloom-filter-cpp": "https://github.com/brave/bloom-filter-cpp.git@9be5c63b14e094156e00c8b28f205e7794f0b92c",
"vendor/requests": "https://github.com/kennethreitz/requests@e4d59bedfd3c7f4f254f4f5d036587bcd8152458",
"vendor/boto": "https://github.com/boto/boto@f7574aa6cc2c819430c1f05e9a1a1a666ef8169b",
"vendor/python-patch": "https://github.com/techtonik/python-patch@2148d5408fafd5c05ac6854dd7deb4e8a4ca4a49",
Expand Down
3 changes: 2 additions & 1 deletion components/brave_component_updater/browser/dat_file_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ LoadDATFileDataResult<T> LoadDATFileData(
std::unique_ptr<T> client;
client = std::make_unique<T>();
if (buffer.empty() ||
!client->deserialize(reinterpret_cast<char*>(&buffer.front())))
!client->deserialize(reinterpret_cast<char*>(&buffer.front()),
buffer.size()))
client.reset();

return LoadDATFileDataResult<T>(
Expand Down
20 changes: 19 additions & 1 deletion components/brave_shields/browser/BUILD.gn
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import("//brave/components/brave_shields/browser/buildflags/buildflags.gni")
import("//extensions/buildflags/buildflags.gni")
import("//brave/vendor/adblock_rust_ffi/config.gni")

source_set("brave_shields") {
public_deps = [
"buildflags",
":adblock_libs"
]

sources = [
Expand Down Expand Up @@ -48,7 +50,7 @@ source_set("brave_shields") {
deps = [
"//brave/components/brave_component_updater/browser",
"//brave/content:common",
"//brave/vendor/ad-block/brave:ad-block",
"//brave/vendor/adblock_rust_ffi:adblock_ffi",
"//brave/vendor/tracking-protection/brave:tracking-protection",
"//brave/vendor/autoplay-whitelist/brave:autoplay-whitelist",
"//chrome/common",
Expand All @@ -69,3 +71,19 @@ source_set("brave_shields") {
]
}
}

if (is_mac) {
bundle_data("adblock_libs") {
sources = [
adblock_lib_path,
]
outputs = [
"{{bundle_contents_dir}}/Libraries/{{source_file_part}}",
]
public_deps = [
"//brave/vendor/adblock_rust_ffi:adblock",
]
}
} else {
group("adblock_libs") {}
}
99 changes: 57 additions & 42 deletions components/brave_shields/browser/ad_block_base_service.cc
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
#include "brave/common/pref_names.h"
#include "brave/components/brave_component_updater/browser/dat_file_util.h"
#include "brave/components/brave_shields/common/brave_shield_constants.h"
#include "brave/vendor/ad-block/ad_block_client.h"
#include "brave/vendor/adblock_rust_ffi/src/wrapper.hpp"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
Expand All @@ -33,53 +33,53 @@ using namespace net::registry_controlled_domains; // NOLINT

namespace {

FilterOption ResourceTypeToFilterOption(content::ResourceType resource_type) {
FilterOption filter_option = FONoFilterOption;
std::string ResourceTypeToString(content::ResourceType resource_type) {
std::string filter_option = "";
switch (resource_type) {
// top level page
case content::ResourceType::kMainFrame:
filter_option = FODocument;
filter_option = "main_frame";
break;
// frame or iframe
case content::ResourceType::kSubFrame:
filter_option = FOSubdocument;
filter_option = "sub_frame";
break;
// a CSS stylesheet
case content::ResourceType::kStylesheet:
filter_option = FOStylesheet;
filter_option = "stylesheet";
break;
// an external script
case content::ResourceType::kScript:
filter_option = FOScript;
filter_option = "script";
break;
// an image (jpg/gif/png/etc)
case content::ResourceType::kFavicon:
case content::ResourceType::kImage:
filter_option = FOImage;
filter_option = "image";
break;
// a font
case content::ResourceType::kFontResource:
filter_option = FOFont;
filter_option = "font";
break;
// an "other" subresource.
case content::ResourceType::kSubResource:
filter_option = FOOther;
filter_option = "other";
break;
// an object (or embed) tag for a plugin.
case content::ResourceType::kObject:
filter_option = FOObject;
filter_option = "object";
break;
// a media resource.
case content::ResourceType::kMedia:
filter_option = FOMedia;
filter_option = "media";
break;
// a XMLHttpRequest
case content::ResourceType::kXhr:
filter_option = FOXmlHttpRequest;
filter_option = "xhr";
break;
// a ping request for <a ping>/sendBeacon.
case content::ResourceType::kPing:
filter_option = FOPing;
filter_option = "ping";
break;
// the main resource of a dedicated worker.
case content::ResourceType::kWorker:
Expand All @@ -93,10 +93,6 @@ FilterOption ResourceTypeToFilterOption(content::ResourceType resource_type) {
case content::ResourceType::kCspReport:
// a resource that a plugin requested.
case content::ResourceType::kPluginResource:
// a service worker navigation preload request.
case content::ResourceType::kNavigationPreload:
// an invalid type (see brave/browser/net/url_context.h)
case brave::BraveRequestInfo::kInvalidResourceType:
default:
break;
}
Expand All @@ -109,7 +105,7 @@ namespace brave_shields {

AdBlockBaseService::AdBlockBaseService(BraveComponent::Delegate* delegate)
: BaseBraveShieldsService(delegate),
ad_block_client_(new AdBlockClient()),
ad_block_client_(new adblock::Engine()),
weak_factory_(this),
weak_factory_io_thread_(this) {
DETACH_FROM_SEQUENCE(sequence_checker_);
Expand All @@ -128,30 +124,27 @@ bool AdBlockBaseService::ShouldStartRequest(const GURL& url,
content::ResourceType resource_type, const std::string& tab_host,
bool* did_match_exception, bool* cancel_request_explicitly) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
FilterOption current_option = ResourceTypeToFilterOption(resource_type);

// Determine third-party here so the library doesn't need to figure it out.
// CreateFromNormalizedTuple is needed because SameDomainOrHost needs
// a URL or origin and not a string to a host name.
if (SameDomainOrHost(url, url::Origin::CreateFromNormalizedTuple(
"https", tab_host.c_str(), 80), INCLUDE_PRIVATE_REGISTRIES)) {
current_option = static_cast<FilterOption>(
current_option | FONotThirdParty);
} else {
current_option = static_cast<FilterOption>(current_option | FOThirdParty);
}

Filter* matching_filter = nullptr;
Filter* matching_exception_filter = nullptr;
if (ad_block_client_->matches(url.spec().c_str(),
current_option, tab_host.c_str(), &matching_filter,
&matching_exception_filter)) {
if (matching_filter && cancel_request_explicitly &&
(matching_filter->filterOption & FOExplicitCancel)) {
*cancel_request_explicitly = true;
bool is_third_party = !SameDomainOrHost(url,
url::Origin::CreateFromNormalizedTuple("https", tab_host.c_str(), 80),
INCLUDE_PRIVATE_REGISTRIES);
bool explicit_cancel;
bool saved_from_exception;
// TODO(bbondy): Use redirect if it is provided.
std::string redirect;
if (ad_block_client_->matches(url.spec(), url.host(),
tab_host, is_third_party, ResourceTypeToString(resource_type),
&explicit_cancel, &saved_from_exception, &redirect)) {
if (cancel_request_explicitly) {
*cancel_request_explicitly = explicit_cancel;
}
// We'd only possibly match an exception filter if we're returning true.
*did_match_exception = false;
if (did_match_exception) {
*did_match_exception = false;
}
// LOG(ERROR) << "AdBlockBaseService::ShouldStartRequest(), host: "
// << tab_host
// << ", resource type: " << resource_type
Expand All @@ -160,7 +153,7 @@ bool AdBlockBaseService::ShouldStartRequest(const GURL& url,
}

if (did_match_exception) {
*did_match_exception = !!matching_exception_filter;
*did_match_exception = saved_from_exception;
}

return true;
Expand All @@ -180,17 +173,27 @@ void AdBlockBaseService::EnableTagOnIOThread(
DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (enabled) {
ad_block_client_->addTag(tag);
tags_.push_back(tag);
} else {
ad_block_client_->removeTag(tag);
std::vector<std::string>::iterator it =
std::find(tags_.begin(), tags_.end(), tag);
if (it != tags_.end()) {
tags_.erase(it);
}
}
}

bool AdBlockBaseService::TagExists(const std::string& tag) {
return std::find(tags_.begin(), tags_.end(), tag) != tags_.end();
}

void AdBlockBaseService::GetDATFileData(const base::FilePath& dat_file_path) {
base::PostTaskAndReplyWithResult(
GetTaskRunner().get(),
FROM_HERE,
base::BindOnce(
&brave_component_updater::LoadDATFileData<AdBlockClient>,
&brave_component_updater::LoadDATFileData<adblock::Engine>,
dat_file_path),
base::BindOnce(&AdBlockBaseService::OnGetDATFileData,
weak_factory_.GetWeakPtr()));
Expand All @@ -215,20 +218,32 @@ void AdBlockBaseService::OnGetDATFileData(GetDATFileDataResult result) {
}

void AdBlockBaseService::UpdateAdBlockClient(
std::unique_ptr<AdBlockClient> ad_block_client,
std::unique_ptr<adblock::Engine> ad_block_client,
brave_component_updater::DATFileDataBuffer buffer) {
DCHECK_CURRENTLY_ON(BrowserThread::IO);
ad_block_client_ = std::move(ad_block_client);
buffer_ = std::move(buffer);
AddKnownTagsToAdBlockInstance();
}

void AdBlockBaseService::AddKnownTagsToAdBlockInstance() {
std::for_each(tags_.begin(), tags_.end(), [&](const std::string tag) {
ad_block_client_->addTag(tag);
});
}


bool AdBlockBaseService::Init() {
return true;
}

AdBlockClient* AdBlockBaseService::GetAdBlockClientForTest() {
return ad_block_client_.get();
void AdBlockBaseService::ResetForTest(const std::string& rules) {
// This is temporary until adblock-rust supports incrementally adding
// filter rules to an existing instance. At which point the hack below
// will dissapear.
DETACH_FROM_SEQUENCE(sequence_checker_);
ad_block_client_.reset(new adblock::Engine(rules));
AddKnownTagsToAdBlockInstance();
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
16 changes: 10 additions & 6 deletions components/brave_shields/browser/ad_block_base_service.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,12 @@
#include "brave/components/brave_component_updater/browser/dat_file_util.h"
#include "content/public/common/resource_type.h"

class AdBlockClient;
class AdBlockServiceTest;

using brave_component_updater::BraveComponent;
namespace adblock {
class Engine;
}

namespace brave_shields {

Expand All @@ -32,7 +34,7 @@ namespace brave_shields {
class AdBlockBaseService : public BaseBraveShieldsService {
public:
using GetDATFileDataResult =
brave_component_updater::LoadDATFileDataResult<AdBlockClient>;
brave_component_updater::LoadDATFileDataResult<adblock::Engine>;

explicit AdBlockBaseService(BraveComponent::Delegate* delegate);
~AdBlockBaseService() override;
Expand All @@ -41,28 +43,30 @@ class AdBlockBaseService : public BaseBraveShieldsService {
const std::string& tab_host, bool* did_match_exception,
bool* cancel_request_explicitly) override;
void EnableTag(const std::string& tag, bool enabled);
bool TagExists(const std::string& tag);

protected:
friend class ::AdBlockServiceTest;
bool Init() override;
void Cleanup() override;

void GetDATFileData(const base::FilePath& dat_file_path);

AdBlockClient* GetAdBlockClientForTest();
void AddKnownTagsToAdBlockInstance();
void ResetForTest(const std::string& rules);

SEQUENCE_CHECKER(sequence_checker_);
std::unique_ptr<AdBlockClient> ad_block_client_;
std::unique_ptr<adblock::Engine> ad_block_client_;

private:
void UpdateAdBlockClient(
std::unique_ptr<AdBlockClient> ad_block_client,
std::unique_ptr<adblock::Engine> ad_block_client,
brave_component_updater::DATFileDataBuffer buffer);
void OnGetDATFileData(GetDATFileDataResult result);
void EnableTagOnIOThread(const std::string& tag, bool enabled);
void OnPreferenceChanges(const std::string& pref_name);

brave_component_updater::DATFileDataBuffer buffer_;
std::vector<std::string> tags_;
base::WeakPtrFactory<AdBlockBaseService> weak_factory_;
base::WeakPtrFactory<AdBlockBaseService> weak_factory_io_thread_;
DISALLOW_COPY_AND_ASSIGN(AdBlockBaseService);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#include "brave/browser/brave_browser_process_impl.h"
#include "brave/common/pref_names.h"
#include "brave/components/brave_shields/browser/ad_block_service.h"
#include "brave/vendor/ad-block/ad_block_client.h"
#include "brave/vendor/adblock_rust_ffi/src/wrapper.hpp"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_thread.h"

Expand Down Expand Up @@ -56,9 +56,7 @@ bool AdBlockCustomFiltersService::UpdateCustomFilters(
void AdBlockCustomFiltersService::UpdateCustomFiltersOnFileTaskRunner(
const std::string& custom_filters) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
ad_block_client_->clear();
if (!custom_filters.empty())
ad_block_client_->parse(custom_filters.c_str());
ad_block_client_.reset(new adblock::Engine(custom_filters.c_str()));
}

///////////////////////////////////////////////////////////////////////////////
Expand Down
Loading