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_action
.h" | |
6 | |
7 #include <limits> | |
8 | |
9 #include "base/lazy_instance.h" | |
10 #include "base/logging.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/strings/stringprintf.h" | |
13 #include "base/values.h" | |
14 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | |
15 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h" | |
16 #include "content/public/browser/resource_request_info.h" | |
17 #include "content/public/common/url_constants.h" | |
18 #include "extensions/browser/api/declarative/deduping_factory.h" | |
19 #include "extensions/browser/api/declarative_webrequest/request_stage.h" | |
20 #include "extensions/browser/api/declarative_webrequest/webrequest_condition.h" | |
21 #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h" | |
22 #include "extensions/browser/api/web_request/web_request_api_constants.h" | |
23 #include "extensions/browser/guest_view/web_view/web_view_renderer_state.h" | |
24 #include "extensions/browser/info_map.h" | |
25 #include "extensions/common/error_utils.h" | |
26 #include "extensions/common/extension.h" | |
27 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | |
28 #include "net/http/http_util.h" | |
29 #include "net/url_request/url_request.h" | |
30 #include "third_party/re2/re2/re2.h" | |
31 | |
32 using content::ResourceRequestInfo; | |
33 | |
34 namespace extensions { | |
35 | |
36 namespace helpers = extension_web_request_api_helpers; | |
37 namespace keys = declarative_webrequest_constants; | |
38 | |
39 namespace { | |
40 // Error messages. | |
41 const char kIgnoreRulesRequiresParameterError[] = | |
42 "IgnoreRules requires at least one parameter."; | |
43 | |
44 const char kTransparentImageUrl[] = "data:image/png;base64,iVBORw0KGgoAAAANSUh" | |
45 "EUgAAAAEAAAABCAYAAAAfFcSJAAAACklEQVR4nGMAAQAABQABDQottAAAAABJRU5ErkJggg=="; | |
46 const char kEmptyDocumentUrl[] = "data:text/html,"; | |
47 | |
48 #define INPUT_FORMAT_VALIDATE(test) do { \ | |
49 if (!(test)) { \ | |
50 *bad_message = true; \ | |
51 return scoped_refptr<const WebRequestAction>(NULL); \ | |
52 } \ | |
53 } while (0) | |
54 | |
55 scoped_ptr<helpers::RequestCookie> ParseRequestCookie( | |
56 const base::DictionaryValue* dict) { | |
57 scoped_ptr<helpers::RequestCookie> result(new helpers::RequestCookie); | |
58 std::string tmp; | |
59 if (dict->GetString(keys::kNameKey, &tmp)) | |
60 result->name.reset(new std::string(tmp)); | |
61 if (dict->GetString(keys::kValueKey, &tmp)) | |
62 result->value.reset(new std::string(tmp)); | |
63 return result.Pass(); | |
64 } | |
65 | |
66 void ParseResponseCookieImpl(const base::DictionaryValue* dict, | |
67 helpers::ResponseCookie* cookie) { | |
68 std::string string_tmp; | |
69 int int_tmp = 0; | |
70 bool bool_tmp = false; | |
71 if (dict->GetString(keys::kNameKey, &string_tmp)) | |
72 cookie->name.reset(new std::string(string_tmp)); | |
73 if (dict->GetString(keys::kValueKey, &string_tmp)) | |
74 cookie->value.reset(new std::string(string_tmp)); | |
75 if (dict->GetString(keys::kExpiresKey, &string_tmp)) | |
76 cookie->expires.reset(new std::string(string_tmp)); | |
77 if (dict->GetInteger(keys::kMaxAgeKey, &int_tmp)) | |
78 cookie->max_age.reset(new int(int_tmp)); | |
79 if (dict->GetString(keys::kDomainKey, &string_tmp)) | |
80 cookie->domain.reset(new std::string(string_tmp)); | |
81 if (dict->GetString(keys::kPathKey, &string_tmp)) | |
82 cookie->path.reset(new std::string(string_tmp)); | |
83 if (dict->GetBoolean(keys::kSecureKey, &bool_tmp)) | |
84 cookie->secure.reset(new bool(bool_tmp)); | |
85 if (dict->GetBoolean(keys::kHttpOnlyKey, &bool_tmp)) | |
86 cookie->http_only.reset(new bool(bool_tmp)); | |
87 } | |
88 | |
89 scoped_ptr<helpers::ResponseCookie> ParseResponseCookie( | |
90 const base::DictionaryValue* dict) { | |
91 scoped_ptr<helpers::ResponseCookie> result(new helpers::ResponseCookie); | |
92 ParseResponseCookieImpl(dict, result.get()); | |
93 return result.Pass(); | |
94 } | |
95 | |
96 scoped_ptr<helpers::FilterResponseCookie> ParseFilterResponseCookie( | |
97 const base::DictionaryValue* dict) { | |
98 scoped_ptr<helpers::FilterResponseCookie> result( | |
99 new helpers::FilterResponseCookie); | |
100 ParseResponseCookieImpl(dict, result.get()); | |
101 | |
102 int int_tmp = 0; | |
103 bool bool_tmp = false; | |
104 if (dict->GetInteger(keys::kAgeUpperBoundKey, &int_tmp)) | |
105 result->age_upper_bound.reset(new int(int_tmp)); | |
106 if (dict->GetInteger(keys::kAgeLowerBoundKey, &int_tmp)) | |
107 result->age_lower_bound.reset(new int(int_tmp)); | |
108 if (dict->GetBoolean(keys::kSessionCookieKey, &bool_tmp)) | |
109 result->session_cookie.reset(new bool(bool_tmp)); | |
110 return result.Pass(); | |
111 } | |
112 | |
113 // Helper function for WebRequestActions that can be instantiated by just | |
114 // calling the constructor. | |
115 template <class T> | |
116 scoped_refptr<const WebRequestAction> CallConstructorFactoryMethod( | |
117 const std::string& instance_type, | |
118 const base::Value* value, | |
119 std::string* error, | |
120 bool* bad_message) { | |
121 return scoped_refptr<const WebRequestAction>(new T); | |
122 } | |
123 | |
124 scoped_refptr<const WebRequestAction> CreateRedirectRequestAction( | |
125 const std::string& instance_type, | |
126 const base::Value* value, | |
127 std::string* error, | |
128 bool* bad_message) { | |
129 const base::DictionaryValue* dict = NULL; | |
130 CHECK(value->GetAsDictionary(&dict)); | |
131 std::string redirect_url_string; | |
132 INPUT_FORMAT_VALIDATE( | |
133 dict->GetString(keys::kRedirectUrlKey, &redirect_url_string)); | |
134 GURL redirect_url(redirect_url_string); | |
135 return scoped_refptr<const WebRequestAction>( | |
136 new WebRequestRedirectAction(redirect_url)); | |
137 } | |
138 | |
139 scoped_refptr<const WebRequestAction> CreateRedirectRequestByRegExAction( | |
140 const std::string& instance_type, | |
141 const base::Value* value, | |
142 std::string* error, | |
143 bool* bad_message) { | |
144 const base::DictionaryValue* dict = NULL; | |
145 CHECK(value->GetAsDictionary(&dict)); | |
146 std::string from; | |
147 std::string to; | |
148 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); | |
149 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kToKey, &to)); | |
150 | |
151 to = WebRequestRedirectByRegExAction::PerlToRe2Style(to); | |
152 | |
153 RE2::Options options; | |
154 options.set_case_sensitive(false); | |
155 scoped_ptr<RE2> from_pattern(new RE2(from, options)); | |
156 | |
157 if (!from_pattern->ok()) { | |
158 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; | |
159 return scoped_refptr<const WebRequestAction>(NULL); | |
160 } | |
161 return scoped_refptr<const WebRequestAction>( | |
162 new WebRequestRedirectByRegExAction(from_pattern.Pass(), to)); | |
163 } | |
164 | |
165 scoped_refptr<const WebRequestAction> CreateSetRequestHeaderAction( | |
166 const std::string& instance_type, | |
167 const base::Value* json_value, | |
168 std::string* error, | |
169 bool* bad_message) { | |
170 const base::DictionaryValue* dict = NULL; | |
171 CHECK(json_value->GetAsDictionary(&dict)); | |
172 std::string name; | |
173 std::string value; | |
174 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | |
175 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); | |
176 if (!net::HttpUtil::IsValidHeaderName(name)) { | |
177 *error = extension_web_request_api_constants::kInvalidHeaderName; | |
178 return scoped_refptr<const WebRequestAction>(NULL); | |
179 } | |
180 if (!net::HttpUtil::IsValidHeaderValue(value)) { | |
181 *error = ErrorUtils::FormatErrorMessage( | |
182 extension_web_request_api_constants::kInvalidHeaderValue, name); | |
183 return scoped_refptr<const WebRequestAction>(NULL); | |
184 } | |
185 return scoped_refptr<const WebRequestAction>( | |
186 new WebRequestSetRequestHeaderAction(name, value)); | |
187 } | |
188 | |
189 scoped_refptr<const WebRequestAction> CreateRemoveRequestHeaderAction( | |
190 const std::string& instance_type, | |
191 const base::Value* value, | |
192 std::string* error, | |
193 bool* bad_message) { | |
194 const base::DictionaryValue* dict = NULL; | |
195 CHECK(value->GetAsDictionary(&dict)); | |
196 std::string name; | |
197 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | |
198 if (!net::HttpUtil::IsValidHeaderName(name)) { | |
199 *error = extension_web_request_api_constants::kInvalidHeaderName; | |
200 return scoped_refptr<const WebRequestAction>(NULL); | |
201 } | |
202 return scoped_refptr<const WebRequestAction>( | |
203 new WebRequestRemoveRequestHeaderAction(name)); | |
204 } | |
205 | |
206 scoped_refptr<const WebRequestAction> CreateAddResponseHeaderAction( | |
207 const std::string& instance_type, | |
208 const base::Value* json_value, | |
209 std::string* error, | |
210 bool* bad_message) { | |
211 const base::DictionaryValue* dict = NULL; | |
212 CHECK(json_value->GetAsDictionary(&dict)); | |
213 std::string name; | |
214 std::string value; | |
215 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | |
216 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); | |
217 if (!net::HttpUtil::IsValidHeaderName(name)) { | |
218 *error = extension_web_request_api_constants::kInvalidHeaderName; | |
219 return scoped_refptr<const WebRequestAction>(NULL); | |
220 } | |
221 if (!net::HttpUtil::IsValidHeaderValue(value)) { | |
222 *error = ErrorUtils::FormatErrorMessage( | |
223 extension_web_request_api_constants::kInvalidHeaderValue, name); | |
224 return scoped_refptr<const WebRequestAction>(NULL); | |
225 } | |
226 return scoped_refptr<const WebRequestAction>( | |
227 new WebRequestAddResponseHeaderAction(name, value)); | |
228 } | |
229 | |
230 scoped_refptr<const WebRequestAction> CreateRemoveResponseHeaderAction( | |
231 const std::string& instance_type, | |
232 const base::Value* json_value, | |
233 std::string* error, | |
234 bool* bad_message) { | |
235 const base::DictionaryValue* dict = NULL; | |
236 CHECK(json_value->GetAsDictionary(&dict)); | |
237 std::string name; | |
238 std::string value; | |
239 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | |
240 bool has_value = dict->GetString(keys::kValueKey, &value); | |
241 if (!net::HttpUtil::IsValidHeaderName(name)) { | |
242 *error = extension_web_request_api_constants::kInvalidHeaderName; | |
243 return scoped_refptr<const WebRequestAction>(NULL); | |
244 } | |
245 if (has_value && !net::HttpUtil::IsValidHeaderValue(value)) { | |
246 *error = ErrorUtils::FormatErrorMessage( | |
247 extension_web_request_api_constants::kInvalidHeaderValue, name); | |
248 return scoped_refptr<const WebRequestAction>(NULL); | |
249 } | |
250 return scoped_refptr<const WebRequestAction>( | |
251 new WebRequestRemoveResponseHeaderAction(name, value, has_value)); | |
252 } | |
253 | |
254 scoped_refptr<const WebRequestAction> CreateIgnoreRulesAction( | |
255 const std::string& instance_type, | |
256 const base::Value* value, | |
257 std::string* error, | |
258 bool* bad_message) { | |
259 const base::DictionaryValue* dict = NULL; | |
260 CHECK(value->GetAsDictionary(&dict)); | |
261 bool has_parameter = false; | |
262 int minimum_priority = std::numeric_limits<int>::min(); | |
263 std::string ignore_tag; | |
264 if (dict->HasKey(keys::kLowerPriorityThanKey)) { | |
265 INPUT_FORMAT_VALIDATE( | |
266 dict->GetInteger(keys::kLowerPriorityThanKey, &minimum_priority)); | |
267 has_parameter = true; | |
268 } | |
269 if (dict->HasKey(keys::kHasTagKey)) { | |
270 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kHasTagKey, &ignore_tag)); | |
271 has_parameter = true; | |
272 } | |
273 if (!has_parameter) { | |
274 *error = kIgnoreRulesRequiresParameterError; | |
275 return scoped_refptr<const WebRequestAction>(NULL); | |
276 } | |
277 return scoped_refptr<const WebRequestAction>( | |
278 new WebRequestIgnoreRulesAction(minimum_priority, ignore_tag)); | |
279 } | |
280 | |
281 scoped_refptr<const WebRequestAction> CreateRequestCookieAction( | |
282 const std::string& instance_type, | |
283 const base::Value* value, | |
284 std::string* error, | |
285 bool* bad_message) { | |
286 using extension_web_request_api_helpers::RequestCookieModification; | |
287 | |
288 const base::DictionaryValue* dict = NULL; | |
289 CHECK(value->GetAsDictionary(&dict)); | |
290 | |
291 linked_ptr<RequestCookieModification> modification( | |
292 new RequestCookieModification); | |
293 | |
294 // Get modification type. | |
295 if (instance_type == keys::kAddRequestCookieType) | |
296 modification->type = helpers::ADD; | |
297 else if (instance_type == keys::kEditRequestCookieType) | |
298 modification->type = helpers::EDIT; | |
299 else if (instance_type == keys::kRemoveRequestCookieType) | |
300 modification->type = helpers::REMOVE; | |
301 else | |
302 INPUT_FORMAT_VALIDATE(false); | |
303 | |
304 // Get filter. | |
305 if (modification->type == helpers::EDIT || | |
306 modification->type == helpers::REMOVE) { | |
307 const base::DictionaryValue* filter = NULL; | |
308 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kFilterKey, &filter)); | |
309 modification->filter = ParseRequestCookie(filter); | |
310 } | |
311 | |
312 // Get new value. | |
313 if (modification->type == helpers::ADD) { | |
314 const base::DictionaryValue* value = NULL; | |
315 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kCookieKey, &value)); | |
316 modification->modification = ParseRequestCookie(value); | |
317 } else if (modification->type == helpers::EDIT) { | |
318 const base::DictionaryValue* value = NULL; | |
319 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kModificationKey, &value)); | |
320 modification->modification = ParseRequestCookie(value); | |
321 } | |
322 | |
323 return scoped_refptr<const WebRequestAction>( | |
324 new WebRequestRequestCookieAction(modification)); | |
325 } | |
326 | |
327 scoped_refptr<const WebRequestAction> CreateResponseCookieAction( | |
328 const std::string& instance_type, | |
329 const base::Value* value, | |
330 std::string* error, | |
331 bool* bad_message) { | |
332 using extension_web_request_api_helpers::ResponseCookieModification; | |
333 | |
334 const base::DictionaryValue* dict = NULL; | |
335 CHECK(value->GetAsDictionary(&dict)); | |
336 | |
337 linked_ptr<ResponseCookieModification> modification( | |
338 new ResponseCookieModification); | |
339 | |
340 // Get modification type. | |
341 if (instance_type == keys::kAddResponseCookieType) | |
342 modification->type = helpers::ADD; | |
343 else if (instance_type == keys::kEditResponseCookieType) | |
344 modification->type = helpers::EDIT; | |
345 else if (instance_type == keys::kRemoveResponseCookieType) | |
346 modification->type = helpers::REMOVE; | |
347 else | |
348 INPUT_FORMAT_VALIDATE(false); | |
349 | |
350 // Get filter. | |
351 if (modification->type == helpers::EDIT || | |
352 modification->type == helpers::REMOVE) { | |
353 const base::DictionaryValue* filter = NULL; | |
354 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kFilterKey, &filter)); | |
355 modification->filter = ParseFilterResponseCookie(filter); | |
356 } | |
357 | |
358 // Get new value. | |
359 if (modification->type == helpers::ADD) { | |
360 const base::DictionaryValue* value = NULL; | |
361 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kCookieKey, &value)); | |
362 modification->modification = ParseResponseCookie(value); | |
363 } else if (modification->type == helpers::EDIT) { | |
364 const base::DictionaryValue* value = NULL; | |
365 INPUT_FORMAT_VALIDATE(dict->GetDictionary(keys::kModificationKey, &value)); | |
366 modification->modification = ParseResponseCookie(value); | |
367 } | |
368 | |
369 return scoped_refptr<const WebRequestAction>( | |
370 new WebRequestResponseCookieAction(modification)); | |
371 } | |
372 | |
373 scoped_refptr<const WebRequestAction> CreateSendMessageToExtensionAction( | |
374 const std::string& name, | |
375 const base::Value* value, | |
376 std::string* error, | |
377 bool* bad_message) { | |
378 const base::DictionaryValue* dict = NULL; | |
379 CHECK(value->GetAsDictionary(&dict)); | |
380 std::string message; | |
381 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kMessageKey, &message)); | |
382 return scoped_refptr<const WebRequestAction>( | |
383 new WebRequestSendMessageToExtensionAction(message)); | |
384 } | |
385 | |
386 struct WebRequestActionFactory { | |
387 DedupingFactory<WebRequestAction> factory; | |
388 | |
389 WebRequestActionFactory() : factory(5) { | |
390 factory.RegisterFactoryMethod( | |
391 keys::kAddRequestCookieType, | |
392 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
393 &CreateRequestCookieAction); | |
394 factory.RegisterFactoryMethod( | |
395 keys::kAddResponseCookieType, | |
396 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
397 &CreateResponseCookieAction); | |
398 factory.RegisterFactoryMethod( | |
399 keys::kAddResponseHeaderType, | |
400 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
401 &CreateAddResponseHeaderAction); | |
402 factory.RegisterFactoryMethod( | |
403 keys::kCancelRequestType, | |
404 DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, | |
405 &CallConstructorFactoryMethod<WebRequestCancelAction>); | |
406 factory.RegisterFactoryMethod( | |
407 keys::kEditRequestCookieType, | |
408 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
409 &CreateRequestCookieAction); | |
410 factory.RegisterFactoryMethod( | |
411 keys::kEditResponseCookieType, | |
412 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
413 &CreateResponseCookieAction); | |
414 factory.RegisterFactoryMethod( | |
415 keys::kRedirectByRegExType, | |
416 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
417 &CreateRedirectRequestByRegExAction); | |
418 factory.RegisterFactoryMethod( | |
419 keys::kRedirectRequestType, | |
420 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
421 &CreateRedirectRequestAction); | |
422 factory.RegisterFactoryMethod( | |
423 keys::kRedirectToTransparentImageType, | |
424 DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, | |
425 &CallConstructorFactoryMethod< | |
426 WebRequestRedirectToTransparentImageAction>); | |
427 factory.RegisterFactoryMethod( | |
428 keys::kRedirectToEmptyDocumentType, | |
429 DedupingFactory<WebRequestAction>::IS_NOT_PARAMETERIZED, | |
430 &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>); | |
431 factory.RegisterFactoryMethod( | |
432 keys::kRemoveRequestCookieType, | |
433 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
434 &CreateRequestCookieAction); | |
435 factory.RegisterFactoryMethod( | |
436 keys::kRemoveResponseCookieType, | |
437 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
438 &CreateResponseCookieAction); | |
439 factory.RegisterFactoryMethod( | |
440 keys::kSetRequestHeaderType, | |
441 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
442 &CreateSetRequestHeaderAction); | |
443 factory.RegisterFactoryMethod( | |
444 keys::kRemoveRequestHeaderType, | |
445 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
446 &CreateRemoveRequestHeaderAction); | |
447 factory.RegisterFactoryMethod( | |
448 keys::kRemoveResponseHeaderType, | |
449 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
450 &CreateRemoveResponseHeaderAction); | |
451 factory.RegisterFactoryMethod( | |
452 keys::kIgnoreRulesType, | |
453 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
454 &CreateIgnoreRulesAction); | |
455 factory.RegisterFactoryMethod( | |
456 keys::kSendMessageToExtensionType, | |
457 DedupingFactory<WebRequestAction>::IS_PARAMETERIZED, | |
458 &CreateSendMessageToExtensionAction); | |
459 } | |
460 }; | |
461 | |
462 base::LazyInstance<WebRequestActionFactory>::Leaky | |
463 g_web_request_action_factory = LAZY_INSTANCE_INITIALIZER; | |
464 | |
465 } // namespace | |
466 | |
467 // | |
468 // WebRequestAction | |
469 // | |
470 | |
471 WebRequestAction::~WebRequestAction() {} | |
472 | |
473 bool WebRequestAction::Equals(const WebRequestAction* other) const { | |
474 return type() == other->type(); | |
475 } | |
476 | |
477 bool WebRequestAction::HasPermission(const InfoMap* extension_info_map, | |
478 const std::string& extension_id, | |
479 const net::URLRequest* request, | |
480 bool crosses_incognito) const { | |
481 if (WebRequestPermissions::HideRequest(extension_info_map, request)) | |
482 return false; | |
483 | |
484 // In unit tests we don't have an extension_info_map object here and skip host | |
485 // permission checks. | |
486 if (!extension_info_map) | |
487 return true; | |
488 | |
489 const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request); | |
490 int process_id = info ? info->GetChildID() : 0; | |
491 | |
492 // The embedder can always access all hosts from within a <webview>. | |
493 // The same is not true of extensions. | |
494 if (WebViewRendererState::GetInstance()->IsGuest(process_id)) | |
495 return true; | |
496 | |
497 WebRequestPermissions::HostPermissionsCheck permission_check = | |
498 WebRequestPermissions::REQUIRE_ALL_URLS; | |
499 switch (host_permissions_strategy()) { | |
500 case STRATEGY_DEFAULT: // Default value is already set. | |
501 break; | |
502 case STRATEGY_NONE: | |
503 permission_check = WebRequestPermissions::DO_NOT_CHECK_HOST; | |
504 break; | |
505 case STRATEGY_HOST: | |
506 permission_check = WebRequestPermissions::REQUIRE_HOST_PERMISSION; | |
507 break; | |
508 } | |
509 return WebRequestPermissions::CanExtensionAccessURL( | |
510 extension_info_map, extension_id, request->url(), crosses_incognito, | |
511 permission_check); | |
512 } | |
513 | |
514 // static | |
515 scoped_refptr<const WebRequestAction> WebRequestAction::Create( | |
516 content::BrowserContext* browser_context, | |
517 const Extension* extension, | |
518 const base::Value& json_action, | |
519 std::string* error, | |
520 bool* bad_message) { | |
521 *error = ""; | |
522 *bad_message = false; | |
523 | |
524 const base::DictionaryValue* action_dict = NULL; | |
525 INPUT_FORMAT_VALIDATE(json_action.GetAsDictionary(&action_dict)); | |
526 | |
527 std::string instance_type; | |
528 INPUT_FORMAT_VALIDATE( | |
529 action_dict->GetString(keys::kInstanceTypeKey, &instance_type)); | |
530 | |
531 WebRequestActionFactory& factory = g_web_request_action_factory.Get(); | |
532 return factory.factory.Instantiate( | |
533 instance_type, action_dict, error, bad_message); | |
534 } | |
535 | |
536 void WebRequestAction::Apply(const std::string& extension_id, | |
537 base::Time extension_install_time, | |
538 ApplyInfo* apply_info) const { | |
539 if (!HasPermission(apply_info->extension_info_map, extension_id, | |
540 apply_info->request_data.request, | |
541 apply_info->crosses_incognito)) | |
542 return; | |
543 if (stages() & apply_info->request_data.stage) { | |
544 LinkedPtrEventResponseDelta delta = CreateDelta( | |
545 apply_info->request_data, extension_id, extension_install_time); | |
546 if (delta.get()) | |
547 apply_info->deltas->push_back(delta); | |
548 if (type() == WebRequestAction::ACTION_IGNORE_RULES) { | |
549 const WebRequestIgnoreRulesAction* ignore_action = | |
550 static_cast<const WebRequestIgnoreRulesAction*>(this); | |
551 if (!ignore_action->ignore_tag().empty()) | |
552 apply_info->ignored_tags->insert(ignore_action->ignore_tag()); | |
553 } | |
554 } | |
555 } | |
556 | |
557 WebRequestAction::WebRequestAction(int stages, | |
558 Type type, | |
559 int minimum_priority, | |
560 HostPermissionsStrategy strategy) | |
561 : stages_(stages), | |
562 type_(type), | |
563 minimum_priority_(minimum_priority), | |
564 host_permissions_strategy_(strategy) {} | |
565 | |
566 // | |
567 // WebRequestCancelAction | |
568 // | |
569 | |
570 WebRequestCancelAction::WebRequestCancelAction() | |
571 : WebRequestAction(ON_BEFORE_REQUEST | ON_BEFORE_SEND_HEADERS | | |
572 ON_HEADERS_RECEIVED | ON_AUTH_REQUIRED, | |
573 ACTION_CANCEL_REQUEST, | |
574 std::numeric_limits<int>::min(), | |
575 STRATEGY_NONE) {} | |
576 | |
577 WebRequestCancelAction::~WebRequestCancelAction() {} | |
578 | |
579 std::string WebRequestCancelAction::GetName() const { | |
580 return keys::kCancelRequestType; | |
581 } | |
582 | |
583 LinkedPtrEventResponseDelta WebRequestCancelAction::CreateDelta( | |
584 const WebRequestData& request_data, | |
585 const std::string& extension_id, | |
586 const base::Time& extension_install_time) const { | |
587 CHECK(request_data.stage & stages()); | |
588 LinkedPtrEventResponseDelta result( | |
589 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
590 result->cancel = true; | |
591 return result; | |
592 } | |
593 | |
594 // | |
595 // WebRequestRedirectAction | |
596 // | |
597 | |
598 WebRequestRedirectAction::WebRequestRedirectAction(const GURL& redirect_url) | |
599 : WebRequestAction(ON_BEFORE_REQUEST | ON_HEADERS_RECEIVED, | |
600 ACTION_REDIRECT_REQUEST, | |
601 std::numeric_limits<int>::min(), | |
602 STRATEGY_DEFAULT), | |
603 redirect_url_(redirect_url) {} | |
604 | |
605 WebRequestRedirectAction::~WebRequestRedirectAction() {} | |
606 | |
607 bool WebRequestRedirectAction::Equals(const WebRequestAction* other) const { | |
608 return WebRequestAction::Equals(other) && | |
609 redirect_url_ == | |
610 static_cast<const WebRequestRedirectAction*>(other)->redirect_url_; | |
611 } | |
612 | |
613 std::string WebRequestRedirectAction::GetName() const { | |
614 return keys::kRedirectRequestType; | |
615 } | |
616 | |
617 LinkedPtrEventResponseDelta WebRequestRedirectAction::CreateDelta( | |
618 const WebRequestData& request_data, | |
619 const std::string& extension_id, | |
620 const base::Time& extension_install_time) const { | |
621 CHECK(request_data.stage & stages()); | |
622 if (request_data.request->url() == redirect_url_) | |
623 return LinkedPtrEventResponseDelta(NULL); | |
624 LinkedPtrEventResponseDelta result( | |
625 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
626 result->new_url = redirect_url_; | |
627 return result; | |
628 } | |
629 | |
630 // | |
631 // WebRequestRedirectToTransparentImageAction | |
632 // | |
633 | |
634 WebRequestRedirectToTransparentImageAction:: | |
635 WebRequestRedirectToTransparentImageAction() | |
636 : WebRequestAction(ON_BEFORE_REQUEST | ON_HEADERS_RECEIVED, | |
637 ACTION_REDIRECT_TO_TRANSPARENT_IMAGE, | |
638 std::numeric_limits<int>::min(), | |
639 STRATEGY_NONE) {} | |
640 | |
641 WebRequestRedirectToTransparentImageAction:: | |
642 ~WebRequestRedirectToTransparentImageAction() {} | |
643 | |
644 std::string WebRequestRedirectToTransparentImageAction::GetName() const { | |
645 return keys::kRedirectToTransparentImageType; | |
646 } | |
647 | |
648 LinkedPtrEventResponseDelta | |
649 WebRequestRedirectToTransparentImageAction::CreateDelta( | |
650 const WebRequestData& request_data, | |
651 const std::string& extension_id, | |
652 const base::Time& extension_install_time) const { | |
653 CHECK(request_data.stage & stages()); | |
654 LinkedPtrEventResponseDelta result( | |
655 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
656 result->new_url = GURL(kTransparentImageUrl); | |
657 return result; | |
658 } | |
659 | |
660 // | |
661 // WebRequestRedirectToEmptyDocumentAction | |
662 // | |
663 | |
664 WebRequestRedirectToEmptyDocumentAction:: | |
665 WebRequestRedirectToEmptyDocumentAction() | |
666 : WebRequestAction(ON_BEFORE_REQUEST | ON_HEADERS_RECEIVED, | |
667 ACTION_REDIRECT_TO_EMPTY_DOCUMENT, | |
668 std::numeric_limits<int>::min(), | |
669 STRATEGY_NONE) {} | |
670 | |
671 WebRequestRedirectToEmptyDocumentAction:: | |
672 ~WebRequestRedirectToEmptyDocumentAction() {} | |
673 | |
674 std::string WebRequestRedirectToEmptyDocumentAction::GetName() const { | |
675 return keys::kRedirectToEmptyDocumentType; | |
676 } | |
677 | |
678 LinkedPtrEventResponseDelta | |
679 WebRequestRedirectToEmptyDocumentAction::CreateDelta( | |
680 const WebRequestData& request_data, | |
681 const std::string& extension_id, | |
682 const base::Time& extension_install_time) const { | |
683 CHECK(request_data.stage & stages()); | |
684 LinkedPtrEventResponseDelta result( | |
685 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
686 result->new_url = GURL(kEmptyDocumentUrl); | |
687 return result; | |
688 } | |
689 | |
690 // | |
691 // WebRequestRedirectByRegExAction | |
692 // | |
693 | |
694 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( | |
695 scoped_ptr<RE2> from_pattern, | |
696 const std::string& to_pattern) | |
697 : WebRequestAction(ON_BEFORE_REQUEST | ON_HEADERS_RECEIVED, | |
698 ACTION_REDIRECT_BY_REGEX_DOCUMENT, | |
699 std::numeric_limits<int>::min(), | |
700 STRATEGY_DEFAULT), | |
701 from_pattern_(from_pattern.Pass()), | |
702 to_pattern_(to_pattern.data(), to_pattern.size()) {} | |
703 | |
704 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} | |
705 | |
706 // About the syntax of the two languages: | |
707 // | |
708 // ICU (Perl) states: | |
709 // $n The text of capture group n will be substituted for $n. n must be >= 0 | |
710 // and not greater than the number of capture groups. A $ not followed by a | |
711 // digit has no special meaning, and will appear in the substitution text | |
712 // as itself, a $. | |
713 // \ Treat the following character as a literal, suppressing any special | |
714 // meaning. Backslash escaping in substitution text is only required for | |
715 // '$' and '\', but may be used on any other character without bad effects. | |
716 // | |
717 // RE2, derived from RE2::Rewrite() | |
718 // \ May only be followed by a digit or another \. If followed by a single | |
719 // digit, both characters represent the respective capture group. If followed | |
720 // by another \, it is used as an escape sequence. | |
721 | |
722 // static | |
723 std::string WebRequestRedirectByRegExAction::PerlToRe2Style( | |
724 const std::string& perl) { | |
725 std::string::const_iterator i = perl.begin(); | |
726 std::string result; | |
727 while (i != perl.end()) { | |
728 if (*i == '$') { | |
729 ++i; | |
730 if (i == perl.end()) { | |
731 result += '$'; | |
732 return result; | |
733 } else if (isdigit(*i)) { | |
734 result += '\\'; | |
735 result += *i; | |
736 } else { | |
737 result += '$'; | |
738 result += *i; | |
739 } | |
740 } else if (*i == '\\') { | |
741 ++i; | |
742 if (i == perl.end()) { | |
743 result += '\\'; | |
744 } else if (*i == '$') { | |
745 result += '$'; | |
746 } else if (*i == '\\') { | |
747 result += "\\\\"; | |
748 } else { | |
749 result += *i; | |
750 } | |
751 } else { | |
752 result += *i; | |
753 } | |
754 ++i; | |
755 } | |
756 return result; | |
757 } | |
758 | |
759 bool WebRequestRedirectByRegExAction::Equals( | |
760 const WebRequestAction* other) const { | |
761 if (!WebRequestAction::Equals(other)) | |
762 return false; | |
763 const WebRequestRedirectByRegExAction* casted_other = | |
764 static_cast<const WebRequestRedirectByRegExAction*>(other); | |
765 return from_pattern_->pattern() == casted_other->from_pattern_->pattern() && | |
766 to_pattern_ == casted_other->to_pattern_; | |
767 } | |
768 | |
769 std::string WebRequestRedirectByRegExAction::GetName() const { | |
770 return keys::kRedirectByRegExType; | |
771 } | |
772 | |
773 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( | |
774 const WebRequestData& request_data, | |
775 const std::string& extension_id, | |
776 const base::Time& extension_install_time) const { | |
777 CHECK(request_data.stage & stages()); | |
778 CHECK(from_pattern_.get()); | |
779 | |
780 const std::string& old_url = request_data.request->url().spec(); | |
781 std::string new_url = old_url; | |
782 if (!RE2::Replace(&new_url, *from_pattern_, to_pattern_) || | |
783 new_url == old_url) { | |
784 return LinkedPtrEventResponseDelta(NULL); | |
785 } | |
786 | |
787 LinkedPtrEventResponseDelta result( | |
788 new extension_web_request_api_helpers::EventResponseDelta( | |
789 extension_id, extension_install_time)); | |
790 result->new_url = GURL(new_url); | |
791 return result; | |
792 } | |
793 | |
794 // | |
795 // WebRequestSetRequestHeaderAction | |
796 // | |
797 | |
798 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( | |
799 const std::string& name, | |
800 const std::string& value) | |
801 : WebRequestAction(ON_BEFORE_SEND_HEADERS, | |
802 ACTION_SET_REQUEST_HEADER, | |
803 std::numeric_limits<int>::min(), | |
804 STRATEGY_DEFAULT), | |
805 name_(name), | |
806 value_(value) {} | |
807 | |
808 WebRequestSetRequestHeaderAction::~WebRequestSetRequestHeaderAction() {} | |
809 | |
810 bool WebRequestSetRequestHeaderAction::Equals( | |
811 const WebRequestAction* other) const { | |
812 if (!WebRequestAction::Equals(other)) | |
813 return false; | |
814 const WebRequestSetRequestHeaderAction* casted_other = | |
815 static_cast<const WebRequestSetRequestHeaderAction*>(other); | |
816 return name_ == casted_other->name_ && value_ == casted_other->value_; | |
817 } | |
818 | |
819 std::string WebRequestSetRequestHeaderAction::GetName() const { | |
820 return keys::kSetRequestHeaderType; | |
821 } | |
822 | |
823 | |
824 LinkedPtrEventResponseDelta | |
825 WebRequestSetRequestHeaderAction::CreateDelta( | |
826 const WebRequestData& request_data, | |
827 const std::string& extension_id, | |
828 const base::Time& extension_install_time) const { | |
829 CHECK(request_data.stage & stages()); | |
830 LinkedPtrEventResponseDelta result( | |
831 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
832 result->modified_request_headers.SetHeader(name_, value_); | |
833 return result; | |
834 } | |
835 | |
836 // | |
837 // WebRequestRemoveRequestHeaderAction | |
838 // | |
839 | |
840 WebRequestRemoveRequestHeaderAction::WebRequestRemoveRequestHeaderAction( | |
841 const std::string& name) | |
842 : WebRequestAction(ON_BEFORE_SEND_HEADERS, | |
843 ACTION_REMOVE_REQUEST_HEADER, | |
844 std::numeric_limits<int>::min(), | |
845 STRATEGY_DEFAULT), | |
846 name_(name) {} | |
847 | |
848 WebRequestRemoveRequestHeaderAction::~WebRequestRemoveRequestHeaderAction() {} | |
849 | |
850 bool WebRequestRemoveRequestHeaderAction::Equals( | |
851 const WebRequestAction* other) const { | |
852 if (!WebRequestAction::Equals(other)) | |
853 return false; | |
854 const WebRequestRemoveRequestHeaderAction* casted_other = | |
855 static_cast<const WebRequestRemoveRequestHeaderAction*>(other); | |
856 return name_ == casted_other->name_; | |
857 } | |
858 | |
859 std::string WebRequestRemoveRequestHeaderAction::GetName() const { | |
860 return keys::kRemoveRequestHeaderType; | |
861 } | |
862 | |
863 LinkedPtrEventResponseDelta | |
864 WebRequestRemoveRequestHeaderAction::CreateDelta( | |
865 const WebRequestData& request_data, | |
866 const std::string& extension_id, | |
867 const base::Time& extension_install_time) const { | |
868 CHECK(request_data.stage & stages()); | |
869 LinkedPtrEventResponseDelta result( | |
870 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
871 result->deleted_request_headers.push_back(name_); | |
872 return result; | |
873 } | |
874 | |
875 // | |
876 // WebRequestAddResponseHeaderAction | |
877 // | |
878 | |
879 WebRequestAddResponseHeaderAction::WebRequestAddResponseHeaderAction( | |
880 const std::string& name, | |
881 const std::string& value) | |
882 : WebRequestAction(ON_HEADERS_RECEIVED, | |
883 ACTION_ADD_RESPONSE_HEADER, | |
884 std::numeric_limits<int>::min(), | |
885 STRATEGY_DEFAULT), | |
886 name_(name), | |
887 value_(value) {} | |
888 | |
889 WebRequestAddResponseHeaderAction::~WebRequestAddResponseHeaderAction() {} | |
890 | |
891 bool WebRequestAddResponseHeaderAction::Equals( | |
892 const WebRequestAction* other) const { | |
893 if (!WebRequestAction::Equals(other)) | |
894 return false; | |
895 const WebRequestAddResponseHeaderAction* casted_other = | |
896 static_cast<const WebRequestAddResponseHeaderAction*>(other); | |
897 return name_ == casted_other->name_ && value_ == casted_other->value_; | |
898 } | |
899 | |
900 std::string WebRequestAddResponseHeaderAction::GetName() const { | |
901 return keys::kAddResponseHeaderType; | |
902 } | |
903 | |
904 LinkedPtrEventResponseDelta | |
905 WebRequestAddResponseHeaderAction::CreateDelta( | |
906 const WebRequestData& request_data, | |
907 const std::string& extension_id, | |
908 const base::Time& extension_install_time) const { | |
909 CHECK(request_data.stage & stages()); | |
910 const net::HttpResponseHeaders* headers = | |
911 request_data.original_response_headers; | |
912 if (!headers) | |
913 return LinkedPtrEventResponseDelta(NULL); | |
914 | |
915 // Don't generate the header if it exists already. | |
916 if (headers->HasHeaderValue(name_, value_)) | |
917 return LinkedPtrEventResponseDelta(NULL); | |
918 | |
919 LinkedPtrEventResponseDelta result( | |
920 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
921 result->added_response_headers.push_back(make_pair(name_, value_)); | |
922 return result; | |
923 } | |
924 | |
925 // | |
926 // WebRequestRemoveResponseHeaderAction | |
927 // | |
928 | |
929 WebRequestRemoveResponseHeaderAction::WebRequestRemoveResponseHeaderAction( | |
930 const std::string& name, | |
931 const std::string& value, | |
932 bool has_value) | |
933 : WebRequestAction(ON_HEADERS_RECEIVED, | |
934 ACTION_REMOVE_RESPONSE_HEADER, | |
935 std::numeric_limits<int>::min(), | |
936 STRATEGY_DEFAULT), | |
937 name_(name), | |
938 value_(value), | |
939 has_value_(has_value) {} | |
940 | |
941 WebRequestRemoveResponseHeaderAction::~WebRequestRemoveResponseHeaderAction() {} | |
942 | |
943 bool WebRequestRemoveResponseHeaderAction::Equals( | |
944 const WebRequestAction* other) const { | |
945 if (!WebRequestAction::Equals(other)) | |
946 return false; | |
947 const WebRequestRemoveResponseHeaderAction* casted_other = | |
948 static_cast<const WebRequestRemoveResponseHeaderAction*>(other); | |
949 return name_ == casted_other->name_ && value_ == casted_other->value_ && | |
950 has_value_ == casted_other->has_value_; | |
951 } | |
952 | |
953 std::string WebRequestRemoveResponseHeaderAction::GetName() const { | |
954 return keys::kRemoveResponseHeaderType; | |
955 } | |
956 | |
957 LinkedPtrEventResponseDelta | |
958 WebRequestRemoveResponseHeaderAction::CreateDelta( | |
959 const WebRequestData& request_data, | |
960 const std::string& extension_id, | |
961 const base::Time& extension_install_time) const { | |
962 CHECK(request_data.stage & stages()); | |
963 const net::HttpResponseHeaders* headers = | |
964 request_data.original_response_headers; | |
965 if (!headers) | |
966 return LinkedPtrEventResponseDelta(NULL); | |
967 | |
968 LinkedPtrEventResponseDelta result( | |
969 new helpers::EventResponseDelta(extension_id, extension_install_time)); | |
970 void* iter = NULL; | |
971 std::string current_value; | |
972 while (headers->EnumerateHeader(&iter, name_, ¤t_value)) { | |
973 if (has_value_ && | |
974 (current_value.size() != value_.size() || | |
975 !std::equal(current_value.begin(), current_value.end(), | |
976 value_.begin(), | |
977 base::CaseInsensitiveCompare<char>()))) { | |
978 continue; | |
979 } | |
980 result->deleted_response_headers.push_back(make_pair(name_, current_value)); | |
981 } | |
982 return result; | |
983 } | |
984 | |
985 // | |
986 // WebRequestIgnoreRulesAction | |
987 // | |
988 | |
989 WebRequestIgnoreRulesAction::WebRequestIgnoreRulesAction( | |
990 int minimum_priority, | |
991 const std::string& ignore_tag) | |
992 : WebRequestAction(ON_BEFORE_REQUEST | ON_BEFORE_SEND_HEADERS | | |
993 ON_HEADERS_RECEIVED | ON_AUTH_REQUIRED, | |
994 ACTION_IGNORE_RULES, | |
995 minimum_priority, | |
996 STRATEGY_NONE), | |
997 ignore_tag_(ignore_tag) {} | |
998 | |
999 WebRequestIgnoreRulesAction::~WebRequestIgnoreRulesAction() {} | |
1000 | |
1001 bool WebRequestIgnoreRulesAction::Equals(const WebRequestAction* other) const { | |
1002 if (!WebRequestAction::Equals(other)) | |
1003 return false; | |
1004 const WebRequestIgnoreRulesAction* casted_other = | |
1005 static_cast<const WebRequestIgnoreRulesAction*>(other); | |
1006 return minimum_priority() == casted_other->minimum_priority() && | |
1007 ignore_tag_ == casted_other->ignore_tag_; | |
1008 } | |
1009 | |
1010 std::string WebRequestIgnoreRulesAction::GetName() const { | |
1011 return keys::kIgnoreRulesType; | |
1012 } | |
1013 | |
1014 LinkedPtrEventResponseDelta WebRequestIgnoreRulesAction::CreateDelta( | |
1015 const WebRequestData& request_data, | |
1016 const std::string& extension_id, | |
1017 const base::Time& extension_install_time) const { | |
1018 CHECK(request_data.stage & stages()); | |
1019 return LinkedPtrEventResponseDelta(NULL); | |
1020 } | |
1021 | |
1022 // | |
1023 // WebRequestRequestCookieAction | |
1024 // | |
1025 | |
1026 WebRequestRequestCookieAction::WebRequestRequestCookieAction( | |
1027 linked_ptr<RequestCookieModification> request_cookie_modification) | |
1028 : WebRequestAction(ON_BEFORE_SEND_HEADERS, | |
1029 ACTION_MODIFY_REQUEST_COOKIE, | |
1030 std::numeric_limits<int>::min(), | |
1031 STRATEGY_DEFAULT), | |
1032 request_cookie_modification_(request_cookie_modification) { | |
1033 CHECK(request_cookie_modification_.get()); | |
1034 } | |
1035 | |
1036 WebRequestRequestCookieAction::~WebRequestRequestCookieAction() {} | |
1037 | |
1038 bool WebRequestRequestCookieAction::Equals( | |
1039 const WebRequestAction* other) const { | |
1040 if (!WebRequestAction::Equals(other)) | |
1041 return false; | |
1042 const WebRequestRequestCookieAction* casted_other = | |
1043 static_cast<const WebRequestRequestCookieAction*>(other); | |
1044 return helpers::NullableEquals( | |
1045 request_cookie_modification_.get(), | |
1046 casted_other->request_cookie_modification_.get()); | |
1047 } | |
1048 | |
1049 std::string WebRequestRequestCookieAction::GetName() const { | |
1050 switch (request_cookie_modification_->type) { | |
1051 case helpers::ADD: | |
1052 return keys::kAddRequestCookieType; | |
1053 case helpers::EDIT: | |
1054 return keys::kEditRequestCookieType; | |
1055 case helpers::REMOVE: | |
1056 return keys::kRemoveRequestCookieType; | |
1057 } | |
1058 NOTREACHED(); | |
1059 return ""; | |
1060 } | |
1061 | |
1062 LinkedPtrEventResponseDelta WebRequestRequestCookieAction::CreateDelta( | |
1063 const WebRequestData& request_data, | |
1064 const std::string& extension_id, | |
1065 const base::Time& extension_install_time) const { | |
1066 CHECK(request_data.stage & stages()); | |
1067 LinkedPtrEventResponseDelta result( | |
1068 new extension_web_request_api_helpers::EventResponseDelta( | |
1069 extension_id, extension_install_time)); | |
1070 result->request_cookie_modifications.push_back( | |
1071 request_cookie_modification_); | |
1072 return result; | |
1073 } | |
1074 | |
1075 // | |
1076 // WebRequestResponseCookieAction | |
1077 // | |
1078 | |
1079 WebRequestResponseCookieAction::WebRequestResponseCookieAction( | |
1080 linked_ptr<ResponseCookieModification> response_cookie_modification) | |
1081 : WebRequestAction(ON_HEADERS_RECEIVED, | |
1082 ACTION_MODIFY_RESPONSE_COOKIE, | |
1083 std::numeric_limits<int>::min(), | |
1084 STRATEGY_DEFAULT), | |
1085 response_cookie_modification_(response_cookie_modification) { | |
1086 CHECK(response_cookie_modification_.get()); | |
1087 } | |
1088 | |
1089 WebRequestResponseCookieAction::~WebRequestResponseCookieAction() {} | |
1090 | |
1091 bool WebRequestResponseCookieAction::Equals( | |
1092 const WebRequestAction* other) const { | |
1093 if (!WebRequestAction::Equals(other)) | |
1094 return false; | |
1095 const WebRequestResponseCookieAction* casted_other = | |
1096 static_cast<const WebRequestResponseCookieAction*>(other); | |
1097 return helpers::NullableEquals( | |
1098 response_cookie_modification_.get(), | |
1099 casted_other->response_cookie_modification_.get()); | |
1100 } | |
1101 | |
1102 std::string WebRequestResponseCookieAction::GetName() const { | |
1103 switch (response_cookie_modification_->type) { | |
1104 case helpers::ADD: | |
1105 return keys::kAddResponseCookieType; | |
1106 case helpers::EDIT: | |
1107 return keys::kEditResponseCookieType; | |
1108 case helpers::REMOVE: | |
1109 return keys::kRemoveResponseCookieType; | |
1110 } | |
1111 NOTREACHED(); | |
1112 return ""; | |
1113 } | |
1114 | |
1115 LinkedPtrEventResponseDelta WebRequestResponseCookieAction::CreateDelta( | |
1116 const WebRequestData& request_data, | |
1117 const std::string& extension_id, | |
1118 const base::Time& extension_install_time) const { | |
1119 CHECK(request_data.stage & stages()); | |
1120 LinkedPtrEventResponseDelta result( | |
1121 new extension_web_request_api_helpers::EventResponseDelta( | |
1122 extension_id, extension_install_time)); | |
1123 result->response_cookie_modifications.push_back( | |
1124 response_cookie_modification_); | |
1125 return result; | |
1126 } | |
1127 | |
1128 // | |
1129 // WebRequestSendMessageToExtensionAction | |
1130 // | |
1131 | |
1132 WebRequestSendMessageToExtensionAction::WebRequestSendMessageToExtensionAction( | |
1133 const std::string& message) | |
1134 : WebRequestAction(ON_BEFORE_REQUEST | ON_BEFORE_SEND_HEADERS | | |
1135 ON_HEADERS_RECEIVED | ON_AUTH_REQUIRED, | |
1136 ACTION_SEND_MESSAGE_TO_EXTENSION, | |
1137 std::numeric_limits<int>::min(), | |
1138 STRATEGY_HOST), | |
1139 message_(message) {} | |
1140 | |
1141 WebRequestSendMessageToExtensionAction:: | |
1142 ~WebRequestSendMessageToExtensionAction() {} | |
1143 | |
1144 bool WebRequestSendMessageToExtensionAction::Equals( | |
1145 const WebRequestAction* other) const { | |
1146 if (!WebRequestAction::Equals(other)) | |
1147 return false; | |
1148 const WebRequestSendMessageToExtensionAction* casted_other = | |
1149 static_cast<const WebRequestSendMessageToExtensionAction*>(other); | |
1150 return message_ == casted_other->message_; | |
1151 } | |
1152 | |
1153 std::string WebRequestSendMessageToExtensionAction::GetName() const { | |
1154 return keys::kSendMessageToExtensionType; | |
1155 } | |
1156 | |
1157 LinkedPtrEventResponseDelta WebRequestSendMessageToExtensionAction::CreateDelta( | |
1158 const WebRequestData& request_data, | |
1159 const std::string& extension_id, | |
1160 const base::Time& extension_install_time) const { | |
1161 CHECK(request_data.stage & stages()); | |
1162 LinkedPtrEventResponseDelta result( | |
1163 new extension_web_request_api_helpers::EventResponseDelta( | |
1164 extension_id, extension_install_time)); | |
1165 result->messages_to_extension.insert(message_); | |
1166 return result; | |
1167 } | |
1168 | |
1169 } // namespace extensions | |
OLD | NEW |