1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_ 6 #define CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_ 7 8 #include <list> 9 #include <map> 10 #include <set> 11 #include <string> 12 #include <vector> 13 14 #include "base/gtest_prod_util.h" 15 #include "base/memory/linked_ptr.h" 16 #include "base/memory/ref_counted.h" 17 #include "base/memory/scoped_ptr.h" 18 #include "base/time/time.h" 19 #include "chrome/browser/extensions/api/declarative/declarative_rule.h" 20 #include "chrome/browser/extensions/api/declarative/rules_registry.h" 21 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h" 22 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action.h" 23 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condition.h" 24 #include "components/url_matcher/url_matcher.h" 25 #include "extensions/browser/info_map.h" 26 27 class Profile; 28 class WebRequestPermissions; 29 30 namespace extension_web_request_api_helpers { 31 struct EventResponseDelta; 32 } 33 34 namespace net { 35 class URLRequest; 36 } 37 38 namespace extensions { 39 40 class RulesRegistryService; 41 42 typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta> 43 LinkedPtrEventResponseDelta; 44 typedef DeclarativeRule<WebRequestCondition, WebRequestAction> WebRequestRule; 45 46 // The WebRequestRulesRegistry is responsible for managing 47 // the internal representation of rules for the Declarative Web Request API. 48 // 49 // Here is the high level overview of this functionality: 50 // 51 // RulesRegistry::Rule consists of Conditions and Actions, these are 52 // represented as a WebRequestRule with WebRequestConditions and 53 // WebRequestRuleActions. 54 // 55 // WebRequestConditions represent JSON dictionaries as the following: 56 // { 57 // 'instanceType': 'URLMatcher', 58 // 'host_suffix': 'example.com', 59 // 'path_prefix': '/query', 60 // 'scheme': 'http' 61 // } 62 // 63 // The evaluation of URL related condition attributes (host_suffix, path_prefix) 64 // is delegated to a URLMatcher, because this is capable of evaluating many 65 // of such URL related condition attributes in parallel. 66 // 67 // For this, the URLRequestCondition has a URLMatcherConditionSet, which 68 // represents the {'host_suffix': 'example.com', 'path_prefix': '/query'} part. 69 // We will then ask the URLMatcher, whether a given URL 70 // "http://www.example.com/query/" has any matches, and the URLMatcher 71 // will respond with the URLMatcherConditionSet::ID. We can map this 72 // to the WebRequestRule and check whether also the other conditions (in this 73 // example 'scheme': 'http') are fulfilled. 74 class WebRequestRulesRegistry : public RulesRegistry { 75 public: 76 // |cache_delegate| can be NULL. In that case it constructs the registry with 77 // storage functionality suspended. 78 WebRequestRulesRegistry(Profile* profile, 79 RulesCacheDelegate* cache_delegate, 80 const WebViewKey& webview_key); 81 82 // TODO(battre): This will become an implementation detail, because we need 83 // a way to also execute the actions of the rules. 84 std::set<const WebRequestRule*> GetMatches( 85 const WebRequestData& request_data_without_ids) const; 86 87 // Returns which modifications should be executed on the network request 88 // according to the rules registered in this registry. 89 std::list<LinkedPtrEventResponseDelta> CreateDeltas( 90 const InfoMap* extension_info_map, 91 const WebRequestData& request_data, 92 bool crosses_incognito); 93 94 // Implementation of RulesRegistry: 95 virtual std::string AddRulesImpl( 96 const std::string& extension_id, 97 const std::vector<linked_ptr<RulesRegistry::Rule> >& rules) OVERRIDE; 98 virtual std::string RemoveRulesImpl( 99 const std::string& extension_id, 100 const std::vector<std::string>& rule_identifiers) OVERRIDE; 101 virtual std::string RemoveAllRulesImpl( 102 const std::string& extension_id) OVERRIDE; 103 104 // Returns true if this object retains no allocated data. Only for debugging. 105 bool IsEmpty() const; 106 107 protected: 108 virtual ~WebRequestRulesRegistry(); 109 110 // Virtual for testing: 111 virtual base::Time GetExtensionInstallationTime( 112 const std::string& extension_id) const; 113 virtual void ClearCacheOnNavigation(); 114 SetExtensionInfoMapForTesting(scoped_refptr<InfoMap> extension_info_map)115 void SetExtensionInfoMapForTesting( 116 scoped_refptr<InfoMap> extension_info_map) { 117 extension_info_map_ = extension_info_map; 118 } 119 120 const std::set<const WebRequestRule*>& rules_with_untriggered_conditions_for_test()121 rules_with_untriggered_conditions_for_test() const { 122 return rules_with_untriggered_conditions_; 123 } 124 125 private: 126 FRIEND_TEST_ALL_PREFIXES(WebRequestRulesRegistrySimpleTest, StageChecker); 127 FRIEND_TEST_ALL_PREFIXES(WebRequestRulesRegistrySimpleTest, 128 HostPermissionsChecker); 129 130 typedef std::map<url_matcher::URLMatcherConditionSet::ID, WebRequestRule*> 131 RuleTriggers; 132 typedef std::map<WebRequestRule::RuleId, linked_ptr<WebRequestRule> > 133 RulesMap; 134 typedef std::set<url_matcher::URLMatcherConditionSet::ID> URLMatches; 135 typedef std::set<const WebRequestRule*> RuleSet; 136 137 // This bundles all consistency checkers. Returns true in case of consistency 138 // and MUST set |error| otherwise. 139 static bool Checker(const Extension* extension, 140 const WebRequestConditionSet* conditions, 141 const WebRequestActionSet* actions, 142 std::string* error); 143 144 // Check that the |extension| has host permissions for all URLs if actions 145 // requiring them are present. 146 static bool HostPermissionsChecker(const Extension* extension, 147 const WebRequestActionSet* actions, 148 std::string* error); 149 150 // Check that every action is applicable in the same request stage as at 151 // least one condition. 152 static bool StageChecker(const WebRequestConditionSet* conditions, 153 const WebRequestActionSet* actions, 154 std::string* error); 155 156 // Helper for RemoveRulesImpl and RemoveAllRulesImpl. Call this before 157 // deleting |rule| from one of the maps in |webrequest_rules_|. It will erase 158 // the rule from |rule_triggers_| and |rules_with_untriggered_conditions_|, 159 // and add every of the rule's URLMatcherConditionSet to 160 // |remove_from_url_matcher|, so that the caller can remove them from the 161 // matcher later. 162 void CleanUpAfterRule(const WebRequestRule* rule, 163 std::vector<url_matcher::URLMatcherConditionSet::ID>* 164 remove_from_url_matcher); 165 166 // This is a helper function to GetMatches. Rules triggered by |url_matches| 167 // get added to |result| if one of their conditions is fulfilled. 168 // |request_data| gets passed to IsFulfilled of the rules' condition sets. 169 void AddTriggeredRules(const URLMatches& url_matches, 170 const WebRequestCondition::MatchData& request_data, 171 RuleSet* result) const; 172 173 // Map that tells us which WebRequestRule may match under the condition that 174 // the URLMatcherConditionSet::ID was returned by the |url_matcher_|. 175 RuleTriggers rule_triggers_; 176 177 // These rules contain condition sets with conditions without URL attributes. 178 // Such conditions are not triggered by URL matcher, so we need to test them 179 // separately. 180 std::set<const WebRequestRule*> rules_with_untriggered_conditions_; 181 182 std::map<WebRequestRule::ExtensionId, RulesMap> webrequest_rules_; 183 184 url_matcher::URLMatcher url_matcher_; 185 186 void* profile_id_; 187 scoped_refptr<InfoMap> extension_info_map_; 188 189 DISALLOW_COPY_AND_ASSIGN(WebRequestRulesRegistry); 190 }; 191 192 } // namespace extensions 193 194 #endif // CHROME_BROWSER_EXTENSIONS_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_ 195