|
@@ -0,0 +1,1351 @@
|
|
|
|
+From: csagan5 <32685696+csagan5@users.noreply.github.com>
|
|
|
|
+Date: Sat, 14 Sep 2019 10:20:08 +0200
|
|
|
|
+Subject: Bromite AdBlockUpdaterService
|
|
|
|
+
|
|
|
|
+Disable look-alike, metrics, ablation and navigation throttles
|
|
|
|
+Do not use experiments to enable/disable presets
|
|
|
|
+Always enable ad filtering
|
|
|
|
+Download filters by checking Last-Modified header first
|
|
|
|
+---
|
|
|
|
+ chrome/browser/after_startup_task_utils.cc | 5 +
|
|
|
|
+ chrome/browser/browser_process.h | 7 +
|
|
|
|
+ chrome/browser/browser_process_impl.cc | 28 +++
|
|
|
|
+ chrome/browser/browser_process_impl.h | 3 +
|
|
|
|
+ chrome/browser/chrome_browser_main.cc | 5 +-
|
|
|
|
+ chrome/browser/chrome_content_browser_client.cc | 18 --
|
|
|
|
+ components/component_updater/BUILD.gn | 6 +
|
|
|
|
+ .../component_updater/adblock_updater_service.cc | 249 +++++++++++++++++++++
|
|
|
|
+ .../component_updater/adblock_updater_service.h | 99 ++++++++
|
|
|
|
+ .../component_updater/download_filters_task.cc | 228 +++++++++++++++++++
|
|
|
|
+ .../component_updater/download_filters_task.h | 131 +++++++++++
|
|
|
|
+ .../content_subresource_filter_throttle_manager.cc | 11 +
|
|
|
|
+ .../content/browser/ruleset_service.cc | 33 ++-
|
|
|
|
+ .../content/browser/ruleset_service.h | 7 +-
|
|
|
|
+ .../content/browser/ruleset_version.cc | 1 +
|
|
|
|
+ .../content/browser/ruleset_version.h | 5 +
|
|
|
|
+ .../content/browser/verified_ruleset_dealer.cc | 2 +
|
|
|
|
+ .../core/browser/subresource_filter_features.cc | 115 +---------
|
|
|
|
+ .../core/common/common_features.cc | 2 +-
|
|
|
|
+ .../frame_host/navigation_throttle_runner.cc | 10 -
|
|
|
|
+ 20 files changed, 818 insertions(+), 147 deletions(-)
|
|
|
|
+ create mode 100644 components/component_updater/adblock_updater_service.cc
|
|
|
|
+ create mode 100644 components/component_updater/adblock_updater_service.h
|
|
|
|
+ create mode 100644 components/component_updater/download_filters_task.cc
|
|
|
|
+ create mode 100644 components/component_updater/download_filters_task.h
|
|
|
|
+
|
|
|
|
+diff --git a/chrome/browser/after_startup_task_utils.cc b/chrome/browser/after_startup_task_utils.cc
|
|
|
|
+--- a/chrome/browser/after_startup_task_utils.cc
|
|
|
|
++++ b/chrome/browser/after_startup_task_utils.cc
|
|
|
|
+@@ -36,6 +36,8 @@
|
|
|
|
+ #include "ui/views/linux_ui/linux_ui.h"
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
++#include "chrome/browser/browser_process.h"
|
|
|
|
++
|
|
|
|
+ using content::BrowserThread;
|
|
|
|
+ using content::WebContents;
|
|
|
|
+ using content::WebContentsObserver;
|
|
|
|
+@@ -135,6 +137,9 @@ void SetBrowserStartupIsComplete() {
|
|
|
|
+ g_after_startup_tasks.Get().clear();
|
|
|
|
+ g_after_startup_tasks.Get().shrink_to_fit();
|
|
|
|
+
|
|
|
|
++ // initialize scheduled updates for the AdBlock updater
|
|
|
|
++ g_browser_process->adblock_updater()->Start();
|
|
|
|
++
|
|
|
|
+ #if defined(OS_LINUX) && !defined(OS_CHROMEOS)
|
|
|
|
+ // Make sure we complete the startup notification sequence, or launchers will
|
|
|
|
+ // get confused by not receiving the expected message from the main process.
|
|
|
|
+diff --git a/chrome/browser/browser_process.h b/chrome/browser/browser_process.h
|
|
|
|
+--- a/chrome/browser/browser_process.h
|
|
|
|
++++ b/chrome/browser/browser_process.h
|
|
|
|
+@@ -22,6 +22,7 @@
|
|
|
|
+ #include "chrome/browser/shell_integration.h"
|
|
|
|
+ #include "chrome/common/buildflags.h"
|
|
|
|
+ #include "media/media_buildflags.h"
|
|
|
|
++#include "components/component_updater/adblock_updater_service.h"
|
|
|
|
+
|
|
|
|
+ class BackgroundModeManager;
|
|
|
|
+ class DownloadRequestLimiter;
|
|
|
|
+@@ -58,6 +59,10 @@ class ComponentUpdateService;
|
|
|
|
+ class SupervisedUserWhitelistInstaller;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
++namespace adblock_updater {
|
|
|
|
++class AdBlockUpdaterService;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
+ namespace extensions {
|
|
|
|
+ class EventRouterForwarder;
|
|
|
|
+ }
|
|
|
|
+@@ -233,6 +238,8 @@ class BrowserProcess {
|
|
|
|
+
|
|
|
|
+ virtual component_updater::ComponentUpdateService* component_updater() = 0;
|
|
|
|
+
|
|
|
|
++ virtual adblock_updater::AdBlockUpdaterService* adblock_updater() = 0;
|
|
|
|
++
|
|
|
|
+ #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
|
|
|
|
+ virtual component_updater::SupervisedUserWhitelistInstaller*
|
|
|
|
+ supervised_user_whitelist_installer() = 0;
|
|
|
|
+diff --git a/chrome/browser/browser_process_impl.cc b/chrome/browser/browser_process_impl.cc
|
|
|
|
+--- a/chrome/browser/browser_process_impl.cc
|
|
|
|
++++ b/chrome/browser/browser_process_impl.cc
|
|
|
|
+@@ -1017,6 +1017,34 @@ BrowserProcessImpl::component_updater() {
|
|
|
|
+ return component_updater_.get();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
++adblock_updater::AdBlockUpdaterService*
|
|
|
|
++BrowserProcessImpl::adblock_updater() {
|
|
|
|
++ if (adblock_updater_)
|
|
|
|
++ return adblock_updater_.get();
|
|
|
|
++
|
|
|
|
++ if (!BrowserThread::CurrentlyOn(BrowserThread::UI))
|
|
|
|
++ return nullptr;
|
|
|
|
++
|
|
|
|
++ std::unique_ptr<component_updater::UpdateScheduler> scheduler;
|
|
|
|
++#if defined(OS_ANDROID)
|
|
|
|
++ if (base::FeatureList::IsEnabled(
|
|
|
|
++ chrome::android::kBackgroundTaskComponentUpdate) &&
|
|
|
|
++ component_updater::BackgroundTaskUpdateScheduler::IsAvailable()) {
|
|
|
|
++ scheduler =
|
|
|
|
++ std::make_unique<component_updater::BackgroundTaskUpdateScheduler>();
|
|
|
|
++ }
|
|
|
|
++#endif
|
|
|
|
++ if (!scheduler)
|
|
|
|
++ scheduler = std::make_unique<component_updater::TimerUpdateScheduler>();
|
|
|
|
++
|
|
|
|
++ adblock_updater_ = std::make_unique<adblock_updater::AdBlockUpdaterService>(
|
|
|
|
++ g_browser_process->system_network_context_manager()->GetSharedURLLoaderFactory(),
|
|
|
|
++ std::move(scheduler),
|
|
|
|
++ g_browser_process->subresource_filter_ruleset_service());
|
|
|
|
++
|
|
|
|
++ return adblock_updater_.get();
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
+ #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
|
|
|
|
+ component_updater::SupervisedUserWhitelistInstaller*
|
|
|
|
+ BrowserProcessImpl::supervised_user_whitelist_installer() {
|
|
|
|
+diff --git a/chrome/browser/browser_process_impl.h b/chrome/browser/browser_process_impl.h
|
|
|
|
+--- a/chrome/browser/browser_process_impl.h
|
|
|
|
++++ b/chrome/browser/browser_process_impl.h
|
|
|
|
+@@ -177,6 +177,7 @@ class BrowserProcessImpl : public BrowserProcess,
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+ component_updater::ComponentUpdateService* component_updater() override;
|
|
|
|
++ adblock_updater::AdBlockUpdaterService* adblock_updater() override;
|
|
|
|
+ #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
|
|
|
|
+ component_updater::SupervisedUserWhitelistInstaller*
|
|
|
|
+ supervised_user_whitelist_installer() override;
|
|
|
|
+@@ -362,6 +363,8 @@ class BrowserProcessImpl : public BrowserProcess,
|
|
|
|
+ // but some users of component updater only install per-user.
|
|
|
|
+ std::unique_ptr<component_updater::ComponentUpdateService> component_updater_;
|
|
|
|
+
|
|
|
|
++ std::unique_ptr<adblock_updater::AdBlockUpdaterService> adblock_updater_;
|
|
|
|
++
|
|
|
|
+ #if BUILDFLAG(ENABLE_SUPERVISED_USERS)
|
|
|
|
+ std::unique_ptr<component_updater::SupervisedUserWhitelistInstaller>
|
|
|
|
+ supervised_user_whitelist_installer_;
|
|
|
|
+diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
|
|
|
|
+--- a/chrome/browser/chrome_browser_main.cc
|
|
|
|
++++ b/chrome/browser/chrome_browser_main.cc
|
|
|
|
+@@ -1739,8 +1739,11 @@ int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
|
|
|
+
|
|
|
|
+ PreBrowserStart();
|
|
|
|
+
|
|
|
|
+- if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate))
|
|
|
|
++ if (!parsed_command_line().HasSwitch(switches::kDisableComponentUpdate)) {
|
|
|
|
+ RegisterComponentsForUpdate(profile_->GetPrefs());
|
|
|
|
++ // force initialisation
|
|
|
|
++ g_browser_process->adblock_updater();
|
|
|
|
++ }
|
|
|
|
+
|
|
|
|
+ variations::VariationsService* variations_service =
|
|
|
|
+ browser_process_->variations_service();
|
|
|
|
+diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc
|
|
|
|
+--- a/chrome/browser/chrome_content_browser_client.cc
|
|
|
|
++++ b/chrome/browser/chrome_content_browser_client.cc
|
|
|
|
+@@ -64,7 +64,6 @@
|
|
|
|
+ #include "chrome/browser/hid/chrome_hid_delegate.h"
|
|
|
|
+ #include "chrome/browser/language/translate_frame_binder.h"
|
|
|
|
+ #include "chrome/browser/lifetime/browser_shutdown.h"
|
|
|
|
+-#include "chrome/browser/lookalikes/lookalike_url_navigation_throttle.h"
|
|
|
|
+ #include "chrome/browser/media/router/media_router_feature.h"
|
|
|
|
+ #include "chrome/browser/media/router/presentation/presentation_service_delegate_impl.h"
|
|
|
|
+ #include "chrome/browser/media/router/presentation/receiver_presentation_service_delegate_impl.h"
|
|
|
|
+@@ -80,7 +79,6 @@
|
|
|
|
+ #include "chrome/browser/net_benchmarking.h"
|
|
|
|
+ #include "chrome/browser/notifications/platform_notification_service_factory.h"
|
|
|
|
+ #include "chrome/browser/notifications/platform_notification_service_impl.h"
|
|
|
|
+-#include "chrome/browser/page_load_metrics/metrics_navigation_throttle.h"
|
|
|
|
+ #include "chrome/browser/page_load_metrics/metrics_web_contents_observer.h"
|
|
|
|
+ #include "chrome/browser/page_load_metrics/page_load_metrics_util.h"
|
|
|
|
+ #include "chrome/browser/password_manager/chrome_password_manager_client.h"
|
|
|
|
+@@ -4085,16 +4083,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
|
|
|
|
+ content::NavigationHandle* handle) {
|
|
|
|
+ std::vector<std::unique_ptr<content::NavigationThrottle>> throttles;
|
|
|
|
+
|
|
|
|
+- // MetricsNavigationThrottle requires that it runs before NavigationThrottles
|
|
|
|
+- // that may delay or cancel navigations, so only NavigationThrottles that
|
|
|
|
+- // don't delay or cancel navigations (e.g. throttles that are only observing
|
|
|
|
+- // callbacks without affecting navigation behavior) should be added before
|
|
|
|
+- // MetricsNavigationThrottle.
|
|
|
|
+- if (handle->IsInMainFrame()) {
|
|
|
|
+- throttles.push_back(
|
|
|
|
+- page_load_metrics::MetricsNavigationThrottle::Create(handle));
|
|
|
|
+- }
|
|
|
|
+-
|
|
|
|
+ #if BUILDFLAG(ENABLE_PLUGINS)
|
|
|
|
+ std::unique_ptr<content::NavigationThrottle> flash_url_throttle =
|
|
|
|
+ FlashDownloadInterception::MaybeCreateThrottleFor(handle);
|
|
|
|
+@@ -4204,12 +4192,6 @@ ChromeContentBrowserClient::CreateThrottlesForNavigation(
|
|
|
|
+ }
|
|
|
|
+ #endif
|
|
|
|
+
|
|
|
|
+- std::unique_ptr<content::NavigationThrottle>
|
|
|
|
+- lookalike_url_navigation_throttle = lookalikes::
|
|
|
|
+- LookalikeUrlNavigationThrottle::MaybeCreateNavigationThrottle(handle);
|
|
|
|
+- if (lookalike_url_navigation_throttle)
|
|
|
|
+- throttles.push_back(std::move(lookalike_url_navigation_throttle));
|
|
|
|
+-
|
|
|
|
+ std::unique_ptr<content::NavigationThrottle> pdf_iframe_throttle =
|
|
|
|
+ PDFIFrameNavigationThrottle::MaybeCreateThrottleFor(handle);
|
|
|
|
+ if (pdf_iframe_throttle)
|
|
|
|
+diff --git a/components/component_updater/BUILD.gn b/components/component_updater/BUILD.gn
|
|
|
|
+--- a/components/component_updater/BUILD.gn
|
|
|
|
++++ b/components/component_updater/BUILD.gn
|
|
|
|
+@@ -10,6 +10,12 @@ static_library("component_updater") {
|
|
|
|
+ "component_updater_command_line_config_policy.h",
|
|
|
|
+ "component_updater_paths.cc",
|
|
|
|
+ "component_updater_paths.h",
|
|
|
|
++
|
|
|
|
++ "adblock_updater_service.cc",
|
|
|
|
++ "adblock_updater_service.h",
|
|
|
|
++ "download_filters_task.cc",
|
|
|
|
++ "download_filters_task.h",
|
|
|
|
++
|
|
|
|
+ "component_updater_service.cc",
|
|
|
|
+ "component_updater_service.h",
|
|
|
|
+ "component_updater_service_internal.h",
|
|
|
|
+diff --git a/components/component_updater/adblock_updater_service.cc b/components/component_updater/adblock_updater_service.cc
|
|
|
|
+new file mode 100644
|
|
|
|
+--- /dev/null
|
|
|
|
++++ b/components/component_updater/adblock_updater_service.cc
|
|
|
|
+@@ -0,0 +1,249 @@
|
|
|
|
++/*
|
|
|
|
++ This file is part of Bromite.
|
|
|
|
++
|
|
|
|
++ Bromite is free software: you can redistribute it and/or modify
|
|
|
|
++ it under the terms of the GNU General Public License as published by
|
|
|
|
++ the Free Software Foundation, either version 3 of the License, or
|
|
|
|
++ (at your option) any later version.
|
|
|
|
++
|
|
|
|
++ Bromite is distributed in the hope that it will be useful,
|
|
|
|
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
++ GNU General Public License for more details.
|
|
|
|
++
|
|
|
|
++ You should have received a copy of the GNU General Public License
|
|
|
|
++ along with Bromite. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
++*/
|
|
|
|
++
|
|
|
|
++#include "components/component_updater/adblock_updater_service.h"
|
|
|
|
++
|
|
|
|
++#include <algorithm>
|
|
|
|
++#include <map>
|
|
|
|
++#include <string>
|
|
|
|
++#include <utility>
|
|
|
|
++#include <vector>
|
|
|
|
++
|
|
|
|
++#include "base/bind.h"
|
|
|
|
++#include "base/bind_helpers.h"
|
|
|
|
++#include "base/callback.h"
|
|
|
|
++#include "base/files/file_path.h"
|
|
|
|
++#include "base/files/file_util.h"
|
|
|
|
++#include "base/logging.h"
|
|
|
|
++#include "base/macros.h"
|
|
|
|
++#include "base/threading/thread_checker.h"
|
|
|
|
++#include "base/threading/thread_task_runner_handle.h"
|
|
|
|
++#include "base/time/time.h"
|
|
|
|
++#include "base/timer/timer.h"
|
|
|
|
++#include "url/gurl.h"
|
|
|
|
++#include "base/strings/safe_sprintf.h"
|
|
|
|
++#include "base/strings/string_number_conversions.h"
|
|
|
|
++
|
|
|
|
++namespace adblock_updater {
|
|
|
|
++
|
|
|
|
++// all constants express seconds
|
|
|
|
++// these could be made configurable
|
|
|
|
++const int initial_check_delay = 5,
|
|
|
|
++ next_check_delay = 60*60*24*7, // 1 week
|
|
|
|
++ on_demand_check_delay = 60; // minimum 1 minute between each on-demand check
|
|
|
|
++
|
|
|
|
++AdBlockUpdaterService::AdBlockUpdaterService(scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory, std::unique_ptr<component_updater::UpdateScheduler> scheduler, subresource_filter::RulesetService* ruleset_service)
|
|
|
|
++ : ruleset_service_(ruleset_service), shared_url_network_factory_(shared_url_network_factory), scheduler_(std::move(scheduler)) {
|
|
|
|
++ DCHECK(ruleset_service);
|
|
|
|
++
|
|
|
|
++ //TODO: retrieve filters URL from config/prefs
|
|
|
|
++ filters_url_ = "https://www.bromite.org/filters/filters.dat";
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++AdBlockUpdaterService::~AdBlockUpdaterService() {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::AddObserver(Observer* observer) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++ observer_list_.AddObserver(observer);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::RemoveObserver(Observer* observer) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++ observer_list_.RemoveObserver(observer);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++//TODO: use this as in: base::Bind(&AdBlockUpdaterService::NotifyObservers, base::Unretained(this)
|
|
|
|
++void AdBlockUpdaterService::NotifyObservers(Event event) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++ for (auto& observer : observer_list_)
|
|
|
|
++ observer.OnEvent(event);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::Start() {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ // avoid multiple scheduling
|
|
|
|
++ if (scheduled_)
|
|
|
|
++ return;
|
|
|
|
++ scheduled_ = true;
|
|
|
|
++
|
|
|
|
++ LOG(INFO) << "AdBlockUpdaterService: starting up. "
|
|
|
|
++ << "First update attempt will take place in "
|
|
|
|
++ << initial_check_delay << " seconds. "
|
|
|
|
++ << "Next update attempt will take place in "
|
|
|
|
++ << next_check_delay << " seconds. ";
|
|
|
|
++
|
|
|
|
++ scheduler_->Schedule(
|
|
|
|
++ base::TimeDelta::FromSeconds(initial_check_delay),
|
|
|
|
++ base::TimeDelta::FromSeconds(next_check_delay),
|
|
|
|
++ base::Bind(&AdBlockUpdaterService::OnDemandScheduledUpdate,
|
|
|
|
++ base::Unretained(this)), base::DoNothing());
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::OnDemandScheduledUpdate(component_updater::UpdateScheduler::OnFinishedCallback on_finished) {
|
|
|
|
++ //TODO: call on_finished
|
|
|
|
++ OnDemandUpdateAsNeeded(false, Callback());
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++bool AdBlockUpdaterService::OnDemandUpdate(Callback on_finished) {
|
|
|
|
++ return OnDemandUpdateAsNeeded(true, std::move(on_finished));
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++bool AdBlockUpdaterService::OnDemandUpdateAsNeeded(bool is_foreground, Callback on_finished) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ // Check if the request is too soon.
|
|
|
|
++ if (!last_update_.is_null()) {
|
|
|
|
++ base::TimeDelta delta =
|
|
|
|
++ base::TimeTicks::Now() - last_update_;
|
|
|
|
++ if (is_updating_ || (delta < base::TimeDelta::FromSeconds(on_demand_check_delay)))
|
|
|
|
++ LOG(INFO) << "AdBlockUpdaterService: update not necessary.";
|
|
|
|
++ return false;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ OnDemandUpdateInternal(is_foreground, std::move(on_finished));
|
|
|
|
++ return true;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::OnDemandUpdateInternal(bool is_foreground, Callback on_finished) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ if (is_updating_) {
|
|
|
|
++ base::ThreadTaskRunnerHandle::Get()->PostTask(
|
|
|
|
++ FROM_HERE, base::BindOnce(std::move(on_finished),
|
|
|
|
++ Error::UPDATE_IN_PROGRESS));
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++ is_updating_ = true;
|
|
|
|
++ last_update_ = base::TimeTicks::Now();
|
|
|
|
++
|
|
|
|
++ base::Time::Exploded e = {0};
|
|
|
|
++ base::Time t = base::Time();
|
|
|
|
++ auto version = ruleset_service_->GetMostRecentlyIndexedVersion();
|
|
|
|
++ LOG(INFO) << "AdBlockUpdaterService: MostRecentIndexedVersion = " << version.content_version;
|
|
|
|
++ std::vector<std::string> tokens =
|
|
|
|
++ base::SplitString(version.content_version, ".", base::KEEP_WHITESPACE, base::SPLIT_WANT_ALL);
|
|
|
|
++ int i = 0;
|
|
|
|
++ bool failed = false;
|
|
|
|
++ for (const std::string& token : tokens) {
|
|
|
|
++ // parse as number
|
|
|
|
++ int n = 0;
|
|
|
|
++ if (!base::StringToInt(token, &n)) {
|
|
|
|
++ failed = true;
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ switch (i++) {
|
|
|
|
++ case 0:
|
|
|
|
++ e.year = 2019 + n;
|
|
|
|
++ break;
|
|
|
|
++ case 1:
|
|
|
|
++ e.month = n + 1;
|
|
|
|
++ break;
|
|
|
|
++ case 2:
|
|
|
|
++ e.day_of_month = n + 1;
|
|
|
|
++ break;
|
|
|
|
++ case 3:
|
|
|
|
++ e.second = n % 60;
|
|
|
|
++ n -= e.second;
|
|
|
|
++ n /= 60;
|
|
|
|
++ e.minute = n % 60;
|
|
|
|
++ e.hour = n / 60;
|
|
|
|
++ break;
|
|
|
|
++ default:
|
|
|
|
++ failed = true;
|
|
|
|
++ break;
|
|
|
|
++ }
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ if (failed) {
|
|
|
|
++ LOG(WARNING) << "AdBlockUpdaterService: failed to parse most recent version as x.y.z.w dot-separated integers";
|
|
|
|
++ } else {
|
|
|
|
++ if (!base::Time::FromUTCExploded(e, &t))
|
|
|
|
++ LOG(WARNING) << "AdBlockUpdaterService: failed to convert version to time.";
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ auto task = base::MakeRefCounted<DownloadFiltersTask>(
|
|
|
|
++ shared_url_network_factory_,
|
|
|
|
++ is_foreground, filters_url_,
|
|
|
|
++ t,
|
|
|
|
++ base::BindOnce(&AdBlockUpdaterService::OnUpdateComplete, base::Unretained(this),
|
|
|
|
++ std::move(on_finished)));
|
|
|
|
++
|
|
|
|
++ // run task now; task is responsible for clearing the is_updating status
|
|
|
|
++ base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
|
|
|
|
++ base::BindOnce(&DownloadFiltersTask::Run, base::Unretained(task.get())));
|
|
|
|
++ tasks_.insert(task);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void AdBlockUpdaterService::OnUpdateComplete(Callback on_finished,
|
|
|
|
++ scoped_refptr<DownloadFiltersTask> task,
|
|
|
|
++ Error error) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ auto file_path = task->file_path();
|
|
|
|
++ if (error == Error::NONE) {
|
|
|
|
++ subresource_filter::UnindexedRulesetInfo ruleset_info;
|
|
|
|
++ ruleset_info.ruleset_path = file_path;
|
|
|
|
++ ruleset_info.delete_ruleset_path = true;
|
|
|
|
++ ruleset_info.content_version = "0.0.0.0";
|
|
|
|
++ DCHECK(!ruleset_info.ruleset_path.empty());
|
|
|
|
++
|
|
|
|
++ // convert time to version
|
|
|
|
++ auto t = task->last_modified();
|
|
|
|
++ bool ignore_version = t.is_null();
|
|
|
|
++ if (!ignore_version) {
|
|
|
|
++ base::Time::Exploded e;
|
|
|
|
++ t.UTCExplode(&e);
|
|
|
|
++
|
|
|
|
++ // convert time to version
|
|
|
|
++ const int major = e.year - 2019,
|
|
|
|
++ minor = e.month - 1,
|
|
|
|
++ patch = e.day_of_month - 1,
|
|
|
|
++ revision = (e.hour*60+e.minute)*60 + e.second;
|
|
|
|
++ if (major < 0)
|
|
|
|
++ LOG(WARNING) << "AdBlockUpdaterService: too old Last-Modified header, ignoring version check.";
|
|
|
|
++ else {
|
|
|
|
++ char version_buffer[32];
|
|
|
|
++ base::strings::SafeSNPrintf(version_buffer, sizeof(version_buffer), "%d.%d.%d.%d",
|
|
|
|
++ major, minor, patch, revision);
|
|
|
|
++
|
|
|
|
++ ruleset_info.content_version = version_buffer;
|
|
|
|
++
|
|
|
|
++ LOG(INFO) << "AdBlockUpdaterService: indexing filters with version " << ruleset_info.content_version;
|
|
|
|
++ }
|
|
|
|
++ } else
|
|
|
|
++ LOG(WARNING) << "AdBlockUpdaterService: invalid Last-Modified header, ignoring version check.";
|
|
|
|
++ ruleset_service_->IndexAndStoreAndPublishRulesetIfNeeded(ruleset_info, ignore_version);
|
|
|
|
++ } else {
|
|
|
|
++ //TODO: generate event for ADBLOCK_NOT_UPDATED in case of error UPDATE_NOT_NEEDED
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ //TODO: run these only when index-and-store is actually finished?
|
|
|
|
++ if (!on_finished.is_null()) {
|
|
|
|
++ base::ThreadTaskRunnerHandle::Get()->PostTask(
|
|
|
|
++ FROM_HERE, base::BindOnce(std::move(on_finished), error));
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // mark as not updating
|
|
|
|
++ is_updating_ = false;
|
|
|
|
++ tasks_.erase(task);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++} // namespace adblock_updater
|
|
|
|
+diff --git a/components/component_updater/adblock_updater_service.h b/components/component_updater/adblock_updater_service.h
|
|
|
|
+new file mode 100644
|
|
|
|
+--- /dev/null
|
|
|
|
++++ b/components/component_updater/adblock_updater_service.h
|
|
|
|
+@@ -0,0 +1,99 @@
|
|
|
|
++/*
|
|
|
|
++ This file is part of Bromite.
|
|
|
|
++
|
|
|
|
++ Bromite is free software: you can redistribute it and/or modify
|
|
|
|
++ it under the terms of the GNU General Public License as published by
|
|
|
|
++ the Free Software Foundation, either version 3 of the License, or
|
|
|
|
++ (at your option) any later version.
|
|
|
|
++
|
|
|
|
++ Bromite is distributed in the hope that it will be useful,
|
|
|
|
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
++ GNU General Public License for more details.
|
|
|
|
++
|
|
|
|
++ You should have received a copy of the GNU General Public License
|
|
|
|
++ along with Bromite. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
++*/
|
|
|
|
++
|
|
|
|
++#ifndef COMPONENTS_ADBLOCK_UPDATER_SERVICE_H
|
|
|
|
++#define COMPONENTS_ADBLOCK_UPDATER_SERVICE_H
|
|
|
|
++
|
|
|
|
++#include <stdint.h>
|
|
|
|
++
|
|
|
|
++#include <memory>
|
|
|
|
++#include <string>
|
|
|
|
++#include <vector>
|
|
|
|
++
|
|
|
|
++#include "base/callback_forward.h"
|
|
|
|
++#include "base/gtest_prod_util.h"
|
|
|
|
++#include "base/memory/ref_counted.h"
|
|
|
|
++#include "base/version.h"
|
|
|
|
++#include "build/build_config.h"
|
|
|
|
++#include "components/component_updater/update_scheduler.h"
|
|
|
|
++#include "url/gurl.h"
|
|
|
|
++#include "components/component_updater/download_filters_task.h"
|
|
|
|
++#include "components/subresource_filter/content/browser/ruleset_service.h"
|
|
|
|
++#include "services/network/public/cpp/shared_url_loader_factory.h"
|
|
|
|
++
|
|
|
|
++namespace adblock_updater {
|
|
|
|
++
|
|
|
|
++// Called when a non-blocking call in this module completes.
|
|
|
|
++using Callback = base::OnceCallback<void(Error error)>;
|
|
|
|
++
|
|
|
|
++class Observer {
|
|
|
|
++ public:
|
|
|
|
++ virtual ~Observer() {}
|
|
|
|
++
|
|
|
|
++ // Called by the update service when a state change happens.
|
|
|
|
++ virtual void OnEvent(Event event) = 0;
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++// The AdBlock update service is in charge of downloading and saving the
|
|
|
|
++// AdBlock filters.
|
|
|
|
++//
|
|
|
|
++// All methods are safe to call ONLY from the browser's main thread.
|
|
|
|
++class AdBlockUpdaterService {
|
|
|
|
++ public:
|
|
|
|
++ AdBlockUpdaterService(scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory, std::unique_ptr<component_updater::UpdateScheduler> scheduler, subresource_filter::RulesetService* ruleset_service);
|
|
|
|
++ ~AdBlockUpdaterService();
|
|
|
|
++
|
|
|
|
++ // Adds an observer for this class. An observer should not be added more
|
|
|
|
++ // than once. The caller retains the ownership of the observer object.
|
|
|
|
++ void AddObserver(Observer* observer);
|
|
|
|
++
|
|
|
|
++ // Removes an observer. It is safe for an observer to be removed while
|
|
|
|
++ // the observers are being notified.
|
|
|
|
++ void RemoveObserver(Observer* observer);
|
|
|
|
++
|
|
|
|
++ // Will schedule automatic updates, run in background.
|
|
|
|
++ void Start();
|
|
|
|
++
|
|
|
|
++ // To be called for an user-triggered update.
|
|
|
|
++ // Will not result in an actual update if the last update was too recently triggered.
|
|
|
|
++ bool OnDemandUpdate(Callback on_finished);
|
|
|
|
++
|
|
|
|
++ private:
|
|
|
|
++ void NotifyObservers(Event event);
|
|
|
|
++ void OnDemandScheduledUpdate(component_updater::UpdateScheduler::OnFinishedCallback on_finished);
|
|
|
|
++ bool OnDemandUpdateAsNeeded(bool is_foreground, Callback on_finished);
|
|
|
|
++ void OnDemandUpdateInternal(bool is_foreground, Callback on_finished);
|
|
|
|
++ void OnUpdateComplete(Callback callback, scoped_refptr<DownloadFiltersTask> task, Error error);
|
|
|
|
++
|
|
|
|
++ base::ObserverList<Observer>::Unchecked observer_list_;
|
|
|
|
++ base::ThreadChecker thread_checker_;
|
|
|
|
++ base::TimeTicks last_update_;
|
|
|
|
++
|
|
|
|
++ subresource_filter::RulesetService* ruleset_service_;
|
|
|
|
++ std::string filters_url_;
|
|
|
|
++
|
|
|
|
++ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
|
|
|
|
++ std::unique_ptr<component_updater::UpdateScheduler> scheduler_;
|
|
|
|
++
|
|
|
|
++ bool is_updating_ = false;
|
|
|
|
++ bool scheduled_ = false;
|
|
|
|
++ std::set<scoped_refptr<DownloadFiltersTask>> tasks_;
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++} // namespace adblock_updater
|
|
|
|
++
|
|
|
|
++#endif // COMPONENTS_ADBLOCK_UPDATER_SERVICE_H
|
|
|
|
+diff --git a/components/component_updater/download_filters_task.cc b/components/component_updater/download_filters_task.cc
|
|
|
|
+new file mode 100644
|
|
|
|
+--- /dev/null
|
|
|
|
++++ b/components/component_updater/download_filters_task.cc
|
|
|
|
+@@ -0,0 +1,228 @@
|
|
|
|
++/*
|
|
|
|
++ This file is part of Bromite.
|
|
|
|
++
|
|
|
|
++ Bromite is free software: you can redistribute it and/or modify
|
|
|
|
++ it under the terms of the GNU General Public License as published by
|
|
|
|
++ the Free Software Foundation, either version 3 of the License, or
|
|
|
|
++ (at your option) any later version.
|
|
|
|
++
|
|
|
|
++ Bromite is distributed in the hope that it will be useful,
|
|
|
|
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
++ GNU General Public License for more details.
|
|
|
|
++
|
|
|
|
++ You should have received a copy of the GNU General Public License
|
|
|
|
++ along with Bromite. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
++*/
|
|
|
|
++#include "components/component_updater/download_filters_task.h"
|
|
|
|
++
|
|
|
|
++#include <utility>
|
|
|
|
++
|
|
|
|
++#include "base/files/file_util.h"
|
|
|
|
++#include "base/bind.h"
|
|
|
|
++#include "base/location.h"
|
|
|
|
++#include "base/threading/thread_task_runner_handle.h"
|
|
|
|
++#include "base/logging.h"
|
|
|
|
++#include "net/base/load_flags.h"
|
|
|
|
++#include "url/gurl.h"
|
|
|
|
++
|
|
|
|
++namespace adblock_updater {
|
|
|
|
++
|
|
|
|
++// maximum 10MB for the filters file
|
|
|
|
++const int kMaxBodySize = 1024 * 1024 * 10;
|
|
|
|
++
|
|
|
|
++const int kMaxRetriesOnNetworkChange = 3;
|
|
|
|
++
|
|
|
|
++const net::NetworkTrafficAnnotationTag traffic_annotation =
|
|
|
|
++ net::DefineNetworkTrafficAnnotation("update_client", R"(
|
|
|
|
++ semantics {
|
|
|
|
++ sender: "Bromite AdBlock filters updater"
|
|
|
|
++ description:
|
|
|
|
++ "The AdBlock filters updater is responsible for updating the subresource filters."
|
|
|
|
++ trigger: "Manual or automatic AdBlock filters updates."
|
|
|
|
++ data:
|
|
|
|
++ "Subresource filters rulesets, binary format"
|
|
|
|
++ destination: WEBSITE
|
|
|
|
++ }
|
|
|
|
++ )");
|
|
|
|
++
|
|
|
|
++DownloadFiltersTask::DownloadFiltersTask(scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
|
|
|
|
++ bool is_foreground, const std::string& filters_url, base::Time min_last_modified,
|
|
|
|
++ Callback callback)
|
|
|
|
++ : shared_url_network_factory_(shared_url_network_factory),
|
|
|
|
++ is_foreground_(is_foreground),
|
|
|
|
++ complete_callback_(std::move(callback)) {
|
|
|
|
++ DCHECK(!filters_url.empty());
|
|
|
|
++ filters_url_ = GURL(filters_url);
|
|
|
|
++ min_last_modified_ = min_last_modified;
|
|
|
|
++
|
|
|
|
++ if (filters_url.empty()) {
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ createSimpleURLLoader(!min_last_modified_.is_null());
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::createSimpleURLLoader(bool headers_only) {
|
|
|
|
++ // always reset response-related fields
|
|
|
|
++ response_code_ = -1;
|
|
|
|
++ final_url_ = GURL();
|
|
|
|
++ download_start_time_ = base::TimeTicks();
|
|
|
|
++
|
|
|
|
++ auto resource_request = std::make_unique<network::ResourceRequest>();
|
|
|
|
++ resource_request->url = filters_url_;
|
|
|
|
++ resource_request->load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA | net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES;
|
|
|
|
++ resource_request->credentials_mode = network::mojom::CredentialsMode::kOmit;
|
|
|
|
++ if (headers_only)
|
|
|
|
++ // will chain two requests - first one is to check last modified header alone
|
|
|
|
++ resource_request->method = "HEAD";
|
|
|
|
++ else
|
|
|
|
++ resource_request->method = "GET";
|
|
|
|
++
|
|
|
|
++ simple_url_loader_ = network::SimpleURLLoader::Create(
|
|
|
|
++ std::move(resource_request), traffic_annotation);
|
|
|
|
++ simple_url_loader_->SetRetryOptions(
|
|
|
|
++ kMaxRetriesOnNetworkChange,
|
|
|
|
++ network::SimpleURLLoader::RetryMode::RETRY_ON_NETWORK_CHANGE);
|
|
|
|
++ simple_url_loader_->SetAllowPartialResults(false);
|
|
|
|
++ simple_url_loader_->SetOnResponseStartedCallback(base::BindOnce(
|
|
|
|
++ &DownloadFiltersTask::OnResponseStarted, base::Unretained(this)));
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++DownloadFiltersTask::~DownloadFiltersTask() {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::Run() {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ // will not be initialized if the URL was empty
|
|
|
|
++ if (!simple_url_loader_) {
|
|
|
|
++ TaskComplete(Error::INVALID_ARGUMENT);
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ download_start_time_ = base::TimeTicks::Now();
|
|
|
|
++ if (min_last_modified_.is_null()) {
|
|
|
|
++ internalDownload();
|
|
|
|
++ } else {
|
|
|
|
++ simple_url_loader_->DownloadHeadersOnly(
|
|
|
|
++ shared_url_network_factory_.get(),
|
|
|
|
++ base::BindOnce(&DownloadFiltersTask::OnHeadersDownloadComplete, base::Unretained(this))
|
|
|
|
++ );
|
|
|
|
++ }
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::internalDownload() {
|
|
|
|
++ simple_url_loader_->DownloadToTempFile(
|
|
|
|
++ shared_url_network_factory_.get(),
|
|
|
|
++ base::BindOnce(
|
|
|
|
++ [](const network::SimpleURLLoader* simple_url_loader,
|
|
|
|
++ update_client::NetworkFetcher::DownloadToFileCompleteCallback download_to_file_complete_callback,
|
|
|
|
++ base::FilePath file_path) {
|
|
|
|
++ std::move(download_to_file_complete_callback)
|
|
|
|
++ .Run(file_path, simple_url_loader->NetError(),
|
|
|
|
++ simple_url_loader->GetContentSize());
|
|
|
|
++ },
|
|
|
|
++ simple_url_loader_.get(),
|
|
|
|
++ base::BindOnce(&DownloadFiltersTask::OnDownloadComplete, base::Unretained(this))
|
|
|
|
++ ), kMaxBodySize);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::OnHeadersDownloadComplete(scoped_refptr<net::HttpResponseHeaders> headers) {
|
|
|
|
++ // something went wrong
|
|
|
|
++ if (headers == nullptr) {
|
|
|
|
++ OnDownloadComplete(base::FilePath(), simple_url_loader_->NetError(), simple_url_loader_->GetContentSize() /* 0 */);
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // ignoring 'headers' as 'Last-Modified' has already been picked up by OnResponseStarted
|
|
|
|
++ const base::TimeDelta dt =
|
|
|
|
++ last_modified_ - min_last_modified_;
|
|
|
|
++
|
|
|
|
++ if (dt.InSeconds() > 0) {
|
|
|
|
++ // prepare for next simple URL loader and trigger download
|
|
|
|
++ createSimpleURLLoader(false);
|
|
|
|
++ internalDownload();
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ // the remote filters are not more recent than known ones
|
|
|
|
++ TaskComplete(Error::UPDATE_NOT_NEEDED);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::OnResponseStarted(
|
|
|
|
++ const GURL& final_url,
|
|
|
|
++ const network::ResourceResponseHead& response_head) {
|
|
|
|
++
|
|
|
|
++ final_url_ = final_url;
|
|
|
|
++ response_code_ = response_head.headers ? response_head.headers->response_code() : -1;
|
|
|
|
++
|
|
|
|
++ if (!response_head.headers->GetLastModifiedValue(&last_modified_))
|
|
|
|
++ LOG(WARNING) << "DownloadFiltersTask: fetching URL '" << final_url.spec() << "' with method " << (min_last_modified_.is_null() ? "GET" : "HEAD") << " (no Last-Modified header)";
|
|
|
|
++ else
|
|
|
|
++ LOG(INFO) << "DownloadFiltersTask: fetching URL '" << final_url.spec() << "' with method " << (min_last_modified_.is_null() ? "GET" : "HEAD");
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::OnDownloadComplete(base::FilePath file_path, int net_error, int64_t content_size) {
|
|
|
|
++ DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
|
|
|
|
++
|
|
|
|
++ const base::TimeTicks download_end_time(base::TimeTicks::Now());
|
|
|
|
++ const base::TimeDelta download_time =
|
|
|
|
++ download_end_time >= download_start_time_
|
|
|
|
++ ? download_end_time - download_start_time_
|
|
|
|
++ : base::TimeDelta();
|
|
|
|
++
|
|
|
|
++ // Consider a 5xx response from the server as an indication to terminate
|
|
|
|
++ // the request and avoid overloading the server in this case.
|
|
|
|
++ // is not accepting requests for the moment.
|
|
|
|
++ int error = -1;
|
|
|
|
++ if (!file_path.empty() && response_code_ == 200) {
|
|
|
|
++ DCHECK_EQ(0, net_error);
|
|
|
|
++ error = 0;
|
|
|
|
++ } else if (response_code_ != -1) {
|
|
|
|
++ error = response_code_;
|
|
|
|
++ } else {
|
|
|
|
++ error = net_error;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ LOG(INFO) << "DownloadFiltersTask: downloaded " << content_size << " bytes in "
|
|
|
|
++ << download_time.InMilliseconds() << "ms from '" << final_url_.spec()
|
|
|
|
++ << "' to '" << file_path << "' with net_error " << net_error << " and error " << error;
|
|
|
|
++
|
|
|
|
++ if (error) {
|
|
|
|
++ TaskComplete(Error::DOWNLOAD_ERROR);
|
|
|
|
++ return;
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
++ file_path_ = file_path;
|
|
|
|
++ TaskComplete(Error::NONE);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::Cancel() {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ LOG(INFO) << "DownloadFiltersTask: update cancelled";
|
|
|
|
++
|
|
|
|
++ // deletion of the simple_url_loader_ will cause cancellation of its active request, if any
|
|
|
|
++
|
|
|
|
++ TaskComplete(Error::UPDATE_CANCELED);
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++void DownloadFiltersTask::TaskComplete(Error error) {
|
|
|
|
++ DCHECK(thread_checker_.CalledOnValidThread());
|
|
|
|
++
|
|
|
|
++ base::ThreadTaskRunnerHandle::Get()->PostTask(
|
|
|
|
++ FROM_HERE, base::BindOnce(std::move(complete_callback_),
|
|
|
|
++ scoped_refptr<DownloadFiltersTask>(this), error));
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++base::Time DownloadFiltersTask::last_modified() {
|
|
|
|
++ return last_modified_;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++base::FilePath DownloadFiltersTask::file_path() {
|
|
|
|
++ return file_path_;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++} // namespace adblock_updater
|
|
|
|
+diff --git a/components/component_updater/download_filters_task.h b/components/component_updater/download_filters_task.h
|
|
|
|
+new file mode 100644
|
|
|
|
+--- /dev/null
|
|
|
|
++++ b/components/component_updater/download_filters_task.h
|
|
|
|
+@@ -0,0 +1,131 @@
|
|
|
|
++/*
|
|
|
|
++ This file is part of Bromite.
|
|
|
|
++
|
|
|
|
++ Bromite is free software: you can redistribute it and/or modify
|
|
|
|
++ it under the terms of the GNU General Public License as published by
|
|
|
|
++ the Free Software Foundation, either version 3 of the License, or
|
|
|
|
++ (at your option) any later version.
|
|
|
|
++
|
|
|
|
++ Bromite is distributed in the hope that it will be useful,
|
|
|
|
++ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
++ GNU General Public License for more details.
|
|
|
|
++
|
|
|
|
++ You should have received a copy of the GNU General Public License
|
|
|
|
++ along with Bromite. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
++*/
|
|
|
|
++
|
|
|
|
++#ifndef COMPONENTS_DOWNLOAD_FILTERS_TASK_H_
|
|
|
|
++#define COMPONENTS_DOWNLOAD_FILTERS_TASK_H_
|
|
|
|
++
|
|
|
|
++#include <string>
|
|
|
|
++#include <vector>
|
|
|
|
++
|
|
|
|
++#include "base/callback.h"
|
|
|
|
++#include "base/macros.h"
|
|
|
|
++#include "base/memory/ref_counted.h"
|
|
|
|
++#include "base/threading/thread_checker.h"
|
|
|
|
++#include "components/update_client/network.h"
|
|
|
|
++#include "url/gurl.h"
|
|
|
|
++#include "base/files/file_path.h"
|
|
|
|
++#include "services/network/public/cpp/shared_url_loader_factory.h"
|
|
|
|
++#include "services/network/public/cpp/simple_url_loader.h"
|
|
|
|
++
|
|
|
|
++namespace adblock_updater {
|
|
|
|
++
|
|
|
|
++// Errors generated as a result of calling Run() or by the service itself (UPDATE_IN_PROGRESS or UPDATE_CANCELED)
|
|
|
|
++enum class Error {
|
|
|
|
++ NONE = 0,
|
|
|
|
++ UPDATE_IN_PROGRESS = 1,
|
|
|
|
++ UPDATE_CANCELED = 2,
|
|
|
|
++ UPDATE_NOT_NEEDED = 3,
|
|
|
|
++ DOWNLOAD_ERROR = 4,
|
|
|
|
++ INVALID_ARGUMENT = 5,
|
|
|
|
++ MAX_VALUE,
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++enum class Event {
|
|
|
|
++ // Sent before the update client does an update check.
|
|
|
|
++ ADBLOCK_CHECKING_FOR_UPDATES = 1,
|
|
|
|
++
|
|
|
|
++ // Sent after the new filters have been downloaded but before the install
|
|
|
|
++ // or the upgrade is attempted.
|
|
|
|
++ ADBLOCK_UPDATE_READY,
|
|
|
|
++
|
|
|
|
++ // Sent when filters are being downloaded.
|
|
|
|
++ ADBLOCK_UPDATE_DOWNLOADING,
|
|
|
|
++
|
|
|
|
++ // Sent when filters have been successfully updated.
|
|
|
|
++ ADBLOCK_UPDATED,
|
|
|
|
++
|
|
|
|
++ // Sent when filters have not been updated because there
|
|
|
|
++ // was no new version available
|
|
|
|
++ //TODO: implement this with the headers check
|
|
|
|
++ ADBLOCK_NOT_UPDATED,
|
|
|
|
++
|
|
|
|
++ // Sent when an error ocurred during an update for any reason, including
|
|
|
|
++ // the update check itself failed, or the download of the update payload
|
|
|
|
++ // failed, or applying the update failed.
|
|
|
|
++ ADBLOCK_UPDATE_ERROR,
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++// Defines a specialized task for updating AdBlock filters.
|
|
|
|
++class DownloadFiltersTask : public base::RefCounted<DownloadFiltersTask> {
|
|
|
|
++ public:
|
|
|
|
++ using Callback =
|
|
|
|
++ base::OnceCallback<void(scoped_refptr<DownloadFiltersTask> task, Error error)>;
|
|
|
|
++
|
|
|
|
++ // |shared_url_network_factory| is injected here for the URL loader factory.
|
|
|
|
++ // |is_foreground| is true when the update task is initiated by the user.
|
|
|
|
++ // |filters_url| is the URL to load filters from.
|
|
|
|
++ // |complete_callback| is called to return the execution flow back to creator of
|
|
|
|
++ // this task when the task is done.
|
|
|
|
++ DownloadFiltersTask(scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory,
|
|
|
|
++ bool is_foreground, const std::string& filters_url, base::Time min_last_modified,
|
|
|
|
++ Callback complete_callback);
|
|
|
|
++
|
|
|
|
++ void Run();
|
|
|
|
++
|
|
|
|
++ void Cancel();
|
|
|
|
++
|
|
|
|
++ base::FilePath file_path();
|
|
|
|
++
|
|
|
|
++ base::Time last_modified();
|
|
|
|
++
|
|
|
|
++ private:
|
|
|
|
++ ~DownloadFiltersTask();
|
|
|
|
++
|
|
|
|
++ void OnDownloadProgress(uint64_t current);
|
|
|
|
++ void OnResponseStarted(const GURL& final_url,
|
|
|
|
++ const network::ResourceResponseHead& response_head);
|
|
|
|
++ void OnDownloadComplete(base::FilePath file_path,
|
|
|
|
++ int net_error,
|
|
|
|
++ int64_t content_size);
|
|
|
|
++ void OnHeadersDownloadComplete(scoped_refptr<net::HttpResponseHeaders> headers);
|
|
|
|
++ void createSimpleURLLoader(bool);
|
|
|
|
++ void internalDownload();
|
|
|
|
++
|
|
|
|
++ // Called when the task has completed either because the task has run or
|
|
|
|
++ // it has been canceled.
|
|
|
|
++ void TaskComplete(Error error);
|
|
|
|
++
|
|
|
|
++ base::ThreadChecker thread_checker_;
|
|
|
|
++ scoped_refptr<network::SharedURLLoaderFactory> shared_url_network_factory_;
|
|
|
|
++ const bool is_foreground_;
|
|
|
|
++ Callback complete_callback_;
|
|
|
|
++ std::unique_ptr<network::SimpleURLLoader> simple_url_loader_;
|
|
|
|
++
|
|
|
|
++ // fields populated while downloading
|
|
|
|
++ base::TimeTicks download_start_time_;
|
|
|
|
++ GURL final_url_, filters_url_;
|
|
|
|
++ int response_code_;
|
|
|
|
++ base::Time last_modified_, min_last_modified_;
|
|
|
|
++ base::FilePath file_path_;
|
|
|
|
++
|
|
|
|
++ friend class base::RefCounted<DownloadFiltersTask>;
|
|
|
|
++ DISALLOW_COPY_AND_ASSIGN(DownloadFiltersTask);
|
|
|
|
++};
|
|
|
|
++
|
|
|
|
++} // namespace update_client
|
|
|
|
++
|
|
|
|
++#endif // COMPONENTS_DOWNLOAD_FILTERS_TASK_H_
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
|
|
|
|
+--- a/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
|
|
|
|
++++ b/components/subresource_filter/content/browser/content_subresource_filter_throttle_manager.cc
|
|
|
|
+@@ -308,6 +308,17 @@ ContentSubresourceFilterThrottleManager::
|
|
|
|
+ throttle->NotifyPageActivationWithRuleset(EnsureRulesetHandle(),
|
|
|
|
+ ad_tagging_state);
|
|
|
|
+ }
|
|
|
|
++
|
|
|
|
++ //TODO: could use same logic as in SubresourceFilterSafeBrowsingActivationThrottle::NotifyResult()
|
|
|
|
++ {
|
|
|
|
++ subresource_filter::ActivationDecision ignored_decision;
|
|
|
|
++ mojom::ActivationState ad_filtering_state;
|
|
|
|
++ ad_filtering_state.activation_level = client_->OnPageActivationComputed(
|
|
|
|
++ navigation_handle, mojom::ActivationLevel::kEnabled, &ignored_decision);
|
|
|
|
++ throttle->NotifyPageActivationWithRuleset(EnsureRulesetHandle(),
|
|
|
|
++ ad_filtering_state);
|
|
|
|
++ }
|
|
|
|
++
|
|
|
|
+ return throttle;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/ruleset_service.cc b/components/subresource_filter/content/browser/ruleset_service.cc
|
|
|
|
+--- a/components/subresource_filter/content/browser/ruleset_service.cc
|
|
|
|
++++ b/components/subresource_filter/content/browser/ruleset_service.cc
|
|
|
|
+@@ -45,9 +45,7 @@ namespace {
|
|
|
|
+
|
|
|
|
+ void RecordIndexAndWriteRulesetResult(
|
|
|
|
+ RulesetService::IndexAndWriteRulesetResult result) {
|
|
|
|
+- UMA_HISTOGRAM_ENUMERATION(
|
|
|
|
+- "SubresourceFilter.WriteRuleset.Result", static_cast<int>(result),
|
|
|
|
+- static_cast<int>(RulesetService::IndexAndWriteRulesetResult::MAX));
|
|
|
|
++ VLOG(1) << "SubresourceFilter.WriteRuleset.Result: " << static_cast<int>(result);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ // Implements operations on a `sentinel file`, which is used as a safeguard to
|
|
|
|
+@@ -197,10 +195,13 @@ RulesetService::RulesetService(
|
|
|
|
+ RulesetService::~RulesetService() {}
|
|
|
|
+
|
|
|
|
+ void RulesetService::IndexAndStoreAndPublishRulesetIfNeeded(
|
|
|
|
+- const UnindexedRulesetInfo& unindexed_ruleset_info) {
|
|
|
|
+- if (unindexed_ruleset_info.content_version.empty())
|
|
|
|
++ const UnindexedRulesetInfo& unindexed_ruleset_info, bool ignore_recent_version) {
|
|
|
|
++ if (unindexed_ruleset_info.content_version.empty()) {
|
|
|
|
++ LOG(INFO) << "RulesetService: ignoring update with empty version.";
|
|
|
|
+ return;
|
|
|
|
++ }
|
|
|
|
+
|
|
|
|
++ if (!ignore_recent_version) {
|
|
|
|
+ // Trying to store a ruleset with the same version for a second time would
|
|
|
|
+ // not only be futile, but would fail on Windows due to "File System
|
|
|
|
+ // Tunneling" as long as the previously stored copy of the rules is still
|
|
|
|
+@@ -210,13 +211,16 @@ void RulesetService::IndexAndStoreAndPublishRulesetIfNeeded(
|
|
|
|
+ if (most_recently_indexed_version.IsCurrentFormatVersion() &&
|
|
|
|
+ most_recently_indexed_version.content_version ==
|
|
|
|
+ unindexed_ruleset_info.content_version) {
|
|
|
|
++ LOG(INFO) << "RulesetService: ignoring update with equal or older version.";
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
++ }
|
|
|
|
+
|
|
|
|
+ // Before initialization, retain information about the most recently supplied
|
|
|
|
+ // unindexed ruleset, to be processed during initialization.
|
|
|
|
+ if (!is_initialized_) {
|
|
|
|
+ queued_unindexed_ruleset_info_ = unindexed_ruleset_info;
|
|
|
|
++ LOG(INFO) << "RulesetService: ignoring update while not initialized.";
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+@@ -235,6 +239,18 @@ IndexedRulesetVersion RulesetService::GetMostRecentlyIndexedVersion() const {
|
|
|
|
+ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
|
|
|
|
+ const base::FilePath& indexed_ruleset_base_dir,
|
|
|
|
+ const UnindexedRulesetInfo& unindexed_ruleset_info) {
|
|
|
|
++ IndexedRulesetVersion version = IndexAndWriteRulesetInternal(indexed_ruleset_base_dir, unindexed_ruleset_info);
|
|
|
|
++ // cleanup temporary file when done
|
|
|
|
++ if (unindexed_ruleset_info.delete_ruleset_path) {
|
|
|
|
++ base::DeleteFile(unindexed_ruleset_info.ruleset_path, false);
|
|
|
|
++ }
|
|
|
|
++ return version;
|
|
|
|
++}
|
|
|
|
++
|
|
|
|
++// static
|
|
|
|
++IndexedRulesetVersion RulesetService::IndexAndWriteRulesetInternal(
|
|
|
|
++ const base::FilePath& indexed_ruleset_base_dir,
|
|
|
|
++ const UnindexedRulesetInfo& unindexed_ruleset_info) {
|
|
|
|
+ base::ScopedBlockingCall scoped_blocking_call(FROM_HERE,
|
|
|
|
+ base::BlockingType::MAY_BLOCK);
|
|
|
|
+
|
|
|
|
+@@ -242,6 +258,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
|
|
|
|
+ unindexed_ruleset_info.ruleset_path,
|
|
|
|
+ base::File::FLAG_OPEN | base::File::FLAG_READ);
|
|
|
|
+ if (!unindexed_ruleset_file.IsValid()) {
|
|
|
|
++ LOG(WARNING) << "RulesetService: failed to open: " << unindexed_ruleset_info.ruleset_path;
|
|
|
|
+ RecordIndexAndWriteRulesetResult(
|
|
|
|
+ IndexAndWriteRulesetResult::FAILED_OPENING_UNINDEXED_RULESET);
|
|
|
|
+ return IndexedRulesetVersion();
|
|
|
|
+@@ -255,6 +272,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
|
|
|
|
+ indexed_ruleset_base_dir, indexed_version);
|
|
|
|
+
|
|
|
|
+ if (!base::CreateDirectory(indexed_ruleset_version_dir)) {
|
|
|
|
++ LOG(WARNING) << "RulesetService: failed to create version dir: " << indexed_ruleset_version_dir;
|
|
|
|
+ RecordIndexAndWriteRulesetResult(
|
|
|
|
+ IndexAndWriteRulesetResult::FAILED_CREATING_VERSION_DIR);
|
|
|
|
+ return IndexedRulesetVersion();
|
|
|
|
+@@ -280,6 +298,7 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
|
|
|
|
+
|
|
|
|
+ RulesetIndexer indexer;
|
|
|
|
+ if (!(*g_index_ruleset_func)(std::move(unindexed_ruleset_file), &indexer)) {
|
|
|
|
++ LOG(WARNING) << "RulesetService: failed parsing.";
|
|
|
|
+ RecordIndexAndWriteRulesetResult(
|
|
|
|
+ IndexAndWriteRulesetResult::FAILED_PARSING_UNINDEXED_RULESET);
|
|
|
|
+ return IndexedRulesetVersion();
|
|
|
|
+@@ -300,6 +319,8 @@ IndexedRulesetVersion RulesetService::IndexAndWriteRuleset(
|
|
|
|
+ if (result != IndexAndWriteRulesetResult::SUCCESS)
|
|
|
|
+ return IndexedRulesetVersion();
|
|
|
|
+
|
|
|
|
++ LOG(INFO) << "RulesetService: successful parsing.";
|
|
|
|
++
|
|
|
|
+ DCHECK(indexed_version.IsValid());
|
|
|
|
+ return indexed_version;
|
|
|
|
+ }
|
|
|
|
+@@ -424,6 +445,7 @@ void RulesetService::IndexAndStoreRuleset(
|
|
|
|
+ void RulesetService::OnWrittenRuleset(WriteRulesetCallback result_callback,
|
|
|
|
+ const IndexedRulesetVersion& version) {
|
|
|
|
+ DCHECK(!result_callback.is_null());
|
|
|
|
++ LOG(INFO) << "RulesetService: valid version: " << version.IsValid();
|
|
|
|
+ if (!version.IsValid())
|
|
|
|
+ return;
|
|
|
|
+ version.SaveToPrefs(local_state_);
|
|
|
|
+@@ -436,7 +458,6 @@ void RulesetService::OpenAndPublishRuleset(
|
|
|
|
+ IndexedRulesetLocator::GetRulesetDataFilePath(
|
|
|
|
+ IndexedRulesetLocator::GetSubdirectoryPathForVersion(
|
|
|
|
+ indexed_ruleset_base_dir_, version));
|
|
|
|
+-
|
|
|
|
+ publisher_->TryOpenAndSetRulesetFile(
|
|
|
|
+ file_path, version.checksum,
|
|
|
|
+ base::BindOnce(&RulesetService::OnRulesetSet, AsWeakPtr()));
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/ruleset_service.h b/components/subresource_filter/content/browser/ruleset_service.h
|
|
|
|
+--- a/components/subresource_filter/content/browser/ruleset_service.h
|
|
|
|
++++ b/components/subresource_filter/content/browser/ruleset_service.h
|
|
|
|
+@@ -173,7 +173,7 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
|
|
|
|
+ //
|
|
|
|
+ // Virtual so that it can be mocked out in tests.
|
|
|
|
+ virtual void IndexAndStoreAndPublishRulesetIfNeeded(
|
|
|
|
+- const UnindexedRulesetInfo& unindexed_ruleset_info);
|
|
|
|
++ const UnindexedRulesetInfo& unindexed_ruleset_info, bool ignore_recent_version = false);
|
|
|
|
+
|
|
|
|
+ // Get the ruleset version associated with the current local_state_.
|
|
|
|
+ IndexedRulesetVersion GetMostRecentlyIndexedVersion() const;
|
|
|
|
+@@ -206,6 +206,11 @@ class RulesetService : public base::SupportsWeakPtr<RulesetService> {
|
|
|
|
+ const base::FilePath& indexed_ruleset_base_dir,
|
|
|
|
+ const UnindexedRulesetInfo& unindexed_ruleset_info);
|
|
|
|
+
|
|
|
|
++ // internal function used to wrap the temporary file deletion for unindexed rulesets
|
|
|
|
++ static IndexedRulesetVersion IndexAndWriteRulesetInternal(
|
|
|
|
++ const base::FilePath& indexed_ruleset_base_dir,
|
|
|
|
++ const UnindexedRulesetInfo& unindexed_ruleset_info);
|
|
|
|
++
|
|
|
|
+ // Reads the rules from the |unindexed_ruleset_file|, and indexes them using
|
|
|
|
+ // |indexer|. Returns whether the entire ruleset could be parsed.
|
|
|
|
+ static bool IndexRuleset(base::File unindexed_ruleset_file,
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/ruleset_version.cc b/components/subresource_filter/content/browser/ruleset_version.cc
|
|
|
|
+--- a/components/subresource_filter/content/browser/ruleset_version.cc
|
|
|
|
++++ b/components/subresource_filter/content/browser/ruleset_version.cc
|
|
|
|
+@@ -25,6 +25,7 @@ const char kSubresourceFilterRulesetChecksum[] =
|
|
|
|
+ } // namespace
|
|
|
|
+
|
|
|
|
+ UnindexedRulesetInfo::UnindexedRulesetInfo() = default;
|
|
|
|
++UnindexedRulesetInfo::UnindexedRulesetInfo(const UnindexedRulesetInfo& other) = default;
|
|
|
|
+ UnindexedRulesetInfo::~UnindexedRulesetInfo() = default;
|
|
|
|
+
|
|
|
|
+ IndexedRulesetVersion::IndexedRulesetVersion() = default;
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/ruleset_version.h b/components/subresource_filter/content/browser/ruleset_version.h
|
|
|
|
+--- a/components/subresource_filter/content/browser/ruleset_version.h
|
|
|
|
++++ b/components/subresource_filter/content/browser/ruleset_version.h
|
|
|
|
+@@ -25,6 +25,7 @@ namespace subresource_filter {
|
|
|
|
+ // filtering rules on disk.
|
|
|
|
+ struct UnindexedRulesetInfo {
|
|
|
|
+ UnindexedRulesetInfo();
|
|
|
|
++ UnindexedRulesetInfo(const UnindexedRulesetInfo& other);
|
|
|
|
+ ~UnindexedRulesetInfo();
|
|
|
|
+
|
|
|
|
+ // The version of the ruleset contents. Because the wire format of unindexed
|
|
|
|
+@@ -43,6 +44,10 @@ struct UnindexedRulesetInfo {
|
|
|
|
+ // can be indicated not only by setting |license_path| to empty, but also by
|
|
|
|
+ // setting it to any non existent path.
|
|
|
|
+ base::FilePath license_path;
|
|
|
|
++
|
|
|
|
++ // Whether to delete or not the ruleset path once done indexing; useful for disposal
|
|
|
|
++ // of temporary files.
|
|
|
|
++ bool delete_ruleset_path;
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+ // Encapsulates the combination of the binary format version of the indexed
|
|
|
|
+diff --git a/components/subresource_filter/content/browser/verified_ruleset_dealer.cc b/components/subresource_filter/content/browser/verified_ruleset_dealer.cc
|
|
|
|
+--- a/components/subresource_filter/content/browser/verified_ruleset_dealer.cc
|
|
|
|
++++ b/components/subresource_filter/content/browser/verified_ruleset_dealer.cc
|
|
|
|
+@@ -35,6 +35,8 @@ base::File VerifiedRulesetDealer::OpenAndSetRulesetFile(
|
|
|
|
+ TRACE_EVENT1(TRACE_DISABLED_BY_DEFAULT("loading"),
|
|
|
|
+ "VerifiedRulesetDealer::OpenAndSetRulesetFile", "file_valid",
|
|
|
|
+ file.IsValid());
|
|
|
|
++
|
|
|
|
++ LOG(INFO) << "OpenAndSetRulesetFile: " << file_path << " is valid: " << file.IsValid();
|
|
|
|
+ if (file.IsValid()) {
|
|
|
|
+ SetRulesetFile(file.Duplicate());
|
|
|
|
+ expected_checksum_ = expected_checksum;
|
|
|
|
+diff --git a/components/subresource_filter/core/browser/subresource_filter_features.cc b/components/subresource_filter/core/browser/subresource_filter_features.cc
|
|
|
|
+--- a/components/subresource_filter/core/browser/subresource_filter_features.cc
|
|
|
|
++++ b/components/subresource_filter/core/browser/subresource_filter_features.cc
|
|
|
|
+@@ -53,69 +53,7 @@ class CommaSeparatedStrings {
|
|
|
|
+ DISALLOW_COPY_AND_ASSIGN(CommaSeparatedStrings);
|
|
|
|
+ };
|
|
|
|
+
|
|
|
|
+-std::string TakeVariationParamOrReturnEmpty(
|
|
|
|
+- std::map<std::string, std::string>* params,
|
|
|
|
+- const std::string& key) {
|
|
|
|
+- auto it = params->find(key);
|
|
|
|
+- if (it == params->end())
|
|
|
|
+- return std::string();
|
|
|
|
+- std::string value = std::move(it->second);
|
|
|
|
+- params->erase(it);
|
|
|
|
+- return value;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-mojom::ActivationLevel ParseActivationLevel(
|
|
|
|
+- const base::StringPiece activation_level) {
|
|
|
|
+- if (base::LowerCaseEqualsASCII(activation_level, kActivationLevelEnabled))
|
|
|
|
+- return mojom::ActivationLevel::kEnabled;
|
|
|
|
+- else if (base::LowerCaseEqualsASCII(activation_level, kActivationLevelDryRun))
|
|
|
|
+- return mojom::ActivationLevel::kDryRun;
|
|
|
|
+- return mojom::ActivationLevel::kDisabled;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-ActivationScope ParseActivationScope(const base::StringPiece activation_scope) {
|
|
|
|
+- if (base::LowerCaseEqualsASCII(activation_scope, kActivationScopeAllSites))
|
|
|
|
+- return ActivationScope::ALL_SITES;
|
|
|
|
+- else if (base::LowerCaseEqualsASCII(activation_scope,
|
|
|
|
+- kActivationScopeActivationList))
|
|
|
|
+- return ActivationScope::ACTIVATION_LIST;
|
|
|
|
+- return ActivationScope::NO_SITES;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-ActivationList ParseActivationList(std::string activation_lists_string) {
|
|
|
|
+- CommaSeparatedStrings activation_lists(std::move(activation_lists_string));
|
|
|
|
+- if (activation_lists.CaseInsensitiveContains(
|
|
|
|
+- kActivationListPhishingInterstitial)) {
|
|
|
|
+- return ActivationList::PHISHING_INTERSTITIAL;
|
|
|
|
+- } else if (activation_lists.CaseInsensitiveContains(
|
|
|
|
+- kActivationListSocialEngineeringAdsInterstitial)) {
|
|
|
|
+- return ActivationList::SOCIAL_ENG_ADS_INTERSTITIAL;
|
|
|
|
+- } else if (activation_lists.CaseInsensitiveContains(
|
|
|
|
+- kActivationListSubresourceFilter)) {
|
|
|
|
+- return ActivationList::SUBRESOURCE_FILTER;
|
|
|
|
+- } else if (activation_lists.CaseInsensitiveContains(
|
|
|
|
+- kActivationListBetterAds)) {
|
|
|
|
+- return ActivationList::BETTER_ADS;
|
|
|
|
+- }
|
|
|
|
+- return ActivationList::NONE;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-// Will return a value between 0 and 1 inclusive.
|
|
|
|
+-double ParsePerformanceMeasurementRate(const std::string& rate) {
|
|
|
|
+- double value = 0.0;
|
|
|
|
+- if (!base::StringToDouble(rate, &value) || value < 0)
|
|
|
|
+- return 0.0;
|
|
|
|
+- return value < 1 ? value : 1;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-int ParseInt(const base::StringPiece value) {
|
|
|
|
+- int result = 0;
|
|
|
|
+- base::StringToInt(value, &result);
|
|
|
|
+- return result;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+-std::vector<Configuration> FillEnabledPresetConfigurations(
|
|
|
|
+- std::map<std::string, std::string>* params) {
|
|
|
|
++std::vector<Configuration> FillEnabledPresetConfigurations() {
|
|
|
|
+ // If ad tagging is enabled, turn on the dryrun automatically.
|
|
|
|
+ bool ad_tagging_enabled = base::FeatureList::IsEnabled(kAdTagging);
|
|
|
|
+ const struct {
|
|
|
|
+@@ -123,25 +61,18 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
|
|
|
|
+ bool enabled_by_default;
|
|
|
|
+ Configuration (*factory_method)();
|
|
|
|
+ } kAvailablePresetConfigurations[] = {
|
|
|
|
+- {kPresetLiveRunOnPhishingSites, true,
|
|
|
|
++ {kPresetLiveRunOnPhishingSites, false,
|
|
|
|
+ &Configuration::MakePresetForLiveRunOnPhishingSites},
|
|
|
|
+ {kPresetPerformanceTestingDryRunOnAllSites, ad_tagging_enabled,
|
|
|
|
+ &Configuration::MakePresetForPerformanceTestingDryRunOnAllSites},
|
|
|
|
+- {kPresetLiveRunForBetterAds, true,
|
|
|
|
++ {kPresetLiveRunForBetterAds, false,
|
|
|
|
+ &Configuration::MakePresetForLiveRunForBetterAds},
|
|
|
|
+ {kPresetLiveRunOnAllSites, true,
|
|
|
|
+ &Configuration::MakePresetForLiveRunOnAllSites}};
|
|
|
|
+
|
|
|
|
+- CommaSeparatedStrings enabled_presets(
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kEnablePresetsParameterName));
|
|
|
|
+- CommaSeparatedStrings disabled_presets(
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kDisablePresetsParameterName));
|
|
|
|
+-
|
|
|
|
+ std::vector<Configuration> enabled_configurations;
|
|
|
|
+ for (const auto& available_preset : kAvailablePresetConfigurations) {
|
|
|
|
+- if ((enabled_presets.CaseInsensitiveContains(available_preset.name) ||
|
|
|
|
+- available_preset.enabled_by_default) &&
|
|
|
|
+- !disabled_presets.CaseInsensitiveContains(available_preset.name)) {
|
|
|
|
++ if (available_preset.enabled_by_default) {
|
|
|
|
+ enabled_configurations.push_back(available_preset.factory_method());
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+@@ -149,46 +80,10 @@ std::vector<Configuration> FillEnabledPresetConfigurations(
|
|
|
|
+ return enabled_configurations;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+-Configuration ParseExperimentalConfiguration(
|
|
|
|
+- std::map<std::string, std::string>* params) {
|
|
|
|
+- Configuration configuration;
|
|
|
|
+-
|
|
|
|
+- // ActivationConditions:
|
|
|
|
+- configuration.activation_conditions.activation_scope = ParseActivationScope(
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kActivationScopeParameterName));
|
|
|
|
+-
|
|
|
|
+- configuration.activation_conditions.activation_list = ParseActivationList(
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kActivationListsParameterName));
|
|
|
|
+-
|
|
|
|
+- configuration.activation_conditions.priority =
|
|
|
|
+- ParseInt(TakeVariationParamOrReturnEmpty(
|
|
|
|
+- params, kActivationPriorityParameterName));
|
|
|
|
+-
|
|
|
|
+- // ActivationOptions:
|
|
|
|
+- configuration.activation_options.activation_level = ParseActivationLevel(
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kActivationLevelParameterName));
|
|
|
|
+-
|
|
|
|
+- configuration.activation_options.performance_measurement_rate =
|
|
|
|
+- ParsePerformanceMeasurementRate(TakeVariationParamOrReturnEmpty(
|
|
|
|
+- params, kPerformanceMeasurementRateParameterName));
|
|
|
|
+-
|
|
|
|
+- // GeneralSettings:
|
|
|
|
+- configuration.general_settings.ruleset_flavor =
|
|
|
|
+- TakeVariationParamOrReturnEmpty(params, kRulesetFlavorParameterName);
|
|
|
|
+-
|
|
|
|
+- return configuration;
|
|
|
|
+-}
|
|
|
|
+-
|
|
|
|
+ std::vector<Configuration> ParseEnabledConfigurations() {
|
|
|
|
+- std::map<std::string, std::string> params;
|
|
|
|
+- base::GetFieldTrialParamsByFeature(kSafeBrowsingSubresourceFilter, ¶ms);
|
|
|
|
+-
|
|
|
|
+ std::vector<Configuration> configs;
|
|
|
|
+ if (base::FeatureList::IsEnabled(kSafeBrowsingSubresourceFilter))
|
|
|
|
+- configs = FillEnabledPresetConfigurations(¶ms);
|
|
|
|
+-
|
|
|
|
+- Configuration experimental_config = ParseExperimentalConfiguration(¶ms);
|
|
|
|
+- configs.push_back(std::move(experimental_config));
|
|
|
|
++ configs = FillEnabledPresetConfigurations();
|
|
|
|
+
|
|
|
|
+ return configs;
|
|
|
|
+ }
|
|
|
|
+diff --git a/components/subresource_filter/core/common/common_features.cc b/components/subresource_filter/core/common/common_features.cc
|
|
|
|
+--- a/components/subresource_filter/core/common/common_features.cc
|
|
|
|
++++ b/components/subresource_filter/core/common/common_features.cc
|
|
|
|
+@@ -6,6 +6,6 @@
|
|
|
|
+
|
|
|
|
+ namespace subresource_filter {
|
|
|
|
+
|
|
|
|
+-const base::Feature kAdTagging{"AdTagging", base::FEATURE_ENABLED_BY_DEFAULT};
|
|
|
|
++const base::Feature kAdTagging{"AdTagging", base::FEATURE_DISABLED_BY_DEFAULT};
|
|
|
|
+
|
|
|
|
+ } // namespace subresource_filter
|
|
|
|
+diff --git a/content/browser/frame_host/navigation_throttle_runner.cc b/content/browser/frame_host/navigation_throttle_runner.cc
|
|
|
|
+--- a/content/browser/frame_host/navigation_throttle_runner.cc
|
|
|
|
++++ b/content/browser/frame_host/navigation_throttle_runner.cc
|
|
|
|
+@@ -8,7 +8,6 @@
|
|
|
|
+ #include "content/browser/frame_host/ancestor_throttle.h"
|
|
|
|
+ #include "content/browser/frame_host/blocked_scheme_navigation_throttle.h"
|
|
|
|
+ #include "content/browser/frame_host/form_submission_throttle.h"
|
|
|
|
+-#include "content/browser/frame_host/history_navigation_ablation_study_navigation_throttle.h"
|
|
|
|
+ #include "content/browser/frame_host/mixed_content_navigation_throttle.h"
|
|
|
|
+ #include "content/browser/frame_host/navigation_handle_impl.h"
|
|
|
|
+ #include "content/browser/frame_host/navigator_delegate.h"
|
|
|
|
+@@ -118,15 +117,6 @@ void NavigationThrottleRunner::RegisterNavigationThrottles() {
|
|
|
|
+ devtools_instrumentation::CreateNavigationThrottles(handle)) {
|
|
|
|
+ AddThrottle(std::move(throttle));
|
|
|
|
+ }
|
|
|
|
+-
|
|
|
|
+- // Delay navigation for an ablation study (if needed).
|
|
|
|
+- AddThrottle(HistoryNavigationAblationStudyNavigationThrottle::
|
|
|
|
+- MaybeCreateForNavigation(handle));
|
|
|
|
+-
|
|
|
|
+- // Insert all testing NavigationThrottles last.
|
|
|
|
+- throttles_.insert(throttles_.end(),
|
|
|
|
+- std::make_move_iterator(testing_throttles.begin()),
|
|
|
|
+- std::make_move_iterator(testing_throttles.end()));
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ NavigationThrottle* NavigationThrottleRunner::GetDeferringThrottle() const {
|
|
|
|
+--
|
|
|
|
+2.11.0
|
|
|
|
+
|