| 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 |