// 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_RULES_REGISTRY_H_ #define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_ #include #include #include #include #include #include "base/gtest_prod_util.h" #include "base/memory/linked_ptr.h" #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/time/time.h" #include "chrome/browser/extensions/api/declarative/declarative_rule.h" #include "chrome/browser/extensions/api/declarative/rules_registry.h" #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h" #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h" #include "components/url_matcher/url_matcher.h" #include "extensions/browser/info_map.h" class Profile; class WebRequestPermissions; namespace extension_web_request_api_helpers { struct EventResponseDelta; } namespace net { class URLRequest; } namespace extensions { class RulesRegistryService; typedef linked_ptr LinkedPtrEventResponseDelta; typedef DeclarativeRule WebRequestRule; // The WebRequestRulesRegistry is responsible for managing // the internal representation of rules for the Declarative Web Request API. // // Here is the high level overview of this functionality: // // RulesRegistry::Rule consists of Conditions and Actions, these are // represented as a WebRequestRule with WebRequestConditions and // WebRequestRuleActions. // // WebRequestConditions represent JSON dictionaries as the following: // { // 'instanceType': 'URLMatcher', // 'host_suffix': 'example.com', // 'path_prefix': '/query', // 'scheme': 'http' // } // // The evaluation of URL related condition attributes (host_suffix, path_prefix) // is delegated to a URLMatcher, because this is capable of evaluating many // of such URL related condition attributes in parallel. // // For this, the URLRequestCondition has a URLMatcherConditionSet, which // represents the {'host_suffix': 'example.com', 'path_prefix': '/query'} part. // We will then ask the URLMatcher, whether a given URL // "http://www.example.com/query/" has any matches, and the URLMatcher // will respond with the URLMatcherConditionSet::ID. We can map this // to the WebRequestRule and check whether also the other conditions (in this // example 'scheme': 'http') are fulfilled. class WebRequestRulesRegistry : public RulesRegistry { public: // |cache_delegate| can be NULL. In that case it constructs the registry with // storage functionality suspended. WebRequestRulesRegistry(Profile* profile, RulesCacheDelegate* cache_delegate, const WebViewKey& webview_key); // TODO(battre): This will become an implementation detail, because we need // a way to also execute the actions of the rules. std::set GetMatches( const WebRequestData& request_data_without_ids) const; // Returns which modifications should be executed on the network request // according to the rules registered in this registry. std::list CreateDeltas( const InfoMap* extension_info_map, const WebRequestData& request_data, bool crosses_incognito); // Implementation of RulesRegistry: virtual std::string AddRulesImpl( const std::string& extension_id, const std::vector >& rules) OVERRIDE; virtual std::string RemoveRulesImpl( const std::string& extension_id, const std::vector& rule_identifiers) OVERRIDE; virtual std::string RemoveAllRulesImpl( const std::string& extension_id) OVERRIDE; // Returns true if this object retains no allocated data. Only for debugging. bool IsEmpty() const; protected: virtual ~WebRequestRulesRegistry(); // Virtual for testing: virtual base::Time GetExtensionInstallationTime( const std::string& extension_id) const; virtual void ClearCacheOnNavigation(); void SetExtensionInfoMapForTesting( scoped_refptr extension_info_map) { extension_info_map_ = extension_info_map; } const std::set& rules_with_untriggered_conditions_for_test() const { return rules_with_untriggered_conditions_; } private: FRIEND_TEST_ALL_PREFIXES(WebRequestRulesRegistrySimpleTest, StageChecker); FRIEND_TEST_ALL_PREFIXES(WebRequestRulesRegistrySimpleTest, HostPermissionsChecker); typedef std::map RuleTriggers; typedef std::map > RulesMap; typedef std::set URLMatches; typedef std::set RuleSet; // This bundles all consistency checkers. Returns true in case of consistency // and MUST set |error| otherwise. static bool Checker(const Extension* extension, const WebRequestConditionSet* conditions, const WebRequestActionSet* actions, std::string* error); // Check that the |extension| has host permissions for all URLs if actions // requiring them are present. static bool HostPermissionsChecker(const Extension* extension, const WebRequestActionSet* actions, std::string* error); // Check that every action is applicable in the same request stage as at // least one condition. static bool StageChecker(const WebRequestConditionSet* conditions, const WebRequestActionSet* actions, std::string* error); // Helper for RemoveRulesImpl and RemoveAllRulesImpl. Call this before // deleting |rule| from one of the maps in |webrequest_rules_|. It will erase // the rule from |rule_triggers_| and |rules_with_untriggered_conditions_|, // and add every of the rule's URLMatcherConditionSet to // |remove_from_url_matcher|, so that the caller can remove them from the // matcher later. void CleanUpAfterRule(const WebRequestRule* rule, std::vector* remove_from_url_matcher); // This is a helper function to GetMatches. Rules triggered by |url_matches| // get added to |result| if one of their conditions is fulfilled. // |request_data| gets passed to IsFulfilled of the rules' condition sets. void AddTriggeredRules(const URLMatches& url_matches, const WebRequestCondition::MatchData& request_data, RuleSet* result) const; // Map that tells us which WebRequestRule may match under the condition that // the URLMatcherConditionSet::ID was returned by the |url_matcher_|. RuleTriggers rule_triggers_; // These rules contain condition sets with conditions without URL attributes. // Such conditions are not triggered by URL matcher, so we need to test them // separately. std::set rules_with_untriggered_conditions_; std::map webrequest_rules_; url_matcher::URLMatcher url_matcher_; void* profile_id_; scoped_refptr extension_info_map_; DISALLOW_COPY_AND_ASSIGN(WebRequestRulesRegistry); }; } // namespace extensions #endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_