summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/api/declarative/declarative_rule.h492
-rw-r--r--chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc387
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc103
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h90
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc68
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc88
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h99
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc13
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h16
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc46
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc19
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc128
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h122
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rule_unittest.cc114
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc51
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h20
-rw-r--r--chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc57
-rw-r--r--chrome/browser/extensions/api/web_request/web_request_api.cc3
-rw-r--r--chrome/chrome_browser_extensions.gypi4
-rw-r--r--chrome/chrome_tests_unit.gypi2
-rw-r--r--tools/json_schema_compiler/any.cc4
-rw-r--r--tools/json_schema_compiler/any.h1
22 files changed, 1156 insertions, 771 deletions
diff --git a/chrome/browser/extensions/api/declarative/declarative_rule.h b/chrome/browser/extensions/api/declarative/declarative_rule.h
new file mode 100644
index 0000000..703ca34
--- /dev/null
+++ b/chrome/browser/extensions/api/declarative/declarative_rule.h
@@ -0,0 +1,492 @@
+// Copyright (c) 2013 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.
+//
+// DeclarativeRule<>, DeclarativeConditionSet<>, and DeclarativeActionSet<>
+// templates usable with multiple different declarativeFoo systems. These are
+// templated on the Condition and Action types that define the behavior of a
+// particular declarative event.
+
+#ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__
+#define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__
+
+#include <limits>
+
+#include "base/memory/linked_ptr.h"
+#include "base/memory/scoped_vector.h"
+#include "base/time.h"
+#include "chrome/common/extensions/api/events.h"
+#include "chrome/common/extensions/matcher/url_matcher.h"
+
+namespace base {
+class Time;
+}
+
+namespace extensions {
+
+// This class stores a set of conditions that may be part of a DeclarativeRule.
+// If any condition is fulfilled, the Actions of the DeclarativeRule can be
+// triggered.
+//
+// ConditionT should be immutable after creation. It must define the following
+// members:
+//
+// // Arguments passed through from ConditionSet::Create.
+// static scoped_ptr<ConditionT> Create(
+// URLMatcherConditionFactory*,
+// // Except this argument gets elements of the AnyVector.
+// const base::Value& definition,
+// std::string* error);
+// // If the Condition needs to be filtered by some
+// // URLMatcherConditionSets, append them to this argument.
+// // DeclarativeConditionSet::GetURLMatcherConditionSets forwards here.
+// void GetURLMatcherConditionSets(
+// URLMatcherConditionSet::Vector* condition_sets)
+// // True if GetURLMatcherConditionSets would append anything to its
+// // argument.
+// bool has_url_matcher_condition_set();
+// // |url_matches| and |match_data| passed through from
+// // ConditionSet::IsFulfilled.
+// bool IsFulfilled(
+// const std::set<URLMatcherConditionSet::ID>& url_matches,
+// const ConditionT::MatchData&);
+template<typename ConditionT>
+class DeclarativeConditionSet {
+ public:
+ typedef std::vector<linked_ptr<json_schema_compiler::any::Any> > AnyVector;
+ typedef std::vector<linked_ptr<const ConditionT> > Conditions;
+ typedef typename Conditions::const_iterator const_iterator;
+
+ // Factory method that creates an WebRequestConditionSet according to the JSON
+ // array |conditions| passed by the extension API.
+ // Sets |error| and returns NULL in case of an error.
+ static scoped_ptr<DeclarativeConditionSet> Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const AnyVector& conditions,
+ std::string* error);
+
+ const Conditions& conditions() const {
+ return conditions_;
+ }
+
+ const_iterator begin() const { return conditions_.begin(); }
+ const_iterator end() const { return conditions_.end(); }
+
+ // If |url_match_trigger| is a member of |url_matches|, then this
+ // returns whether the corresponding condition is fulfilled
+ // wrt. |request_data|. If |url_match_trigger| is -1, this function
+ // returns whether any of the conditions without URL attributes is
+ // satisfied.
+ //
+ // Conditions for which has_url_matcher_condition_set() is false are always
+ // checked (aside from short-circuiting when an earlier condition already
+ // matched.)
+ //
+ // Conditions for which has_url_matcher_condition_set() is true are only
+ // checked if one of the URLMatcherConditionSets returned by
+ // GetURLMatcherConditionSets() has an id listed in url_matches. That means
+ // that if |match_data| contains URL matches for two pieces of a request,
+ // their union should appear in |url_matches|. For kinds of MatchData that
+ // only have one type of URL, |url_matches| is forwarded on to
+ // ConditionT::IsFulfilled(), so it doesn't need to appear in |match_data|.
+ bool IsFulfilled(URLMatcherConditionSet::ID url_match_trigger,
+ const std::set<URLMatcherConditionSet::ID>& url_matches,
+ const typename ConditionT::MatchData& match_data) const;
+
+ // Appends the URLMatcherConditionSet from all conditions to |condition_sets|.
+ void GetURLMatcherConditionSets(
+ URLMatcherConditionSet::Vector* condition_sets) const;
+
+ // Returns whether there are some conditions without UrlFilter attributes.
+ bool HasConditionsWithoutUrls() const {
+ return !conditions_without_urls_.empty();
+ }
+
+ private:
+ typedef std::map<URLMatcherConditionSet::ID, const ConditionT*>
+ URLMatcherIdToCondition;
+
+ DeclarativeConditionSet(
+ const Conditions& conditions,
+ const URLMatcherIdToCondition& match_id_to_condition,
+ const std::vector<const ConditionT*>& conditions_without_urls);
+
+ const URLMatcherIdToCondition match_id_to_condition_;
+ const Conditions conditions_;
+ const std::vector<const ConditionT*> conditions_without_urls_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeclarativeConditionSet);
+};
+
+// Immutable container for multiple actions.
+//
+// ActionT should be immutable after creation. It must define the following
+// members:
+//
+// // Arguments passed through from ActionSet::Create.
+// static scoped_ptr<ActionT> Create(
+// // Except this argument gets elements of the AnyVector.
+// const base::Value& definition,
+// std::string* error, bool* bad_message);
+// void Apply(const std::string& extension_id,
+// const base::Time& extension_install_time,
+// // Contains action-type-specific in/out parameters.
+// typename ActionT::ApplyInfo* apply_info) const;
+// // Only needed if the RulesRegistry calls DeclarativeActionSet::Revert().
+// void Revert(const std::string& extension_id,
+// const base::Time& extension_install_time,
+// // Contains action-type-specific in/out parameters.
+// typename ActionT::ApplyInfo* apply_info) const;
+// // Return the minimum priority of rules that can be evaluated after this
+// // action runs. Return MIN_INT by default.
+// int GetMinimumPriority() const;
+//
+// TODO(battre): As DeclarativeActionSet can become the single owner of all
+// actions, we can optimize here by making some of them singletons (e.g. Cancel
+// actions).
+template<typename ActionT>
+class DeclarativeActionSet {
+ public:
+ typedef std::vector<linked_ptr<json_schema_compiler::any::Any> > AnyVector;
+ typedef std::vector<linked_ptr<const ActionT> > Actions;
+
+ explicit DeclarativeActionSet(const Actions& actions);
+
+ // Factory method that instantiates a DeclarativeActionSet according to
+ // |actions| which represents the array of actions received from the
+ // extension API.
+ static scoped_ptr<DeclarativeActionSet> Create(const AnyVector& actions,
+ std::string* error,
+ bool* bad_message);
+
+ // Rules call this method when their conditions are fulfilled.
+ void Apply(const std::string& extension_id,
+ const base::Time& extension_install_time,
+ typename ActionT::ApplyInfo* apply_info) const;
+
+ // Rules call this method when they have stateful conditions, and those
+ // conditions stop being fulfilled. Rules with event-based conditions (e.g. a
+ // network request happened) will never Revert() an action.
+ void Revert(const std::string& extension_id,
+ const base::Time& extension_install_time,
+ typename ActionT::ApplyInfo* apply_info) const;
+
+ // Returns the minimum priority of rules that may be evaluated after
+ // this rule. Defaults to MIN_INT.
+ int GetMinimumPriority() const;
+
+ const Actions& actions() const { return actions_; }
+
+ private:
+ const Actions actions_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeclarativeActionSet);
+};
+
+// Representation of a rule of a declarative API:
+// https://developer.chrome.com/beta/extensions/events.html#declarative.
+// Generally a RulesRegistry will hold a collection of Rules for a given
+// declarative API and contain the logic for matching and applying them.
+//
+// See DeclarativeConditionSet and DeclarativeActionSet for the requirements on
+// ConditionT and ActionT.
+template<typename ConditionT, typename ActionT>
+class DeclarativeRule {
+ public:
+ typedef std::string ExtensionId;
+ typedef std::string RuleId;
+ typedef std::pair<ExtensionId, RuleId> GlobalRuleId;
+ typedef int Priority;
+ typedef DeclarativeConditionSet<ConditionT> ConditionSet;
+ typedef DeclarativeActionSet<ActionT> ActionSet;
+ typedef extensions::api::events::Rule JsonRule;
+
+ // Checks whether the set of |conditions| and |actions| are consistent.
+ // Returns true in case of consistency and MUST set |error| otherwise.
+ typedef bool (*ConsistencyChecker)(const ConditionSet* conditions,
+ const ActionSet* actions,
+ std::string* error);
+
+ DeclarativeRule(const GlobalRuleId& id,
+ base::Time extension_installation_time,
+ scoped_ptr<ConditionSet> conditions,
+ scoped_ptr<ActionSet> actions,
+ Priority priority);
+
+ // Creates a DeclarativeRule for an extension given a json definition. The
+ // format of each condition and action's json is up to the specific ConditionT
+ // and ActionT.
+ //
+ // Before constructing the final rule, calls check_consistency(conditions,
+ // actions, error) and returns NULL if it fails. Pass NULL if no consistency
+ // check is needed. If |error| is empty, the translation was successful and
+ // the returned rule is internally consistent.
+ static scoped_ptr<DeclarativeRule> Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const std::string& extension_id,
+ base::Time extension_installation_time,
+ linked_ptr<JsonRule> rule,
+ ConsistencyChecker check_consistency,
+ std::string* error);
+
+ const GlobalRuleId& id() const { return id_; }
+ const std::string& extension_id() const { return id_.first; }
+ const ConditionSet& conditions() const { return *conditions_; }
+ const ActionSet& actions() const { return *actions_; }
+ Priority priority() const { return priority_; }
+
+ // Calls actions().Apply(extension_id(), extension_installation_time_,
+ // apply_info). This function should only be called when the conditions_ are
+ // fulfilled (from a semantic point of view; no harm is done if this function
+ // is called at other times for testing purposes).
+ void Apply(typename ActionT::ApplyInfo* apply_info) const;
+
+ // Returns the minimum priority of rules that may be evaluated after
+ // this rule. Defaults to MIN_INT. Only valid if the conditions of this rule
+ // are fulfilled.
+ Priority GetMinimumPriority() const;
+
+ private:
+ GlobalRuleId id_;
+ base::Time extension_installation_time_; // For precedences of rules.
+ scoped_ptr<ConditionSet> conditions_;
+ scoped_ptr<ActionSet> actions_;
+ Priority priority_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeclarativeRule);
+};
+
+// Implementation details below here.
+
+//
+// DeclarativeConditionSet
+//
+
+template<typename ConditionT>
+bool DeclarativeConditionSet<ConditionT>::IsFulfilled(
+ URLMatcherConditionSet::ID url_match_trigger,
+ const std::set<URLMatcherConditionSet::ID>& url_matches,
+ const typename ConditionT::MatchData& match_data) const {
+ if (url_match_trigger == -1) {
+ // Invalid trigger -- indication that we should only check conditions
+ // without URL attributes.
+ for (typename std::vector<const ConditionT*>::const_iterator it =
+ conditions_without_urls_.begin();
+ it != conditions_without_urls_.end(); ++it) {
+ if ((*it)->IsFulfilled(url_matches, match_data))
+ return true;
+ }
+ return false;
+ }
+
+ typename URLMatcherIdToCondition::const_iterator triggered =
+ match_id_to_condition_.find(url_match_trigger);
+ return (triggered != match_id_to_condition_.end() &&
+ triggered->second->IsFulfilled(url_matches, match_data));
+}
+
+template<typename ConditionT>
+void DeclarativeConditionSet<ConditionT>::GetURLMatcherConditionSets(
+ URLMatcherConditionSet::Vector* condition_sets) const {
+ for (typename Conditions::const_iterator i = conditions_.begin();
+ i != conditions_.end(); ++i) {
+ (*i)->GetURLMatcherConditionSets(condition_sets);
+ }
+}
+
+// static
+template<typename ConditionT>
+scoped_ptr<DeclarativeConditionSet<ConditionT> >
+DeclarativeConditionSet<ConditionT>::Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const AnyVector& conditions,
+ std::string* error) {
+ Conditions result;
+
+ for (AnyVector::const_iterator i = conditions.begin();
+ i != conditions.end(); ++i) {
+ CHECK(i->get());
+ scoped_ptr<ConditionT> condition =
+ ConditionT::Create(url_matcher_condition_factory,
+ (*i)->value(), error);
+ if (!error->empty())
+ return scoped_ptr<DeclarativeConditionSet>(NULL);
+ result.push_back(make_linked_ptr(condition.release()));
+ }
+
+ URLMatcherIdToCondition match_id_to_condition;
+ std::vector<const ConditionT*> conditions_without_urls;
+ URLMatcherConditionSet::Vector condition_sets;
+
+ for (typename Conditions::const_iterator i = result.begin();
+ i != result.end(); ++i) {
+ condition_sets.clear();
+ (*i)->GetURLMatcherConditionSets(&condition_sets);
+ if (condition_sets.empty()) {
+ conditions_without_urls.push_back(i->get());
+ } else {
+ for (URLMatcherConditionSet::Vector::const_iterator
+ match_set = condition_sets.begin();
+ match_set != condition_sets.end(); ++match_set)
+ match_id_to_condition[(*match_set)->id()] = i->get();
+ }
+ }
+
+ return make_scoped_ptr(new DeclarativeConditionSet(
+ result, match_id_to_condition, conditions_without_urls));
+}
+
+template<typename ConditionT>
+DeclarativeConditionSet<ConditionT>::DeclarativeConditionSet(
+ const Conditions& conditions,
+ const URLMatcherIdToCondition& match_id_to_condition,
+ const std::vector<const ConditionT*>& conditions_without_urls)
+ : match_id_to_condition_(match_id_to_condition),
+ conditions_(conditions),
+ conditions_without_urls_(conditions_without_urls) {}
+
+//
+// DeclarativeActionSet
+//
+
+template<typename ActionT>
+DeclarativeActionSet<ActionT>::DeclarativeActionSet(const Actions& actions)
+ : actions_(actions) {}
+
+// static
+template<typename ActionT>
+scoped_ptr<DeclarativeActionSet<ActionT> >
+DeclarativeActionSet<ActionT>::Create(
+ const AnyVector& actions,
+ std::string* error,
+ bool* bad_message) {
+ *error = "";
+ *bad_message = false;
+ Actions result;
+
+ for (AnyVector::const_iterator i = actions.begin();
+ i != actions.end(); ++i) {
+ CHECK(i->get());
+ scoped_ptr<ActionT> action =
+ ActionT::Create((*i)->value(), error, bad_message);
+ if (!error->empty() || *bad_message)
+ return scoped_ptr<DeclarativeActionSet>(NULL);
+ result.push_back(make_linked_ptr(action.release()));
+ }
+
+ return scoped_ptr<DeclarativeActionSet>(new DeclarativeActionSet(result));
+}
+
+template<typename ActionT>
+void DeclarativeActionSet<ActionT>::Apply(
+ const std::string& extension_id,
+ const base::Time& extension_install_time,
+ typename ActionT::ApplyInfo* apply_info) const {
+ for (typename Actions::const_iterator i = actions_.begin();
+ i != actions_.end(); ++i)
+ (*i)->Apply(extension_id, extension_install_time, apply_info);
+}
+
+template<typename ActionT>
+void DeclarativeActionSet<ActionT>::Revert(
+ const std::string& extension_id,
+ const base::Time& extension_install_time,
+ typename ActionT::ApplyInfo* apply_info) const {
+ for (typename Actions::const_iterator i = actions_.begin();
+ i != actions_.end(); ++i)
+ (*i)->Revert(extension_id, extension_install_time, apply_info);
+}
+
+template<typename ActionT>
+int DeclarativeActionSet<ActionT>::GetMinimumPriority() const {
+ int minimum_priority = std::numeric_limits<int>::min();
+ for (typename Actions::const_iterator i = actions_.begin();
+ i != actions_.end(); ++i) {
+ minimum_priority = std::max(minimum_priority, (*i)->GetMinimumPriority());
+ }
+ return minimum_priority;
+}
+
+//
+// DeclarativeRule
+//
+
+template<typename ConditionT, typename ActionT>
+DeclarativeRule<ConditionT, ActionT>::DeclarativeRule(
+ const GlobalRuleId& id,
+ base::Time extension_installation_time,
+ scoped_ptr<ConditionSet> conditions,
+ scoped_ptr<ActionSet> actions,
+ Priority priority)
+ : id_(id),
+ extension_installation_time_(extension_installation_time),
+ conditions_(conditions.release()),
+ actions_(actions.release()),
+ priority_(priority) {
+ CHECK(conditions_.get());
+ CHECK(actions_.get());
+}
+
+// static
+template<typename ConditionT, typename ActionT>
+scoped_ptr<DeclarativeRule<ConditionT, ActionT> >
+DeclarativeRule<ConditionT, ActionT>::Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const std::string& extension_id,
+ base::Time extension_installation_time,
+ linked_ptr<JsonRule> rule,
+ ConsistencyChecker check_consistency,
+ std::string* error) {
+ scoped_ptr<DeclarativeRule> error_result;
+
+ scoped_ptr<ConditionSet> conditions = ConditionSet::Create(
+ url_matcher_condition_factory, rule->conditions, error);
+ if (!error->empty())
+ return error_result.Pass();
+ CHECK(conditions.get());
+
+ bool bad_message = false;
+ scoped_ptr<ActionSet> actions =
+ ActionSet::Create(rule->actions, error, &bad_message);
+ if (bad_message) {
+ // TODO(battre) Export concept of bad_message to caller, the extension
+ // should be killed in case it is true.
+ *error = "An action of a rule set had an invalid "
+ "structure that should have been caught by the JSON validator.";
+ return error_result.Pass();
+ }
+ if (!error->empty() || bad_message)
+ return error_result.Pass();
+ CHECK(actions.get());
+
+ if (check_consistency &&
+ !check_consistency(conditions.get(), actions.get(), error)) {
+ DCHECK(!error->empty());
+ return error_result.Pass();
+ }
+
+ CHECK(rule->priority.get());
+ int priority = *(rule->priority);
+
+ GlobalRuleId rule_id(extension_id, *(rule->id));
+ return scoped_ptr<DeclarativeRule>(
+ new DeclarativeRule(rule_id, extension_installation_time,
+ conditions.Pass(), actions.Pass(), priority));
+}
+
+template<typename ConditionT, typename ActionT>
+void DeclarativeRule<ConditionT, ActionT>::Apply(
+ typename ActionT::ApplyInfo* apply_info) const {
+ return actions_->Apply(extension_id(),
+ extension_installation_time_,
+ apply_info);
+}
+
+template<typename ConditionT, typename ActionT>
+int DeclarativeRule<ConditionT, ActionT>::GetMinimumPriority() const {
+ return actions_->GetMinimumPriority();
+}
+
+} // namespace extensions
+
+#endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_DECLARATIVE_RULE_H__
diff --git a/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc b/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc
new file mode 100644
index 0000000..509d0db
--- /dev/null
+++ b/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc
@@ -0,0 +1,387 @@
+// Copyright (c) 2013 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 "chrome/browser/extensions/api/declarative/declarative_rule.h"
+
+#include "base/message_loop.h"
+#include "base/test/values_test_util.h"
+#include "base/values.h"
+#include "chrome/common/extensions/matcher/url_matcher_constants.h"
+#include "testing/gmock/include/gmock/gmock.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace extensions {
+
+using json_schema_compiler::any::Any;
+using base::test::ParseJson;
+
+struct RecordingCondition {
+ typedef int MatchData;
+
+ URLMatcherConditionFactory* factory;
+ scoped_ptr<base::Value> value;
+
+ void GetURLMatcherConditionSets(
+ URLMatcherConditionSet::Vector* condition_sets) const {
+ // No condition sets.
+ }
+
+ bool has_url_matcher_condition_set() const {
+ return false;
+ }
+
+ static scoped_ptr<RecordingCondition> Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const base::Value& condition,
+ std::string* error) {
+ const base::DictionaryValue* dict = NULL;
+ if (condition.GetAsDictionary(&dict) && dict->HasKey("bad_key")) {
+ *error = "Found error key";
+ return scoped_ptr<RecordingCondition>();
+ }
+
+ scoped_ptr<RecordingCondition> result(new RecordingCondition());
+ result->factory = url_matcher_condition_factory;
+ result->value.reset(condition.DeepCopy());
+ return result.Pass();
+ }
+};
+typedef DeclarativeConditionSet<RecordingCondition> RecordingConditionSet;
+
+TEST(DeclarativeConditionTest, ErrorConditionSet) {
+ URLMatcher matcher;
+ RecordingConditionSet::AnyVector conditions;
+ conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"key\": 1}"))));
+ conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"bad_key\": 2}"))));
+
+ std::string error;
+ scoped_ptr<RecordingConditionSet> result =
+ RecordingConditionSet::Create(matcher.condition_factory(),
+ conditions, &error);
+ EXPECT_EQ("Found error key", error);
+ ASSERT_FALSE(result);
+}
+
+TEST(DeclarativeConditionTest, CreateConditionSet) {
+ URLMatcher matcher;
+ RecordingConditionSet::AnyVector conditions;
+ conditions.push_back(make_linked_ptr(new Any(ParseJson("{\"key\": 1}"))));
+ conditions.push_back(make_linked_ptr(new Any(ParseJson("[\"val1\", 2]"))));
+
+ // Test insertion
+ std::string error;
+ scoped_ptr<RecordingConditionSet> result =
+ RecordingConditionSet::Create(matcher.condition_factory(),
+ conditions, &error);
+ EXPECT_EQ("", error);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(2u, result->conditions().size());
+
+ EXPECT_EQ(matcher.condition_factory(), result->conditions()[0]->factory);
+ EXPECT_TRUE(ParseJson("{\"key\": 1}")->Equals(
+ result->conditions()[0]->value.get()));
+}
+
+struct FulfillableCondition {
+ typedef int MatchData;
+
+ scoped_refptr<URLMatcherConditionSet> condition_set;
+ int condition_set_id;
+ int max_value;
+
+ URLMatcherConditionSet::ID url_matcher_condition_set_id() const {
+ return condition_set_id;
+ }
+
+ bool has_url_matcher_condition_set() const {
+ return true;
+ }
+
+ scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const {
+ return condition_set;
+ }
+
+ void GetURLMatcherConditionSets(
+ URLMatcherConditionSet::Vector* condition_sets) const {
+ if (condition_set)
+ condition_sets->push_back(condition_set);
+ }
+
+ bool IsFulfilled(const std::set<URLMatcherConditionSet::ID>& url_matches,
+ int match_data) const {
+ if (condition_set_id != -1 && !ContainsKey(url_matches, condition_set_id))
+ return false;
+ return match_data <= max_value;
+ }
+
+ static scoped_ptr<FulfillableCondition> Create(
+ URLMatcherConditionFactory* url_matcher_condition_factory,
+ const base::Value& condition,
+ std::string* error) {
+ scoped_ptr<FulfillableCondition> result(new FulfillableCondition());
+ const base::DictionaryValue* dict;
+ if (!condition.GetAsDictionary(&dict)) {
+ *error = "Expected dict";
+ return result.Pass();
+ }
+ if (!dict->GetInteger("url_id", &result->condition_set_id))
+ result->condition_set_id = -1;
+ if (!dict->GetInteger("max", &result->max_value))
+ *error = "Expected integer at ['max']";
+ if (result->condition_set_id != -1) {
+ result->condition_set = new URLMatcherConditionSet(
+ result->condition_set_id,
+ URLMatcherConditionSet::Conditions());
+ }
+ return result.Pass();
+ }
+};
+
+TEST(DeclarativeConditionTest, FulfillConditionSet) {
+ typedef DeclarativeConditionSet<FulfillableCondition> FulfillableConditionSet;
+ FulfillableConditionSet::AnyVector conditions;
+ conditions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"url_id\": 1, \"max\": 3}"))));
+ conditions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"url_id\": 2, \"max\": 5}"))));
+ conditions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"url_id\": 3, \"max\": 1}"))));
+ conditions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"max\": -5}")))); // No url.
+
+ // Test insertion
+ std::string error;
+ scoped_ptr<FulfillableConditionSet> result =
+ FulfillableConditionSet::Create(NULL, conditions, &error);
+ ASSERT_EQ("", error);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(4u, result->conditions().size());
+
+ std::set<URLMatcherConditionSet::ID> url_matches;
+ EXPECT_FALSE(result->IsFulfilled(1, url_matches, 0))
+ << "Testing an ID that's not in url_matches forwards to the Condition, "
+ << "which doesn't match.";
+ EXPECT_FALSE(result->IsFulfilled(-1, url_matches, 0))
+ << "Testing the 'no ID' value tries to match the 4th condition, but "
+ << "its max is too low.";
+ EXPECT_TRUE(result->IsFulfilled(-1, url_matches, -5))
+ << "Testing the 'no ID' value tries to match the 4th condition, and "
+ << "this value is low enough.";
+
+ url_matches.insert(1);
+ EXPECT_TRUE(result->IsFulfilled(1, url_matches, 3))
+ << "Tests a condition with a url matcher, for a matching value.";
+ EXPECT_FALSE(result->IsFulfilled(1, url_matches, 4))
+ << "Tests a condition with a url matcher, for a non-matching value "
+ << "that would match a different condition.";
+ url_matches.insert(2);
+ EXPECT_TRUE(result->IsFulfilled(2, url_matches, 4))
+ << "Tests with 2 elements in the match set.";
+
+ // Check the condition sets:
+ URLMatcherConditionSet::Vector condition_sets;
+ result->GetURLMatcherConditionSets(&condition_sets);
+ ASSERT_EQ(3U, condition_sets.size());
+ EXPECT_EQ(1, condition_sets[0]->id());
+ EXPECT_EQ(2, condition_sets[1]->id());
+ EXPECT_EQ(3, condition_sets[2]->id());
+}
+
+// DeclarativeAction
+
+struct SummingAction {
+ typedef int ApplyInfo;
+
+ int increment;
+ int min_priority;
+
+ static scoped_ptr<SummingAction> Create(const base::Value& action,
+ std::string* error,
+ bool* bad_message) {
+ scoped_ptr<SummingAction> result(new SummingAction());
+ const base::DictionaryValue* dict = NULL;
+ EXPECT_TRUE(action.GetAsDictionary(&dict));
+ if (dict->HasKey("error")) {
+ EXPECT_TRUE(dict->GetString("error", error));
+ return result.Pass();
+ }
+ if (dict->HasKey("bad")) {
+ *bad_message = true;
+ return result.Pass();
+ }
+
+ EXPECT_TRUE(dict->GetInteger("value", &result->increment));
+ dict->GetInteger("priority", &result->min_priority);
+ return result.Pass();
+ }
+
+ void Apply(const std::string& extension_id,
+ const base::Time& install_time,
+ int* sum) const {
+ *sum += increment;
+ }
+
+ int GetMinimumPriority() const {
+ return min_priority;
+ }
+};
+typedef DeclarativeActionSet<SummingAction> SummingActionSet;
+
+TEST(DeclarativeActionTest, ErrorActionSet) {
+ SummingActionSet::AnyVector actions;
+ actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 1}"))));
+ actions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"error\": \"the error\"}"))));
+
+ std::string error;
+ bool bad = false;
+ scoped_ptr<SummingActionSet> result =
+ SummingActionSet::Create(actions, &error, &bad);
+ EXPECT_EQ("the error", error);
+ EXPECT_FALSE(bad);
+ EXPECT_FALSE(result);
+
+ actions.clear();
+ actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 1}"))));
+ actions.push_back(make_linked_ptr(new Any(ParseJson("{\"bad\": 3}"))));
+ result = SummingActionSet::Create(actions, &error, &bad);
+ EXPECT_EQ("", error);
+ EXPECT_TRUE(bad);
+ EXPECT_FALSE(result);
+}
+
+TEST(DeclarativeActionTest, ApplyActionSet) {
+ SummingActionSet::AnyVector actions;
+ actions.push_back(make_linked_ptr(new Any(ParseJson(
+ "{\"value\": 1,"
+ " \"priority\": 5}"))));
+ actions.push_back(make_linked_ptr(new Any(ParseJson("{\"value\": 2}"))));
+
+ // Test insertion
+ std::string error;
+ bool bad = false;
+ scoped_ptr<SummingActionSet> result =
+ SummingActionSet::Create(actions, &error, &bad);
+ EXPECT_EQ("", error);
+ EXPECT_FALSE(bad);
+ ASSERT_TRUE(result);
+ EXPECT_EQ(2u, result->actions().size());
+
+ int sum = 0;
+ result->Apply("ext_id", base::Time(), &sum);
+ EXPECT_EQ(3, sum);
+ EXPECT_EQ(5, result->GetMinimumPriority());
+}
+
+TEST(DeclarativeRuleTest, Create) {
+ typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
+ linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule);
+ ASSERT_TRUE(Rule::JsonRule::Populate(
+ *ParseJson("{ \n"
+ " \"id\": \"rule1\", \n"
+ " \"conditions\": [ \n"
+ " {\"url_id\": 1, \"max\": 3}, \n"
+ " {\"url_id\": 2, \"max\": 5}, \n"
+ " ], \n"
+ " \"actions\": [ \n"
+ " { \n"
+ " \"value\": 2 \n"
+ " } \n"
+ " ], \n"
+ " \"priority\": 200 \n"
+ "}"),
+ json_rule.get()));
+
+ const char kExtensionId[] = "ext1";
+
+ base::Time install_time = base::Time::Now();
+
+ URLMatcher matcher;
+ std::string error;
+ scoped_ptr<Rule> rule(Rule::Create(matcher.condition_factory(), kExtensionId,
+ install_time, json_rule, NULL, &error));
+ EXPECT_EQ("", error);
+ ASSERT_TRUE(rule.get());
+
+ EXPECT_EQ(kExtensionId, rule->id().first);
+ EXPECT_EQ("rule1", rule->id().second);
+
+ EXPECT_EQ(200, rule->priority());
+
+ const Rule::ConditionSet& condition_set = rule->conditions();
+ const Rule::ConditionSet::Conditions& conditions =
+ condition_set.conditions();
+ ASSERT_EQ(2u, conditions.size());
+ EXPECT_EQ(3, conditions[0]->max_value);
+ EXPECT_EQ(5, conditions[1]->max_value);
+
+ const Rule::ActionSet& action_set = rule->actions();
+ const Rule::ActionSet::Actions& actions = action_set.actions();
+ ASSERT_EQ(1u, actions.size());
+ EXPECT_EQ(2, actions[0]->increment);
+
+ int sum = 0;
+ rule->Apply(&sum);
+ EXPECT_EQ(2, sum);
+}
+
+bool AtLeastOneCondition(
+ const DeclarativeConditionSet<FulfillableCondition>* conditions,
+ const DeclarativeActionSet<SummingAction>* actions,
+ std::string* error) {
+ if (conditions->conditions().empty()) {
+ *error = "No conditions";
+ return false;
+ }
+ return true;
+}
+
+TEST(DeclarativeRuleTest, CheckConsistency) {
+ typedef DeclarativeRule<FulfillableCondition, SummingAction> Rule;
+ URLMatcher matcher;
+ std::string error;
+ linked_ptr<Rule::JsonRule> json_rule(new Rule::JsonRule);
+ const char kExtensionId[] = "ext1";
+
+ ASSERT_TRUE(Rule::JsonRule::Populate(
+ *ParseJson("{ \n"
+ " \"id\": \"rule1\", \n"
+ " \"conditions\": [ \n"
+ " {\"url_id\": 1, \"max\": 3}, \n"
+ " {\"url_id\": 2, \"max\": 5}, \n"
+ " ], \n"
+ " \"actions\": [ \n"
+ " { \n"
+ " \"value\": 2 \n"
+ " } \n"
+ " ], \n"
+ " \"priority\": 200 \n"
+ "}"),
+ json_rule.get()));
+ scoped_ptr<Rule> rule(
+ Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(),
+ json_rule, &AtLeastOneCondition, &error));
+ EXPECT_TRUE(rule);
+ EXPECT_EQ("", error);
+
+ ASSERT_TRUE(Rule::JsonRule::Populate(
+ *ParseJson("{ \n"
+ " \"id\": \"rule1\", \n"
+ " \"conditions\": [ \n"
+ " ], \n"
+ " \"actions\": [ \n"
+ " { \n"
+ " \"value\": 2 \n"
+ " } \n"
+ " ], \n"
+ " \"priority\": 200 \n"
+ "}"),
+ json_rule.get()));
+ rule = Rule::Create(matcher.condition_factory(), kExtensionId, base::Time(),
+ json_rule, &AtLeastOneCondition, &error);
+ EXPECT_FALSE(rule);
+ EXPECT_EQ("No conditions", error);
+}
+
+} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc
index 8d573de..f0b1fd7 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc
@@ -12,6 +12,7 @@
#include "base/string_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
#include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
@@ -440,70 +441,26 @@ scoped_ptr<WebRequestAction> WebRequestAction::Create(
return scoped_ptr<WebRequestAction>();
}
-
-//
-// WebRequestActionSet
-//
-
-WebRequestActionSet::WebRequestActionSet(const Actions& actions)
- : actions_(actions) {}
-
-WebRequestActionSet::~WebRequestActionSet() {}
-
-// static
-scoped_ptr<WebRequestActionSet> WebRequestActionSet::Create(
- const AnyVector& actions,
- std::string* error,
- bool* bad_message) {
- *error = "";
- *bad_message = false;
- Actions result;
-
- for (AnyVector::const_iterator i = actions.begin();
- i != actions.end(); ++i) {
- CHECK(i->get());
- scoped_ptr<WebRequestAction> action =
- WebRequestAction::Create((*i)->value(), error, bad_message);
- if (!error->empty() || *bad_message)
- return scoped_ptr<WebRequestActionSet>(NULL);
- result.push_back(make_linked_ptr(action.release()));
- }
-
- return scoped_ptr<WebRequestActionSet>(new WebRequestActionSet(result));
-}
-
-std::list<LinkedPtrEventResponseDelta> WebRequestActionSet::CreateDeltas(
- const ExtensionInfoMap* extension_info_map,
- const std::string& extension_id,
- const WebRequestRule::RequestData& request_data,
- bool crosses_incognito,
- const base::Time& extension_install_time) const {
- std::list<LinkedPtrEventResponseDelta> result;
- for (Actions::const_iterator i = actions_.begin(); i != actions_.end(); ++i) {
- if (!(*i)->HasPermission(extension_info_map, extension_id,
- request_data.request, crosses_incognito))
- continue;
- if ((*i)->GetStages() & request_data.stage) {
- LinkedPtrEventResponseDelta delta = (*i)->CreateDelta(
- request_data, extension_id, extension_install_time);
- if (delta.get()) {
- if ((*i)->DeltaHasPermission(extension_info_map, extension_id,
- request_data.request, crosses_incognito,
- delta))
- result.push_back(delta);
- }
+void WebRequestAction::Apply(const std::string& extension_id,
+ base::Time extension_install_time,
+ ApplyInfo* apply_info) const {
+ if (!HasPermission(apply_info->extension_info_map, extension_id,
+ apply_info->request_data.request,
+ apply_info->crosses_incognito))
+ return;
+ if (GetStages() & apply_info->request_data.stage) {
+ LinkedPtrEventResponseDelta delta = CreateDelta(
+ apply_info->request_data, extension_id, extension_install_time);
+ if (delta.get()) {
+ if (DeltaHasPermission(apply_info->extension_info_map, extension_id,
+ apply_info->request_data.request,
+ apply_info->crosses_incognito,
+ delta))
+ apply_info->deltas->push_back(delta);
}
}
- return result;
}
-int WebRequestActionSet::GetMinimumPriority() const {
- int minimum_priority = std::numeric_limits<int>::min();
- for (Actions::const_iterator i = actions_.begin(); i != actions_.end(); ++i) {
- minimum_priority = std::max(minimum_priority, (*i)->GetMinimumPriority());
- }
- return minimum_priority;
-}
//
// WebRequestCancelAction
@@ -528,7 +485,7 @@ WebRequestCancelAction::GetHostPermissionsStrategy() const {
}
LinkedPtrEventResponseDelta WebRequestCancelAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -561,7 +518,7 @@ WebRequestRedirectAction::GetHostPermissionsStrategy() const {
}
LinkedPtrEventResponseDelta WebRequestRedirectAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -599,7 +556,7 @@ WebRequestRedirectToTransparentImageAction::GetHostPermissionsStrategy() const {
LinkedPtrEventResponseDelta
WebRequestRedirectToTransparentImageAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -635,7 +592,7 @@ WebRequestRedirectToEmptyDocumentAction::GetHostPermissionsStrategy() const {
LinkedPtrEventResponseDelta
WebRequestRedirectToEmptyDocumentAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -724,7 +681,7 @@ WebRequestRedirectByRegExAction::GetHostPermissionsStrategy() const {
}
LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -768,7 +725,7 @@ WebRequestSetRequestHeaderAction::GetType() const {
LinkedPtrEventResponseDelta
WebRequestSetRequestHeaderAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -800,7 +757,7 @@ WebRequestRemoveRequestHeaderAction::GetType() const {
LinkedPtrEventResponseDelta
WebRequestRemoveRequestHeaderAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -834,7 +791,7 @@ WebRequestAddResponseHeaderAction::GetType() const {
LinkedPtrEventResponseDelta
WebRequestAddResponseHeaderAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -879,7 +836,7 @@ WebRequestRemoveResponseHeaderAction::GetType() const {
LinkedPtrEventResponseDelta
WebRequestRemoveResponseHeaderAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -935,7 +892,7 @@ WebRequestIgnoreRulesAction::GetHostPermissionsStrategy() const {
}
LinkedPtrEventResponseDelta WebRequestIgnoreRulesAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -963,7 +920,7 @@ WebRequestAction::Type WebRequestRequestCookieAction::GetType() const {
}
LinkedPtrEventResponseDelta WebRequestRequestCookieAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -996,7 +953,7 @@ WebRequestAction::Type WebRequestResponseCookieAction::GetType() const {
}
LinkedPtrEventResponseDelta WebRequestResponseCookieAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
@@ -1030,7 +987,7 @@ WebRequestAction::Type WebRequestSendMessageToExtensionAction::GetType() const {
}
LinkedPtrEventResponseDelta WebRequestSendMessageToExtensionAction::CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const {
CHECK(request_data.stage & GetStages());
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
index f68b904..46b382e 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h
@@ -11,12 +11,13 @@
#include "base/compiler_specific.h"
#include "base/memory/linked_ptr.h"
+#include "chrome/browser/extensions/api/declarative/declarative_rule.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
#include "chrome/common/extensions/api/events.h"
#include "googleurl/src/gurl.h"
+class ExtensionInfoMap;
class WebRequestPermission;
namespace base {
@@ -31,6 +32,7 @@ struct EventResponseDelta;
namespace extensions {
class Extension;
+struct DeclarativeWebRequestData;
}
namespace net {
@@ -77,6 +79,16 @@ class WebRequestAction {
// after creating the delta.
};
+ // Information necessary to decide how to apply a WebRequestAction
+ // inside a matching rule.
+ struct ApplyInfo {
+ const ExtensionInfoMap* extension_info_map;
+ const DeclarativeWebRequestData& request_data;
+ bool crosses_incognito;
+ // Modified by each applied action:
+ std::list<LinkedPtrEventResponseDelta>* deltas;
+ };
+
WebRequestAction();
virtual ~WebRequestAction();
@@ -135,53 +147,19 @@ class WebRequestAction {
// Returns a description of the modification to the request caused by
// this action.
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const = 0;
-};
-
-// Immutable container for multiple actions.
-//
-// TODO(battre): As WebRequestActionSet can become the single owner of all
-// actions, we can optimize here by making some of them singletons (e.g. Cancel
-// actions).
-class WebRequestActionSet {
- public:
- typedef std::vector<linked_ptr<json_schema_compiler::any::Any> > AnyVector;
- typedef std::vector<linked_ptr<WebRequestAction> > Actions;
-
- explicit WebRequestActionSet(const Actions& actions);
- virtual ~WebRequestActionSet();
-
- // Factory method that instantiates a WebRequestActionSet according to
- // |actions| which represents the array of actions received from the
- // extension API.
- static scoped_ptr<WebRequestActionSet> Create(const AnyVector& actions,
- std::string* error,
- bool* bad_message);
-
- // Returns a description of the modifications to |request_data.request| caused
- // by the |actions_| that can be executed at |request.stage|. If |extension|
- // is not NULL, permissions of extensions are checked.
- std::list<LinkedPtrEventResponseDelta> CreateDeltas(
- const ExtensionInfoMap* extension_info_map,
- const std::string& extension_id,
- const WebRequestRule::RequestData& request_data,
- bool crosses_incognito,
- const base::Time& extension_install_time) const;
-
- // Returns the minimum priority of rules that may be evaluated after
- // this rule. Defaults to MIN_INT.
- int GetMinimumPriority() const;
- const Actions& actions() const { return actions_; }
-
- private:
- Actions actions_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRequestActionSet);
+ // Applies this action to a request, recording the results into
+ // apply_info.deltas.
+ void Apply(const std::string& extension_id,
+ base::Time extension_install_time,
+ ApplyInfo* apply_info) const;
};
+typedef DeclarativeActionSet<WebRequestAction> WebRequestActionSet;
+
//
// The following are concrete actions.
//
@@ -197,7 +175,7 @@ class WebRequestCancelAction : public WebRequestAction {
virtual Type GetType() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -216,7 +194,7 @@ class WebRequestRedirectAction : public WebRequestAction {
virtual Type GetType() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -237,7 +215,7 @@ class WebRequestRedirectToTransparentImageAction : public WebRequestAction {
virtual Type GetType() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -257,7 +235,7 @@ class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction {
virtual Type GetType() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -283,7 +261,7 @@ class WebRequestRedirectByRegExAction : public WebRequestAction {
virtual Type GetType() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -305,7 +283,7 @@ class WebRequestSetRequestHeaderAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -325,7 +303,7 @@ class WebRequestRemoveRequestHeaderAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -345,7 +323,7 @@ class WebRequestAddResponseHeaderAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -367,7 +345,7 @@ class WebRequestRemoveResponseHeaderAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -390,7 +368,7 @@ class WebRequestIgnoreRulesAction : public WebRequestAction {
virtual int GetMinimumPriority() const OVERRIDE;
virtual HostPermissionsStrategy GetHostPermissionsStrategy() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -413,7 +391,7 @@ class WebRequestRequestCookieAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -436,7 +414,7 @@ class WebRequestResponseCookieAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
@@ -456,7 +434,7 @@ class WebRequestSendMessageToExtensionAction : public WebRequestAction {
virtual int GetStages() const OVERRIDE;
virtual Type GetType() const OVERRIDE;
virtual LinkedPtrEventResponseDelta CreateDelta(
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
const std::string& extension_id,
const base::Time& extension_install_time) const OVERRIDE;
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
index ee15049..db4f6ea 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc
@@ -6,6 +6,7 @@
#include "base/message_loop.h"
#include "base/values.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
#include "chrome/common/extensions/extension_constants.h"
@@ -56,54 +57,6 @@ TEST(WebRequestActionTest, CreateAction) {
EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, result->GetType());
}
-TEST(WebRequestActionTest, CreateActionSet) {
- std::string error;
- bool bad_message = false;
- scoped_ptr<WebRequestActionSet> result;
-
- WebRequestActionSet::AnyVector input;
-
- // Test empty input.
- error.clear();
- result = WebRequestActionSet::Create(input, &error, &bad_message);
- EXPECT_TRUE(error.empty()) << error;
- EXPECT_FALSE(bad_message);
- ASSERT_TRUE(result.get());
- EXPECT_TRUE(result->actions().empty());
- EXPECT_EQ(std::numeric_limits<int>::min(), result->GetMinimumPriority());
-
- DictionaryValue correct_action;
- correct_action.SetString(keys::kInstanceTypeKey, keys::kIgnoreRulesType);
- correct_action.SetInteger(keys::kLowerPriorityThanKey, 10);
- DictionaryValue incorrect_action;
- incorrect_action.SetString(keys::kInstanceTypeKey, kUnknownActionType);
-
- // Test success.
- linked_ptr<json_schema_compiler::any::Any> action1 = make_linked_ptr(
- new json_schema_compiler::any::Any);
- action1->Init(correct_action);
- input.push_back(action1);
- error.clear();
- result = WebRequestActionSet::Create(input, &error, &bad_message);
- EXPECT_TRUE(error.empty()) << error;
- EXPECT_FALSE(bad_message);
- ASSERT_TRUE(result.get());
- ASSERT_EQ(1u, result->actions().size());
- EXPECT_EQ(WebRequestAction::ACTION_IGNORE_RULES,
- result->actions()[0]->GetType());
- EXPECT_EQ(10, result->GetMinimumPriority());
-
- // Test failure.
- linked_ptr<json_schema_compiler::any::Any> action2 = make_linked_ptr(
- new json_schema_compiler::any::Any);
- action2->Init(incorrect_action);
- input.push_back(action2);
- error.clear();
- result = WebRequestActionSet::Create(input, &error, &bad_message);
- EXPECT_NE("", error);
- EXPECT_FALSE(result.get());
-}
-
// Test capture group syntax conversions of WebRequestRedirectByRegExAction
TEST(WebRequestActionTest, PerlToRe2Style) {
#define CallPerlToRe2Style WebRequestRedirectByRegExAction::PerlToRe2Style
@@ -147,19 +100,20 @@ TEST(WebRequestActionTest, TestPermissions) {
// Check that redirect works on regular URLs but not on protected URLs.
net::TestURLRequest regular_request(GURL("http://test.com"), NULL, &context);
- std::list<LinkedPtrEventResponseDelta> deltas =
- action_set->CreateDeltas(
- NULL, "ext1",
- WebRequestRule::RequestData(&regular_request, ON_BEFORE_REQUEST),
- false, base::Time());
+ std::list<LinkedPtrEventResponseDelta> deltas;
+ DeclarativeWebRequestData request_data(&regular_request, ON_BEFORE_REQUEST);
+ WebRequestAction::ApplyInfo apply_info = {
+ NULL, request_data, false, &deltas
+ };
+ action_set->Apply("ext1", base::Time(), &apply_info);
EXPECT_EQ(1u, deltas.size());
net::TestURLRequest protected_request(GURL("http://clients1.google.com"),
NULL, &context);
- deltas = action_set->CreateDeltas(
- NULL, "ext1",
- WebRequestRule::RequestData(&protected_request, ON_BEFORE_REQUEST),
- false, base::Time());
+ deltas.clear();
+ request_data =
+ DeclarativeWebRequestData(&protected_request, ON_BEFORE_REQUEST);
+ action_set->Apply("ext1", base::Time(), &apply_info);
EXPECT_EQ(0u, deltas.size());
}
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc
index 97fed38..4a80a5a 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc
@@ -59,7 +59,7 @@ WebRequestCondition::~WebRequestCondition() {}
bool WebRequestCondition::IsFulfilled(
const std::set<URLMatcherConditionSet::ID>& url_matches,
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & applicable_request_stages_)) {
// A condition that cannot be evaluated is considered as violated.
return false;
@@ -148,90 +148,4 @@ scoped_ptr<WebRequestCondition> WebRequestCondition::Create(
return result.Pass();
}
-//
-// WebRequestConditionSet
-//
-
-WebRequestConditionSet::~WebRequestConditionSet() {}
-
-bool WebRequestConditionSet::IsFulfilled(
- URLMatcherConditionSet::ID url_match_trigger,
- const std::set<URLMatcherConditionSet::ID>& url_matches,
- const WebRequestRule::RequestData& request_data) const {
- if (url_match_trigger == -1) {
- // Invalid trigger -- indication that we should only check conditions
- // without URL attributes.
- for (std::vector<const WebRequestCondition*>::const_iterator it =
- conditions_without_urls_.begin();
- it != conditions_without_urls_.end(); ++it) {
- if ((*it)->IsFulfilled(url_matches, request_data))
- return true;
- }
- return false;
- }
-
- URLMatcherIdToCondition::const_iterator triggered =
- match_id_to_condition_.find(url_match_trigger);
- return (triggered != match_id_to_condition_.end() &&
- triggered->second->IsFulfilled(url_matches, request_data));
-}
-
-void WebRequestConditionSet::GetURLMatcherConditionSets(
- URLMatcherConditionSet::Vector* condition_sets) const {
- for (Conditions::const_iterator i = conditions_.begin();
- i != conditions_.end(); ++i) {
- scoped_refptr<URLMatcherConditionSet> set =
- (*i)->url_matcher_condition_set();
- if (set.get())
- condition_sets->push_back(set);
- }
-}
-
-// static
-scoped_ptr<WebRequestConditionSet> WebRequestConditionSet::Create(
- URLMatcherConditionFactory* url_matcher_condition_factory,
- const AnyVector& conditions,
- std::string* error) {
- Conditions result;
-
- for (AnyVector::const_iterator i = conditions.begin();
- i != conditions.end(); ++i) {
- CHECK(i->get());
- scoped_ptr<WebRequestCondition> condition =
- WebRequestCondition::Create(url_matcher_condition_factory,
- (*i)->value(), error);
- if (!error->empty())
- return scoped_ptr<WebRequestConditionSet>(NULL);
- result.push_back(make_linked_ptr(condition.release()));
- }
-
- URLMatcherIdToCondition match_id_to_condition;
- std::vector<const WebRequestCondition*> conditions_without_urls;
-
- for (Conditions::const_iterator i = result.begin(); i != result.end(); ++i) {
- const URLMatcherConditionSet* set = (*i)->url_matcher_condition_set().get();
- if (set) {
- URLMatcherConditionSet::ID id = set->id();
- match_id_to_condition[id] = i->get();
- } else {
- conditions_without_urls.push_back(i->get());
- }
- }
-
- return make_scoped_ptr(new WebRequestConditionSet(
- result, match_id_to_condition, conditions_without_urls));
-}
-
-bool WebRequestConditionSet::HasConditionsWithoutUrls() const {
- return !conditions_without_urls_.empty();
-}
-
-WebRequestConditionSet::WebRequestConditionSet(
- const Conditions& conditions,
- const URLMatcherIdToCondition& match_id_to_condition,
- const std::vector<const WebRequestCondition*>& conditions_without_urls)
- : match_id_to_condition_(match_id_to_condition),
- conditions_(conditions),
- conditions_without_urls_(conditions_without_urls) {}
-
} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
index d1fdcdf..fd8c4c1a 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h
@@ -12,12 +12,31 @@
#include "base/basictypes.h"
#include "base/memory/linked_ptr.h"
+#include "chrome/browser/extensions/api/declarative/declarative_rule.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/common/extensions/matcher/url_matcher.h"
+#include "net/http/http_response_headers.h"
namespace extensions {
+// Container for information about a URLRequest to determine which
+// rules apply to the request.
+struct DeclarativeWebRequestData {
+ DeclarativeWebRequestData(net::URLRequest* request, RequestStage stage)
+ : request(request), stage(stage),
+ original_response_headers(NULL) {}
+ DeclarativeWebRequestData(
+ net::URLRequest* request, RequestStage stage,
+ const net::HttpResponseHeaders* original_response_headers)
+ : request(request), stage(stage),
+ original_response_headers(original_response_headers) {}
+ net::URLRequest* request;
+ RequestStage stage;
+ // Additional information about requests that is not
+ // available in all request stages.
+ const net::HttpResponseHeaders* original_response_headers;
+};
+
// Representation of a condition in the Declarative WebRequest API. A condition
// consists of several attributes. Each of these attributes needs to be
// fulfilled in order for the condition to be fulfilled.
@@ -37,6 +56,8 @@ namespace extensions {
// WebRequestConditionSet::GetURLMatcherConditionSets.
class WebRequestCondition {
public:
+ typedef DeclarativeWebRequestData MatchData;
+
WebRequestCondition(
scoped_refptr<URLMatcherConditionSet> url_matcher_conditions,
const WebRequestConditionAttributes& condition_attributes);
@@ -52,20 +73,18 @@ class WebRequestCondition {
// Returns whether the request matches this condition. |url_matches| lists
// the IDs that match the request's URL.
bool IsFulfilled(const std::set<URLMatcherConditionSet::ID> &url_matches,
- const WebRequestRule::RequestData &request_data) const;
-
- // Returns a URLMatcherConditionSet::ID which is the canonical representation
- // for all URL patterns that need to be matched by this WebRequestCondition.
- // This ID is registered in a URLMatcher that can inform us in case of a
- // match.
- URLMatcherConditionSet::ID url_matcher_condition_set_id() const {
- DCHECK(url_matcher_conditions_.get());
- return url_matcher_conditions_->id();
+ const DeclarativeWebRequestData& request_data) const;
+
+ // True if this condition has a url filter.
+ bool has_url_matcher_condition_set() const {
+ return url_matcher_conditions_ != NULL;
}
- // Returns the set of conditions that are checked on the URL. May be NULL.
- scoped_refptr<URLMatcherConditionSet> url_matcher_condition_set() const {
- return url_matcher_conditions_;
+ // If this Condition has a url filter, appends it to |condition_sets|.
+ void GetURLMatcherConditionSets(
+ URLMatcherConditionSet::Vector* condition_sets) const {
+ if (url_matcher_conditions_)
+ condition_sets->push_back(url_matcher_conditions_);
}
// Returns the condition attributes checked by this condition.
@@ -93,59 +112,7 @@ class WebRequestCondition {
DISALLOW_COPY_AND_ASSIGN(WebRequestCondition);
};
-// This class stores a set of conditions that may be part of a WebRequestRule.
-// If any condition is fulfilled, the WebRequestActions of the WebRequestRule
-// can be triggered.
-class WebRequestConditionSet {
- public:
- typedef std::vector<linked_ptr<json_schema_compiler::any::Any> > AnyVector;
- typedef std::vector<linked_ptr<WebRequestCondition> > Conditions;
-
- ~WebRequestConditionSet();
-
- // Factory method that creates an WebRequestConditionSet according to the JSON
- // array |conditions| passed by the extension API.
- // Sets |error| and returns NULL in case of an error.
- static scoped_ptr<WebRequestConditionSet> Create(
- URLMatcherConditionFactory* url_matcher_condition_factory,
- const AnyVector& conditions,
- std::string* error);
-
- const Conditions& conditions() const {
- return conditions_;
- }
-
- // If |url_match_trigger| is a member of |url_matches|, then this returns
- // whether the corresponding condition is fulfilled wrt. |request_data|. If
- // |url_match_trigger| is -1, this function returns whether any of the
- // conditions without URL attributes is satisfied.
- bool IsFulfilled(
- URLMatcherConditionSet::ID url_match_trigger,
- const std::set<URLMatcherConditionSet::ID>& url_matches,
- const WebRequestRule::RequestData& request_data) const;
-
- // Appends the URLMatcherConditionSet from all conditions to |condition_sets|.
- void GetURLMatcherConditionSets(
- URLMatcherConditionSet::Vector* condition_sets) const;
-
- // Returns whether there are some conditions without UrlFilter attributes.
- bool HasConditionsWithoutUrls() const;
-
- private:
- typedef std::map<URLMatcherConditionSet::ID, const WebRequestCondition*>
- URLMatcherIdToCondition;
-
- WebRequestConditionSet(
- const Conditions& conditions,
- const URLMatcherIdToCondition& match_id_to_condition,
- const std::vector<const WebRequestCondition*>& conditions_without_urls);
-
- const URLMatcherIdToCondition match_id_to_condition_;
- const Conditions conditions_;
- const std::vector<const WebRequestCondition*> conditions_without_urls_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRequestConditionSet);
-};
+typedef DeclarativeConditionSet<WebRequestCondition> WebRequestConditionSet;
} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
index 78ccb28..78e1b2b 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc
@@ -11,6 +11,7 @@
#include "base/stringprintf.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
#include "content/public/browser/resource_request_info.h"
@@ -151,7 +152,7 @@ int WebRequestConditionAttributeResourceType::GetStages() const {
}
bool WebRequestConditionAttributeResourceType::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & GetStages()))
return false;
const content::ResourceRequestInfo* info =
@@ -222,7 +223,7 @@ int WebRequestConditionAttributeContentType::GetStages() const {
}
bool WebRequestConditionAttributeContentType::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & GetStages()))
return false;
std::string content_type;
@@ -567,7 +568,7 @@ int WebRequestConditionAttributeRequestHeaders::GetStages() const {
}
bool WebRequestConditionAttributeRequestHeaders::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & GetStages()))
return false;
@@ -631,7 +632,7 @@ int WebRequestConditionAttributeResponseHeaders::GetStages() const {
}
bool WebRequestConditionAttributeResponseHeaders::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & GetStages()))
return false;
@@ -702,7 +703,7 @@ int WebRequestConditionAttributeThirdParty::GetStages() const {
}
bool WebRequestConditionAttributeThirdParty::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
if (!(request_data.stage & GetStages()))
return false;
@@ -797,7 +798,7 @@ int WebRequestConditionAttributeStages::GetStages() const {
}
bool WebRequestConditionAttributeStages::IsFulfilled(
- const WebRequestRule::RequestData& request_data) const {
+ const DeclarativeWebRequestData& request_data) const {
// Note: removing '!=' triggers warning C4800 on the VS compiler.
return (request_data.stage & GetStages()) != 0;
}
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
index a87def4..db4daea 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h
@@ -13,7 +13,6 @@
#include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/common/extensions/api/events.h"
#include "webkit/glue/resource_type.h"
@@ -28,6 +27,7 @@ class URLRequest;
namespace extensions {
class HeaderMatcher;
+struct DeclarativeWebRequestData;
// Base class for all condition attributes of the declarative Web Request API
// except for condition attribute to test URLPatterns.
@@ -61,7 +61,7 @@ class WebRequestConditionAttribute {
// Returns whether the condition is fulfilled for this request.
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const = 0;
+ const DeclarativeWebRequestData& request_data) const = 0;
virtual Type GetType() const = 0;
@@ -97,7 +97,7 @@ class WebRequestConditionAttributeResourceType
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
@@ -127,7 +127,7 @@ class WebRequestConditionAttributeContentType
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
@@ -162,7 +162,7 @@ class WebRequestConditionAttributeRequestHeaders
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
@@ -196,7 +196,7 @@ class WebRequestConditionAttributeResponseHeaders
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
@@ -226,7 +226,7 @@ class WebRequestConditionAttributeThirdParty
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
@@ -255,7 +255,7 @@ class WebRequestConditionAttributeStages
// Implementation of WebRequestConditionAttribute:
virtual int GetStages() const OVERRIDE;
virtual bool IsFulfilled(
- const WebRequestRule::RequestData& request_data) const OVERRIDE;
+ const DeclarativeWebRequestData& request_data) const OVERRIDE;
virtual Type GetType() const OVERRIDE;
private:
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
index ac0e29a..b0e2989 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc
@@ -9,8 +9,8 @@
#include "base/memory/scoped_vector.h"
#include "base/message_loop.h"
#include "base/values.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request_test_util.h"
#include "net/test/test_server.h"
@@ -90,14 +90,14 @@ TEST(WebRequestConditionAttributeTest, ResourceType) {
content::ResourceRequestInfo::AllocateForTesting(&url_request_ok,
ResourceType::MAIN_FRAME, NULL, -1, -1);
EXPECT_TRUE(attribute->IsFulfilled(
- WebRequestRule::RequestData(&url_request_ok, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&url_request_ok, ON_BEFORE_REQUEST)));
net::TestURLRequest url_request_fail(
GURL("http://www.example.com"), NULL, &context);
content::ResourceRequestInfo::AllocateForTesting(&url_request_ok,
ResourceType::SUB_FRAME, NULL, -1, -1);
EXPECT_FALSE(attribute->IsFulfilled(
- WebRequestRule::RequestData(&url_request_fail, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&url_request_fail, ON_BEFORE_REQUEST)));
}
TEST(WebRequestConditionAttributeTest, ContentType) {
@@ -129,11 +129,11 @@ TEST(WebRequestConditionAttributeTest, ContentType) {
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_include.get());
EXPECT_FALSE(attribute_include->IsFulfilled(
- WebRequestRule::RequestData(&url_request, ON_BEFORE_REQUEST,
- url_request.response_headers())));
+ DeclarativeWebRequestData(&url_request, ON_BEFORE_REQUEST,
+ url_request.response_headers())));
EXPECT_TRUE(attribute_include->IsFulfilled(
- WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
- url_request.response_headers())));
+ DeclarativeWebRequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
scoped_ptr<WebRequestConditionAttribute> attribute_exclude =
WebRequestConditionAttribute::Create(
@@ -141,8 +141,8 @@ TEST(WebRequestConditionAttributeTest, ContentType) {
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_exclude.get());
EXPECT_FALSE(attribute_exclude->IsFulfilled(
- WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
- url_request.response_headers())));
+ DeclarativeWebRequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
content_types.Clear();
content_types.Append(Value::CreateStringValue("something/invalid"));
@@ -152,8 +152,8 @@ TEST(WebRequestConditionAttributeTest, ContentType) {
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_unincluded.get());
EXPECT_FALSE(attribute_unincluded->IsFulfilled(
- WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
- url_request.response_headers())));
+ DeclarativeWebRequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
scoped_ptr<WebRequestConditionAttribute> attribute_unexcluded =
WebRequestConditionAttribute::Create(
@@ -161,8 +161,8 @@ TEST(WebRequestConditionAttributeTest, ContentType) {
EXPECT_EQ("", error);
ASSERT_TRUE(attribute_unexcluded.get());
EXPECT_TRUE(attribute_unexcluded->IsFulfilled(
- WebRequestRule::RequestData(&url_request, ON_HEADERS_RECEIVED,
- url_request.response_headers())));
+ DeclarativeWebRequestData(&url_request, ON_HEADERS_RECEIVED,
+ url_request.response_headers())));
}
// Testing WebRequestConditionAttributeThirdParty.
@@ -200,21 +200,21 @@ TEST(WebRequestConditionAttributeTest, ThirdParty) {
continue;
const RequestStage stage = static_cast<RequestStage>(i);
url_request.set_first_party_for_cookies(url_empty);
- EXPECT_FALSE(third_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_FALSE(third_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
- EXPECT_TRUE(first_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_TRUE(first_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
url_request.set_first_party_for_cookies(url_b);
- EXPECT_TRUE(third_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_TRUE(third_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
- EXPECT_FALSE(first_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_FALSE(first_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
url_request.set_first_party_for_cookies(url_a);
- EXPECT_FALSE(third_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_FALSE(third_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
- EXPECT_TRUE(first_party_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_TRUE(first_party_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, stage)));
}
}
@@ -283,17 +283,17 @@ TEST(WebRequestConditionAttributeTest, Stages) {
net::TestURLRequest url_request(url_empty, &delegate, &context);
for (size_t i = 0; i < arraysize(active_stages); ++i) {
- EXPECT_FALSE(empty_attribute->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_FALSE(empty_attribute->IsFulfilled(DeclarativeWebRequestData(
&url_request, active_stages[i].first)));
for (size_t j = 0; j < one_stage_attributes.size(); ++j) {
EXPECT_EQ(
i == j,
- one_stage_attributes[j]->IsFulfilled(WebRequestRule::RequestData(
+ one_stage_attributes[j]->IsFulfilled(DeclarativeWebRequestData(
&url_request, active_stages[i].first)));
}
- EXPECT_TRUE(attribute_with_all->IsFulfilled(WebRequestRule::RequestData(
+ EXPECT_TRUE(attribute_with_all->IsFulfilled(DeclarativeWebRequestData(
&url_request, active_stages[i].first)));
}
}
@@ -386,7 +386,7 @@ void MatchAndCheck(const std::vector< std::vector<const std::string*> >& tests,
ASSERT_EQ("", error);
ASSERT_TRUE(attribute.get());
- *result = attribute->IsFulfilled(WebRequestRule::RequestData(
+ *result = attribute->IsFulfilled(DeclarativeWebRequestData(
url_request, stage, url_request->response_headers()));
}
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc
index 70eb2e2..0db6afb 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc
@@ -10,7 +10,6 @@
#include "base/test/values_test_util.h"
#include "base/values.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/common/extensions/matcher/url_matcher_constants.h"
#include "content/public/browser/resource_request_info.h"
#include "net/url_request/url_request_test_util.h"
@@ -70,7 +69,7 @@ TEST(WebRequestConditionTest, CreateCondition) {
ASSERT_TRUE(result.get());
URLMatcherConditionSet::Vector url_matcher_condition_set;
- url_matcher_condition_set.push_back(result->url_matcher_condition_set());
+ result->GetURLMatcherConditionSets(&url_matcher_condition_set);
matcher.AddConditionSets(url_matcher_condition_set);
std::set<URLMatcherConditionSet::ID> url_match_ids;
@@ -83,7 +82,7 @@ TEST(WebRequestConditionTest, CreateCondition) {
ResourceType::MAIN_FRAME, NULL, -1, -1);
EXPECT_TRUE(result->IsFulfilled(
url_match_ids,
- WebRequestRule::RequestData(&match_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&match_request, ON_BEFORE_REQUEST)));
GURL https_url("https://www.example.com");
net::TestURLRequest wrong_resource_type(https_url, NULL, &context);
@@ -94,7 +93,7 @@ TEST(WebRequestConditionTest, CreateCondition) {
ResourceType::SUB_FRAME, NULL, -1, -1);
EXPECT_FALSE(result->IsFulfilled(
url_match_ids,
- WebRequestRule::RequestData(&wrong_resource_type, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&wrong_resource_type, ON_BEFORE_REQUEST)));
}
// Conditions without UrlFilter attributes need to be independent of URL
@@ -160,17 +159,17 @@ TEST(WebRequestConditionTest, NoUrlAttributes) {
// attributes are fulfilled.
EXPECT_FALSE(condition_no_url_false->IsFulfilled(
dummy_match_set,
- WebRequestRule::RequestData(&https_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&https_request, ON_BEFORE_REQUEST)));
EXPECT_TRUE(condition_no_url_true->IsFulfilled(
dummy_match_set,
- WebRequestRule::RequestData(&https_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&https_request, ON_BEFORE_REQUEST)));
// 2. An empty condition (in particular, without UrlFilter attributes) is
// always fulfilled.
EXPECT_TRUE(condition_empty->IsFulfilled(
dummy_match_set,
- WebRequestRule::RequestData(&https_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&https_request, ON_BEFORE_REQUEST)));
}
TEST(WebRequestConditionTest, CreateConditionSet) {
@@ -231,7 +230,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) {
EXPECT_TRUE(result->IsFulfilled(
*(url_match_ids.begin()),
url_match_ids,
- WebRequestRule::RequestData(&http_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&http_request, ON_BEFORE_REQUEST)));
GURL https_url("https://www.example.com");
url_match_ids = matcher.MatchURL(https_url);
@@ -240,7 +239,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) {
EXPECT_TRUE(result->IsFulfilled(
*(url_match_ids.begin()),
url_match_ids,
- WebRequestRule::RequestData(&https_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&https_request, ON_BEFORE_REQUEST)));
// Check that both, hostPrefix and hostSuffix are evaluated.
GURL https_foo_url("https://foo.example.com");
@@ -250,7 +249,7 @@ TEST(WebRequestConditionTest, CreateConditionSet) {
EXPECT_FALSE(result->IsFulfilled(
-1,
url_match_ids,
- WebRequestRule::RequestData(&https_foo_request, ON_BEFORE_REQUEST)));
+ DeclarativeWebRequestData(&https_foo_request, ON_BEFORE_REQUEST)));
}
TEST(WebRequestConditionTest, TestPortFilter) {
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc
deleted file mode 100644
index 896a577..0000000
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
-
-#include "base/logging.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
-#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
-#include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
-#include "chrome/browser/extensions/extension_info_map.h"
-#include "chrome/common/extensions/extension.h"
-
-namespace {
-const char kInvalidActionDatatype[] = "An action of a rule set had an invalid "
- "structure that should have been caught by the JSON validator.";
-const char kActionCannotBeExecuted[] = "An action can never be executed "
- "because there are is no time in the request life-cycle during which the "
- "conditions can be checked and the action can possibly be executed.";
-} // namespace
-
-namespace extensions {
-
-WebRequestRule::WebRequestRule(
- const GlobalRuleId& id,
- base::Time extension_installation_time,
- scoped_ptr<WebRequestConditionSet> conditions,
- scoped_ptr<WebRequestActionSet> actions,
- Priority priority)
- : id_(id),
- extension_installation_time_(extension_installation_time),
- conditions_(conditions.release()),
- actions_(actions.release()),
- priority_(priority) {
- CHECK(conditions_.get());
- CHECK(actions_.get());
-}
-
-WebRequestRule::~WebRequestRule() {}
-
-// static
-bool WebRequestRule::CheckConsistency(
- WebRequestConditionSet* conditions,
- WebRequestActionSet* actions,
- std::string* error) {
- // Actions and conditions can be checked and executed in specific phases
- // of each web request. We consider a rule inconsistent if there is an action
- // that cannot be triggered by any condition.
- for (WebRequestActionSet::Actions::const_iterator action_iter =
- actions->actions().begin();
- action_iter != actions->actions().end();
- ++action_iter) {
- bool found_matching_condition = false;
- for (WebRequestConditionSet::Conditions::const_iterator condition_iter =
- conditions->conditions().begin();
- condition_iter != conditions->conditions().end() &&
- !found_matching_condition;
- ++condition_iter) {
- // Test the intersection of bit masks, this is intentionally & and not &&.
- if ((*action_iter)->GetStages() & (*condition_iter)->stages())
- found_matching_condition = true;
- }
- if (!found_matching_condition) {
- *error = kActionCannotBeExecuted;
- return false;
- }
- }
- return true;
-}
-
-// static
-scoped_ptr<WebRequestRule> WebRequestRule::Create(
- URLMatcherConditionFactory* url_matcher_condition_factory,
- const std::string& extension_id,
- base::Time extension_installation_time,
- linked_ptr<RulesRegistry::Rule> rule,
- std::string* error) {
- scoped_ptr<WebRequestRule> error_result;
-
- scoped_ptr<WebRequestConditionSet> conditions =
- WebRequestConditionSet::Create(
- url_matcher_condition_factory, rule->conditions, error);
- if (!error->empty())
- return error_result.Pass();
- CHECK(conditions.get());
-
- bool bad_message = false;
- scoped_ptr<WebRequestActionSet> actions =
- WebRequestActionSet::Create(rule->actions, error, &bad_message);
- if (bad_message) {
- // TODO(battre) Export concept of bad_message to caller, the extension
- // should be killed in case it is true.
- *error = kInvalidActionDatatype;
- return error_result.Pass();
- }
- if (!error->empty() || bad_message)
- return error_result.Pass();
- CHECK(actions.get());
-
- if (!CheckConsistency(conditions.get(), actions.get(), error)) {
- DCHECK(!error->empty());
- return error_result.Pass();
- }
-
- CHECK(rule->priority.get());
- int priority = *(rule->priority);
-
- GlobalRuleId rule_id(extension_id, *(rule->id));
- return scoped_ptr<WebRequestRule>(
- new WebRequestRule(rule_id, extension_installation_time,
- conditions.Pass(), actions.Pass(), priority));
-}
-
-std::list<LinkedPtrEventResponseDelta> WebRequestRule::CreateDeltas(
- const ExtensionInfoMap* extension_info_map,
- const RequestData& request_data,
- bool crosses_incognito) const {
- return actions_->CreateDeltas(extension_info_map, extension_id(),
- request_data, crosses_incognito,
- extension_installation_time_);
-}
-
-int WebRequestRule::GetMinimumPriority() const {
- return actions_->GetMinimumPriority();
-}
-
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h
deleted file mode 100644
index e7c2dcf..0000000
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h
+++ /dev/null
@@ -1,122 +0,0 @@
-// Copyright (c) 2012 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.
-
-#ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULE_H_
-#define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULE_H_
-
-#include <list>
-#include <vector>
-
-#include "base/compiler_specific.h"
-#include "base/time.h"
-#include "chrome/browser/extensions/api/declarative/rules_registry.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
-
-class ExtensionInfoMap;
-class WebRequestPermissions;
-
-namespace extensions {
-class Extension;
-class URLMatcherConditionFactory;
-class WebRequestActionSet;
-class WebRequestConditionSet;
-}
-
-namespace extension_web_request_api_helpers {
-struct EventResponseDelta;
-}
-
-namespace net {
-class HttpResponseHeaders;
-class URLRequest;
-}
-
-namespace extensions {
-
-typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta>
- LinkedPtrEventResponseDelta;
-
-// Representation of a rule of the declarative Web Request API
-class WebRequestRule {
- public:
- typedef std::string ExtensionId;
- typedef std::string RuleId;
- typedef std::pair<ExtensionId, RuleId> GlobalRuleId;
- typedef int Priority;
-
- struct RequestData {
- RequestData(net::URLRequest* request, RequestStage stage)
- : request(request), stage(stage),
- original_response_headers(NULL) {}
- RequestData(net::URLRequest* request, RequestStage stage,
- const net::HttpResponseHeaders* original_response_headers)
- : request(request), stage(stage),
- original_response_headers(original_response_headers) {}
- net::URLRequest* request;
- RequestStage stage;
- // Additional information about requests that is not
- // available in all request stages.
- const net::HttpResponseHeaders* original_response_headers;
- };
-
- WebRequestRule(const GlobalRuleId& id,
- base::Time extension_installation_time,
- scoped_ptr<WebRequestConditionSet> conditions,
- scoped_ptr<WebRequestActionSet> actions,
- Priority priority);
- virtual ~WebRequestRule();
-
- // If |error| is empty, the translation was successful and the returned
- // rule is internally consistent.
- static scoped_ptr<WebRequestRule> Create(
- URLMatcherConditionFactory* url_matcher_condition_factory,
- const std::string& extension_id,
- base::Time extension_installation_time,
- linked_ptr<RulesRegistry::Rule> rule,
- std::string* error);
-
- const GlobalRuleId& id() const { return id_; }
- const std::string& extension_id() const { return id_.first; }
- const WebRequestConditionSet& conditions() const { return *conditions_; }
- const WebRequestActionSet& actions() const { return *actions_; }
- Priority priority() const { return priority_; }
-
- // Creates all deltas resulting from the ActionSet. This function should
- // only be called when the conditions_ are fulfilled (from a semantic point
- // of view; no harm is done if this function is called at other times for
- // testing purposes).
- // If |extension| is set, deltas are suppressed if the |extension| does not
- // have have sufficient permissions to modify the request. The returned list
- // may be empty in this case.
- std::list<LinkedPtrEventResponseDelta> CreateDeltas(
- const ExtensionInfoMap* extension_info_map,
- const RequestData& request_data,
- bool crosses_incognito) const;
-
- // Returns the minimum priority of rules that may be evaluated after
- // this rule. Defaults to MAX_INT. Only valid if the conditions of this rule
- // are fulfilled.
- Priority GetMinimumPriority() const;
-
- private:
- // Checks whether the set of |conditions| and |actions| are consistent,
- // meaning for example that we do not allow combining an |action| that needs
- // to be executed before the |condition| can be fulfilled.
- // Returns true in case of consistency and MUST set |error| otherwise.
- static bool CheckConsistency(WebRequestConditionSet* conditions,
- WebRequestActionSet* actions,
- std::string* error);
-
- GlobalRuleId id_;
- base::Time extension_installation_time_; // For precedences of rules.
- scoped_ptr<WebRequestConditionSet> conditions_;
- scoped_ptr<WebRequestActionSet> actions_;
- Priority priority_;
-
- DISALLOW_COPY_AND_ASSIGN(WebRequestRule);
-};
-
-} // namespace extensions
-
-#endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULE_H_
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule_unittest.cc
deleted file mode 100644
index d3caa4e..0000000
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rule_unittest.cc
+++ /dev/null
@@ -1,114 +0,0 @@
-// Copyright (c) 2012 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 "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
-
-#include "base/json/json_reader.h"
-#include "base/memory/linked_ptr.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h"
-#include "chrome/common/extensions/matcher/url_matcher.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace extensions {
-
-namespace {
-const char kExtId[] = "ext1";
-} // namespace
-
-TEST(WebRequestRuleTest, Create) {
- const char kRule[] =
- "{ \n"
- " \"id\": \"rule1\", \n"
- " \"conditions\": [ \n"
- " { \n"
- " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
- " \"url\": {\"hostSuffix\": \"foo.com\"}, \n"
- " \"contentType\": [\"image/jpeg\"] \n"
- " } \n"
- " ], \n"
- " \"actions\": [ \n"
- " { \n"
- " \"instanceType\": \"declarativeWebRequest.CancelRequest\" \n"
- " } \n"
- " ], \n"
- " \"priority\": 200 \n"
- "} ";
-
- scoped_ptr<Value> value(base::JSONReader::Read(kRule));
- ASSERT_TRUE(value.get());
-
- linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule);
- ASSERT_TRUE(RulesRegistry::Rule::Populate(*value, rule.get()));
-
- URLMatcher matcher;
- std::string error;
- scoped_ptr<WebRequestRule> web_request_rule(
- WebRequestRule::Create(matcher.condition_factory(), kExtId, base::Time(),
- rule, &error));
- ASSERT_TRUE(web_request_rule.get());
- EXPECT_TRUE(error.empty());
-
- EXPECT_EQ(kExtId, web_request_rule->id().first);
- EXPECT_EQ("rule1", web_request_rule->id().second);
-
- EXPECT_EQ(200, web_request_rule->priority());
-
- const WebRequestConditionSet& condition_set = web_request_rule->conditions();
- const WebRequestConditionSet::Conditions conditions =
- condition_set.conditions();
- ASSERT_EQ(1u, conditions.size());
- linked_ptr<WebRequestCondition> condition = conditions[0];
- const WebRequestConditionAttributes& condition_attributes =
- condition->condition_attributes();
- ASSERT_EQ(1u, condition_attributes.size());
- EXPECT_EQ(WebRequestConditionAttribute::CONDITION_CONTENT_TYPE,
- condition_attributes[0]->GetType());
-
- const WebRequestActionSet& action_set = web_request_rule->actions();
- const WebRequestActionSet::Actions& actions = action_set.actions();
- ASSERT_EQ(1u, actions.size());
- EXPECT_EQ(WebRequestAction::ACTION_CANCEL_REQUEST, actions[0]->GetType());
-}
-
-TEST(WebRequestRuleTest, CheckConsistency) {
- // The contentType condition can only be evaluated during ON_HEADERS_RECEIVED
- // but the redirect action can only be executed during ON_BEFORE_REQUEST.
- // Therefore, this is an inconsistent rule that needs to be flagged.
- const char kRule[] =
- "{ \n"
- " \"id\": \"rule1\", \n"
- " \"conditions\": [ \n"
- " { \n"
- " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
- " \"url\": {\"hostSuffix\": \"foo.com\"}, \n"
- " \"contentType\": [\"image/jpeg\"] \n"
- " } \n"
- " ], \n"
- " \"actions\": [ \n"
- " { \n"
- " \"instanceType\": \"declarativeWebRequest.RedirectRequest\",\n"
- " \"redirectUrl\": \"http://bar.com\" \n"
- " } \n"
- " ], \n"
- " \"priority\": 200 \n"
- "} ";
-
- scoped_ptr<Value> value(base::JSONReader::Read(kRule));
- ASSERT_TRUE(value.get());
-
- linked_ptr<RulesRegistry::Rule> rule(new RulesRegistry::Rule);
- ASSERT_TRUE(RulesRegistry::Rule::Populate(*value, rule.get()));
-
- URLMatcher matcher;
- std::string error;
- scoped_ptr<WebRequestRule> web_request_rule(
- WebRequestRule::Create(matcher.condition_factory(), kExtId, base::Time(),
- rule, &error));
- EXPECT_FALSE(web_request_rule.get());
- EXPECT_FALSE(error.empty());
-}
-
-} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc
index 06477a1..0e90c2d 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc
@@ -15,6 +15,12 @@
#include "chrome/browser/extensions/extension_system.h"
#include "net/url_request/url_request.h"
+namespace {
+const char kActionCannotBeExecuted[] = "An action can never be executed "
+ "because there are is no time in the request life-cycle during which the "
+ "conditions can be checked and the action can possibly be executed.";
+} // namespace
+
namespace extensions {
WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile,
@@ -26,7 +32,7 @@ WebRequestRulesRegistry::WebRequestRulesRegistry(Profile* profile,
std::set<const WebRequestRule*>
WebRequestRulesRegistry::GetMatches(
- const WebRequestRule::RequestData& request_data) {
+ const DeclarativeWebRequestData& request_data) {
typedef std::set<const WebRequestRule*> RuleSet;
typedef std::set<URLMatcherConditionSet::ID> URLMatches;
@@ -57,7 +63,7 @@ WebRequestRulesRegistry::GetMatches(
std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas(
const ExtensionInfoMap* extension_info_map,
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
bool crosses_incognito) {
if (webrequest_rules_.empty())
return std::list<LinkedPtrEventResponseDelta>();
@@ -107,8 +113,12 @@ std::list<LinkedPtrEventResponseDelta> WebRequestRulesRegistry::CreateDeltas(
if (priority_of_rule < current_min_priority)
continue;
- std::list<LinkedPtrEventResponseDelta> rule_result =
- rule->CreateDeltas(extension_info_map, request_data, crosses_incognito);
+
+ std::list<LinkedPtrEventResponseDelta> rule_result;
+ WebRequestAction::ApplyInfo apply_info = {
+ extension_info_map, request_data, crosses_incognito, &rule_result
+ };
+ rule->Apply(&apply_info);
result.splice(result.begin(), rule_result);
min_priorities[extension_id] = std::max(current_min_priority,
@@ -133,7 +143,8 @@ std::string WebRequestRulesRegistry::AddRulesImpl(
scoped_ptr<WebRequestRule> webrequest_rule(
WebRequestRule::Create(url_matcher_.condition_factory(), extension_id,
- extension_installation_time, *rule, &error));
+ extension_installation_time, *rule,
+ &CheckConsistency, &error));
if (!error.empty()) {
// We don't return here, because we want to clear temporary
// condition sets in the url_matcher_.
@@ -259,4 +270,34 @@ void WebRequestRulesRegistry::ClearCacheOnNavigation() {
extension_web_request_api_helpers::ClearCacheOnNavigation();
}
+// static
+bool WebRequestRulesRegistry::CheckConsistency(
+ const WebRequestConditionSet* conditions,
+ const WebRequestActionSet* actions,
+ std::string* error) {
+ // Actions and conditions can be checked and executed in specific phases
+ // of each web request. We consider a rule inconsistent if there is an action
+ // that cannot be triggered by any condition.
+ for (WebRequestActionSet::Actions::const_iterator action_iter =
+ actions->actions().begin();
+ action_iter != actions->actions().end();
+ ++action_iter) {
+ bool found_matching_condition = false;
+ for (WebRequestConditionSet::Conditions::const_iterator condition_iter =
+ conditions->conditions().begin();
+ condition_iter != conditions->conditions().end() &&
+ !found_matching_condition;
+ ++condition_iter) {
+ // Test the intersection of bit masks, this is intentionally & and not &&.
+ if ((*action_iter)->GetStages() & (*condition_iter)->stages())
+ found_matching_condition = true;
+ }
+ if (!found_matching_condition) {
+ *error = kActionCannotBeExecuted;
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h
index 6433f5c..9746a9b 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h
@@ -14,9 +14,11 @@
#include "base/time.h"
#include "base/memory/linked_ptr.h"
#include "base/memory/ref_counted.h"
+#include "chrome/browser/extensions/api/declarative/declarative_rule.h"
#include "chrome/browser/extensions/api/declarative/rules_registry_with_cache.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h"
+#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h"
#include "chrome/browser/extensions/extension_info_map.h"
#include "chrome/common/extensions/matcher/url_matcher.h"
@@ -35,6 +37,10 @@ namespace extensions {
class RulesRegistryService;
+typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta>
+ LinkedPtrEventResponseDelta;
+typedef DeclarativeRule<WebRequestCondition, WebRequestAction> WebRequestRule;
+
// The WebRequestRulesRegistry is responsible for managing
// the internal representation of rules for the Declarative Web Request API.
//
@@ -70,13 +76,13 @@ class WebRequestRulesRegistry : public RulesRegistryWithCache {
// TODO(battre): This will become an implementation detail, because we need
// a way to also execute the actions of the rules.
std::set<const WebRequestRule*> GetMatches(
- const WebRequestRule::RequestData& request_data);
+ const DeclarativeWebRequestData& request_data);
// Returns which modifications should be executed on the network request
// according to the rules registered in this registry.
std::list<LinkedPtrEventResponseDelta> CreateDeltas(
const ExtensionInfoMap* extension_info_map,
- const WebRequestRule::RequestData& request_data,
+ const DeclarativeWebRequestData& request_data,
bool crosses_incognito);
// Implementation of RulesRegistryWithCache:
@@ -107,6 +113,14 @@ class WebRequestRulesRegistry : public RulesRegistryWithCache {
}
private:
+ // Checks whether the set of |conditions| and |actions| are consistent,
+ // meaning for example that we do not allow combining an |action| that needs
+ // to be executed before the |condition| can be fulfilled.
+ // Returns true in case of consistency and MUST set |error| otherwise.
+ static bool CheckConsistency(const WebRequestConditionSet* conditions,
+ const WebRequestActionSet* actions,
+ std::string* error);
+
typedef std::map<URLMatcherConditionSet::ID, WebRequestRule*> RuleTriggers;
typedef std::map<WebRequestRule::GlobalRuleId, linked_ptr<WebRequestRule> >
RulesMap;
diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
index 0b89abb..a2b8dc7 100644
--- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
+++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc
@@ -6,17 +6,18 @@
#include <vector>
+#include "base/json/json_reader.h"
#include "base/memory/linked_ptr.h"
#include "base/message_loop.h"
#include "base/stl_util.h"
#include "base/test/values_test_util.h"
#include "base/values.h"
-#include "chrome/common/extensions/matcher/url_matcher_constants.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
+#include "chrome/common/extensions/matcher/url_matcher_constants.h"
#include "content/public/test/test_browser_thread.h"
#include "net/url_request/url_request_test_util.h"
+#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
@@ -30,6 +31,8 @@ const char kRuleId4[] = "rule4";
namespace extensions {
+using testing::HasSubstr;
+
namespace helpers = extension_web_request_api_helpers;
namespace keys = declarative_webrequest_constants;
namespace keys2 = url_matcher_constants;
@@ -317,7 +320,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) {
net::TestURLRequestContext context;
net::TestURLRequest http_request(http_url, NULL, &context);
matches = registry->GetMatches(
- WebRequestRule::RequestData(&http_request, ON_BEFORE_REQUEST));
+ DeclarativeWebRequestData(&http_request, ON_BEFORE_REQUEST));
EXPECT_EQ(2u, matches.size());
std::set<WebRequestRule::GlobalRuleId> matches_ids;
@@ -330,7 +333,7 @@ TEST_F(WebRequestRulesRegistryTest, AddRulesImpl) {
GURL foobar_url("http://www.foobar.com");
net::TestURLRequest foobar_request(foobar_url, NULL, &context);
matches = registry->GetMatches(
- WebRequestRule::RequestData(&foobar_request, ON_BEFORE_REQUEST));
+ DeclarativeWebRequestData(&foobar_request, ON_BEFORE_REQUEST));
EXPECT_EQ(1u, matches.size());
WebRequestRule::GlobalRuleId expected_pair =
std::make_pair(kExtensionId, kRuleId2);
@@ -458,7 +461,7 @@ TEST_F(WebRequestRulesRegistryTest, Precedences) {
std::list<LinkedPtrEventResponseDelta> deltas =
registry->CreateDeltas(
NULL,
- WebRequestRule::RequestData(&request, ON_BEFORE_REQUEST),
+ DeclarativeWebRequestData(&request, ON_BEFORE_REQUEST),
false);
// The second extension is installed later and will win for this reason
@@ -508,7 +511,7 @@ TEST_F(WebRequestRulesRegistryTest, Priorities) {
std::list<LinkedPtrEventResponseDelta> deltas =
registry->CreateDeltas(
NULL,
- WebRequestRule::RequestData(&request, ON_BEFORE_REQUEST),
+ DeclarativeWebRequestData(&request, ON_BEFORE_REQUEST),
false);
// The redirect by the first extension is ignored due to the ignore rule.
@@ -550,11 +553,51 @@ TEST_F(WebRequestRulesRegistryTest, GetMatchesCheckFulfilled) {
net::TestURLRequestContext context;
net::TestURLRequest http_request(http_url, NULL, &context);
matches = registry->GetMatches(
- WebRequestRule::RequestData(&http_request, ON_BEFORE_REQUEST));
+ DeclarativeWebRequestData(&http_request, ON_BEFORE_REQUEST));
EXPECT_EQ(1u, matches.size());
WebRequestRule::GlobalRuleId expected_pair = std::make_pair(kExtensionId,
kRuleId3);
EXPECT_EQ(expected_pair, (*matches.begin())->id());
}
+TEST_F(WebRequestRulesRegistryTest, CheckConsistency) {
+ // The contentType condition can only be evaluated during ON_HEADERS_RECEIVED
+ // but the redirect action can only be executed during ON_BEFORE_REQUEST.
+ // Therefore, this is an inconsistent rule that needs to be flagged.
+ const char kRule[] =
+ "{ \n"
+ " \"id\": \"rule1\", \n"
+ " \"conditions\": [ \n"
+ " { \n"
+ " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n"
+ " \"url\": {\"hostSuffix\": \"foo.com\"}, \n"
+ " \"contentType\": [\"image/jpeg\"] \n"
+ " } \n"
+ " ], \n"
+ " \"actions\": [ \n"
+ " { \n"
+ " \"instanceType\": \"declarativeWebRequest.RedirectRequest\",\n"
+ " \"redirectUrl\": \"http://bar.com\" \n"
+ " } \n"
+ " ], \n"
+ " \"priority\": 200 \n"
+ "} ";
+
+ scoped_ptr<Value> value(base::JSONReader::Read(kRule));
+ ASSERT_TRUE(value.get());
+
+ std::vector<linked_ptr<RulesRegistry::Rule> > rules;
+ rules.push_back(make_linked_ptr(new RulesRegistry::Rule));
+ ASSERT_TRUE(RulesRegistry::Rule::Populate(*value, rules.back().get()));
+
+ scoped_refptr<WebRequestRulesRegistry> registry(
+ new TestWebRequestRulesRegistry());
+
+ URLMatcher matcher;
+ std::string error = registry->AddRulesImpl(kExtensionId, rules);
+ EXPECT_THAT(error, HasSubstr("no time in the request life-cycle"));
+ EXPECT_TRUE(registry->IsEmpty());
+}
+
+
} // namespace extensions
diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc
index b53ef97..a1e07b2 100644
--- a/chrome/browser/extensions/api/web_request/web_request_api.cc
+++ b/chrome/browser/extensions/api/web_request/web_request_api.cc
@@ -19,7 +19,6 @@
#include "chrome/browser/chrome_content_browser_client.h"
#include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h"
-#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h"
#include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h"
#include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h"
#include "chrome/browser/extensions/api/web_request/upload_data_presenter.h"
@@ -1648,7 +1647,7 @@ bool ExtensionWebRequestEventRouter::ProcessDeclarativeRules(
helpers::EventResponseDeltas result =
rules_registry->CreateDeltas(
extension_info_map,
- extensions::WebRequestRule::RequestData(
+ extensions::DeclarativeWebRequestData(
request, request_stage, original_response_headers),
i->second);
diff --git a/chrome/chrome_browser_extensions.gypi b/chrome/chrome_browser_extensions.gypi
index c7bf5d8..567dd3d 100644
--- a/chrome/chrome_browser_extensions.gypi
+++ b/chrome/chrome_browser_extensions.gypi
@@ -137,6 +137,7 @@
'browser/extensions/api/debugger/debugger_api_constants.h',
'browser/extensions/api/declarative/declarative_api.cc',
'browser/extensions/api/declarative/declarative_api.h',
+ 'browser/extensions/api/declarative/declarative_rule.h',
'browser/extensions/api/declarative/initializing_rules_registry.cc',
'browser/extensions/api/declarative/initializing_rules_registry.h',
'browser/extensions/api/declarative/rules_registry.cc',
@@ -159,8 +160,6 @@
'browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h',
'browser/extensions/api/declarative_webrequest/webrequest_constants.cc',
'browser/extensions/api/declarative_webrequest/webrequest_constants.h',
- 'browser/extensions/api/declarative_webrequest/webrequest_rule.cc',
- 'browser/extensions/api/declarative_webrequest/webrequest_rule.h',
'browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc',
'browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h',
'browser/extensions/api/developer_private/developer_private_api.cc',
@@ -774,7 +773,6 @@
['include', '^browser/extensions/api/declarative_webrequest/webrequest_condition.cc'],
['include', '^browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc'],
['include', '^browser/extensions/api/declarative_webrequest/webrequest_constants.cc'],
- ['include', '^browser/extensions/api/declarative_webrequest/webrequest_rule.cc'],
['include', '^browser/extensions/api/declarative_webrequest/webrequest_rules_registry.cc'],
['include', '^browser/extensions/api/extension_action/extension_page_actions_api_constants.cc'],
['include', '^browser/extensions/api/messaging/extension_message_port.cc'],
diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi
index 72b8d41..0312d05 100644
--- a/chrome/chrome_tests_unit.gypi
+++ b/chrome/chrome_tests_unit.gypi
@@ -651,13 +651,13 @@
'browser/extensions/api/content_settings/content_settings_store_unittest.cc',
'browser/extensions/api/content_settings/content_settings_unittest.cc',
'browser/extensions/api/cookies/cookies_unittest.cc',
+ 'browser/extensions/api/declarative/declarative_rule_unittest.cc',
'browser/extensions/api/declarative/initializing_rules_registry_unittest.cc',
'browser/extensions/api/declarative/rules_registry_service_unittest.cc',
'browser/extensions/api/declarative/rules_registry_with_cache_unittest.cc',
'browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc',
'browser/extensions/api/declarative_webrequest/webrequest_condition_attribute_unittest.cc',
'browser/extensions/api/declarative_webrequest/webrequest_condition_unittest.cc',
- 'browser/extensions/api/declarative_webrequest/webrequest_rule_unittest.cc',
'browser/extensions/api/declarative_webrequest/webrequest_rules_registry_unittest.cc',
'browser/extensions/api/dial/dial_device_data_unittest.cc',
'browser/extensions/api/dial/dial_registry_unittest.cc',
diff --git a/tools/json_schema_compiler/any.cc b/tools/json_schema_compiler/any.cc
index b429567..cd4e5c3 100644
--- a/tools/json_schema_compiler/any.cc
+++ b/tools/json_schema_compiler/any.cc
@@ -12,6 +12,10 @@ namespace any {
Any::Any() {}
+Any::Any(scoped_ptr<base::Value> from_value)
+ : value_(from_value.Pass()) {
+}
+
Any::~Any() {}
void Any::Init(const base::Value& from_value) {
diff --git a/tools/json_schema_compiler/any.h b/tools/json_schema_compiler/any.h
index 9e44048..83b84d6 100644
--- a/tools/json_schema_compiler/any.h
+++ b/tools/json_schema_compiler/any.h
@@ -19,6 +19,7 @@ namespace any {
class Any {
public:
Any();
+ explicit Any(scoped_ptr<base::Value> from_value);
~Any();
// Initializes the Value in this Any. Fails if already initialized.