diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 05:24:42 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-05-23 05:24:42 +0000 |
commit | c7efdca8af946ea21e60314b8e8fdee99e4fd2fb (patch) | |
tree | 19ff832edd0bcaaef78a6f6e3c5663ca2dc68097 | |
parent | e454c292859f95ffc24f57a5f8838d040961362c (diff) | |
download | chromium_src-c7efdca8af946ea21e60314b8e8fdee99e4fd2fb.zip chromium_src-c7efdca8af946ea21e60314b8e8fdee99e4fd2fb.tar.gz chromium_src-c7efdca8af946ea21e60314b8e8fdee99e4fd2fb.tar.bz2 |
Use DedupingFactory for Declarative WebRequest API
BUG=234232
Review URL: https://chromiumcodereview.appspot.com/14109029
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@201705 0039d316-1c4b-4281-b951-d872f2087c98
15 files changed, 638 insertions, 341 deletions
diff --git a/chrome/browser/extensions/api/declarative/declarative_rule.h b/chrome/browser/extensions/api/declarative/declarative_rule.h index 2a8ea82..bdc36fe 100644 --- a/chrome/browser/extensions/api/declarative/declarative_rule.h +++ b/chrome/browser/extensions/api/declarative/declarative_rule.h @@ -135,7 +135,7 @@ template<typename ActionT> class DeclarativeActionSet { public: typedef std::vector<linked_ptr<base::Value> > AnyVector; - typedef std::vector<linked_ptr<const ActionT> > Actions; + typedef std::vector<scoped_refptr<const ActionT> > Actions; explicit DeclarativeActionSet(const Actions& actions); @@ -356,10 +356,11 @@ DeclarativeActionSet<ActionT>::Create( for (AnyVector::const_iterator i = actions.begin(); i != actions.end(); ++i) { CHECK(i->get()); - scoped_ptr<ActionT> action = ActionT::Create(**i, error, bad_message); + scoped_refptr<const ActionT> action = + ActionT::Create(**i, error, bad_message); if (!error->empty() || *bad_message) return scoped_ptr<DeclarativeActionSet>(NULL); - result.push_back(make_linked_ptr(action.release())); + result.push_back(action); } return scoped_ptr<DeclarativeActionSet>(new DeclarativeActionSet(result)); diff --git a/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc b/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc index 620e98b..cb0f693 100644 --- a/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc +++ b/chrome/browser/extensions/api/declarative/declarative_rule_unittest.cc @@ -198,41 +198,52 @@ TEST(DeclarativeConditionTest, FulfillConditionSet) { // DeclarativeAction -struct SummingAction { +class SummingAction : public base::RefCounted<SummingAction> { + public: typedef int ApplyInfo; - int increment; - int min_priority; + SummingAction(int increment, int min_priority) + : increment_(increment), min_priority_(min_priority) {} - static scoped_ptr<SummingAction> Create(const base::Value& action, - std::string* error, - bool* bad_message) { - scoped_ptr<SummingAction> result(new SummingAction()); + static scoped_refptr<const SummingAction> Create(const base::Value& action, + std::string* error, + bool* bad_message) { + int increment = 0; + int min_priority = 0; const base::DictionaryValue* dict = NULL; EXPECT_TRUE(action.GetAsDictionary(&dict)); if (dict->HasKey("error")) { EXPECT_TRUE(dict->GetString("error", error)); - return result.Pass(); + return scoped_refptr<const SummingAction>(NULL); } if (dict->HasKey("bad")) { *bad_message = true; - return result.Pass(); + return scoped_refptr<const SummingAction>(NULL); } - EXPECT_TRUE(dict->GetInteger("value", &result->increment)); - dict->GetInteger("priority", &result->min_priority); - return result.Pass(); + EXPECT_TRUE(dict->GetInteger("value", &increment)); + dict->GetInteger("priority", &min_priority); + return scoped_refptr<const SummingAction>( + new SummingAction(increment, min_priority)); } void Apply(const std::string& extension_id, const base::Time& install_time, int* sum) const { - *sum += increment; + *sum += increment_; } + int increment() const { return increment_; } int minimum_priority() const { - return min_priority; + return min_priority_; } + + private: + friend class base::RefCounted<SummingAction>; + virtual ~SummingAction() {} + + int increment_; + int min_priority_; }; typedef DeclarativeActionSet<SummingAction> SummingActionSet; @@ -330,7 +341,7 @@ TEST(DeclarativeRuleTest, Create) { 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); + EXPECT_EQ(2, actions[0]->increment()); int sum = 0; rule->Apply(&sum); diff --git a/chrome/browser/extensions/api/declarative_content/content_action.cc b/chrome/browser/extensions/api/declarative_content/content_action.cc index 24661dd..c3a17c3 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action.cc @@ -31,7 +31,7 @@ const char kInvalidInstanceTypeError[] = #define INPUT_FORMAT_VALIDATE(test) do { \ if (!(test)) { \ *bad_message = true; \ - return scoped_ptr<ContentAction>(NULL); \ + return scoped_refptr<ContentAction>(NULL); \ } \ } while (0) @@ -43,7 +43,6 @@ const char kInvalidInstanceTypeError[] = class ShowPageAction : public ContentAction { public: ShowPageAction() {} - virtual ~ShowPageAction() {} // Implementation of ContentAction: virtual Type GetType() const OVERRIDE { return ACTION_SHOW_PAGE_ACTION; } @@ -73,6 +72,7 @@ class ShowPageAction : public ContentAction { DCHECK(extension); return ExtensionActionManager::Get(profile)->GetPageAction(*extension); } + virtual ~ShowPageAction() {} DISALLOW_COPY_AND_ASSIGN(ShowPageAction); }; @@ -80,11 +80,11 @@ class ShowPageAction : public ContentAction { // Helper function for ContentActions that can be instantiated by just // calling the constructor. template <class T> -scoped_ptr<ContentAction> CallConstructorFactoryMethod( +scoped_refptr<ContentAction> CallConstructorFactoryMethod( const base::DictionaryValue* dict, std::string* error, bool* bad_message) { - return scoped_ptr<ContentAction>(new T); + return scoped_refptr<ContentAction>(new T); } struct ContentActionFactory { @@ -93,7 +93,7 @@ struct ContentActionFactory { // messages in case the extension passed an action that was syntactically // correct but semantically incorrect. |bad_message| is set to true in case // |dict| does not confirm to the validated JSON specification. - typedef scoped_ptr<ContentAction> + typedef scoped_refptr<ContentAction> (* FactoryMethod)(const base::DictionaryValue* /* dict */, std::string* /* error */, bool* /* bad_message */); @@ -121,7 +121,7 @@ ContentAction::ContentAction() {} ContentAction::~ContentAction() {} // static -scoped_ptr<ContentAction> ContentAction::Create( +scoped_refptr<ContentAction> ContentAction::Create( const base::Value& json_action, std::string* error, bool* bad_message) { @@ -142,7 +142,7 @@ scoped_ptr<ContentAction> ContentAction::Create( return (*factory_method_iter->second)(action_dict, error, bad_message); *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); - return scoped_ptr<ContentAction>(); + return scoped_refptr<ContentAction>(); } } // namespace extensions diff --git a/chrome/browser/extensions/api/declarative_content/content_action.h b/chrome/browser/extensions/api/declarative_content/content_action.h index 4750ac9..799f5c1 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action.h +++ b/chrome/browser/extensions/api/declarative_content/content_action.h @@ -8,7 +8,7 @@ #include <string> #include <vector> -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "chrome/browser/extensions/api/declarative/declarative_rule.h" class Profile; @@ -25,7 +25,7 @@ class WebContents; namespace extensions { // Base class for all ContentActions of the declarative content API. -class ContentAction { +class ContentAction : public base::RefCounted<ContentAction> { public: // Type identifiers for concrete ContentActions. enum Type { @@ -38,7 +38,6 @@ class ContentAction { }; ContentAction(); - virtual ~ContentAction(); virtual Type GetType() const = 0; @@ -58,9 +57,13 @@ class ContentAction { // Sets |error| and returns NULL in case of a semantic error that cannot // be caught by schema validation. Sets |bad_message| and returns NULL // in case the input is syntactically unexpected. - static scoped_ptr<ContentAction> Create(const base::Value& json_action, + static scoped_refptr<ContentAction> Create(const base::Value& json_action, std::string* error, bool* bad_message); + + protected: + friend class base::RefCounted<ContentAction>; + virtual ~ContentAction(); }; typedef DeclarativeActionSet<ContentAction> ContentActionSet; diff --git a/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc b/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc index 95d4517..bce9c80c 100644 --- a/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_content/content_action_unittest.cc @@ -24,7 +24,7 @@ TEST(DeclarativeContentActionTest, InvalidCreation) { TestExtensionEnvironment env; std::string error; bool bad_message = false; - scoped_ptr<ContentAction> result; + scoped_refptr<const ContentAction> result; // Test wrong data type passed. error.clear(); @@ -56,7 +56,7 @@ TEST(DeclarativeContentActionTest, ShowPageAction) { std::string error; bool bad_message = false; - scoped_ptr<ContentAction> result = ContentAction::Create( + scoped_refptr<const ContentAction> result = ContentAction::Create( *ParseJson("{\n" " \"instanceType\": \"declarativeContent.ShowPageAction\",\n" "}"), diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc index fa9349f..6cf40a0 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc @@ -11,6 +11,7 @@ #include "base/stringprintf.h" #include "base/string_util.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative/deduping_factory.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" @@ -30,8 +31,6 @@ namespace keys = declarative_webrequest_constants; namespace { // Error messages. -const char kInvalidInstanceTypeError[] = - "An action has an invalid instanceType: %s"; const char kIgnoreRulesRequiresParameterError[] = "IgnoreRules requires at least one parameter."; @@ -42,7 +41,7 @@ const char kEmptyDocumentUrl[] = "data:text/html,"; #define INPUT_FORMAT_VALIDATE(test) do { \ if (!(test)) { \ *bad_message = true; \ - return scoped_ptr<WebRequestAction>(NULL); \ + return scoped_refptr<const WebRequestAction>(NULL); \ } \ } while (0) @@ -107,29 +106,36 @@ scoped_ptr<helpers::FilterResponseCookie> ParseFilterResponseCookie( // Helper function for WebRequestActions that can be instantiated by just // calling the constructor. template <class T> -scoped_ptr<WebRequestAction> CallConstructorFactoryMethod( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CallConstructorFactoryMethod( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { - return scoped_ptr<WebRequestAction>(new T); + return scoped_refptr<const WebRequestAction>(new T); } -scoped_ptr<WebRequestAction> CreateRedirectRequestAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateRedirectRequestAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); std::string redirect_url_string; INPUT_FORMAT_VALIDATE( dict->GetString(keys::kRedirectUrlKey, &redirect_url_string)); GURL redirect_url(redirect_url_string); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestRedirectAction(redirect_url)); } -scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateRedirectRequestByRegExAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); std::string from; std::string to; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); @@ -143,62 +149,77 @@ scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( if (!from_pattern->ok()) { *error = "Invalid pattern '" + from + "' -> '" + to + "'"; - return scoped_ptr<WebRequestAction>(NULL); + return scoped_refptr<const WebRequestAction>(NULL); } - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestRedirectByRegExAction(from_pattern.Pass(), to)); } -scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateSetRequestHeaderAction( + const std::string& instance_type, + const base::Value* json_value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(json_value->GetAsDictionary(&dict)); std::string name; std::string value; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestSetRequestHeaderAction(name, value)); } -scoped_ptr<WebRequestAction> CreateRemoveRequestHeaderAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateRemoveRequestHeaderAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); std::string name; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestRemoveRequestHeaderAction(name)); } -scoped_ptr<WebRequestAction> CreateAddResponseHeaderAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateAddResponseHeaderAction( + const std::string& instance_type, + const base::Value* json_value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(json_value->GetAsDictionary(&dict)); std::string name; std::string value; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestAddResponseHeaderAction(name, value)); } -scoped_ptr<WebRequestAction> CreateRemoveResponseHeaderAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateRemoveResponseHeaderAction( + const std::string& instance_type, + const base::Value* json_value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(json_value->GetAsDictionary(&dict)); std::string name; std::string value; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); bool has_value = dict->GetString(keys::kValueKey, &value); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestRemoveResponseHeaderAction(name, value, has_value)); } -scoped_ptr<WebRequestAction> CreateIgnoreRulesAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateIgnoreRulesAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); bool has_parameter = false; int minimum_priority = std::numeric_limits<int>::min(); std::string ignore_tag; @@ -213,25 +234,26 @@ scoped_ptr<WebRequestAction> CreateIgnoreRulesAction( } if (!has_parameter) { *error = kIgnoreRulesRequiresParameterError; - return scoped_ptr<WebRequestAction>(NULL); + return scoped_refptr<const WebRequestAction>(NULL); } - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestIgnoreRulesAction(minimum_priority, ignore_tag)); } -scoped_ptr<WebRequestAction> CreateRequestCookieAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateRequestCookieAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { using extension_web_request_api_helpers::RequestCookieModification; + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); + linked_ptr<RequestCookieModification> modification( new RequestCookieModification); // Get modification type. - std::string instance_type; - INPUT_FORMAT_VALIDATE( - dict->GetString(keys::kInstanceTypeKey, &instance_type)); if (instance_type == keys::kAddRequestCookieType) modification->type = helpers::ADD; else if (instance_type == keys::kEditRequestCookieType) @@ -260,23 +282,24 @@ scoped_ptr<WebRequestAction> CreateRequestCookieAction( modification->modification = ParseRequestCookie(value); } - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestRequestCookieAction(modification)); } -scoped_ptr<WebRequestAction> CreateResponseCookieAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateResponseCookieAction( + const std::string& instance_type, + const base::Value* value, std::string* error, bool* bad_message) { using extension_web_request_api_helpers::ResponseCookieModification; + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); + linked_ptr<ResponseCookieModification> modification( new ResponseCookieModification); // Get modification type. - std::string instance_type; - INPUT_FORMAT_VALIDATE( - dict->GetString(keys::kInstanceTypeKey, &instance_type)); if (instance_type == keys::kAddResponseCookieType) modification->type = helpers::ADD; else if (instance_type == keys::kEditResponseCookieType) @@ -305,76 +328,101 @@ scoped_ptr<WebRequestAction> CreateResponseCookieAction( modification->modification = ParseResponseCookie(value); } - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestResponseCookieAction(modification)); } -scoped_ptr<WebRequestAction> CreateSendMessageToExtensionAction( - const base::DictionaryValue* dict, +scoped_refptr<const WebRequestAction> CreateSendMessageToExtensionAction( + const std::string& name, + const base::Value* value, std::string* error, bool* bad_message) { + const base::DictionaryValue* dict = NULL; + CHECK(value->GetAsDictionary(&dict)); std::string message; INPUT_FORMAT_VALIDATE(dict->GetString(keys::kMessageKey, &message)); - return scoped_ptr<WebRequestAction>( + return scoped_refptr<const WebRequestAction>( new WebRequestSendMessageToExtensionAction(message)); } struct WebRequestActionFactory { - // Factory methods for WebRequestAction instances. |dict| contains the json - // dictionary that describes the action. |error| is used to return error - // messages in case the extension passed an action that was syntactically - // correct but semantically incorrect. |bad_message| is set to true in case - // |dict| does not confirm to the validated JSON specification. - typedef scoped_ptr<WebRequestAction> - (* FactoryMethod)(const base::DictionaryValue* /* dict */ , - std::string* /* error */, - bool* /* bad_message */); - typedef std::map<WebRequestAction::Type, const std::string> ActionNames; - // Maps the name of a declarativeWebRequest action type to the factory - // function creating it. - std::map<std::string, FactoryMethod> factory_methods; + DedupingFactory<WebRequestAction> factory; // Translates action types into the corresponding JavaScript names. ActionNames action_names; - WebRequestActionFactory() { - factory_methods[keys::kAddRequestCookieType] = - &CreateRequestCookieAction; - factory_methods[keys::kAddResponseCookieType] = - &CreateResponseCookieAction; - factory_methods[keys::kAddResponseHeaderType] = - &CreateAddResponseHeaderAction; - factory_methods[keys::kCancelRequestType] = - &CallConstructorFactoryMethod<WebRequestCancelAction>; - factory_methods[keys::kEditRequestCookieType] = - &CreateRequestCookieAction; - factory_methods[keys::kEditResponseCookieType] = - &CreateResponseCookieAction; - factory_methods[keys::kRedirectByRegExType] = - &CreateRedirectRequestByRegExAction; - factory_methods[keys::kRedirectRequestType] = - &CreateRedirectRequestAction; - factory_methods[keys::kRedirectToTransparentImageType] = + WebRequestActionFactory() : factory(5) { + factory.RegisterFactoryMethod( + keys::kAddRequestCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRequestCookieAction); + factory.RegisterFactoryMethod( + keys::kAddResponseCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateResponseCookieAction); + factory.RegisterFactoryMethod( + keys::kAddResponseHeaderType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateAddResponseHeaderAction); + factory.RegisterFactoryMethod( + keys::kCancelRequestType, + DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, + &CallConstructorFactoryMethod<WebRequestCancelAction>); + factory.RegisterFactoryMethod( + keys::kEditRequestCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRequestCookieAction); + factory.RegisterFactoryMethod( + keys::kEditResponseCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateResponseCookieAction); + factory.RegisterFactoryMethod( + keys::kRedirectByRegExType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRedirectRequestByRegExAction); + factory.RegisterFactoryMethod( + keys::kRedirectRequestType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRedirectRequestAction); + factory.RegisterFactoryMethod( + keys::kRedirectToTransparentImageType, + DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, &CallConstructorFactoryMethod< - WebRequestRedirectToTransparentImageAction>; - factory_methods[keys::kRedirectToEmptyDocumentType] = - &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>; - factory_methods[keys::kRemoveRequestCookieType] = - &CreateRequestCookieAction; - factory_methods[keys::kRemoveResponseCookieType] = - &CreateResponseCookieAction; - factory_methods[keys::kSetRequestHeaderType] = - &CreateSetRequestHeaderAction; - factory_methods[keys::kRemoveRequestHeaderType] = - &CreateRemoveRequestHeaderAction; - factory_methods[keys::kRemoveResponseHeaderType] = - &CreateRemoveResponseHeaderAction; - factory_methods[keys::kIgnoreRulesType] = - &CreateIgnoreRulesAction; - factory_methods[keys::kSendMessageToExtensionType] = - &CreateSendMessageToExtensionAction; + WebRequestRedirectToTransparentImageAction>); + factory.RegisterFactoryMethod( + keys::kRedirectToEmptyDocumentType, + DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, + &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>); + factory.RegisterFactoryMethod( + keys::kRemoveRequestCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRequestCookieAction); + factory.RegisterFactoryMethod( + keys::kRemoveResponseCookieType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateResponseCookieAction); + factory.RegisterFactoryMethod( + keys::kSetRequestHeaderType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateSetRequestHeaderAction); + factory.RegisterFactoryMethod( + keys::kRemoveRequestHeaderType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRemoveRequestHeaderAction); + factory.RegisterFactoryMethod( + keys::kRemoveResponseHeaderType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateRemoveResponseHeaderAction); + factory.RegisterFactoryMethod( + keys::kIgnoreRulesType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateIgnoreRulesAction); + factory.RegisterFactoryMethod( + keys::kSendMessageToExtensionType, + DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, + &CreateSendMessageToExtensionAction); #define INSERT_ACTION_NAME(type, name) \ action_names.insert(ActionNames::value_type(type, name)); @@ -427,6 +475,10 @@ base::LazyInstance<WebRequestActionFactory>::Leaky WebRequestAction::~WebRequestAction() {} +bool WebRequestAction::Equals(const WebRequestAction* other) const { + return type() == other->type(); +} + const std::string& WebRequestAction::GetName() const { const WebRequestActionFactory::ActionNames& names = g_web_request_action_factory.Get().action_names; @@ -466,7 +518,7 @@ bool WebRequestAction::HasPermission(const ExtensionInfoMap* extension_info_map, } // static -scoped_ptr<WebRequestAction> WebRequestAction::Create( +scoped_refptr<const WebRequestAction> WebRequestAction::Create( const base::Value& json_action, std::string* error, bool* bad_message) { @@ -481,13 +533,8 @@ scoped_ptr<WebRequestAction> WebRequestAction::Create( action_dict->GetString(keys::kInstanceTypeKey, &instance_type)); WebRequestActionFactory& factory = g_web_request_action_factory.Get(); - std::map<std::string, WebRequestActionFactory::FactoryMethod>::iterator - factory_method_iter = factory.factory_methods.find(instance_type); - if (factory_method_iter != factory.factory_methods.end()) - return (*factory_method_iter->second)(action_dict, error, bad_message); - - *error = base::StringPrintf(kInvalidInstanceTypeError, instance_type.c_str()); - return scoped_ptr<WebRequestAction>(); + return factory.factory.Instantiate( + instance_type, action_dict, error, bad_message); } void WebRequestAction::Apply(const std::string& extension_id, @@ -557,6 +604,12 @@ WebRequestRedirectAction::WebRequestRedirectAction(const GURL& redirect_url) WebRequestRedirectAction::~WebRequestRedirectAction() {} +bool WebRequestRedirectAction::Equals(const WebRequestAction* other) const { + return WebRequestAction::Equals(other) && + redirect_url_ == + static_cast<const WebRequestRedirectAction*>(other)->redirect_url_; +} + LinkedPtrEventResponseDelta WebRequestRedirectAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -691,6 +744,16 @@ std::string WebRequestRedirectByRegExAction::PerlToRe2Style( return result; } +bool WebRequestRedirectByRegExAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestRedirectByRegExAction* casted_other = + static_cast<const WebRequestRedirectByRegExAction*>(other); + return from_pattern_->pattern() == casted_other->from_pattern_->pattern() && + to_pattern_ == casted_other->to_pattern_; +} + LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -728,6 +791,15 @@ WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( WebRequestSetRequestHeaderAction::~WebRequestSetRequestHeaderAction() {} +bool WebRequestSetRequestHeaderAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestSetRequestHeaderAction* casted_other = + static_cast<const WebRequestSetRequestHeaderAction*>(other); + return name_ == casted_other->name_ && value_ == casted_other->value_; +} + LinkedPtrEventResponseDelta WebRequestSetRequestHeaderAction::CreateDelta( const WebRequestData& request_data, @@ -754,6 +826,15 @@ WebRequestRemoveRequestHeaderAction::WebRequestRemoveRequestHeaderAction( WebRequestRemoveRequestHeaderAction::~WebRequestRemoveRequestHeaderAction() {} +bool WebRequestRemoveRequestHeaderAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestRemoveRequestHeaderAction* casted_other = + static_cast<const WebRequestRemoveRequestHeaderAction*>(other); + return name_ == casted_other->name_; +} + LinkedPtrEventResponseDelta WebRequestRemoveRequestHeaderAction::CreateDelta( const WebRequestData& request_data, @@ -782,6 +863,15 @@ WebRequestAddResponseHeaderAction::WebRequestAddResponseHeaderAction( WebRequestAddResponseHeaderAction::~WebRequestAddResponseHeaderAction() {} +bool WebRequestAddResponseHeaderAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestAddResponseHeaderAction* casted_other = + static_cast<const WebRequestAddResponseHeaderAction*>(other); + return name_ == casted_other->name_ && value_ == casted_other->value_; +} + LinkedPtrEventResponseDelta WebRequestAddResponseHeaderAction::CreateDelta( const WebRequestData& request_data, @@ -821,6 +911,16 @@ WebRequestRemoveResponseHeaderAction::WebRequestRemoveResponseHeaderAction( WebRequestRemoveResponseHeaderAction::~WebRequestRemoveResponseHeaderAction() {} +bool WebRequestRemoveResponseHeaderAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestRemoveResponseHeaderAction* casted_other = + static_cast<const WebRequestRemoveResponseHeaderAction*>(other); + return name_ == casted_other->name_ && value_ == casted_other->value_ && + has_value_ == casted_other->has_value_; +} + LinkedPtrEventResponseDelta WebRequestRemoveResponseHeaderAction::CreateDelta( const WebRequestData& request_data, @@ -865,6 +965,15 @@ WebRequestIgnoreRulesAction::WebRequestIgnoreRulesAction( WebRequestIgnoreRulesAction::~WebRequestIgnoreRulesAction() {} +bool WebRequestIgnoreRulesAction::Equals(const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestIgnoreRulesAction* casted_other = + static_cast<const WebRequestIgnoreRulesAction*>(other); + return minimum_priority() == casted_other->minimum_priority() && + ignore_tag_ == casted_other->ignore_tag_; +} + LinkedPtrEventResponseDelta WebRequestIgnoreRulesAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -889,6 +998,17 @@ WebRequestRequestCookieAction::WebRequestRequestCookieAction( WebRequestRequestCookieAction::~WebRequestRequestCookieAction() {} +bool WebRequestRequestCookieAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestRequestCookieAction* casted_other = + static_cast<const WebRequestRequestCookieAction*>(other); + return helpers::NullableEquals( + request_cookie_modification_.get(), + casted_other->request_cookie_modification_.get()); +} + LinkedPtrEventResponseDelta WebRequestRequestCookieAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -918,6 +1038,17 @@ WebRequestResponseCookieAction::WebRequestResponseCookieAction( WebRequestResponseCookieAction::~WebRequestResponseCookieAction() {} +bool WebRequestResponseCookieAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestResponseCookieAction* casted_other = + static_cast<const WebRequestResponseCookieAction*>(other); + return helpers::NullableEquals( + response_cookie_modification_.get(), + casted_other->response_cookie_modification_.get()); +} + LinkedPtrEventResponseDelta WebRequestResponseCookieAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -947,6 +1078,15 @@ WebRequestSendMessageToExtensionAction::WebRequestSendMessageToExtensionAction( WebRequestSendMessageToExtensionAction:: ~WebRequestSendMessageToExtensionAction() {} +bool WebRequestSendMessageToExtensionAction::Equals( + const WebRequestAction* other) const { + if (!WebRequestAction::Equals(other)) + return false; + const WebRequestSendMessageToExtensionAction* casted_other = + static_cast<const WebRequestSendMessageToExtensionAction*>(other); + return message_ == casted_other->message_; +} + LinkedPtrEventResponseDelta WebRequestSendMessageToExtensionAction::CreateDelta( const WebRequestData& request_data, const std::string& extension_id, diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h index 1745e9a..1c7fdda 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h @@ -11,6 +11,7 @@ #include "base/compiler_specific.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_webrequest/request_stage.h" #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" @@ -49,7 +50,7 @@ typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta> LinkedPtrEventResponseDelta; // Base class for all WebRequestActions of the declarative Web Request API. -class WebRequestAction { +class WebRequestAction : public base::RefCounted<WebRequestAction> { public: // Type identifiers for concrete WebRequestActions. If you add a new type, // also update |action_names| in WebRequestActionFactory, update the @@ -91,8 +92,6 @@ class WebRequestAction { std::set<std::string>* ignored_tags; }; - virtual ~WebRequestAction(); - int stages() const { return stages_; } @@ -101,6 +100,10 @@ class WebRequestAction { return type_; } + // Compares the Type of two WebRequestActions, needs to be overridden for + // parameterized types. + virtual bool Equals(const WebRequestAction* other) const; + // Return the JavaScript type name corresponding to type(). If there are // more names, they are returned separated by a colon. const std::string& GetName() const; @@ -131,9 +134,10 @@ class WebRequestAction { // Sets |error| and returns NULL in case of a semantic error that cannot // be caught by schema validation. Sets |bad_message| and returns NULL // in case the input is syntactically unexpected. - static scoped_ptr<WebRequestAction> Create(const base::Value& json_action, - std::string* error, - bool* bad_message); + static scoped_refptr<const WebRequestAction> Create( + const base::Value& json_action, + std::string* error, + bool* bad_message); // Returns a description of the modification to the request caused by // this action. @@ -149,6 +153,8 @@ class WebRequestAction { ApplyInfo* apply_info) const; protected: + friend class base::RefCounted<WebRequestAction>; + virtual ~WebRequestAction(); WebRequestAction(int stages, Type type, int minimum_priority, @@ -179,7 +185,6 @@ typedef DeclarativeActionSet<WebRequestAction> WebRequestActionSet; class WebRequestCancelAction : public WebRequestAction { public: WebRequestCancelAction(); - virtual ~WebRequestCancelAction(); // Implementation of WebRequestAction: virtual LinkedPtrEventResponseDelta CreateDelta( @@ -188,6 +193,7 @@ class WebRequestCancelAction : public WebRequestAction { const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestCancelAction(); DISALLOW_COPY_AND_ASSIGN(WebRequestCancelAction); }; @@ -195,15 +201,17 @@ class WebRequestCancelAction : public WebRequestAction { class WebRequestRedirectAction : public WebRequestAction { public: explicit WebRequestRedirectAction(const GURL& redirect_url); - virtual ~WebRequestRedirectAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRedirectAction(); + GURL redirect_url_; // Target to which the request shall be redirected. DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectAction); @@ -213,7 +221,6 @@ class WebRequestRedirectAction : public WebRequestAction { class WebRequestRedirectToTransparentImageAction : public WebRequestAction { public: WebRequestRedirectToTransparentImageAction(); - virtual ~WebRequestRedirectToTransparentImageAction(); // Implementation of WebRequestAction: virtual LinkedPtrEventResponseDelta CreateDelta( @@ -222,6 +229,7 @@ class WebRequestRedirectToTransparentImageAction : public WebRequestAction { const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRedirectToTransparentImageAction(); DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToTransparentImageAction); }; @@ -230,7 +238,6 @@ class WebRequestRedirectToTransparentImageAction : public WebRequestAction { class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction { public: WebRequestRedirectToEmptyDocumentAction(); - virtual ~WebRequestRedirectToEmptyDocumentAction(); // Implementation of WebRequestAction: virtual LinkedPtrEventResponseDelta CreateDelta( @@ -239,6 +246,7 @@ class WebRequestRedirectToEmptyDocumentAction : public WebRequestAction { const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRedirectToEmptyDocumentAction(); DISALLOW_COPY_AND_ASSIGN(WebRequestRedirectToEmptyDocumentAction); }; @@ -249,19 +257,21 @@ class WebRequestRedirectByRegExAction : public WebRequestAction { // capture groups are referenced in Perl style ($1, $2, ...). explicit WebRequestRedirectByRegExAction(scoped_ptr<re2::RE2> from_pattern, const std::string& to_pattern); - virtual ~WebRequestRedirectByRegExAction(); // Conversion of capture group styles between Perl style ($1, $2, ...) and // RE2 (\1, \2, ...). static std::string PerlToRe2Style(const std::string& perl); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRedirectByRegExAction(); + scoped_ptr<re2::RE2> from_pattern_; std::string to_pattern_; @@ -273,15 +283,17 @@ class WebRequestSetRequestHeaderAction : public WebRequestAction { public: WebRequestSetRequestHeaderAction(const std::string& name, const std::string& value); - virtual ~WebRequestSetRequestHeaderAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestSetRequestHeaderAction(); + std::string name_; std::string value_; DISALLOW_COPY_AND_ASSIGN(WebRequestSetRequestHeaderAction); @@ -291,15 +303,17 @@ class WebRequestSetRequestHeaderAction : public WebRequestAction { class WebRequestRemoveRequestHeaderAction : public WebRequestAction { public: explicit WebRequestRemoveRequestHeaderAction(const std::string& name); - virtual ~WebRequestRemoveRequestHeaderAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRemoveRequestHeaderAction(); + std::string name_; DISALLOW_COPY_AND_ASSIGN(WebRequestRemoveRequestHeaderAction); }; @@ -309,15 +323,17 @@ class WebRequestAddResponseHeaderAction : public WebRequestAction { public: WebRequestAddResponseHeaderAction(const std::string& name, const std::string& value); - virtual ~WebRequestAddResponseHeaderAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestAddResponseHeaderAction(); + std::string name_; std::string value_; DISALLOW_COPY_AND_ASSIGN(WebRequestAddResponseHeaderAction); @@ -329,15 +345,17 @@ class WebRequestRemoveResponseHeaderAction : public WebRequestAction { explicit WebRequestRemoveResponseHeaderAction(const std::string& name, const std::string& value, bool has_value); - virtual ~WebRequestRemoveResponseHeaderAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRemoveResponseHeaderAction(); + std::string name_; std::string value_; bool has_value_; @@ -349,9 +367,9 @@ class WebRequestIgnoreRulesAction : public WebRequestAction { public: explicit WebRequestIgnoreRulesAction(int minimum_priority, const std::string& ignore_tag); - virtual ~WebRequestIgnoreRulesAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, @@ -359,6 +377,8 @@ class WebRequestIgnoreRulesAction : public WebRequestAction { const std::string& ignore_tag() const { return ignore_tag_; } private: + virtual ~WebRequestIgnoreRulesAction(); + // Rules are ignored if they have a tag matching |ignore_tag_| and // |ignore_tag_| is non-empty. std::string ignore_tag_; @@ -373,15 +393,17 @@ class WebRequestRequestCookieAction : public WebRequestAction { explicit WebRequestRequestCookieAction( linked_ptr<RequestCookieModification> request_cookie_modification); - virtual ~WebRequestRequestCookieAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestRequestCookieAction(); + linked_ptr<RequestCookieModification> request_cookie_modification_; DISALLOW_COPY_AND_ASSIGN(WebRequestRequestCookieAction); }; @@ -394,15 +416,17 @@ class WebRequestResponseCookieAction : public WebRequestAction { explicit WebRequestResponseCookieAction( linked_ptr<ResponseCookieModification> response_cookie_modification); - virtual ~WebRequestResponseCookieAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestResponseCookieAction(); + linked_ptr<ResponseCookieModification> response_cookie_modification_; DISALLOW_COPY_AND_ASSIGN(WebRequestResponseCookieAction); }; @@ -412,15 +436,17 @@ class WebRequestResponseCookieAction : public WebRequestAction { class WebRequestSendMessageToExtensionAction : public WebRequestAction { public: explicit WebRequestSendMessageToExtensionAction(const std::string& message); - virtual ~WebRequestSendMessageToExtensionAction(); // Implementation of WebRequestAction: + virtual bool Equals(const WebRequestAction* other) const OVERRIDE; virtual LinkedPtrEventResponseDelta CreateDelta( const WebRequestData& request_data, const std::string& extension_id, const base::Time& extension_install_time) const OVERRIDE; private: + virtual ~WebRequestSendMessageToExtensionAction(); + std::string message_; DISALLOW_COPY_AND_ASSIGN(WebRequestSendMessageToExtensionAction); }; 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 1bb8691..e7fbecf 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action_unittest.cc @@ -176,7 +176,7 @@ void WebRequestActionWithThreadsTest::CheckActionNeedsAllUrls( TEST(WebRequestActionTest, CreateAction) { std::string error; bool bad_message = false; - scoped_ptr<WebRequestAction> result; + scoped_refptr<const WebRequestAction> result; // Test wrong data type passed. error.clear(); diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc index 141e514..6432eb3 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.cc @@ -27,7 +27,6 @@ const char kExpectedDictionary[] = "A condition has to be a dictionary."; const char kConditionWithoutInstanceType[] = "A condition had no instanceType"; const char kExpectedOtherConditionType[] = "Expected a condition of type " "declarativeWebRequest.RequestMatcher"; -const char kUnknownConditionAttribute[] = "Unknown condition attribute '%s'"; const char kInvalidTypeOfParamter[] = "Attribute '%s' has an invalid type"; const char kConditionCannotBeFulfilled[] = "A condition can never be " "fulfilled because its attributes cannot all be tested at the " @@ -171,18 +170,14 @@ scoped_ptr<WebRequestCondition> WebRequestCondition::Create( url_matcher_condition_factory, dict, ++g_next_id, error); } } - } else if (WebRequestConditionAttribute::IsKnownType( - condition_attribute_name)) { - scoped_ptr<WebRequestConditionAttribute> attribute = + } else { + scoped_refptr<const WebRequestConditionAttribute> attribute = WebRequestConditionAttribute::Create( condition_attribute_name, &condition_attribute_value, error); if (attribute.get()) - attributes.push_back(make_linked_ptr(attribute.release())); - } else { - *error = base::StringPrintf(kUnknownConditionAttribute, - condition_attribute_name.c_str()); + attributes.push_back(attribute); } if (!error->empty()) return scoped_ptr<WebRequestCondition>(NULL); diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h index 607283f..e017a6a 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h @@ -89,11 +89,6 @@ class WebRequestCondition { void GetURLMatcherConditionSets( URLMatcherConditionSet::Vector* condition_sets) const; - // Returns the condition attributes checked by this condition. - const WebRequestConditionAttributes condition_attributes() const { - return condition_attributes_; - } - // Returns a bit vector representing extensions::RequestStage. The bit vector // contains a 1 for each request stage during which the condition can be // tested. 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 58d4484..199b149 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.cc @@ -6,10 +6,12 @@ #include <algorithm> +#include "base/lazy_instance.h" #include "base/logging.h" #include "base/string_util.h" #include "base/stringprintf.h" #include "base/values.h" +#include "chrome/browser/extensions/api/declarative/deduping_factory.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" @@ -29,17 +31,68 @@ using base::ListValue; using base::StringValue; using base::Value; +namespace helpers = extension_web_request_api_helpers; +namespace keys = extensions::declarative_webrequest_constants; + +namespace extensions { + namespace { // Error messages. const char kUnknownConditionAttribute[] = "Unknown matching condition: '*'"; const char kInvalidValue[] = "Condition '*' has an invalid value"; -} -namespace helpers = extension_web_request_api_helpers; +struct WebRequestConditionAttributeFactory { + DedupingFactory<WebRequestConditionAttribute> factory; + + WebRequestConditionAttributeFactory() : factory(5) { + factory.RegisterFactoryMethod( + keys::kResourceTypeKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeResourceType::Create); + + factory.RegisterFactoryMethod( + keys::kContentTypeKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeContentType::Create); + factory.RegisterFactoryMethod( + keys::kExcludeContentTypeKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeContentType::Create); + + factory.RegisterFactoryMethod( + keys::kRequestHeadersKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeRequestHeaders::Create); + factory.RegisterFactoryMethod( + keys::kExcludeRequestHeadersKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeRequestHeaders::Create); + + factory.RegisterFactoryMethod( + keys::kResponseHeadersKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeResponseHeaders::Create); + factory.RegisterFactoryMethod( + keys::kExcludeResponseHeadersKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeResponseHeaders::Create); + + factory.RegisterFactoryMethod( + keys::kThirdPartyKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeThirdParty::Create); + + factory.RegisterFactoryMethod( + keys::kStagesKey, + DedupingFactory<WebRequestConditionAttribute>::IS_PARAMETERIZED, + &WebRequestConditionAttributeStages::Create); + } +}; -namespace extensions { +base::LazyInstance<WebRequestConditionAttributeFactory>::Leaky + g_web_request_condition_attribute_factory = LAZY_INSTANCE_INITIALIZER; -namespace keys = declarative_webrequest_constants; +} // namespace // // WebRequestConditionAttribute @@ -49,48 +102,21 @@ WebRequestConditionAttribute::WebRequestConditionAttribute() {} WebRequestConditionAttribute::~WebRequestConditionAttribute() {} -// static -bool WebRequestConditionAttribute::IsKnownType( - const std::string& instance_type) { - return - WebRequestConditionAttributeResourceType::IsMatchingType(instance_type) || - WebRequestConditionAttributeContentType::IsMatchingType(instance_type) || - WebRequestConditionAttributeRequestHeaders::IsMatchingType( - instance_type) || - WebRequestConditionAttributeResponseHeaders::IsMatchingType( - instance_type) || - WebRequestConditionAttributeThirdParty::IsMatchingType(instance_type) || - WebRequestConditionAttributeStages::IsMatchingType(instance_type); +bool WebRequestConditionAttribute::Equals( + const WebRequestConditionAttribute* other) const { + return GetType() == other->GetType(); } // static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttribute::Create( const std::string& name, const base::Value* value, std::string* error) { CHECK(value != NULL && error != NULL); - if (WebRequestConditionAttributeResourceType::IsMatchingType(name)) { - return WebRequestConditionAttributeResourceType::Create(name, value, error); - } else if (WebRequestConditionAttributeContentType::IsMatchingType(name)) { - return WebRequestConditionAttributeContentType::Create(name, value, error); - } else if (WebRequestConditionAttributeRequestHeaders::IsMatchingType( - name)) { - return WebRequestConditionAttributeRequestHeaders::Create( - name, value, error); - } else if (WebRequestConditionAttributeResponseHeaders::IsMatchingType( - name)) { - return WebRequestConditionAttributeResponseHeaders::Create( - name, value, error); - } else if (WebRequestConditionAttributeThirdParty::IsMatchingType(name)) { - return WebRequestConditionAttributeThirdParty::Create(name, value, error); - } else if (WebRequestConditionAttributeStages::IsMatchingType(name)) { - return WebRequestConditionAttributeStages::Create(name, value, error); - } - - *error = ErrorUtils::FormatErrorMessage(kUnknownConditionAttribute, - name); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + bool bad_message = false; + return g_web_request_condition_attribute_factory.Get().factory.Instantiate( + name, value, error, &bad_message); } // @@ -106,24 +132,18 @@ WebRequestConditionAttributeResourceType:: ~WebRequestConditionAttributeResourceType() {} // static -bool WebRequestConditionAttributeResourceType::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kResourceTypeKey; -} - -// static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeResourceType::Create( - const std::string& name, + const std::string& instance_type, const base::Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); - + std::string* error, + bool* bad_message) { + DCHECK(instance_type == keys::kResourceTypeKey); const ListValue* value_as_list = NULL; if (!value->GetAsList(&value_as_list)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, - keys::kResourceTypeKey); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + keys::kResourceTypeKey); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } size_t number_types = value_as_list->GetSize(); @@ -136,13 +156,13 @@ WebRequestConditionAttributeResourceType::Create( if (!value_as_list->GetString(i, &resource_type_string) || !helpers::ParseResourceType(resource_type_string, &type)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, - keys::kResourceTypeKey); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + keys::kResourceTypeKey); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } passed_types.push_back(type); } - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeResourceType(passed_types)); } @@ -169,6 +189,15 @@ WebRequestConditionAttributeResourceType::GetType() const { return CONDITION_RESOURCE_TYPE; } +bool WebRequestConditionAttributeResourceType::Equals( + const WebRequestConditionAttribute* other) const { + if (!WebRequestConditionAttribute::Equals(other)) + return false; + const WebRequestConditionAttributeResourceType* casted_other = + static_cast<const WebRequestConditionAttributeResourceType*>(other); + return types_ == casted_other->types_; +} + // // WebRequestConditionAttributeContentType // @@ -184,24 +213,18 @@ WebRequestConditionAttributeContentType:: ~WebRequestConditionAttributeContentType() {} // static -bool WebRequestConditionAttributeContentType::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kContentTypeKey || - instance_type == keys::kExcludeContentTypeKey; -} - -// static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeContentType::Create( const std::string& name, const base::Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); + std::string* error, + bool* bad_message) { + DCHECK(name == keys::kContentTypeKey || name == keys::kExcludeContentTypeKey); const ListValue* value_as_list = NULL; if (!value->GetAsList(&value_as_list)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } std::vector<std::string> content_types; for (ListValue::const_iterator it = value_as_list->begin(); @@ -209,12 +232,12 @@ WebRequestConditionAttributeContentType::Create( std::string content_type; if (!(*it)->GetAsString(&content_type)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, name); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } content_types.push_back(content_type); } - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeContentType( content_types, name == keys::kContentTypeKey)); } @@ -250,6 +273,16 @@ WebRequestConditionAttributeContentType::GetType() const { return CONDITION_CONTENT_TYPE; } +bool WebRequestConditionAttributeContentType::Equals( + const WebRequestConditionAttribute* other) const { + if (!WebRequestConditionAttribute::Equals(other)) + return false; + const WebRequestConditionAttributeContentType* casted_other = + static_cast<const WebRequestConditionAttributeContentType*>(other); + return content_types_ == casted_other->content_types_ && + inclusive_ == casted_other->inclusive_; +} + // Manages a set of tests to be applied to name-value pairs representing // headers. This is a helper class to header-related condition attributes. // It contains a set of test groups. A name-value pair satisfies the whole @@ -510,13 +543,6 @@ WebRequestConditionAttributeRequestHeaders( WebRequestConditionAttributeRequestHeaders:: ~WebRequestConditionAttributeRequestHeaders() {} -// static -bool WebRequestConditionAttributeRequestHeaders::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kRequestHeadersKey || - instance_type == keys::kExcludeRequestHeadersKey; -} - namespace { scoped_ptr<const HeaderMatcher> PrepareHeaderMatcher( @@ -539,19 +565,21 @@ scoped_ptr<const HeaderMatcher> PrepareHeaderMatcher( } // namespace // static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeRequestHeaders::Create( const std::string& name, const base::Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); + std::string* error, + bool* bad_message) { + DCHECK(name == keys::kRequestHeadersKey || + name == keys::kExcludeRequestHeadersKey); scoped_ptr<const HeaderMatcher> header_matcher( PrepareHeaderMatcher(name, value, error)); if (header_matcher.get() == NULL) - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeRequestHeaders( header_matcher.Pass(), name == keys::kRequestHeadersKey)); } @@ -585,6 +613,12 @@ WebRequestConditionAttributeRequestHeaders::GetType() const { return CONDITION_REQUEST_HEADERS; } +bool WebRequestConditionAttributeRequestHeaders::Equals( + const WebRequestConditionAttribute* other) const { + // Comparing headers is too heavy, so we skip it entirely. + return false; +} + // // WebRequestConditionAttributeResponseHeaders // @@ -600,26 +634,21 @@ WebRequestConditionAttributeResponseHeaders:: ~WebRequestConditionAttributeResponseHeaders() {} // static -bool WebRequestConditionAttributeResponseHeaders::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kResponseHeadersKey || - instance_type == keys::kExcludeResponseHeadersKey; -} - -// static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeResponseHeaders::Create( const std::string& name, const base::Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); + std::string* error, + bool* bad_message) { + DCHECK(name == keys::kResponseHeadersKey || + name == keys::kExcludeResponseHeadersKey); scoped_ptr<const HeaderMatcher> header_matcher( PrepareHeaderMatcher(name, value, error)); if (header_matcher.get() == NULL) - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeResponseHeaders( header_matcher.Pass(), name == keys::kResponseHeadersKey)); } @@ -657,6 +686,11 @@ WebRequestConditionAttributeResponseHeaders::GetType() const { return CONDITION_RESPONSE_HEADERS; } +bool WebRequestConditionAttributeResponseHeaders::Equals( + const WebRequestConditionAttribute* other) const { + return false; +} + // // WebRequestConditionAttributeThirdParty // @@ -669,27 +703,22 @@ WebRequestConditionAttributeThirdParty:: ~WebRequestConditionAttributeThirdParty() {} // static -bool WebRequestConditionAttributeThirdParty::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kThirdPartyKey; -} - -// static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeThirdParty::Create( const std::string& name, const base::Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); + std::string* error, + bool* bad_message) { + DCHECK(name == keys::kThirdPartyKey); bool third_party = false; // Dummy value, gets overwritten. if (!value->GetAsBoolean(&third_party)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, keys::kThirdPartyKey); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeThirdParty(third_party)); } @@ -720,6 +749,15 @@ WebRequestConditionAttributeThirdParty::GetType() const { return CONDITION_THIRD_PARTY; } +bool WebRequestConditionAttributeThirdParty::Equals( + const WebRequestConditionAttribute* other) const { + if (!WebRequestConditionAttribute::Equals(other)) + return false; + const WebRequestConditionAttributeThirdParty* casted_other = + static_cast<const WebRequestConditionAttributeThirdParty*>(other); + return match_third_party_ == casted_other->match_third_party_; +} + // // WebRequestConditionAttributeStages // @@ -731,12 +769,6 @@ WebRequestConditionAttributeStages(int allowed_stages) WebRequestConditionAttributeStages:: ~WebRequestConditionAttributeStages() {} -// static -bool WebRequestConditionAttributeStages::IsMatchingType( - const std::string& instance_type) { - return instance_type == keys::kStagesKey; -} - namespace { // Reads strings stored in |value|, which is expected to be a ListValue, and @@ -773,20 +805,21 @@ bool ParseListOfStages(const Value& value, int* out_stages) { } // namespace // static -scoped_ptr<WebRequestConditionAttribute> +scoped_refptr<const WebRequestConditionAttribute> WebRequestConditionAttributeStages::Create(const std::string& name, const Value* value, - std::string* error) { - DCHECK(IsMatchingType(name)); + std::string* error, + bool* bad_message) { + DCHECK(name == keys::kStagesKey); int allowed_stages = 0; if (!ParseListOfStages(*value, &allowed_stages)) { *error = ErrorUtils::FormatErrorMessage(kInvalidValue, keys::kStagesKey); - return scoped_ptr<WebRequestConditionAttribute>(NULL); + return scoped_refptr<const WebRequestConditionAttribute>(NULL); } - return scoped_ptr<WebRequestConditionAttribute>( + return scoped_refptr<const WebRequestConditionAttribute>( new WebRequestConditionAttributeStages(allowed_stages)); } @@ -805,4 +838,13 @@ WebRequestConditionAttributeStages::GetType() const { return CONDITION_STAGES; } +bool WebRequestConditionAttributeStages::Equals( + const WebRequestConditionAttribute* other) const { + if (!WebRequestConditionAttribute::Equals(other)) + return false; + const WebRequestConditionAttributeStages* casted_other = + static_cast<const WebRequestConditionAttributeStages*>(other); + return allowed_stages_ == casted_other->allowed_stages_; +} + } // namespace extensions 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 34c7113..01eb6de 100644 --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_condition_attribute.h @@ -9,9 +9,8 @@ #include <vector> #include "base/basictypes.h" -#include "base/memory/linked_ptr.h" +#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" -#include "base/memory/scoped_vector.h" #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" #include "chrome/common/extensions/api/events.h" #include "webkit/glue/resource_type.h" @@ -31,7 +30,8 @@ struct WebRequestData; // Base class for all condition attributes of the declarative Web Request API // except for condition attribute to test URLPatterns. -class WebRequestConditionAttribute { +class WebRequestConditionAttribute + : public base::RefCounted<WebRequestConditionAttribute> { public: enum Type { CONDITION_RESOURCE_TYPE, @@ -43,13 +43,12 @@ class WebRequestConditionAttribute { }; WebRequestConditionAttribute(); - virtual ~WebRequestConditionAttribute(); // Factory method that creates a WebRequestConditionAttribute for the JSON // dictionary {|name|: |value|} passed by the extension API. Sets |error| and // returns NULL if something fails. // The ownership of |value| remains at the caller. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, std::string* error); @@ -65,15 +64,19 @@ class WebRequestConditionAttribute { virtual Type GetType() const = 0; - // Returns whether condition attributes of type |instance_type| are known - // and can be instantiated by Create(). - static bool IsKnownType(const std::string& instance_type); + // Compares the Type of two WebRequestConditionAttributes, needs to be + // overridden for parameterized types. + virtual bool Equals(const WebRequestConditionAttribute* other) const; + + protected: + friend class base::RefCounted<WebRequestConditionAttribute>; + virtual ~WebRequestConditionAttribute(); private: DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttribute); }; -typedef std::vector<linked_ptr<WebRequestConditionAttribute> > +typedef std::vector<scoped_refptr<const WebRequestConditionAttribute> > WebRequestConditionAttributes; // @@ -84,27 +87,26 @@ typedef std::vector<linked_ptr<WebRequestConditionAttribute> > class WebRequestConditionAttributeResourceType : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeResourceType(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( - const std::string& name, + static scoped_refptr<const WebRequestConditionAttribute> Create( + const std::string& instance_type, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: explicit WebRequestConditionAttributeResourceType( const std::vector<ResourceType::Type>& types); + virtual ~WebRequestConditionAttributeResourceType(); - std::vector<ResourceType::Type> types_; + const std::vector<ResourceType::Type> types_; DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeResourceType); }; @@ -114,29 +116,28 @@ class WebRequestConditionAttributeResourceType class WebRequestConditionAttributeContentType : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeContentType(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: explicit WebRequestConditionAttributeContentType( const std::vector<std::string>& include_content_types, bool inclusive); + virtual ~WebRequestConditionAttributeContentType(); - std::vector<std::string> content_types_; - bool inclusive_; + const std::vector<std::string> content_types_; + const bool inclusive_; DISALLOW_COPY_AND_ASSIGN(WebRequestConditionAttributeContentType); }; @@ -149,25 +150,24 @@ class WebRequestConditionAttributeContentType class WebRequestConditionAttributeRequestHeaders : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeRequestHeaders(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: WebRequestConditionAttributeRequestHeaders( scoped_ptr<const HeaderMatcher> header_matcher, bool positive); + virtual ~WebRequestConditionAttributeRequestHeaders(); const scoped_ptr<const HeaderMatcher> header_matcher_; const bool positive_; @@ -183,25 +183,24 @@ class WebRequestConditionAttributeRequestHeaders class WebRequestConditionAttributeResponseHeaders : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeResponseHeaders(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: WebRequestConditionAttributeResponseHeaders( scoped_ptr<const HeaderMatcher> header_matcher, bool positive); + virtual ~WebRequestConditionAttributeResponseHeaders(); const scoped_ptr<const HeaderMatcher> header_matcher_; const bool positive_; @@ -213,24 +212,23 @@ class WebRequestConditionAttributeResponseHeaders class WebRequestConditionAttributeThirdParty : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeThirdParty(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: explicit WebRequestConditionAttributeThirdParty(bool match_third_party); + virtual ~WebRequestConditionAttributeThirdParty(); const bool match_third_party_; @@ -242,24 +240,23 @@ class WebRequestConditionAttributeThirdParty class WebRequestConditionAttributeStages : public WebRequestConditionAttribute { public: - virtual ~WebRequestConditionAttributeStages(); - - static bool IsMatchingType(const std::string& instance_type); - // Factory method, see WebRequestConditionAttribute::Create. - static scoped_ptr<WebRequestConditionAttribute> Create( + static scoped_refptr<const WebRequestConditionAttribute> Create( const std::string& name, const base::Value* value, - std::string* error); + std::string* error, + bool* bad_message); // Implementation of WebRequestConditionAttribute: virtual int GetStages() const OVERRIDE; virtual bool IsFulfilled( const WebRequestData& request_data) const OVERRIDE; virtual Type GetType() const OVERRIDE; + virtual bool Equals(const WebRequestConditionAttribute* other) const OVERRIDE; private: explicit WebRequestConditionAttributeStages(int allowed_stages); + virtual ~WebRequestConditionAttributeStages(); const int allowed_stages_; // Composition of RequestStage values. 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 c76a86b..ea35ef8 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 @@ -6,7 +6,6 @@ #include "base/basictypes.h" #include "base/files/file_path.h" -#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" @@ -35,7 +34,7 @@ TEST(WebRequestConditionAttributeTest, CreateConditionAttribute) { MessageLoop message_loop(MessageLoop::TYPE_IO); std::string error; - scoped_ptr<WebRequestConditionAttribute> result; + scoped_refptr<const WebRequestConditionAttribute> result; StringValue string_value("main_frame"); ListValue resource_types; resource_types.Append(Value::CreateStringValue("main_frame")); @@ -80,7 +79,7 @@ TEST(WebRequestConditionAttributeTest, ResourceType) { // ResourceType::Type is not 0, the default value. resource_types.Append(Value::CreateStringValue("sub_frame")); - scoped_ptr<WebRequestConditionAttribute> attribute = + scoped_refptr<const WebRequestConditionAttribute> attribute = WebRequestConditionAttribute::Create( keys::kResourceTypeKey, &resource_types, &error); EXPECT_EQ("", error); @@ -107,7 +106,7 @@ TEST(WebRequestConditionAttributeTest, ContentType) { MessageLoop message_loop(MessageLoop::TYPE_IO); std::string error; - scoped_ptr<WebRequestConditionAttribute> result; + scoped_refptr<const WebRequestConditionAttribute> result; net::SpawnedTestServer test_server( net::SpawnedTestServer::TYPE_HTTP, @@ -125,7 +124,7 @@ TEST(WebRequestConditionAttributeTest, ContentType) { ListValue content_types; content_types.Append(Value::CreateStringValue("text/plain")); - scoped_ptr<WebRequestConditionAttribute> attribute_include = + scoped_refptr<const WebRequestConditionAttribute> attribute_include = WebRequestConditionAttribute::Create( keys::kContentTypeKey, &content_types, &error); EXPECT_EQ("", error); @@ -137,7 +136,7 @@ TEST(WebRequestConditionAttributeTest, ContentType) { WebRequestData(&url_request, ON_HEADERS_RECEIVED, url_request.response_headers()))); - scoped_ptr<WebRequestConditionAttribute> attribute_exclude = + scoped_refptr<const WebRequestConditionAttribute> attribute_exclude = WebRequestConditionAttribute::Create( keys::kExcludeContentTypeKey, &content_types, &error); EXPECT_EQ("", error); @@ -148,7 +147,7 @@ TEST(WebRequestConditionAttributeTest, ContentType) { content_types.Clear(); content_types.Append(Value::CreateStringValue("something/invalid")); - scoped_ptr<WebRequestConditionAttribute> attribute_unincluded = + scoped_refptr<const WebRequestConditionAttribute> attribute_unincluded = WebRequestConditionAttribute::Create( keys::kContentTypeKey, &content_types, &error); EXPECT_EQ("", error); @@ -157,7 +156,7 @@ TEST(WebRequestConditionAttributeTest, ContentType) { WebRequestData(&url_request, ON_HEADERS_RECEIVED, url_request.response_headers()))); - scoped_ptr<WebRequestConditionAttribute> attribute_unexcluded = + scoped_refptr<const WebRequestConditionAttribute> attribute_unexcluded = WebRequestConditionAttribute::Create( keys::kExcludeContentTypeKey, &content_types, &error); EXPECT_EQ("", error); @@ -175,7 +174,7 @@ TEST(WebRequestConditionAttributeTest, ThirdParty) { std::string error; const FundamentalValue value_true(true); // This attribute matches only third party requests. - scoped_ptr<WebRequestConditionAttribute> third_party_attribute = + scoped_refptr<const WebRequestConditionAttribute> third_party_attribute = WebRequestConditionAttribute::Create(keys::kThirdPartyKey, &value_true, &error); @@ -183,7 +182,7 @@ TEST(WebRequestConditionAttributeTest, ThirdParty) { ASSERT_TRUE(third_party_attribute.get()); const FundamentalValue value_false(false); // This attribute matches only first party requests. - scoped_ptr<WebRequestConditionAttribute> first_party_attribute = + scoped_refptr<const WebRequestConditionAttribute> first_party_attribute = WebRequestConditionAttribute::Create(keys::kThirdPartyKey, &value_false, &error); @@ -247,7 +246,7 @@ TEST(WebRequestConditionAttributeTest, Stages) { // Create an attribute with an empty set of applicable stages. ListValue empty_list; - scoped_ptr<WebRequestConditionAttribute> empty_attribute = + scoped_refptr<const WebRequestConditionAttribute> empty_attribute = WebRequestConditionAttribute::Create(keys::kStagesKey, &empty_list, &error); @@ -258,7 +257,7 @@ TEST(WebRequestConditionAttributeTest, Stages) { ListValue all_stages; for (size_t i = 0; i < arraysize(active_stages); ++i) all_stages.AppendString(active_stages[i].second); - scoped_ptr<WebRequestConditionAttribute> attribute_with_all = + scoped_refptr<const WebRequestConditionAttribute> attribute_with_all = WebRequestConditionAttribute::Create(keys::kStagesKey, &all_stages, &error); @@ -266,7 +265,8 @@ TEST(WebRequestConditionAttributeTest, Stages) { ASSERT_TRUE(attribute_with_all.get()); // Create one attribute for each single stage, to be applicable in that stage. - ScopedVector<WebRequestConditionAttribute> one_stage_attributes; + std::vector<scoped_refptr<const WebRequestConditionAttribute> > + one_stage_attributes; for (size_t i = 0; i < arraysize(active_stages); ++i) { ListValue single_stage_list; @@ -274,7 +274,7 @@ TEST(WebRequestConditionAttributeTest, Stages) { one_stage_attributes.push_back( WebRequestConditionAttribute::Create(keys::kStagesKey, &single_stage_list, - &error).release()); + &error)); EXPECT_EQ("", error); ASSERT_TRUE(one_stage_attributes.back() != NULL); } @@ -382,7 +382,7 @@ void MatchAndCheck(const std::vector< std::vector<const std::string*> >& tests, } std::string error; - scoped_ptr<WebRequestConditionAttribute> attribute = + scoped_refptr<const WebRequestConditionAttribute> attribute = WebRequestConditionAttribute::Create(key, &contains_headers, &error); ASSERT_EQ("", error); ASSERT_TRUE(attribute.get()); diff --git a/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc b/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc index 3b80f2f..3c7b446 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc +++ b/chrome/browser/extensions/api/web_request/web_request_api_helpers.cc @@ -101,23 +101,97 @@ bool ParseCookieLifetime(net::ParsedCookie* cookie, return false; } +bool NullableEquals(const int* a, const int* b) { + if ((a && !b) || (!a && b)) + return false; + return (!a) || (*a == *b); +} + +bool NullableEquals(const bool* a, const bool* b) { + if ((a && !b) || (!a && b)) + return false; + return (!a) || (*a == *b); +} + +bool NullableEquals(const std::string* a, const std::string* b) { + if ((a && !b) || (!a && b)) + return false; + return (!a) || (*a == *b); +} + } // namespace RequestCookie::RequestCookie() {} RequestCookie::~RequestCookie() {} +bool NullableEquals(const RequestCookie* a, const RequestCookie* b) { + if ((a && !b) || (!a && b)) + return false; + if (!a) + return true; + return NullableEquals(a->name.get(), b->name.get()) && + NullableEquals(a->value.get(), b->value.get()); +} + ResponseCookie::ResponseCookie() {} ResponseCookie::~ResponseCookie() {} +bool NullableEquals(const ResponseCookie* a, const ResponseCookie* b) { + if ((a && !b) || (!a && b)) + return false; + if (!a) + return true; + return NullableEquals(a->name.get(), b->name.get()) && + NullableEquals(a->value.get(), b->value.get()) && + NullableEquals(a->expires.get(), b->expires.get()) && + NullableEquals(a->max_age.get(), b->max_age.get()) && + NullableEquals(a->domain.get(), b->domain.get()) && + NullableEquals(a->path.get(), b->path.get()) && + NullableEquals(a->secure.get(), b->secure.get()) && + NullableEquals(a->http_only.get(), b->http_only.get()); +} + FilterResponseCookie::FilterResponseCookie() {} FilterResponseCookie::~FilterResponseCookie() {} +bool NullableEquals(const FilterResponseCookie* a, + const FilterResponseCookie* b) { + if ((a && !b) || (!a && b)) + return false; + if (!a) + return true; + return NullableEquals(a->age_lower_bound.get(), b->age_lower_bound.get()) && + NullableEquals(a->age_upper_bound.get(), b->age_upper_bound.get()) && + NullableEquals(a->session_cookie.get(), b->session_cookie.get()); +} + RequestCookieModification::RequestCookieModification() {} RequestCookieModification::~RequestCookieModification() {} +bool NullableEquals(const RequestCookieModification* a, + const RequestCookieModification* b) { + if ((a && !b) || (!a && b)) + return false; + if (!a) + return true; + return NullableEquals(a->filter.get(), b->filter.get()) && + NullableEquals(a->modification.get(), b->modification.get()); +} + ResponseCookieModification::ResponseCookieModification() : type(ADD) {} ResponseCookieModification::~ResponseCookieModification() {} +bool NullableEquals(const ResponseCookieModification* a, + const ResponseCookieModification* b) { + if ((a && !b) || (!a && b)) + return false; + if (!a) + return true; + return a->type == b->type && + NullableEquals(a->filter.get(), b->filter.get()) && + NullableEquals(a->modification.get(), b->modification.get()); +} + EventResponseDelta::EventResponseDelta( const std::string& extension_id, const base::Time& extension_install_time) : extension_id(extension_id), diff --git a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h index 5555451..d14f5ca 100644 --- a/chrome/browser/extensions/api/web_request/web_request_api_helpers.h +++ b/chrome/browser/extensions/api/web_request/web_request_api_helpers.h @@ -52,6 +52,8 @@ struct RequestCookie { DISALLOW_COPY_AND_ASSIGN(RequestCookie); }; +bool NullableEquals(const RequestCookie* a, const RequestCookie* b); + // Data container for ResponseCookies as defined in the declarative WebRequest // API definition. struct ResponseCookie { @@ -69,6 +71,8 @@ struct ResponseCookie { DISALLOW_COPY_AND_ASSIGN(ResponseCookie); }; +bool NullableEquals(const ResponseCookie* a, const ResponseCookie* b); + // Data container for FilterResponseCookies as defined in the declarative // WebRequest API definition. struct FilterResponseCookie : ResponseCookie { @@ -81,6 +85,9 @@ struct FilterResponseCookie : ResponseCookie { DISALLOW_COPY_AND_ASSIGN(FilterResponseCookie); }; +bool NullableEquals(const FilterResponseCookie* a, + const FilterResponseCookie* b); + enum CookieModificationType { ADD, EDIT, @@ -99,6 +106,9 @@ struct RequestCookieModification { DISALLOW_COPY_AND_ASSIGN(RequestCookieModification); }; +bool NullableEquals(const RequestCookieModification* a, + const RequestCookieModification* b); + struct ResponseCookieModification { ResponseCookieModification(); ~ResponseCookieModification(); @@ -111,6 +121,9 @@ struct ResponseCookieModification { DISALLOW_COPY_AND_ASSIGN(ResponseCookieModification); }; +bool NullableEquals(const ResponseCookieModification* a, + const ResponseCookieModification* b); + typedef std::vector<linked_ptr<RequestCookieModification> > RequestCookieModifications; typedef std::vector<linked_ptr<ResponseCookieModification> > |