Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action .h" | 5 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_action .h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/stringprintf.h" | 11 #include "base/stringprintf.h" |
| 12 #include "base/string_util.h" | 12 #include "base/string_util.h" |
| 13 #include "base/utf_string_conversions.h" | |
| 13 #include "base/values.h" | 14 #include "base/values.h" |
| 14 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" | 15 #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" |
| 15 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" | 16 #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_consta nts.h" |
| 16 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" | 17 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
| 17 #include "net/url_request/url_request.h" | 18 #include "net/url_request/url_request.h" |
| 18 | 19 |
| 19 namespace extensions { | 20 namespace extensions { |
| 20 | 21 |
| 21 namespace keys = declarative_webrequest_constants; | 22 namespace keys = declarative_webrequest_constants; |
| 22 | 23 |
| (...skipping 28 matching lines...) Expand all Loading... | |
| 51 std::string* error, | 52 std::string* error, |
| 52 bool* bad_message) { | 53 bool* bad_message) { |
| 53 std::string redirect_url_string; | 54 std::string redirect_url_string; |
| 54 INPUT_FORMAT_VALIDATE( | 55 INPUT_FORMAT_VALIDATE( |
| 55 dict->GetString(keys::kRedirectUrlKey, &redirect_url_string)); | 56 dict->GetString(keys::kRedirectUrlKey, &redirect_url_string)); |
| 56 GURL redirect_url(redirect_url_string); | 57 GURL redirect_url(redirect_url_string); |
| 57 return scoped_ptr<WebRequestAction>( | 58 return scoped_ptr<WebRequestAction>( |
| 58 new WebRequestRedirectAction(redirect_url)); | 59 new WebRequestRedirectAction(redirect_url)); |
| 59 } | 60 } |
| 60 | 61 |
| 62 scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( | |
| 63 const base::DictionaryValue* dict, | |
| 64 std::string* error, | |
| 65 bool* bad_message) { | |
| 66 std::string from; | |
| 67 std::string to; | |
| 68 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); | |
| 69 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kToKey, &to)); | |
| 70 | |
| 71 UParseError parse_error; | |
| 72 UErrorCode status = U_ZERO_ERROR; | |
| 73 scoped_ptr<icu::RegexPattern> pattern( | |
| 74 icu::RegexPattern::compile(icu::UnicodeString(from.c_str(), from.size()), | |
|
Matt Perry
2012/05/30 18:55:50
I thought the consensus on the thread was to evalu
battre
2012/05/31 16:01:32
As discussed, we will change this to RE2 before re
| |
| 75 0, parse_error, status)); | |
| 76 if (U_FAILURE(status) || !pattern.get()) { | |
| 77 *error = "Invalid pattern '" + from + "' -> '" + to + "'"; | |
| 78 return scoped_ptr<WebRequestAction>(NULL); | |
| 79 } | |
| 80 return scoped_ptr<WebRequestAction>( | |
| 81 new WebRequestRedirectByRegExAction(pattern.Pass(), to)); | |
| 82 } | |
| 83 | |
| 61 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( | 84 scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( |
| 62 const base::DictionaryValue* dict, | 85 const base::DictionaryValue* dict, |
| 63 std::string* error, | 86 std::string* error, |
| 64 bool* bad_message) { | 87 bool* bad_message) { |
| 65 std::string name; | 88 std::string name; |
| 66 std::string value; | 89 std::string value; |
| 67 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); | 90 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kNameKey, &name)); |
| 68 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); | 91 INPUT_FORMAT_VALIDATE(dict->GetString(keys::kValueKey, &value)); |
| 69 return scoped_ptr<WebRequestAction>( | 92 return scoped_ptr<WebRequestAction>( |
| 70 new WebRequestSetRequestHeaderAction(name, value)); | 93 new WebRequestSetRequestHeaderAction(name, value)); |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 125 (* FactoryMethod)(const base::DictionaryValue* /* dict */ , | 148 (* FactoryMethod)(const base::DictionaryValue* /* dict */ , |
| 126 std::string* /* error */, | 149 std::string* /* error */, |
| 127 bool* /* bad_message */); | 150 bool* /* bad_message */); |
| 128 std::map<std::string, FactoryMethod> factory_methods; | 151 std::map<std::string, FactoryMethod> factory_methods; |
| 129 | 152 |
| 130 WebRequestActionFactory() { | 153 WebRequestActionFactory() { |
| 131 factory_methods[keys::kAddResponseHeaderType] = | 154 factory_methods[keys::kAddResponseHeaderType] = |
| 132 &CreateAddResponseHeaderAction; | 155 &CreateAddResponseHeaderAction; |
| 133 factory_methods[keys::kCancelRequestType] = | 156 factory_methods[keys::kCancelRequestType] = |
| 134 &CallConstructorFactoryMethod<WebRequestCancelAction>; | 157 &CallConstructorFactoryMethod<WebRequestCancelAction>; |
| 158 factory_methods[keys::kRedirectByRegExType] = | |
| 159 &CreateRedirectRequestByRegExAction; | |
| 135 factory_methods[keys::kRedirectRequestType] = | 160 factory_methods[keys::kRedirectRequestType] = |
| 136 &CreateRedirectRequestAction; | 161 &CreateRedirectRequestAction; |
| 137 factory_methods[keys::kRedirectToTransparentImageType] = | 162 factory_methods[keys::kRedirectToTransparentImageType] = |
| 138 &CallConstructorFactoryMethod< | 163 &CallConstructorFactoryMethod< |
| 139 WebRequestRedirectToTransparentImageAction>; | 164 WebRequestRedirectToTransparentImageAction>; |
| 140 factory_methods[keys::kRedirectToEmptyDocumentType] = | 165 factory_methods[keys::kRedirectToEmptyDocumentType] = |
| 141 &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>; | 166 &CallConstructorFactoryMethod<WebRequestRedirectToEmptyDocumentAction>; |
| 142 factory_methods[keys::kSetRequestHeaderType] = | 167 factory_methods[keys::kSetRequestHeaderType] = |
| 143 &CreateSetRequestHeaderAction; | 168 &CreateSetRequestHeaderAction; |
| 144 factory_methods[keys::kRemoveRequestHeaderType] = | 169 factory_methods[keys::kRemoveRequestHeaderType] = |
| (...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 377 const base::Time& extension_install_time) const { | 402 const base::Time& extension_install_time) const { |
| 378 CHECK(request_stage & GetStages()); | 403 CHECK(request_stage & GetStages()); |
| 379 LinkedPtrEventResponseDelta result( | 404 LinkedPtrEventResponseDelta result( |
| 380 new extension_web_request_api_helpers::EventResponseDelta( | 405 new extension_web_request_api_helpers::EventResponseDelta( |
| 381 extension_id, extension_install_time)); | 406 extension_id, extension_install_time)); |
| 382 result->new_url = GURL(kEmptyDocumentUrl); | 407 result->new_url = GURL(kEmptyDocumentUrl); |
| 383 return result; | 408 return result; |
| 384 } | 409 } |
| 385 | 410 |
| 386 // | 411 // |
| 412 // WebRequestRedirectByRegExAction | |
| 413 // | |
| 414 | |
| 415 WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( | |
| 416 scoped_ptr<icu::RegexPattern> from_pattern, | |
| 417 const std::string& to_pattern) | |
| 418 : from_pattern_(from_pattern.Pass()), | |
| 419 to_pattern_(to_pattern.c_str(), to_pattern.size()) {} | |
|
Matt Perry
2012/05/30 19:18:26
nit: prefer data() instead of c_str() when you're
battre
2012/05/31 16:01:32
Done.
| |
| 420 | |
| 421 WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} | |
| 422 | |
| 423 int WebRequestRedirectByRegExAction::GetStages() const { | |
| 424 return ON_BEFORE_REQUEST; | |
| 425 } | |
| 426 | |
| 427 WebRequestAction::Type WebRequestRedirectByRegExAction::GetType() const { | |
| 428 return WebRequestAction::ACTION_REDIRECT_BY_REGEX_DOCUMENT; | |
| 429 } | |
| 430 | |
| 431 LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( | |
| 432 net::URLRequest* request, | |
| 433 RequestStages request_stage, | |
| 434 const WebRequestRule::OptionalRequestData& optional_request_data, | |
| 435 const std::string& extension_id, | |
| 436 const base::Time& extension_install_time) const { | |
| 437 CHECK(request_stage & GetStages()); | |
| 438 CHECK(from_pattern_.get()); | |
| 439 | |
| 440 UErrorCode status = U_ZERO_ERROR; | |
| 441 const std::string& old_url = request->url().spec(); | |
| 442 icu::UnicodeString old_url_unicode(old_url.c_str(), old_url.size()); | |
| 443 | |
| 444 scoped_ptr<icu::RegexMatcher> matcher( | |
| 445 from_pattern_->matcher(old_url_unicode, status)); | |
| 446 if (U_FAILURE(status) || !matcher.get()) | |
| 447 return LinkedPtrEventResponseDelta(NULL); | |
| 448 | |
| 449 icu::UnicodeString new_url = matcher->replaceAll(to_pattern_, status); | |
| 450 if (U_FAILURE(status)) | |
| 451 return LinkedPtrEventResponseDelta(NULL); | |
| 452 | |
| 453 std::string new_url_utf8; | |
| 454 UTF16ToUTF8(new_url.getBuffer(), new_url.length(), &new_url_utf8); | |
| 455 | |
| 456 if (new_url_utf8 == request->url().spec()) | |
| 457 return LinkedPtrEventResponseDelta(NULL); | |
| 458 | |
| 459 LinkedPtrEventResponseDelta result( | |
| 460 new extension_web_request_api_helpers::EventResponseDelta( | |
| 461 extension_id, extension_install_time)); | |
| 462 result->new_url = GURL(new_url_utf8); | |
| 463 return result; | |
| 464 } | |
| 465 | |
| 466 // | |
| 387 // WebRequestSetRequestHeaderAction | 467 // WebRequestSetRequestHeaderAction |
| 388 // | 468 // |
| 389 | 469 |
| 390 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( | 470 WebRequestSetRequestHeaderAction::WebRequestSetRequestHeaderAction( |
| 391 const std::string& name, | 471 const std::string& name, |
| 392 const std::string& value) | 472 const std::string& value) |
| 393 : name_(name), | 473 : name_(name), |
| 394 value_(value) { | 474 value_(value) { |
| 395 } | 475 } |
| 396 | 476 |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 478 } | 558 } |
| 479 | 559 |
| 480 LinkedPtrEventResponseDelta | 560 LinkedPtrEventResponseDelta |
| 481 WebRequestAddResponseHeaderAction::CreateDelta( | 561 WebRequestAddResponseHeaderAction::CreateDelta( |
| 482 net::URLRequest* request, | 562 net::URLRequest* request, |
| 483 RequestStages request_stage, | 563 RequestStages request_stage, |
| 484 const WebRequestRule::OptionalRequestData& optional_request_data, | 564 const WebRequestRule::OptionalRequestData& optional_request_data, |
| 485 const std::string& extension_id, | 565 const std::string& extension_id, |
| 486 const base::Time& extension_install_time) const { | 566 const base::Time& extension_install_time) const { |
| 487 CHECK(request_stage & GetStages()); | 567 CHECK(request_stage & GetStages()); |
| 568 net::HttpResponseHeaders* headers = | |
| 569 optional_request_data.original_response_headers; | |
| 570 if (!headers) | |
| 571 return LinkedPtrEventResponseDelta(NULL); | |
| 572 | |
| 573 // Don't generate the header if it exists already. | |
| 574 if (headers->HasHeaderValue(name_, value_)) | |
| 575 return LinkedPtrEventResponseDelta(NULL); | |
| 576 | |
| 488 LinkedPtrEventResponseDelta result( | 577 LinkedPtrEventResponseDelta result( |
| 489 new extension_web_request_api_helpers::EventResponseDelta( | 578 new extension_web_request_api_helpers::EventResponseDelta( |
| 490 extension_id, extension_install_time)); | 579 extension_id, extension_install_time)); |
| 491 | |
| 492 net::HttpResponseHeaders* headers = | |
| 493 optional_request_data.original_response_headers; | |
| 494 if (!headers) | |
| 495 return result; | |
| 496 | |
| 497 // Don't generate the header if it exists already. | |
| 498 if (headers->HasHeaderValue(name_, value_)) | |
| 499 return result; | |
| 500 | |
| 501 result->added_response_headers.push_back(make_pair(name_, value_)); | 580 result->added_response_headers.push_back(make_pair(name_, value_)); |
| 502 return result; | 581 return result; |
| 503 } | 582 } |
| 504 | 583 |
| 505 // | 584 // |
| 506 // WebRequestRemoveResponseHeaderAction | 585 // WebRequestRemoveResponseHeaderAction |
| 507 // | 586 // |
| 508 | 587 |
| 509 WebRequestRemoveResponseHeaderAction::WebRequestRemoveResponseHeaderAction( | 588 WebRequestRemoveResponseHeaderAction::WebRequestRemoveResponseHeaderAction( |
| 510 const std::string& name, | 589 const std::string& name, |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 527 } | 606 } |
| 528 | 607 |
| 529 LinkedPtrEventResponseDelta | 608 LinkedPtrEventResponseDelta |
| 530 WebRequestRemoveResponseHeaderAction::CreateDelta( | 609 WebRequestRemoveResponseHeaderAction::CreateDelta( |
| 531 net::URLRequest* request, | 610 net::URLRequest* request, |
| 532 RequestStages request_stage, | 611 RequestStages request_stage, |
| 533 const WebRequestRule::OptionalRequestData& optional_request_data, | 612 const WebRequestRule::OptionalRequestData& optional_request_data, |
| 534 const std::string& extension_id, | 613 const std::string& extension_id, |
| 535 const base::Time& extension_install_time) const { | 614 const base::Time& extension_install_time) const { |
| 536 CHECK(request_stage & GetStages()); | 615 CHECK(request_stage & GetStages()); |
| 616 net::HttpResponseHeaders* headers = | |
| 617 optional_request_data.original_response_headers; | |
| 618 if (!headers) | |
| 619 return LinkedPtrEventResponseDelta(NULL); | |
| 620 | |
| 537 LinkedPtrEventResponseDelta result( | 621 LinkedPtrEventResponseDelta result( |
| 538 new extension_web_request_api_helpers::EventResponseDelta( | 622 new extension_web_request_api_helpers::EventResponseDelta( |
| 539 extension_id, extension_install_time)); | 623 extension_id, extension_install_time)); |
| 540 net::HttpResponseHeaders* headers = | |
| 541 optional_request_data.original_response_headers; | |
| 542 if (!headers) | |
| 543 return result; | |
| 544 void* iter = NULL; | 624 void* iter = NULL; |
| 545 std::string current_value; | 625 std::string current_value; |
| 546 while (headers->EnumerateHeader(&iter, name_, ¤t_value)) { | 626 while (headers->EnumerateHeader(&iter, name_, ¤t_value)) { |
| 547 if (has_value_ && | 627 if (has_value_ && |
| 548 (current_value.size() != value_.size() || | 628 (current_value.size() != value_.size() || |
| 549 !std::equal(current_value.begin(), current_value.end(), | 629 !std::equal(current_value.begin(), current_value.end(), |
| 550 value_.begin(), | 630 value_.begin(), |
| 551 base::CaseInsensitiveCompare<char>()))) { | 631 base::CaseInsensitiveCompare<char>()))) { |
| 552 continue; | 632 continue; |
| 553 } | 633 } |
| (...skipping 30 matching lines...) Expand all Loading... | |
| 584 net::URLRequest* request, | 664 net::URLRequest* request, |
| 585 RequestStages request_stage, | 665 RequestStages request_stage, |
| 586 const WebRequestRule::OptionalRequestData& optional_request_data, | 666 const WebRequestRule::OptionalRequestData& optional_request_data, |
| 587 const std::string& extension_id, | 667 const std::string& extension_id, |
| 588 const base::Time& extension_install_time) const { | 668 const base::Time& extension_install_time) const { |
| 589 CHECK(request_stage & GetStages()); | 669 CHECK(request_stage & GetStages()); |
| 590 return LinkedPtrEventResponseDelta(NULL); | 670 return LinkedPtrEventResponseDelta(NULL); |
| 591 } | 671 } |
| 592 | 672 |
| 593 } // namespace extensions | 673 } // namespace extensions |
| OLD | NEW |