Chromium Code Reviews| Index: chrome/browser/browsing_data/browsing_data_remover_filter.cc |
| diff --git a/chrome/browser/browsing_data/browsing_data_remover_filter.cc b/chrome/browser/browsing_data/browsing_data_remover_filter.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..75b667897b8fea441502fe470d0749e96352600a |
| --- /dev/null |
| +++ b/chrome/browser/browsing_data/browsing_data_remover_filter.cc |
| @@ -0,0 +1,163 @@ |
| +// Copyright 2016 The Chromium Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include <string> |
| +#include <vector> |
| + |
| +#include "base/bind.h" |
| +#include "chrome/browser/browsing_data/browsing_data_remover_filter.h" |
| +#include "components/content_settings/core/common/content_settings_pattern.h" |
| +#include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| + |
| +using net::registry_controlled_domains::GetDomainAndRegistry; |
| +using net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES; |
| +using Relation = ContentSettingsPattern::Relation; |
| + |
| +namespace { |
| + |
| +bool NoopFilter(const GURL& url) { |
| + return true; |
| +} |
| + |
| +} // namespace |
| + |
| +BrowsingDataRemoverFilter::BrowsingDataRemoverFilter(Mode mode) : mode_(mode) {} |
| + |
| +BrowsingDataRemoverFilter::~BrowsingDataRemoverFilter() {} |
| + |
| +void BrowsingDataRemoverFilter::AddOrigin(const url::Origin& origin) { |
| + // TODO(msramek): Optimize OriginFilterBuilder for larger filters if needed. |
| + DCHECK_LE(origin_list_.size(), 10U) << "OriginFilterBuilder is only suitable " |
| + "for creating small filters."; |
| + |
| + // By limiting the filter to non-unique origins, we can guarantee that |
| + // origin1 < origin2 && origin1 > origin2 <=> origin1.isSameOrigin(origin2). |
| + // This means that std::set::find() will use the same semantics for |
| + // origin comparison as Origin::IsSameOriginWith(). Furthermore, this |
| + // means that two filters are equal iff they are equal element-wise. |
| + DCHECK(!origin.unique()) << "Invalid origin passed into OriginFilter."; |
| + |
| + // TODO(msramek): All urls with file scheme currently map to the same |
| + // origin. This is currently not a problem, but if it becomes one, |
| + // consider recognizing the URL path. |
| + |
| + origin_list_.insert(origin); |
| +} |
| + |
| +void BrowsingDataRemoverFilter::AddRegisterableDomain( |
| + const std::string& domain) { |
| + DCHECK_EQ(GetDomainAndRegistry("www." + domain, INCLUDE_PRIVATE_REGISTRIES), |
|
msramek
2016/04/07 16:19:12
Please explain this DCHECK.
dmurph
2016/04/08 23:33:45
Done.
|
| + domain); |
| + domain_list_.insert(domain); |
| +} |
| + |
| +void BrowsingDataRemoverFilter::SetMode(Mode mode) { |
| + mode_ = mode; |
| +} |
| + |
| +bool BrowsingDataRemoverFilter::IsEmptyBlacklist() const { |
| + return mode_ == Mode::BLACKLIST && origin_list_.empty(); |
| +} |
| + |
| +base::Callback<bool(const GURL&)> |
| +BrowsingDataRemoverFilter::BuildSameOriginOrDomainFilter() const { |
| + std::set<url::Origin>* origins = new std::set<url::Origin>(origin_list_); |
| + std::set<std::string>* domains = new std::set<std::string>(domain_list_); |
| + return base::Bind(&BrowsingDataRemoverFilter::MatchesURL, |
| + base::Owned(origins), base::Owned(domains), mode_); |
| +} |
| + |
| +base::Callback<bool(const ContentSettingsPattern& pattern)> |
| +BrowsingDataRemoverFilter::BuildWebsiteSettingsPatternMatchesFilter() const { |
| + std::set<url::Origin>* origins = new std::set<url::Origin>(origin_list_); |
| + std::vector<ContentSettingsPattern>* patterns_from_domains = |
| + new std::vector<ContentSettingsPattern>(domain_list_.size()); |
| + |
| + ContentSettingsPattern::BuilderInterface* builder = |
| + ContentSettingsPattern::CreateBuilder(false); |
|
msramek
2016/04/07 16:19:12
nit: /* validate */
dmurph
2016/04/08 23:33:45
Done.
|
| + for (const std::string& domain : domain_list_) { |
| + patterns_from_domains->push_back(builder->WithSchemeWildcard() |
| + ->WithPortWildcard() |
| + ->WithDomainWildcard() |
| + ->WithPathWildcard() |
| + ->WithHost(domain) |
| + ->Build()); |
| + } |
| + |
| + return base::Bind(&BrowsingDataRemoverFilter::MatchesWebsiteSettingsPattern, |
| + base::Owned(origins), base::Owned(patterns_from_domains), |
| + mode_); |
| +} |
| + |
| +base::Callback<bool(const net::CanonicalCookie& pattern)> |
| +BrowsingDataRemoverFilter::BuildDomainCookieFilter() const { |
| + std::set<std::string>* domains_and_ips = |
| + new std::set<std::string>(domain_list_); |
| + for (const url::Origin origin : origin_list_) { |
| + GURL origin_url(origin.Serialize()); |
| + if (origin_url.HostIsIPAddress()) { |
| + domains_and_ips->insert(origin_url.host()); |
| + } else { |
| + domains_and_ips->insert( |
| + GetDomainAndRegistry(origin.host(), INCLUDE_PRIVATE_REGISTRIES)); |
| + } |
| + } |
| + return base::Bind( |
| + &BrowsingDataRemoverFilter::MatchesCookieForRegisterableDomainsAndIPs, |
| + base::Owned(domains_and_ips), mode_); |
| +} |
| + |
| +// static |
| +base::Callback<bool(const GURL&)> BrowsingDataRemoverFilter::BuildNoopFilter() { |
| + return base::Bind(&NoopFilter); |
| +} |
| + |
| +// static |
| +bool BrowsingDataRemoverFilter::MatchesURL( |
| + std::set<url::Origin>* origins, |
| + std::set<std::string>* registerable_domains, |
| + Mode mode, |
| + const GURL& url) { |
| + return (((origins->find(url::Origin(url)) != origins->end()) || |
| + (registerable_domains->find( |
| + GetDomainAndRegistry(url, INCLUDE_PRIVATE_REGISTRIES)) != |
| + registerable_domains->end())) == (mode == WHITELIST)); |
| +} |
| + |
| +// static |
| +bool BrowsingDataRemoverFilter::MatchesWebsiteSettingsPattern( |
| + std::set<url::Origin>* origins, |
| + std::vector<ContentSettingsPattern>* domain_patterns, |
| + Mode mode, |
| + const ContentSettingsPattern& pattern) { |
| + for (const url::Origin& origin : *origins) { |
| + if (pattern.Matches(GURL(origin.Serialize()))) |
| + return mode == WHITELIST; |
| + } |
| + for (const ContentSettingsPattern& domain : *domain_patterns) { |
| + Relation relation = pattern.Compare(domain); |
| + if (relation == Relation::IDENTITY || relation == Relation::PREDECESSOR) |
| + return mode == WHITELIST; |
| + } |
| + return mode != WHITELIST; |
| +} |
| + |
| +// static |
| +bool BrowsingDataRemoverFilter::MatchesCookieForRegisterableDomainsAndIPs( |
| + std::set<std::string>* domains_and_ips, |
| + Mode mode, |
| + const net::CanonicalCookie& cookie) { |
| + if (domains_and_ips->empty()) |
| + return mode == BLACKLIST; |
| + std::string cookie_domain = cookie.Domain(); |
| + if (cookie.IsDomainCookie()) |
| + cookie_domain = cookie_domain.substr(1); |
| + std::string parsed_cookie_domain = |
| + GetDomainAndRegistry(cookie_domain, INCLUDE_PRIVATE_REGISTRIES); |
| + // This means we're an IP address. |
| + if (parsed_cookie_domain.empty()) |
| + parsed_cookie_domain = cookie_domain; |
| + return (mode == WHITELIST) == (domains_and_ips->find(parsed_cookie_domain) != |
| + domains_and_ips->end()); |
| +} |