| Index: extensions/browser/api/declarative_net_request/matcher_util.cc
|
| diff --git a/extensions/browser/api/declarative_net_request/matcher_util.cc b/extensions/browser/api/declarative_net_request/matcher_util.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..7236282b4ad4c31c33502d48e45029117a2021a3
|
| --- /dev/null
|
| +++ b/extensions/browser/api/declarative_net_request/matcher_util.cc
|
| @@ -0,0 +1,188 @@
|
| +// Copyright 2017 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 "extensions/browser/api/declarative_net_request/matcher_util.h"
|
| +
|
| +#include "base/files/file_util.h"
|
| +#include "base/files/memory_mapped_file.h"
|
| +#include "base/memory/ptr_util.h"
|
| +#include "base/metrics/histogram_macros.h"
|
| +#include "base/threading/thread_restrictions.h"
|
| +#include "components/subresource_filter/core/common/first_party_origin.h"
|
| +#include "components/subresource_filter/core/common/flat/extension_metadata_generated.h"
|
| +#include "content/public/browser/resource_request_info.h"
|
| +#include "extensions/browser/info_map.h"
|
| +#include "net/url_request/url_request.h"
|
| +
|
| +namespace extensions {
|
| +namespace declarative_net_request {
|
| +
|
| +namespace {
|
| +
|
| +ElementType ToElementType(content::ResourceType type) {
|
| + switch (type) {
|
| + case content::RESOURCE_TYPE_LAST_TYPE:
|
| + case content::RESOURCE_TYPE_PREFETCH:
|
| + case content::RESOURCE_TYPE_CSP_REPORT: // TODO
|
| + case content::RESOURCE_TYPE_SUB_RESOURCE: // TODO
|
| + return ElementType::ElementType_OTHER;
|
| + case content::RESOURCE_TYPE_SCRIPT:
|
| + case content::RESOURCE_TYPE_WORKER:
|
| + case content::RESOURCE_TYPE_SHARED_WORKER:
|
| + case content::RESOURCE_TYPE_SERVICE_WORKER:
|
| + return ElementType::ElementType_SCRIPT;
|
| + case content::RESOURCE_TYPE_IMAGE:
|
| + case content::RESOURCE_TYPE_FAVICON:
|
| + return ElementType::ElementType_IMAGE;
|
| + case content::RESOURCE_TYPE_STYLESHEET:
|
| + return ElementType::ElementType_STYLESHEET;
|
| + case content::RESOURCE_TYPE_OBJECT:
|
| + case content::RESOURCE_TYPE_PLUGIN_RESOURCE: // TODO
|
| + return ElementType::ElementType_OBJECT;
|
| + case content::RESOURCE_TYPE_XHR:
|
| + return ElementType::ElementType_XMLHTTPREQUEST;
|
| + case content::RESOURCE_TYPE_MAIN_FRAME: // TODO
|
| + case content::RESOURCE_TYPE_SUB_FRAME:
|
| + return ElementType::ElementType_SUBDOCUMENT;
|
| + case content::RESOURCE_TYPE_PING:
|
| + return ElementType::ElementType_PING;
|
| + case content::RESOURCE_TYPE_MEDIA:
|
| + return ElementType::ElementType_MEDIA;
|
| + case content::RESOURCE_TYPE_FONT_RESOURCE:
|
| + return ElementType::ElementType_FONT;
|
| + }
|
| + NOTREACHED();
|
| + return ElementType::ElementType_OTHER;
|
| +}
|
| +
|
| +subresource_filter::proto::ElementType ToProtoElementType(ElementType type) {
|
| + switch (type) {
|
| + case ElementType::ElementType_OTHER:
|
| + return subresource_filter::proto::ELEMENT_TYPE_OTHER;
|
| + case ElementType::ElementType_SCRIPT:
|
| + return subresource_filter::proto::ELEMENT_TYPE_SCRIPT;
|
| + case ElementType::ElementType_IMAGE:
|
| + return subresource_filter::proto::ELEMENT_TYPE_IMAGE;
|
| + case ElementType::ElementType_STYLESHEET:
|
| + return subresource_filter::proto::ELEMENT_TYPE_STYLESHEET;
|
| + case ElementType::ElementType_OBJECT:
|
| + return subresource_filter::proto::ELEMENT_TYPE_OBJECT;
|
| + case ElementType::ElementType_XMLHTTPREQUEST:
|
| + return subresource_filter::proto::ELEMENT_TYPE_XMLHTTPREQUEST;
|
| + case ElementType::ElementType_OBJECT_SUBREQUEST:
|
| + return subresource_filter::proto::ELEMENT_TYPE_OBJECT_SUBREQUEST;
|
| + case ElementType::ElementType_SUBDOCUMENT:
|
| + return subresource_filter::proto::ELEMENT_TYPE_SUBDOCUMENT;
|
| + case ElementType::ElementType_PING:
|
| + return subresource_filter::proto::ELEMENT_TYPE_PING;
|
| + case ElementType::ElementType_MEDIA:
|
| + return subresource_filter::proto::ELEMENT_TYPE_MEDIA;
|
| + case ElementType::ElementType_FONT:
|
| + return subresource_filter::proto::ELEMENT_TYPE_FONT;
|
| + case ElementType::ElementType_POPUP:
|
| + return subresource_filter::proto::ELEMENT_TYPE_POPUP;
|
| + case ElementType::ElementType_WEBSOCKET:
|
| + return subresource_filter::proto::ELEMENT_TYPE_WEBSOCKET;
|
| + default:
|
| + NOTREACHED();
|
| + return subresource_filter::proto::ELEMENT_TYPE_UNSPECIFIED;
|
| + }
|
| +}
|
| +
|
| +ElementType GetElementType(const net::URLRequest* request) {
|
| + DCHECK(request);
|
| + if (request->url().SchemeIsWSOrWSS())
|
| + return ElementType::ElementType_WEBSOCKET;
|
| + const auto* info = content::ResourceRequestInfo::ForRequest(request);
|
| + return info ? ToElementType(info->GetResourceType())
|
| + : ElementType::ElementType_OTHER;
|
| +}
|
| +
|
| +} // namespace
|
| +
|
| +ExtensionIndexedRulesetMatcher::ExtensionIndexedRulesetMatcher(
|
| + std::unique_ptr<base::MemoryMappedFile,
|
| + content::BrowserThread::DeleteOnFileThread> ruleset_file)
|
| + : ruleset_file_(std::move(ruleset_file)),
|
| + root_(flat::GetExtensionIndexedRuleset(ruleset_file_->data())),
|
| + blacklist_matcher_(root_->blacklist_index()),
|
| + whitelist_matcher_(root_->whitelist_index()),
|
| + redirect_matcher_(root_->redirect_index()),
|
| + extension_metdata_(root_->extension_metdata()) {}
|
| +
|
| +bool ExtensionIndexedRulesetMatcher::ShouldBlockRequest(
|
| + const GURL& url,
|
| + const url::Origin& first_party_origin,
|
| + ElementType element_type,
|
| + bool is_third_party) {
|
| + return !!blacklist_matcher_.FindMatch(
|
| + url, first_party_origin, ToProtoElementType(element_type),
|
| + subresource_filter::proto::ACTIVATION_TYPE_UNSPECIFIED,
|
| + is_third_party, false) &&
|
| + !whitelist_matcher_.FindMatch(
|
| + url, first_party_origin, ToProtoElementType(element_type),
|
| + subresource_filter::proto::ACTIVATION_TYPE_UNSPECIFIED,
|
| + is_third_party, false);
|
| +}
|
| +
|
| +bool ShouldBlockRequest(void* BrowserContext,
|
| + const InfoMap* info_map,
|
| + net::URLRequest* request) {
|
| + SCOPED_UMA_HISTOGRAM_TIMER("DNR.ShouldBlockRequest");
|
| + const GURL& url = request->url();
|
| + const base::Optional<url::Origin> initiator = request->initiator();
|
| + const url::Origin first_party_origin =
|
| + initiator ? initiator.value() : url::Origin();
|
| + ElementType element_type = GetElementType(request);
|
| + const bool is_third_party =
|
| + subresource_filter::FirstPartyOrigin::IsThirdParty(url,
|
| + first_party_origin);
|
| +
|
| + for (const auto& pair : *info_map->ruleset_manager()->rules_map()) {
|
| + // const string& extension_id = pair.first.id;
|
| +
|
| + if (pair.second->ShouldBlockRequest(url, first_party_origin, element_type,
|
| + is_third_party))
|
| + return true;
|
| + }
|
| + return false;
|
| +}
|
| +
|
| +std::unique_ptr<ExtensionIndexedRulesetMatcher>
|
| +CreateVerifiedExtensionIndexedRulesetMatcher(
|
| + const base::FilePath& indexed_ruleset_path) {
|
| + SCOPED_UMA_HISTOGRAM_TIMER("DNR.LoadRulesetMatcher");
|
| + base::ThreadRestrictions::AssertIOAllowed();
|
| +
|
| + // TODO log error uma.
|
| + if (!base::PathExists(indexed_ruleset_path)) {
|
| + NOTREACHED() << "Ruleset file does not exist";
|
| + return nullptr;
|
| + }
|
| +
|
| + std::unique_ptr<base::MemoryMappedFile,
|
| + content::BrowserThread::DeleteOnFileThread>
|
| + ruleset_file(new base::MemoryMappedFile());
|
| + LOG(ERROR) << "--------indexed_ruleset_path " << indexed_ruleset_path.value()
|
| + << "\n";
|
| + if (!ruleset_file->Initialize(indexed_ruleset_path,
|
| + base::MemoryMappedFile::READ_ONLY)) {
|
| + NOTREACHED() << "Error reading indexed ruleset";
|
| + return nullptr;
|
| + }
|
| +
|
| + LOG(ERROR) << "--------initialized ruleset\n";
|
| +
|
| + // TODO we should also verify file checksum.
|
| + flatbuffers::Verifier verifier(ruleset_file->data(), ruleset_file->length());
|
| + if (!flat::VerifyExtensionIndexedRulesetBuffer(verifier)) {
|
| + NOTREACHED() << "Buffer could not be verified";
|
| + }
|
| +
|
| + return base::MakeUnique<ExtensionIndexedRulesetMatcher>(
|
| + std::move(ruleset_file));
|
| +}
|
| +
|
| +} // namespace declarative_net_request
|
| +} // namespace extensions
|
|
|