OLD | NEW |
| (Empty) |
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 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_condit
ion.h" | |
6 | |
7 #include <set> | |
8 | |
9 #include "base/memory/scoped_ptr.h" | |
10 #include "base/message_loop/message_loop.h" | |
11 #include "base/test/values_test_util.h" | |
12 #include "base/values.h" | |
13 #include "components/url_matcher/url_matcher_constants.h" | |
14 #include "content/public/browser/resource_request_info.h" | |
15 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" | |
16 #include "net/base/request_priority.h" | |
17 #include "net/url_request/url_request.h" | |
18 #include "net/url_request/url_request_test_util.h" | |
19 #include "testing/gtest/include/gtest/gtest.h" | |
20 | |
21 using content::ResourceType; | |
22 using url_matcher::URLMatcher; | |
23 using url_matcher::URLMatcherConditionSet; | |
24 | |
25 namespace extensions { | |
26 | |
27 TEST(WebRequestConditionTest, CreateCondition) { | |
28 // Necessary for TestURLRequest. | |
29 base::MessageLoopForIO message_loop; | |
30 URLMatcher matcher; | |
31 | |
32 std::string error; | |
33 scoped_ptr<WebRequestCondition> result; | |
34 | |
35 // Test wrong condition name passed. | |
36 error.clear(); | |
37 result = WebRequestCondition::Create( | |
38 NULL, | |
39 matcher.condition_factory(), | |
40 *base::test::ParseJson( | |
41 "{ \"invalid\": \"foobar\", \n" | |
42 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
43 "}"), | |
44 &error); | |
45 EXPECT_FALSE(error.empty()); | |
46 EXPECT_FALSE(result.get()); | |
47 | |
48 // Test wrong datatype in host_suffix. | |
49 error.clear(); | |
50 result = WebRequestCondition::Create( | |
51 NULL, | |
52 matcher.condition_factory(), | |
53 *base::test::ParseJson( | |
54 "{ \n" | |
55 " \"url\": [], \n" | |
56 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
57 "}"), | |
58 &error); | |
59 EXPECT_FALSE(error.empty()); | |
60 EXPECT_FALSE(result.get()); | |
61 | |
62 // Test success (can we support multiple criteria?) | |
63 error.clear(); | |
64 result = WebRequestCondition::Create( | |
65 NULL, | |
66 matcher.condition_factory(), | |
67 *base::test::ParseJson( | |
68 "{ \n" | |
69 " \"resourceType\": [\"main_frame\"], \n" | |
70 " \"url\": { \"hostSuffix\": \"example.com\" }, \n" | |
71 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
72 "}"), | |
73 &error); | |
74 EXPECT_EQ("", error); | |
75 ASSERT_TRUE(result.get()); | |
76 | |
77 URLMatcherConditionSet::Vector url_matcher_condition_set; | |
78 result->GetURLMatcherConditionSets(&url_matcher_condition_set); | |
79 matcher.AddConditionSets(url_matcher_condition_set); | |
80 | |
81 net::TestURLRequestContext context; | |
82 const GURL http_url("http://www.example.com"); | |
83 scoped_ptr<net::URLRequest> match_request(context.CreateRequest( | |
84 http_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
85 WebRequestData data(match_request.get(), ON_BEFORE_REQUEST); | |
86 WebRequestDataWithMatchIds request_data(&data); | |
87 request_data.url_match_ids = matcher.MatchURL(http_url); | |
88 EXPECT_EQ(1u, request_data.url_match_ids.size()); | |
89 content::ResourceRequestInfo::AllocateForTesting( | |
90 match_request.get(), | |
91 content::RESOURCE_TYPE_MAIN_FRAME, | |
92 NULL, | |
93 -1, | |
94 -1, | |
95 -1, | |
96 false); | |
97 EXPECT_TRUE(result->IsFulfilled(request_data)); | |
98 | |
99 const GURL https_url("https://www.example.com"); | |
100 scoped_ptr<net::URLRequest> wrong_resource_type(context.CreateRequest( | |
101 https_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
102 data.request = wrong_resource_type.get(); | |
103 request_data.url_match_ids = matcher.MatchURL(http_url); | |
104 // Make sure IsFulfilled does not fail because of URL matching. | |
105 EXPECT_EQ(1u, request_data.url_match_ids.size()); | |
106 content::ResourceRequestInfo::AllocateForTesting( | |
107 wrong_resource_type.get(), | |
108 content::RESOURCE_TYPE_SUB_FRAME, | |
109 NULL, | |
110 -1, | |
111 -1, | |
112 -1, | |
113 false); | |
114 EXPECT_FALSE(result->IsFulfilled(request_data)); | |
115 } | |
116 | |
117 TEST(WebRequestConditionTest, CreateConditionFirstPartyForCookies) { | |
118 // Necessary for TestURLRequest. | |
119 base::MessageLoopForIO message_loop; | |
120 URLMatcher matcher; | |
121 | |
122 std::string error; | |
123 scoped_ptr<WebRequestCondition> result; | |
124 | |
125 result = WebRequestCondition::Create( | |
126 NULL, | |
127 matcher.condition_factory(), | |
128 *base::test::ParseJson( | |
129 "{ \n" | |
130 " \"firstPartyForCookiesUrl\": { \"hostPrefix\": \"fpfc\"}, \n" | |
131 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
132 "}"), | |
133 &error); | |
134 EXPECT_EQ("", error); | |
135 ASSERT_TRUE(result.get()); | |
136 | |
137 URLMatcherConditionSet::Vector url_matcher_condition_set; | |
138 result->GetURLMatcherConditionSets(&url_matcher_condition_set); | |
139 matcher.AddConditionSets(url_matcher_condition_set); | |
140 | |
141 net::TestURLRequestContext context; | |
142 const GURL http_url("http://www.example.com"); | |
143 const GURL first_party_url("http://fpfc.example.com"); | |
144 scoped_ptr<net::URLRequest> match_request(context.CreateRequest( | |
145 http_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
146 WebRequestData data(match_request.get(), ON_BEFORE_REQUEST); | |
147 WebRequestDataWithMatchIds request_data(&data); | |
148 request_data.url_match_ids = matcher.MatchURL(http_url); | |
149 EXPECT_EQ(0u, request_data.url_match_ids.size()); | |
150 request_data.first_party_url_match_ids = matcher.MatchURL(first_party_url); | |
151 EXPECT_EQ(1u, request_data.first_party_url_match_ids.size()); | |
152 content::ResourceRequestInfo::AllocateForTesting( | |
153 match_request.get(), | |
154 content::RESOURCE_TYPE_MAIN_FRAME, | |
155 NULL, | |
156 -1, | |
157 -1, | |
158 -1, | |
159 false); | |
160 EXPECT_TRUE(result->IsFulfilled(request_data)); | |
161 } | |
162 | |
163 // Conditions without UrlFilter attributes need to be independent of URL | |
164 // matching results. We test here that: | |
165 // 1. A non-empty condition without UrlFilter attributes is fulfilled iff its | |
166 // attributes are fulfilled. | |
167 // 2. An empty condition (in particular, without UrlFilter attributes) is | |
168 // always fulfilled. | |
169 TEST(WebRequestConditionTest, NoUrlAttributes) { | |
170 // Necessary for TestURLRequest. | |
171 base::MessageLoopForIO message_loop; | |
172 URLMatcher matcher; | |
173 std::string error; | |
174 | |
175 // The empty condition. | |
176 error.clear(); | |
177 scoped_ptr<WebRequestCondition> condition_empty = WebRequestCondition::Create( | |
178 NULL, | |
179 matcher.condition_factory(), | |
180 *base::test::ParseJson( | |
181 "{ \n" | |
182 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
183 "}"), | |
184 &error); | |
185 EXPECT_EQ("", error); | |
186 ASSERT_TRUE(condition_empty.get()); | |
187 | |
188 // A condition without a UrlFilter attribute, which is always true. | |
189 error.clear(); | |
190 scoped_ptr<WebRequestCondition> condition_no_url_true = | |
191 WebRequestCondition::Create( | |
192 NULL, | |
193 matcher.condition_factory(), | |
194 *base::test::ParseJson( | |
195 "{ \n" | |
196 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", " | |
197 "\n" | |
198 // There is no "1st party for cookies" URL in the requests below, | |
199 // therefore all requests are considered first party for cookies. | |
200 " \"thirdPartyForCookies\": false, \n" | |
201 "}"), | |
202 &error); | |
203 EXPECT_EQ("", error); | |
204 ASSERT_TRUE(condition_no_url_true.get()); | |
205 | |
206 // A condition without a UrlFilter attribute, which is always false. | |
207 error.clear(); | |
208 scoped_ptr<WebRequestCondition> condition_no_url_false = | |
209 WebRequestCondition::Create( | |
210 NULL, | |
211 matcher.condition_factory(), | |
212 *base::test::ParseJson( | |
213 "{ \n" | |
214 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", " | |
215 "\n" | |
216 " \"thirdPartyForCookies\": true, \n" | |
217 "}"), | |
218 &error); | |
219 EXPECT_EQ("", error); | |
220 ASSERT_TRUE(condition_no_url_false.get()); | |
221 | |
222 net::TestURLRequestContext context; | |
223 scoped_ptr<net::URLRequest> https_request(context.CreateRequest( | |
224 GURL("https://www.example.com"), net::DEFAULT_PRIORITY, NULL, NULL)); | |
225 | |
226 // 1. A non-empty condition without UrlFilter attributes is fulfilled iff its | |
227 // attributes are fulfilled. | |
228 WebRequestData data(https_request.get(), ON_BEFORE_REQUEST); | |
229 EXPECT_FALSE( | |
230 condition_no_url_false->IsFulfilled(WebRequestDataWithMatchIds(&data))); | |
231 | |
232 data = WebRequestData(https_request.get(), ON_BEFORE_REQUEST); | |
233 EXPECT_TRUE( | |
234 condition_no_url_true->IsFulfilled(WebRequestDataWithMatchIds(&data))); | |
235 | |
236 // 2. An empty condition (in particular, without UrlFilter attributes) is | |
237 // always fulfilled. | |
238 data = WebRequestData(https_request.get(), ON_BEFORE_REQUEST); | |
239 EXPECT_TRUE(condition_empty->IsFulfilled(WebRequestDataWithMatchIds(&data))); | |
240 } | |
241 | |
242 TEST(WebRequestConditionTest, CreateConditionSet) { | |
243 // Necessary for TestURLRequest. | |
244 base::MessageLoopForIO message_loop; | |
245 URLMatcher matcher; | |
246 | |
247 WebRequestConditionSet::AnyVector conditions; | |
248 conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson( | |
249 "{ \n" | |
250 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
251 " \"url\": { \n" | |
252 " \"hostSuffix\": \"example.com\", \n" | |
253 " \"schemes\": [\"http\"], \n" | |
254 " }, \n" | |
255 "}").release())); | |
256 conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson( | |
257 "{ \n" | |
258 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
259 " \"url\": { \n" | |
260 " \"hostSuffix\": \"example.com\", \n" | |
261 " \"hostPrefix\": \"www\", \n" | |
262 " \"schemes\": [\"https\"], \n" | |
263 " }, \n" | |
264 "}").release())); | |
265 | |
266 // Test insertion | |
267 std::string error; | |
268 scoped_ptr<WebRequestConditionSet> result = WebRequestConditionSet::Create( | |
269 NULL, matcher.condition_factory(), conditions, &error); | |
270 EXPECT_EQ("", error); | |
271 ASSERT_TRUE(result.get()); | |
272 EXPECT_EQ(2u, result->conditions().size()); | |
273 | |
274 // Tell the URLMatcher about our shiny new patterns. | |
275 URLMatcherConditionSet::Vector url_matcher_condition_set; | |
276 result->GetURLMatcherConditionSets(&url_matcher_condition_set); | |
277 matcher.AddConditionSets(url_matcher_condition_set); | |
278 | |
279 // Test that the result is correct and matches http://www.example.com and | |
280 // https://www.example.com | |
281 GURL http_url("http://www.example.com"); | |
282 net::TestURLRequestContext context; | |
283 scoped_ptr<net::URLRequest> http_request(context.CreateRequest( | |
284 http_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
285 WebRequestData data(http_request.get(), ON_BEFORE_REQUEST); | |
286 WebRequestDataWithMatchIds request_data(&data); | |
287 request_data.url_match_ids = matcher.MatchURL(http_url); | |
288 EXPECT_EQ(1u, request_data.url_match_ids.size()); | |
289 EXPECT_TRUE(result->IsFulfilled(*(request_data.url_match_ids.begin()), | |
290 request_data)); | |
291 | |
292 GURL https_url("https://www.example.com"); | |
293 request_data.url_match_ids = matcher.MatchURL(https_url); | |
294 EXPECT_EQ(1u, request_data.url_match_ids.size()); | |
295 scoped_ptr<net::URLRequest> https_request(context.CreateRequest( | |
296 https_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
297 data.request = https_request.get(); | |
298 EXPECT_TRUE(result->IsFulfilled(*(request_data.url_match_ids.begin()), | |
299 request_data)); | |
300 | |
301 // Check that both, hostPrefix and hostSuffix are evaluated. | |
302 GURL https_foo_url("https://foo.example.com"); | |
303 request_data.url_match_ids = matcher.MatchURL(https_foo_url); | |
304 EXPECT_EQ(0u, request_data.url_match_ids.size()); | |
305 scoped_ptr<net::URLRequest> https_foo_request(context.CreateRequest( | |
306 https_foo_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
307 data.request = https_foo_request.get(); | |
308 EXPECT_FALSE(result->IsFulfilled(-1, request_data)); | |
309 } | |
310 | |
311 TEST(WebRequestConditionTest, TestPortFilter) { | |
312 // Necessary for TestURLRequest. | |
313 base::MessageLoopForIO message_loop; | |
314 URLMatcher matcher; | |
315 | |
316 WebRequestConditionSet::AnyVector conditions; | |
317 conditions.push_back(linked_ptr<base::Value>(base::test::ParseJson( | |
318 "{ \n" | |
319 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
320 " \"url\": { \n" | |
321 " \"ports\": [80, [1000, 1010]], \n" // Allow 80;1000-1010. | |
322 " \"hostSuffix\": \"example.com\", \n" | |
323 " }, \n" | |
324 "}").release())); | |
325 | |
326 // Test insertion | |
327 std::string error; | |
328 scoped_ptr<WebRequestConditionSet> result = WebRequestConditionSet::Create( | |
329 NULL, matcher.condition_factory(), conditions, &error); | |
330 EXPECT_EQ("", error); | |
331 ASSERT_TRUE(result.get()); | |
332 EXPECT_EQ(1u, result->conditions().size()); | |
333 | |
334 // Tell the URLMatcher about our shiny new patterns. | |
335 URLMatcherConditionSet::Vector url_matcher_condition_set; | |
336 result->GetURLMatcherConditionSets(&url_matcher_condition_set); | |
337 matcher.AddConditionSets(url_matcher_condition_set); | |
338 | |
339 std::set<URLMatcherConditionSet::ID> url_match_ids; | |
340 | |
341 // Test various URLs. | |
342 GURL http_url("http://www.example.com"); | |
343 net::TestURLRequestContext context; | |
344 scoped_ptr<net::URLRequest> http_request(context.CreateRequest( | |
345 http_url, net::DEFAULT_PRIORITY, NULL, NULL)); | |
346 url_match_ids = matcher.MatchURL(http_url); | |
347 ASSERT_EQ(1u, url_match_ids.size()); | |
348 | |
349 GURL http_url_80("http://www.example.com:80"); | |
350 scoped_ptr<net::URLRequest> http_request_80(context.CreateRequest( | |
351 http_url_80, net::DEFAULT_PRIORITY, NULL, NULL)); | |
352 url_match_ids = matcher.MatchURL(http_url_80); | |
353 ASSERT_EQ(1u, url_match_ids.size()); | |
354 | |
355 GURL http_url_1000("http://www.example.com:1000"); | |
356 scoped_ptr<net::URLRequest> http_request_1000(context.CreateRequest( | |
357 http_url_1000, net::DEFAULT_PRIORITY, NULL, NULL)); | |
358 url_match_ids = matcher.MatchURL(http_url_1000); | |
359 ASSERT_EQ(1u, url_match_ids.size()); | |
360 | |
361 GURL http_url_2000("http://www.example.com:2000"); | |
362 scoped_ptr<net::URLRequest> http_request_2000(context.CreateRequest( | |
363 http_url_2000, net::DEFAULT_PRIORITY, NULL, NULL)); | |
364 url_match_ids = matcher.MatchURL(http_url_2000); | |
365 ASSERT_EQ(0u, url_match_ids.size()); | |
366 } | |
367 | |
368 // Create a condition with two attributes: one on the request header and one on | |
369 // the response header. The Create() method should fail and complain that it is | |
370 // impossible that both conditions are fulfilled at the same time. | |
371 TEST(WebRequestConditionTest, ConditionsWithConflictingStages) { | |
372 // Necessary for TestURLRequest. | |
373 base::MessageLoopForIO message_loop; | |
374 URLMatcher matcher; | |
375 | |
376 std::string error; | |
377 scoped_ptr<WebRequestCondition> result; | |
378 | |
379 // Test error on incompatible application stages for involved attributes. | |
380 error.clear(); | |
381 result = WebRequestCondition::Create( | |
382 NULL, | |
383 matcher.condition_factory(), | |
384 *base::test::ParseJson( | |
385 "{ \n" | |
386 " \"instanceType\": \"declarativeWebRequest.RequestMatcher\", \n" | |
387 // Pass a JS array with one empty object to each of the header | |
388 // filters. | |
389 " \"requestHeaders\": [{}], \n" | |
390 " \"responseHeaders\": [{}], \n" | |
391 "}"), | |
392 &error); | |
393 EXPECT_FALSE(error.empty()); | |
394 EXPECT_FALSE(result.get()); | |
395 } | |
396 | |
397 } // namespace extensions | |
OLD | NEW |