Commit abf8d983 authored by Kelvin Jiang's avatar Kelvin Jiang Committed by Commit Bot

[DNR] Add flatbuffer schemas and indexing for modifyHeader rules

Bug: 947591
Change-Id: I06b2ff6505ed0f1efd326df2a73cac8ee3ec35bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2081363
Commit-Queue: Kelvin Jiang <kelvinjiang@chromium.org>
Reviewed-by: default avatarKaran Bhatia <karandeepb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#751592}
parent 05edc003
...@@ -59,7 +59,9 @@ bool IsExtraHeadersMatcherInternal( ...@@ -59,7 +59,9 @@ bool IsExtraHeadersMatcherInternal(
const ExtensionUrlPatternIndexMatcher::UrlPatternIndexList* index_list) { const ExtensionUrlPatternIndexMatcher::UrlPatternIndexList* index_list) {
// We only support removing a subset of extra headers currently. If that // We only support removing a subset of extra headers currently. If that
// changes, the implementation here should change as well. // changes, the implementation here should change as well.
static_assert(flat::IndexType_count == 5, // TODO(crbug.com/947591): Modify this method for
// flat::IndexType_modify_headers.
static_assert(flat::IndexType_count == 6,
"Modify this method to ensure IsExtraHeadersMatcherInternal is " "Modify this method to ensure IsExtraHeadersMatcherInternal is "
"updated as new actions are added."); "updated as new actions are added.");
static const flat::IndexType extra_header_indices[] = { static const flat::IndexType extra_header_indices[] = {
...@@ -189,6 +191,7 @@ ExtensionUrlPatternIndexMatcher::GetBeforeRequestActionHelper( ...@@ -189,6 +191,7 @@ ExtensionUrlPatternIndexMatcher::GetBeforeRequestActionHelper(
return CreateUpgradeAction(params, *rule); return CreateUpgradeAction(params, *rule);
case flat::ActionType_allow_all_requests: case flat::ActionType_allow_all_requests:
case flat::ActionType_remove_headers: case flat::ActionType_remove_headers:
case flat::ActionType_modify_headers:
case flat::ActionType_count: case flat::ActionType_count:
NOTREACHED(); NOTREACHED();
} }
......
...@@ -18,6 +18,7 @@ enum ActionType : ubyte { ...@@ -18,6 +18,7 @@ enum ActionType : ubyte {
redirect, redirect,
upgrade_scheme, upgrade_scheme,
remove_headers, remove_headers,
modify_headers,
allow_all_requests, allow_all_requests,
/// Number of actions. Must be the last entry. /// Number of actions. Must be the last entry.
count count
...@@ -74,6 +75,11 @@ table UrlRuleMetadata { ...@@ -74,6 +75,11 @@ table UrlRuleMetadata {
/// UrlTransform for this rule. /// UrlTransform for this rule.
transform : UrlTransform; transform : UrlTransform;
/// A list of ModifyHeaderInfo, for both request and response headers. Valid
/// for "modifyHeaders" rules.
request_headers: [ModifyHeaderInfo];
response_headers: [ModifyHeaderInfo];
} }
/// This provides a mapping from an index type to its index within /// This provides a mapping from an index type to its index within
...@@ -91,6 +97,8 @@ enum IndexType : ubyte { ...@@ -91,6 +97,8 @@ enum IndexType : ubyte {
remove_referer_header, remove_referer_header,
remove_set_cookie_header, remove_set_cookie_header,
modify_headers,
/// Number of indices. Must be the last entry. /// Number of indices. Must be the last entry.
count count
} }
...@@ -103,6 +111,19 @@ enum RemoveHeaderType : ubyte (bit_flags) { ...@@ -103,6 +111,19 @@ enum RemoveHeaderType : ubyte (bit_flags) {
set_cookie set_cookie
} }
/// The type of header operation for modifyHeaders rules. Corresponds to
/// extensions::api::declarative_net_request::HeaderOperation.
enum HeaderOperation : ubyte {
remove
}
/// Describes the header to be modified and operation to be performed on it.
/// Corresponds to extensions::api::declarative_net_request::ModifyHeaderInfo.
table ModifyHeaderInfo {
operation: HeaderOperation;
header: string;
}
/// Completely represents a rule with a regex filter. /// Completely represents a rule with a regex filter.
table RegexRule { table RegexRule {
/// The underlying UrlRule. /// The underlying UrlRule.
......
...@@ -152,6 +152,33 @@ FlatOffset<flat::UrlTransform> BuildTransformOffset( ...@@ -152,6 +152,33 @@ FlatOffset<flat::UrlTransform> BuildTransformOffset(
clear_fragment, fragment, username, password); clear_fragment, fragment, username, password);
} }
FlatVectorOffset<flat::ModifyHeaderInfo> BuildModifyHeaderInfoOffset(
flatbuffers::FlatBufferBuilder* builder,
const std::vector<dnr_api::ModifyHeaderInfo>& modify_header_list) {
std::vector<FlatOffset<flat::ModifyHeaderInfo>> flat_modify_header_list;
flat_modify_header_list.reserve(modify_header_list.size());
for (const dnr_api::ModifyHeaderInfo& header_info : modify_header_list) {
flat::HeaderOperation operation = flat::HeaderOperation_remove;
switch (header_info.operation) {
case dnr_api::HeaderOperation::HEADER_OPERATION_NONE:
NOTREACHED();
break;
case dnr_api::HEADER_OPERATION_REMOVE:
operation = flat::HeaderOperation_remove;
break;
}
FlatStringOffset header_name =
builder->CreateSharedString(header_info.header);
flat_modify_header_list.push_back(
flat::CreateModifyHeaderInfo(*builder, operation, header_name));
}
return builder->CreateVector(flat_modify_header_list);
}
} // namespace } // namespace
FlatRulesetIndexer::FlatRulesetIndexer() FlatRulesetIndexer::FlatRulesetIndexer()
...@@ -206,10 +233,17 @@ void FlatRulesetIndexer::AddUrlRule(const IndexedRule& indexed_rule) { ...@@ -206,10 +233,17 @@ void FlatRulesetIndexer::AddUrlRule(const IndexedRule& indexed_rule) {
transform_offset = transform_offset =
BuildTransformOffset(&builder_, *indexed_rule.url_transform); BuildTransformOffset(&builder_, *indexed_rule.url_transform);
} }
FlatVectorOffset<flat::ModifyHeaderInfo> request_headers_offset =
BuildModifyHeaderInfoOffset(&builder_, indexed_rule.request_headers);
FlatVectorOffset<flat::ModifyHeaderInfo> response_headers_offset =
BuildModifyHeaderInfoOffset(&builder_, indexed_rule.response_headers);
metadata_.push_back(flat::CreateUrlRuleMetadata( metadata_.push_back(flat::CreateUrlRuleMetadata(
builder_, indexed_rule.id, builder_, indexed_rule.id,
ConvertToFlatActionType(indexed_rule.action_type), redirect_url_offset, ConvertToFlatActionType(indexed_rule.action_type), redirect_url_offset,
transform_offset)); transform_offset, request_headers_offset, response_headers_offset));
} }
void FlatRulesetIndexer::Finish() { void FlatRulesetIndexer::Finish() {
...@@ -281,6 +315,7 @@ FlatRulesetIndexer::GetBuilders(const IndexedRule& indexed_rule) { ...@@ -281,6 +315,7 @@ FlatRulesetIndexer::GetBuilders(const IndexedRule& indexed_rule) {
case dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS: case dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS:
return GetRemoveHeaderBuilders(indexed_rule.remove_headers_set); return GetRemoveHeaderBuilders(indexed_rule.remove_headers_set);
case dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS: case dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS:
return {index_builders_[flat::IndexType_modify_headers].get()};
case dnr_api::RULE_ACTION_TYPE_NONE: case dnr_api::RULE_ACTION_TYPE_NONE:
break; break;
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
#include "extensions/browser/api/declarative_net_request/constants.h" #include "extensions/browser/api/declarative_net_request/constants.h"
#include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h" #include "extensions/browser/api/declarative_net_request/flat/extension_ruleset_generated.h"
#include "extensions/browser/api/declarative_net_request/indexed_rule.h" #include "extensions/browser/api/declarative_net_request/indexed_rule.h"
#include "extensions/browser/api/declarative_net_request/test_utils.h"
#include "extensions/browser/api/declarative_net_request/utils.h" #include "extensions/browser/api/declarative_net_request/utils.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
...@@ -45,6 +46,36 @@ std::vector<std::string> ToVector( ...@@ -45,6 +46,36 @@ std::vector<std::string> ToVector(
return result; return result;
} }
// Helper to convert a flatbuffer vector of flat::ModifyHeaderInfo to a
// std::vector of dnr_api::ModifyHeaderInfo
std::vector<dnr_api::ModifyHeaderInfo> ToVector(
const ::flatbuffers::Vector<::flatbuffers::Offset<flat::ModifyHeaderInfo>>*
vec) {
if (!vec)
return std::vector<dnr_api::ModifyHeaderInfo>();
std::vector<dnr_api::ModifyHeaderInfo> result;
result.reserve(vec->size());
for (auto* flat_header_info : *vec) {
dnr_api::ModifyHeaderInfo header_info;
const flat::HeaderOperation flat_operation = flat_header_info->operation();
switch (flat_operation) {
case flat::HeaderOperation_remove:
header_info.operation = dnr_api::HEADER_OPERATION_REMOVE;
break;
};
const flatbuffers::String* flat_header = flat_header_info->header();
DCHECK(flat_header);
header_info.header = ToString(flat_header);
result.push_back(std::move(header_info));
}
return result;
}
// Helper to create a generic URLTransform. // Helper to create a generic URLTransform.
std::unique_ptr<dnr_api::URLTransform> CreateUrlTransform() { std::unique_ptr<dnr_api::URLTransform> CreateUrlTransform() {
const char* transform = R"( const char* transform = R"(
...@@ -127,7 +158,9 @@ IndexedRule CreateIndexedRule( ...@@ -127,7 +158,9 @@ IndexedRule CreateIndexedRule(
dnr_api::RuleActionType action_type, dnr_api::RuleActionType action_type,
std::set<dnr_api::RemoveHeaderType> remove_headers_set, std::set<dnr_api::RemoveHeaderType> remove_headers_set,
std::unique_ptr<dnr_api::URLTransform> url_transform, std::unique_ptr<dnr_api::URLTransform> url_transform,
base::Optional<std::string> regex_substitution) { base::Optional<std::string> regex_substitution,
std::vector<dnr_api::ModifyHeaderInfo> request_headers,
std::vector<dnr_api::ModifyHeaderInfo> response_headers) {
IndexedRule rule; IndexedRule rule;
rule.id = id; rule.id = id;
rule.priority = priority; rule.priority = priority;
...@@ -145,11 +178,14 @@ IndexedRule CreateIndexedRule( ...@@ -145,11 +178,14 @@ IndexedRule CreateIndexedRule(
rule.remove_headers_set = std::move(remove_headers_set); rule.remove_headers_set = std::move(remove_headers_set);
rule.url_transform = std::move(url_transform); rule.url_transform = std::move(url_transform);
rule.regex_substitution = std::move(regex_substitution); rule.regex_substitution = std::move(regex_substitution);
rule.request_headers = std::move(request_headers);
rule.response_headers = std::move(response_headers);
return rule; return rule;
} }
// Compares |indexed_rule| and |rule| for equality. Ignores the redirect url // Compares |indexed_rule| and |rule| for equality. Ignores the redirect url and
// since it's not stored as part of flat_rule::UrlRule. // the list of request and response headers since they're not stored as part of
// flat_rule::UrlRule.
bool AreRulesEqual(const IndexedRule* indexed_rule, bool AreRulesEqual(const IndexedRule* indexed_rule,
const flat_rule::UrlRule* rule) { const flat_rule::UrlRule* rule) {
CHECK(indexed_rule); CHECK(indexed_rule);
...@@ -279,6 +315,21 @@ void VerifyExtensionMetadata( ...@@ -279,6 +315,21 @@ void VerifyExtensionMetadata(
return VerifyUrlTransform(*pair.metadata->transform()); return VerifyUrlTransform(*pair.metadata->transform());
} }
auto are_header_modifications_equal =
[](const ::flatbuffers::Vector<
::flatbuffers::Offset<flat::ModifyHeaderInfo>>* metadata_headers,
const std::vector<dnr_api::ModifyHeaderInfo>& indexed_headers) {
return std::equal(indexed_headers.begin(), indexed_headers.end(),
ToVector(metadata_headers).begin(),
EqualsForTesting);
};
EXPECT_TRUE(are_header_modifications_equal(
pair.metadata->request_headers(), pair.indexed_rule->request_headers));
EXPECT_TRUE(
are_header_modifications_equal(pair.metadata->response_headers(),
pair.indexed_rule->response_headers));
return true; return true;
}; };
...@@ -353,14 +404,14 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -353,14 +404,14 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_NONE, flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_BOUNDARY, "google.com", {"a.com"}, {"x.a.com"}, flat_rule::AnchorType_BOUNDARY, "google.com", {"a.com"}, {"x.a.com"},
base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {}, nullptr, base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {}, nullptr,
base::nullopt)); base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
2, kMinValidPriority, flat_rule::OptionFlag_APPLIES_TO_THIRD_PARTY, 2, kMinValidPriority, flat_rule::OptionFlag_APPLIES_TO_THIRD_PARTY,
flat_rule::ElementType_IMAGE | flat_rule::ElementType_WEBSOCKET, flat_rule::ElementType_IMAGE | flat_rule::ElementType_WEBSOCKET,
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED,
flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*google*", flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*google*",
{"a.com"}, {}, base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {}, {"a.com"}, {}, base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
// Redirect rules. // Redirect rules.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
...@@ -369,26 +420,26 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -369,26 +420,26 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_SUBDOMAIN, flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_SUBDOMAIN,
flat_rule::AnchorType_BOUNDARY, "google.com", {}, {}, flat_rule::AnchorType_BOUNDARY, "google.com", {}, {},
"http://example1.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr, "http://example1.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr,
base::nullopt)); base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
10, 2, flat_rule::OptionFlag_NONE, 10, 2, flat_rule::OptionFlag_NONE,
flat_rule::ElementType_SUBDOCUMENT | flat_rule::ElementType_SCRIPT, flat_rule::ElementType_SUBDOCUMENT | flat_rule::ElementType_SCRIPT,
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING,
flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "example1", {}, flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "example1", {},
{"a.com"}, "http://example2.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, {"a.com"}, "http://example2.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
9, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_NONE, 9, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_NONE,
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED,
flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*", {}, {}, flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*", {}, {},
"http://example2.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr, "http://example2.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr,
base::nullopt)); base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
100, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_NONE, 100, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_NONE,
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_WILDCARDED,
flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*", {}, {}, flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "*", {}, {},
base::nullopt, dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, base::nullopt, dnr_api::RULE_ACTION_TYPE_REDIRECT, {},
CreateUrlTransform(), base::nullopt)); CreateUrlTransform(), base::nullopt, {}, {}));
// Allow rules. // Allow rules.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
...@@ -397,7 +448,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -397,7 +448,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING,
flat_rule::AnchorType_SUBDOMAIN, flat_rule::AnchorType_NONE, flat_rule::AnchorType_SUBDOMAIN, flat_rule::AnchorType_NONE,
"example1.com", {"xyz.com"}, {}, base::nullopt, "example1.com", {"xyz.com"}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_ALLOW, {}, nullptr, base::nullopt)); dnr_api::RULE_ACTION_TYPE_ALLOW, {}, nullptr, base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
16, kMinValidPriority, 16, kMinValidPriority,
flat_rule::OptionFlag_IS_WHITELIST | flat_rule::OptionFlag_IS_WHITELIST |
...@@ -405,7 +456,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -405,7 +456,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
flat_rule::ElementType_IMAGE, flat_rule::ActivationType_NONE, flat_rule::ElementType_IMAGE, flat_rule::ActivationType_NONE,
flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_NONE, flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_NONE, "example3", {}, {}, base::nullopt, flat_rule::AnchorType_NONE, "example3", {}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_ALLOW, {}, nullptr, base::nullopt)); dnr_api::RULE_ACTION_TYPE_ALLOW, {}, nullptr, base::nullopt, {}, {}));
// Remove request header rules. // Remove request header rules.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
...@@ -416,7 +467,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -416,7 +467,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS, dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS,
{dnr_api::REMOVE_HEADER_TYPE_COOKIE, {dnr_api::REMOVE_HEADER_TYPE_COOKIE,
dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE}, dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
21, kMinValidPriority, flat_rule::OptionFlag_NONE, 21, kMinValidPriority, flat_rule::OptionFlag_NONE,
flat_rule::ElementType_NONE, flat_rule::ActivationType_NONE, flat_rule::ElementType_NONE, flat_rule::ActivationType_NONE,
...@@ -425,13 +476,44 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -425,13 +476,44 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS, dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS,
{dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE, {dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE,
dnr_api::REMOVE_HEADER_TYPE_COOKIE, dnr_api::REMOVE_HEADER_TYPE_REFERER}, dnr_api::REMOVE_HEADER_TYPE_COOKIE, dnr_api::REMOVE_HEADER_TYPE_REFERER},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
// Allow all requests rule.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
22, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_SUBDOCUMENT, 22, 3, flat_rule::OptionFlag_NONE, flat_rule::ElementType_SUBDOCUMENT,
flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING, flat_rule::ActivationType_NONE, flat_rule::UrlPatternType_SUBSTRING,
flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "example.com", {}, flat_rule::AnchorType_NONE, flat_rule::AnchorType_NONE, "example.com", {},
{}, base::nullopt, dnr_api::RULE_ACTION_TYPE_ALLOWALLREQUESTS, {}, {}, base::nullopt, dnr_api::RULE_ACTION_TYPE_ALLOWALLREQUESTS, {},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
// Modify headers rules.
std::vector<dnr_api::ModifyHeaderInfo> request_headers_1;
request_headers_1.push_back(
CreateModifyHeaderInfo(dnr_api::HEADER_OPERATION_REMOVE, "cookie"));
std::vector<dnr_api::ModifyHeaderInfo> response_headers_1;
response_headers_1.push_back(
CreateModifyHeaderInfo(dnr_api::HEADER_OPERATION_REMOVE, "set-cookie"));
rules_to_index.push_back(CreateIndexedRule(
23, kMinValidPriority, flat_rule::OptionFlag_IS_CASE_INSENSITIVE,
flat_rule::ElementType_SUBDOCUMENT, flat_rule::ActivationType_NONE,
flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_SUBDOMAIN,
flat_rule::AnchorType_NONE, "example.com", {}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS, {}, nullptr, base::nullopt,
std::move(request_headers_1), std::move(response_headers_1)));
std::vector<dnr_api::ModifyHeaderInfo> request_headers_2;
request_headers_2.push_back(
CreateModifyHeaderInfo(dnr_api::HEADER_OPERATION_REMOVE, "referer"));
rules_to_index.push_back(CreateIndexedRule(
24, kMinValidPriority, flat_rule::OptionFlag_IS_CASE_INSENSITIVE,
flat_rule::ElementType_SUBDOCUMENT, flat_rule::ActivationType_NONE,
flat_rule::UrlPatternType_SUBSTRING, flat_rule::AnchorType_SUBDOMAIN,
flat_rule::AnchorType_NONE, "example.com", {}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS, {}, nullptr, base::nullopt,
std::move(request_headers_2), {}));
// Note: It's unsafe to store/return pointers to a mutable vector since the // Note: It's unsafe to store/return pointers to a mutable vector since the
// vector can resize/reallocate invalidating the existing pointers/iterators. // vector can resize/reallocate invalidating the existing pointers/iterators.
...@@ -443,6 +525,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -443,6 +525,7 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
&rules_to_index[0], &rules_to_index[1], &rules_to_index[2], &rules_to_index[0], &rules_to_index[1], &rules_to_index[2],
&rules_to_index[3], &rules_to_index[4], &rules_to_index[5], &rules_to_index[3], &rules_to_index[4], &rules_to_index[5],
&rules_to_index[6], &rules_to_index[7]}; &rules_to_index[6], &rules_to_index[7]};
expected_index_lists[flat::IndexType_allow_all_requests] = { expected_index_lists[flat::IndexType_allow_all_requests] = {
&rules_to_index[10]}; &rules_to_index[10]};
...@@ -453,6 +536,9 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) { ...@@ -453,6 +536,9 @@ TEST_F(FlatRulesetIndexerTest, MultipleRules) {
expected_index_lists[flat::IndexType_remove_set_cookie_header] = { expected_index_lists[flat::IndexType_remove_set_cookie_header] = {
&rules_to_index[8], &rules_to_index[9]}; &rules_to_index[8], &rules_to_index[9]};
expected_index_lists[flat::IndexType_modify_headers] = {&rules_to_index[11],
&rules_to_index[12]};
AddRulesAndVerifyIndex(rules_to_index, expected_index_lists); AddRulesAndVerifyIndex(rules_to_index, expected_index_lists);
} }
...@@ -467,7 +553,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -467,7 +553,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE, flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_NONE, R"(^https://(abc|def))", {"a.com"}, flat_rule::AnchorType_NONE, R"(^https://(abc|def))", {"a.com"},
{"x.a.com"}, base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {}, nullptr, {"x.a.com"}, base::nullopt, dnr_api::RULE_ACTION_TYPE_BLOCK, {}, nullptr,
base::nullopt)); base::nullopt, {}, {}));
// Redirect rule. // Redirect rule.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
15, 2, flat_rule::OptionFlag_APPLIES_TO_FIRST_PARTY, 15, 2, flat_rule::OptionFlag_APPLIES_TO_FIRST_PARTY,
...@@ -475,7 +561,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -475,7 +561,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE, flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_NONE, R"(^(http|https))", {}, {}, flat_rule::AnchorType_NONE, R"(^(http|https))", {}, {},
"http://example1.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr, "http://example1.com", dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr,
base::nullopt)); base::nullopt, {}, {}));
// Regex substitution rule. // Regex substitution rule.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
10, 29, flat_rule::OptionFlag_APPLIES_TO_FIRST_PARTY, 10, 29, flat_rule::OptionFlag_APPLIES_TO_FIRST_PARTY,
...@@ -483,7 +569,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -483,7 +569,7 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE, flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_NONE, R"((\d+\).google.com)", {}, {}, base::nullopt, flat_rule::AnchorType_NONE, R"((\d+\).google.com)", {}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr, dnr_api::RULE_ACTION_TYPE_REDIRECT, {}, nullptr,
R"(http://redirect.com?num=\1)")); R"(http://redirect.com?num=\1)", {}, {}));
// Remove headers rule. // Remove headers rule.
rules_to_index.push_back(CreateIndexedRule( rules_to_index.push_back(CreateIndexedRule(
20, kMinValidPriority, flat_rule::OptionFlag_IS_CASE_INSENSITIVE, 20, kMinValidPriority, flat_rule::OptionFlag_IS_CASE_INSENSITIVE,
...@@ -493,7 +579,19 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -493,7 +579,19 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS, dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS,
{dnr_api::REMOVE_HEADER_TYPE_COOKIE, {dnr_api::REMOVE_HEADER_TYPE_COOKIE,
dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE}, dnr_api::REMOVE_HEADER_TYPE_SETCOOKIE},
nullptr, base::nullopt)); nullptr, base::nullopt, {}, {}));
// Modify headers rule.
std::vector<dnr_api::ModifyHeaderInfo> request_headers;
request_headers.push_back(
CreateModifyHeaderInfo(dnr_api::HEADER_OPERATION_REMOVE, "referer"));
rules_to_index.push_back(CreateIndexedRule(
21, kMinValidPriority, flat_rule::OptionFlag_IS_CASE_INSENSITIVE,
flat_rule::ElementType_SUBDOCUMENT, flat_rule::ActivationType_NONE,
flat_rule::UrlPatternType_REGEXP, flat_rule::AnchorType_NONE,
flat_rule::AnchorType_NONE, "*", {}, {}, base::nullopt,
dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS, {}, nullptr, base::nullopt,
std::move(request_headers), {}));
FlatRulesetIndexer indexer; FlatRulesetIndexer indexer;
const flat::ExtensionIndexedRuleset* ruleset = const flat::ExtensionIndexedRuleset* ruleset =
...@@ -515,12 +613,13 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -515,12 +613,13 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
} }
ASSERT_TRUE(ruleset->regex_rules()); ASSERT_TRUE(ruleset->regex_rules());
ASSERT_EQ(4u, ruleset->regex_rules()->size()); ASSERT_EQ(5u, ruleset->regex_rules()->size());
const flat::RegexRule* blocking_rule = nullptr; const flat::RegexRule* blocking_rule = nullptr;
const flat::RegexRule* redirect_rule = nullptr; const flat::RegexRule* redirect_rule = nullptr;
const flat::RegexRule* regex_substitution_rule = nullptr; const flat::RegexRule* regex_substitution_rule = nullptr;
const flat::RegexRule* remove_header_rule = nullptr; const flat::RegexRule* remove_header_rule = nullptr;
const flat::RegexRule* modify_header_rule = nullptr;
for (const auto* regex_rule : *ruleset->regex_rules()) { for (const auto* regex_rule : *ruleset->regex_rules()) {
if (regex_rule->action_type() == flat::ActionType_block) if (regex_rule->action_type() == flat::ActionType_block)
blocking_rule = regex_rule; blocking_rule = regex_rule;
...@@ -531,6 +630,8 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -531,6 +630,8 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
redirect_rule = regex_rule; redirect_rule = regex_rule;
} else if (regex_rule->action_type() == flat::ActionType_remove_headers) } else if (regex_rule->action_type() == flat::ActionType_remove_headers)
remove_header_rule = regex_rule; remove_header_rule = regex_rule;
else if (regex_rule->action_type() == flat::ActionType_modify_headers)
modify_header_rule = regex_rule;
} }
ASSERT_TRUE(blocking_rule); ASSERT_TRUE(blocking_rule);
...@@ -556,6 +657,12 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) { ...@@ -556,6 +657,12 @@ TEST_F(FlatRulesetIndexerTest, RegexRules) {
EXPECT_EQ(flat::RemoveHeaderType_cookie | flat::RemoveHeaderType_set_cookie, EXPECT_EQ(flat::RemoveHeaderType_cookie | flat::RemoveHeaderType_set_cookie,
remove_header_rule->remove_headers_mask()); remove_header_rule->remove_headers_mask());
EXPECT_FALSE(remove_header_rule->regex_substitution()); EXPECT_FALSE(remove_header_rule->regex_substitution());
ASSERT_TRUE(modify_header_rule);
EXPECT_TRUE(
AreRulesEqual(&rules_to_index[4], modify_header_rule->url_rule()));
EXPECT_EQ(0u, modify_header_rule->remove_headers_mask());
EXPECT_FALSE(modify_header_rule->regex_substitution());
} }
} // namespace } // namespace
......
...@@ -26,6 +26,7 @@ enum ActionType : ubyte { ...@@ -26,6 +26,7 @@ enum ActionType : ubyte {
redirect, redirect,
upgrade_scheme, upgrade_scheme,
remove_headers, remove_headers,
modify_headers,
allow_all_requests, allow_all_requests,
count count
} }
...@@ -54,6 +55,8 @@ table UrlRuleMetadata { ...@@ -54,6 +55,8 @@ table UrlRuleMetadata {
action : ActionType; action : ActionType;
redirect_url : string; redirect_url : string;
transform : UrlTransform; transform : UrlTransform;
request_headers: [ModifyHeaderInfo];
response_headers: [ModifyHeaderInfo];
} }
enum IndexType : ubyte { enum IndexType : ubyte {
before_request_except_allow_all_requests = 0, before_request_except_allow_all_requests = 0,
...@@ -61,6 +64,7 @@ enum IndexType : ubyte { ...@@ -61,6 +64,7 @@ enum IndexType : ubyte {
remove_cookie_header, remove_cookie_header,
remove_referer_header, remove_referer_header,
remove_set_cookie_header, remove_set_cookie_header,
modify_headers,
count count
} }
enum RemoveHeaderType : ubyte (bit_flags) { enum RemoveHeaderType : ubyte (bit_flags) {
...@@ -68,6 +72,13 @@ enum RemoveHeaderType : ubyte (bit_flags) { ...@@ -68,6 +72,13 @@ enum RemoveHeaderType : ubyte (bit_flags) {
referer, referer,
set_cookie set_cookie
} }
enum HeaderOperation : ubyte {
remove
}
table ModifyHeaderInfo {
operation: HeaderOperation;
header: string;
}
table RegexRule { table RegexRule {
url_rule: url_pattern_index.flat.UrlRule; url_rule: url_pattern_index.flat.UrlRule;
action_type: ActionType; action_type: ActionType;
...@@ -145,7 +156,7 @@ TEST_F(IndexedRulesetFormatVersionTest, CheckVersionUpdated) { ...@@ -145,7 +156,7 @@ TEST_F(IndexedRulesetFormatVersionTest, CheckVersionUpdated) {
EXPECT_EQ(StripCommentsAndWhitespace(kFlatbufferSchemaExpected), EXPECT_EQ(StripCommentsAndWhitespace(kFlatbufferSchemaExpected),
StripCommentsAndWhitespace(flatbuffer_schema)) StripCommentsAndWhitespace(flatbuffer_schema))
<< "Schema change detected; update this test and the schema version."; << "Schema change detected; update this test and the schema version.";
EXPECT_EQ(15, GetIndexedRulesetFormatVersionForTesting()) EXPECT_EQ(16, GetIndexedRulesetFormatVersionForTesting())
<< "Update this test if you update the schema version."; << "Update this test if you update the schema version.";
} }
......
...@@ -25,7 +25,9 @@ bool IsExtraHeadersMatcherInternal( ...@@ -25,7 +25,9 @@ bool IsExtraHeadersMatcherInternal(
// We only support removing a subset of extra headers currently. If that // We only support removing a subset of extra headers currently. If that
// changes, the implementation here should change as well. // changes, the implementation here should change as well.
static_assert(flat::ActionType_count == 6, // TODO(crbug.com/947591): Modify this method for
// flat::ActionType_modify_headers.
static_assert(flat::ActionType_count == 7,
"Modify this method to ensure IsExtraHeadersMatcherInternal is " "Modify this method to ensure IsExtraHeadersMatcherInternal is "
"updated as new actions are added."); "updated as new actions are added.");
...@@ -64,6 +66,7 @@ bool IsBeforeRequestAction(flat::ActionType action_type) { ...@@ -64,6 +66,7 @@ bool IsBeforeRequestAction(flat::ActionType action_type) {
case flat::ActionType_allow_all_requests: case flat::ActionType_allow_all_requests:
return true; return true;
case flat::ActionType_remove_headers: case flat::ActionType_remove_headers:
case flat::ActionType_modify_headers:
return false; return false;
case flat::ActionType_count: case flat::ActionType_count:
NOTREACHED(); NOTREACHED();
...@@ -185,6 +188,7 @@ RegexRulesMatcher::GetBeforeRequestActionIgnoringAncestors( ...@@ -185,6 +188,7 @@ RegexRulesMatcher::GetBeforeRequestActionIgnoringAncestors(
case flat::ActionType_allow_all_requests: case flat::ActionType_allow_all_requests:
return CreateAllowAllRequestsAction(params, rule); return CreateAllowAllRequestsAction(params, rule);
case flat::ActionType_remove_headers: case flat::ActionType_remove_headers:
case flat::ActionType_modify_headers:
case flat::ActionType_count: case flat::ActionType_count:
NOTREACHED(); NOTREACHED();
break; break;
......
...@@ -180,7 +180,9 @@ bool RulesetManager::HasExtraHeadersMatcherForRequest( ...@@ -180,7 +180,9 @@ bool RulesetManager::HasExtraHeadersMatcherForRequest(
// We only support removing a subset of extra headers currently. If that // We only support removing a subset of extra headers currently. If that
// changes, the implementation here should change as well. // changes, the implementation here should change as well.
static_assert(flat::ActionType_count == 6, // TODO(crbug.com/947591): Modify this method for
// flat::ActionType_modify_headers.
static_assert(flat::ActionType_count == 7,
"Modify this method to ensure HasExtraHeadersMatcherForRequest " "Modify this method to ensure HasExtraHeadersMatcherForRequest "
"is updated as new actions are added."); "is updated as new actions are added.");
......
...@@ -57,7 +57,9 @@ RequestAction CreateRequestActionForTesting(RequestAction::Type type, ...@@ -57,7 +57,9 @@ RequestAction CreateRequestActionForTesting(RequestAction::Type type,
// with gtest. This reuses the logic used to test action equality in // with gtest. This reuses the logic used to test action equality in
// TestRequestACtion in test_utils.h. // TestRequestACtion in test_utils.h.
bool operator==(const RequestAction& lhs, const RequestAction& rhs) { bool operator==(const RequestAction& lhs, const RequestAction& rhs) {
static_assert(flat::IndexType_count == 5, // TODO(crbug.com/947591): Modify this method for
// flat::IndexType_modify_headers.
static_assert(flat::IndexType_count == 6,
"Modify this method to ensure it stays updated as new actions " "Modify this method to ensure it stays updated as new actions "
"are added."); "are added.");
......
...@@ -37,7 +37,7 @@ namespace dnr_api = api::declarative_net_request; ...@@ -37,7 +37,7 @@ namespace dnr_api = api::declarative_net_request;
// url_pattern_index.fbs. Whenever an extension with an indexed ruleset format // url_pattern_index.fbs. Whenever an extension with an indexed ruleset format
// version different from the one currently used by Chrome is loaded, the // version different from the one currently used by Chrome is loaded, the
// extension ruleset will be reindexed. // extension ruleset will be reindexed.
constexpr int kIndexedRulesetFormatVersion = 15; constexpr int kIndexedRulesetFormatVersion = 16;
// This static assert is meant to catch cases where // This static assert is meant to catch cases where
// url_pattern_index::kUrlPatternIndexFormatVersion is incremented without // url_pattern_index::kUrlPatternIndexFormatVersion is incremented without
...@@ -256,11 +256,12 @@ flat::ActionType ConvertToFlatActionType(dnr_api::RuleActionType action_type) { ...@@ -256,11 +256,12 @@ flat::ActionType ConvertToFlatActionType(dnr_api::RuleActionType action_type) {
return flat::ActionType_redirect; return flat::ActionType_redirect;
case dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS: case dnr_api::RULE_ACTION_TYPE_REMOVEHEADERS:
return flat::ActionType_remove_headers; return flat::ActionType_remove_headers;
case dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS:
return flat::ActionType_modify_headers;
case dnr_api::RULE_ACTION_TYPE_UPGRADESCHEME: case dnr_api::RULE_ACTION_TYPE_UPGRADESCHEME:
return flat::ActionType_upgrade_scheme; return flat::ActionType_upgrade_scheme;
case dnr_api::RULE_ACTION_TYPE_ALLOWALLREQUESTS: case dnr_api::RULE_ACTION_TYPE_ALLOWALLREQUESTS:
return flat::ActionType_allow_all_requests; return flat::ActionType_allow_all_requests;
case dnr_api::RULE_ACTION_TYPE_MODIFYHEADERS:
case dnr_api::RULE_ACTION_TYPE_NONE: case dnr_api::RULE_ACTION_TYPE_NONE:
break; break;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment