Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(139)

Side by Side Diff: chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc

Issue 10449069: Support redirects by regular expression in declarative WebRequest API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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_, &current_value)) { 626 while (headers->EnumerateHeader(&iter, name_, &current_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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698