Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(681)

Unified Diff: extensions/browser/api/declarative_net_request/ruleset_manager.cc

Issue 2881453002: DNR Prototype: With flatbuffers
Patch Set: -- Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: extensions/browser/api/declarative_net_request/ruleset_manager.cc
diff --git a/extensions/browser/api/declarative_net_request/ruleset_manager.cc b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
new file mode 100644
index 0000000000000000000000000000000000000000..391a8c9c1747a0b4355f71b63c6461000f7c7044
--- /dev/null
+++ b/extensions/browser/api/declarative_net_request/ruleset_manager.cc
@@ -0,0 +1,251 @@
+// 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/ruleset_manager.h"
+#include "base/threading/thread_restrictions.h"
+#include "components/subresource_filter/core/common/flat/extension_metadata_generated.h"
+#include "components/subresource_filter/core/common/flat/url_pattern_index_generated.h"
+#include "content/public/browser/browser_thread.h"
+#include "extensions/browser/info_map.h"
+#include "extensions/common/api/declarative_net_request/indexed_rule.h"
+#include "extensions/common/api/declarative_net_request/ruleset_indexer.h"
+
+namespace extensions {
+namespace declarative_net_request {
+
+namespace {
+
+using UrlPatternIndex = subresource_filter::flat::UrlPatternIndex;
+using UrlRule = subresource_filter::flat::UrlRule;
+using FlatUrlRuleList = flatbuffers::Vector<flatbuffers::Offset<UrlRule>>;
+using DomainList =
+ flatbuffers::Vector<flatbuffers::Offset<flatbuffers::String>>;
+using ExtensionRuleMetadata = flat::ExtensionRuleMetadata;
+using ExtensionMetadataList =
+ flatbuffers::Vector<flatbuffers::Offset<ExtensionRuleMetadata>>;
+
+// const std::pair<OptionFlag, std::string> kOptionsPairs[] = {
+// {OptionFlag::OptionFlag_IS_WHITELIST, "IS_WHITELIST"},
+// {OptionFlag::OptionFlag_APPLIES_TO_FIRST_PARTY, "APPLIES_TO_FIRST_PARTY"},
+// {OptionFlag::OptionFlag_APPLIES_TO_THIRD_PARTY, "APPLIES_TO_THIRD_PARTY"},
+// {OptionFlag::OptionFlag_IS_MATCH_CASE, "IS_MATCH_CASE"},
+// };
+
+// const std::pair<AnchorType, std::string> kAnchorPairs[] = {
+// {AnchorType::AnchorType_NONE, "NONE"},
+// {AnchorType::AnchorType_BOUNDARY, "BOUNDARY"},
+// {AnchorType::AnchorType_SUBDOMAIN, "SUBDOMAIN"},
+// };
+
+// const std::pair<UrlPatternType, std::string> kUrlPatternPairs[] = {
+// {UrlPatternType::UrlPatternType_SUBSTRING, "SUBSTRING"},
+// {UrlPatternType::UrlPatternType_WILDCARDED, "WILDCARDED"},
+// {UrlPatternType::UrlPatternType_REGEXP, "REGEXP"},
+// };
+
+// const std::pair<ActivationType, std::string> kActivationPairs[] = {
+// {ActivationType::ActivationType_DOCUMENT, "DOCUMENT"},
+// {ActivationType::ActivationType_ELEM_HIDE, "ELEM_HIDE"},
+// {ActivationType::ActivationType_GENERIC_HIDE, "GENERIC_HIDE"},
+// {ActivationType::ActivationType_GENERIC_BLOCK, "GENERIC_BLOCK"},
+// };
+
+// const std::pair<ElementType, std::string> kElementTypePairs[] = {
+// {ElementType::ElementType_OTHER, "OTHER"},
+// {ElementType::ElementType_SCRIPT, "SCRIPT"},
+// {ElementType::ElementType_IMAGE, "IMAGE"},
+// {ElementType::ElementType_STYLESHEET, "STYLESHEET"},
+// {ElementType::ElementType_OBJECT, "OBJECT"},
+// {ElementType::ElementType_XMLHTTPREQUEST, "XMLHTTPREQUEST"},
+// {ElementType::ElementType_OBJECT_SUBREQUEST, "OBJECT_SUBREQUEST"},
+// {ElementType::ElementType_SUBDOCUMENT, "SUBDOCUMENT"},
+// {ElementType::ElementType_PING, "PING"},
+// {ElementType::ElementType_MEDIA, "MEDIA"},
+// {ElementType::ElementType_FONT, "FONT"},
+// {ElementType::ElementType_POPUP, "POPUP"},
+// {ElementType::ElementType_WEBSOCKET, "WEBSOCKET"},
+// };
+
+// void PrintDomainList(const std::string& msg, const DomainList* domain_list) {
+// LOG(ERROR) << "--------msg " << msg << "\n";
+// for(const auto* domain : *domain_list) {
+// LOG(ERROR) << "--------*domain " << domain->c_str() << "\n";
+// }
+// }
+
+// template <typename A, typename B,typename C>
+// std::string PrintMask(const std::pair<A, B> pairs[], size_t len, C elem) {
+// std::string s;
+// for(size_t i = 0; i < len; i++) {
+// if(elem & pairs[i].first)
+// s += pairs[i].second + " ";
+// }
+// return s;
+// }
+
+// template <typename A, typename B,typename C>
+// std::string PrintEqual(const std::pair<A, B> pairs[], size_t len, C elem) {
+// for(size_t i = 0; i < len; i++) {
+// if(elem == pairs[i].first)
+// return pairs[i].second;
+// }
+// return "";
+// }
+
+// std::string PrintOptions(uint8_t options_mask) {
+// return PrintMask(kOptionsPairs, arraysize(kOptionsPairs), options_mask);
+// }
+
+// std::string PrintAnchor(uint8_t anchor) {
+// return PrintEqual(kAnchorPairs, arraysize(kAnchorPairs), anchor);
+// }
+
+// std::string PrintUrlPatternType(uint8_t url_pattern_type) {
+// return PrintEqual(kUrlPatternPairs, arraysize(kUrlPatternPairs),
+// url_pattern_type);
+// }
+
+// std::string PrintActivation(uint8_t activation_mask) {
+// return PrintMask(kActivationPairs, arraysize(kActivationPairs),
+// activation_mask);
+// }
+
+// std::string PrintElements(uint16_t element_mask) {
+// return PrintMask(kElementTypePairs, arraysize(kElementTypePairs),
+// element_mask);
+// }
+
+// void PrintRuleList(const std::string& msg, const FlatUrlRuleList* rule_list)
+// {
+// LOG(ERROR) << "--------msg " << msg << "\n";
+// for(const auto* rule : *rule_list) {
+// LOG(ERROR) << "--------rule->id() " << rule->id() << "\n";
+// LOG(ERROR) << "--------rule->priority() " << rule->priority() << "\n";
+// LOG(ERROR) << "--------rule->options() " << PrintOptions(rule->options())
+// << "\n"; LOG(ERROR) << "--------rule->element_types() " <<
+// PrintElements(rule->element_types()) << "\n"; LOG(ERROR) <<
+// "--------rule->activation_types() " <<
+// PrintActivation(rule->activation_types()) << "\n"; LOG(ERROR) <<
+// "--------rule->url_pattern_type() " <<
+// PrintUrlPatternType(rule->url_pattern_type()) << "\n"; LOG(ERROR) <<
+// "--------rule->anchor_left() " << PrintAnchor(rule->anchor_left()) <<
+// "\n"; LOG(ERROR) << "--------rule->anchor_right() " <<
+// PrintAnchor(rule->anchor_right()) << "\n"; LOG(ERROR) <<
+// "--------rule->url_pattern() " << rule->url_pattern()->c_str() << "\n";
+// PrintDomainList("included_domains", rule->domains_included());
+// PrintDomainList("excluded_domains", rule->domains_excluded());
+// }
+// }
+
+// std::string string_to_hex(const std::string& input)
+// {
+// static const char* const lut = "0123456789ABCDEF";
+// size_t len = input.length();
+
+// std::string output;
+// output.reserve(2 * len);
+// for (size_t i = 0; i < len; ++i)
+// {
+// const unsigned char c = input[i];
+// output.push_back(lut[c >> 4]);
+// output.push_back(lut[c & 15]);
+// }
+// return output;
+// }
+
+// void PrintIndex(const std::string& str, const UrlPatternIndex* index) {
+// LOG(ERROR) << "--------str " << str << "\n";
+// LOG(ERROR) << "--------index->n() " << index->n() << "\n";
+// const ::subresource_filter::flat::NGramToRules* empty_slot =
+// index->ngram_index_empty_slot(); PrintRuleList("fallback_rules",
+// index->fallback_rules()); for(const auto* n_gram_rules:
+// *index->ngram_index()) {
+// if (n_gram_rules == empty_slot)
+// continue;
+// PrintRuleList("rule_list" + std::to_string(n_gram_rules->ngram()),
+// n_gram_rules->rule_list());
+// }
+// }
+
+// void PrintExtensionMetadata(const std::string& msg, const
+// ExtensionMetadataList* metadata_list) {
+// LOG(ERROR) << "--------msg " << msg << "\n";
+// for (const auto* metadata : *metadata_list) {
+// LOG(ERROR) << "--------metadata->id() " << metadata->id() << "\n";
+// LOG(ERROR) << "--------metadata->redirect_url()->c_str() " <<
+// metadata->redirect_url()->c_str() << "\n";
+// }
+// }
+
+// void PrintIndexedRuleset(base::MemoryMappedFile* file) {
+// RulesetIndexer::SerializedData data(file->data(), file->length());
+// std::string file_data(reinterpret_cast<const char*>(data.first),
+// data.second); LOG(ERROR) << "--------file_data " <<
+// string_to_hex(file_data) << "\n"; flatbuffers::Verifier
+// verifier(data.first, data.second); bool verify =
+// flat::VerifyExtensionIndexedRulesetBuffer(verifier); LOG(ERROR) <<
+// "--------verify " << verify << "\n"; CHECK(verify);
+
+// const flat::ExtensionIndexedRuleset* ruleset =
+// flat::GetExtensionIndexedRuleset(data.first); PrintIndex("blacklist_index",
+// ruleset->blacklist_index()); PrintIndex("whitelist_index",
+// ruleset->whitelist_index()); PrintIndex("redirect_index",
+// ruleset->redirect_index()); PrintExtensionMetadata("extension_metdata",
+// ruleset->extension_metdata());
+// }
+}
+
+RulesetManager::ExtensionKey::ExtensionKey(ExtensionId extension_id,
+ base::Time extension_install_time)
+ : id(std::move(extension_id)),
+ install_time(std::move(extension_install_time)) {}
+RulesetManager::ExtensionKey::~ExtensionKey() = default;
+
+// Comparator to ensure that ExtensionKey are sorted in order of decreasing
+// extension install time i.e. most recently installed extension first. For
+// equal install times, sort by id. This is also necessary since a set uses the
+// this to prevent duplicates. Hence only sorting on a single parameter would
+// be incorrect.
+bool RulesetManager::ExtensionKeyComparator::operator()(
+ const ExtensionKey& lhs,
+ const ExtensionKey& rhs) const {
+ return lhs.install_time > rhs.install_time || lhs.id < rhs.id;
+}
+
+RulesetManager::RulesetManager(InfoMap* info_map) : info_map_(info_map) {
+ DCHECK(info_map_);
+}
+RulesetManager::~RulesetManager() = default;
+
+void RulesetManager::AddRuleset(
+ ExtensionId extension_id,
+ std::unique_ptr<ExtensionIndexedRulesetMatcher> ruleset_matcher) {
+ DCHECK(info_map_);
+ base::Time install_time = info_map_->GetInstallTime(extension_id);
+ ExtensionKey key(std::move(extension_id), std::move(install_time));
+ // PrintIndexedRuleset(ruleset.get());
+ auto it = rules_.insert(std::make_pair(key, std::move(ruleset_matcher)));
+ // Verify insertion actually occured.
+ DCHECK(it.second);
+}
+
+// Todo actually this should take a const std::string&, since it won't be moved.
+// But then the API would become inconsistent.
+void RulesetManager::RemoveRuleset(ExtensionId extension_id) {
+ DCHECK(info_map_);
+ base::Time install_time = info_map_->GetInstallTime(extension_id);
+ LOG(ERROR) << "--------Removing ruleset for " << extension_id;
+ // This is a bit problematic. We are depending on info map to provide the
+ // extension install time. If the provided time changes, the key won't be
+ // removed. And we won't be able to ensure that single key for single id.
+ // TODO Add DCHECK to ensure keys for ids are unique.
+ // TODO yeah this is probematic as Info::RemoveExtension may be called first.
+ // Check.
+ ExtensionKey key(std::move(extension_id), std::move(install_time));
+ size_t erase_count = rules_.erase(key);
+ DCHECK_EQ(1u, erase_count);
+}
+
+} // namespace declarative_net_request
+} // namespace extensions

Powered by Google App Engine
This is Rietveld 408576698