1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
// 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 EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_
#define EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_
#include <list>
#include <map>
#include <set>
#include <string>
#include <vector>
#include "base/gtest_prod_util.h"
#include "base/macros.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 "components/url_matcher/url_matcher.h"
#include "extensions/browser/api/declarative/declarative_rule.h"
#include "extensions/browser/api/declarative/rules_registry.h"
#include "extensions/browser/api/declarative_webrequest/request_stage.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_action.h"
#include "extensions/browser/api/declarative_webrequest/webrequest_condition.h"
#include "extensions/browser/info_map.h"
class WebRequestPermissions;
namespace content {
class BrowserContext;
}
namespace extension_web_request_api_helpers {
struct EventResponseDelta;
}
namespace net {
class URLRequest;
}
namespace extensions {
class RulesRegistryService;
typedef linked_ptr<extension_web_request_api_helpers::EventResponseDelta>
LinkedPtrEventResponseDelta;
typedef DeclarativeRule<WebRequestCondition, WebRequestAction> WebRequestRule;
// The WebRequestRulesRegistry is responsible for managing
// the internal representation of rules for the Declarative Web Request API.
//
// Here is the high level overview of this functionality:
//
// api::events::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(content::BrowserContext* browser_context,
RulesCacheDelegate* cache_delegate,
int rules_registry_id);
// TODO(battre): This will become an implementation detail, because we need
// a way to also execute the actions of the rules.
std::set<const WebRequestRule*> GetMatches(
const 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<LinkedPtrEventResponseDelta> CreateDeltas(
const InfoMap* extension_info_map,
const WebRequestData& request_data,
bool crosses_incognito);
// Implementation of RulesRegistry:
std::string AddRulesImpl(
const std::string& extension_id,
const std::vector<linked_ptr<api::events::Rule>>& rules) override;
std::string RemoveRulesImpl(
const std::string& extension_id,
const std::vector<std::string>& rule_identifiers) override;
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:
~WebRequestRulesRegistry() override;
// Virtual for testing:
virtual base::Time GetExtensionInstallationTime(
const std::string& extension_id) const;
virtual void ClearCacheOnNavigation();
void SetExtensionInfoMapForTesting(
scoped_refptr<InfoMap> extension_info_map) {
extension_info_map_ = extension_info_map;
}
const std::set<const WebRequestRule*>&
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<url_matcher::URLMatcherConditionSet::ID,
const WebRequestRule*> RuleTriggers;
typedef std::map<WebRequestRule::RuleId, linked_ptr<const WebRequestRule>>
RulesMap;
typedef std::set<url_matcher::URLMatcherConditionSet::ID> URLMatches;
typedef std::set<const WebRequestRule*> 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<url_matcher::URLMatcherConditionSet::ID>*
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<const WebRequestRule*> rules_with_untriggered_conditions_;
std::map<WebRequestRule::ExtensionId, RulesMap> webrequest_rules_;
url_matcher::URLMatcher url_matcher_;
content::BrowserContext* browser_context_;
scoped_refptr<InfoMap> extension_info_map_;
DISALLOW_COPY_AND_ASSIGN(WebRequestRulesRegistry);
};
} // namespace extensions
#endif // EXTENSIONS_BROWSER_API_DECLARATIVE_WEBREQUEST_WEBREQUEST_RULES_REGISTRY_H_
|