Chromium Code Reviews| Index: chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc |
| diff --git a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc |
| index 271afc1d9bbf284899aa2e65271fee9d1010156d..39223410c7aacf759c2f5132cb948a47fb63a10d 100644 |
| --- a/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc |
| +++ b/chrome/browser/extensions/api/declarative_webrequest/webrequest_action.cc |
| @@ -10,6 +10,7 @@ |
| #include "base/logging.h" |
| #include "base/stringprintf.h" |
| #include "base/string_util.h" |
| +#include "base/utf_string_conversions.h" |
| #include "base/values.h" |
| #include "chrome/browser/extensions/api/declarative_webrequest/request_stages.h" |
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_constants.h" |
| @@ -58,6 +59,28 @@ scoped_ptr<WebRequestAction> CreateRedirectRequestAction( |
| new WebRequestRedirectAction(redirect_url)); |
| } |
| +scoped_ptr<WebRequestAction> CreateRedirectRequestByRegExAction( |
| + const base::DictionaryValue* dict, |
| + std::string* error, |
| + bool* bad_message) { |
| + std::string from; |
| + std::string to; |
| + INPUT_FORMAT_VALIDATE(dict->GetString(keys::kFromKey, &from)); |
| + INPUT_FORMAT_VALIDATE(dict->GetString(keys::kToKey, &to)); |
| + |
| + UParseError parse_error; |
| + UErrorCode status = U_ZERO_ERROR; |
| + scoped_ptr<icu::RegexPattern> pattern( |
| + 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
|
| + 0, parse_error, status)); |
| + if (U_FAILURE(status) || !pattern.get()) { |
| + *error = "Invalid pattern '" + from + "' -> '" + to + "'"; |
| + return scoped_ptr<WebRequestAction>(NULL); |
| + } |
| + return scoped_ptr<WebRequestAction>( |
| + new WebRequestRedirectByRegExAction(pattern.Pass(), to)); |
| +} |
| + |
| scoped_ptr<WebRequestAction> CreateSetRequestHeaderAction( |
| const base::DictionaryValue* dict, |
| std::string* error, |
| @@ -132,6 +155,8 @@ struct WebRequestActionFactory { |
| &CreateAddResponseHeaderAction; |
| factory_methods[keys::kCancelRequestType] = |
| &CallConstructorFactoryMethod<WebRequestCancelAction>; |
| + factory_methods[keys::kRedirectByRegExType] = |
| + &CreateRedirectRequestByRegExAction; |
| factory_methods[keys::kRedirectRequestType] = |
| &CreateRedirectRequestAction; |
| factory_methods[keys::kRedirectToTransparentImageType] = |
| @@ -384,6 +409,61 @@ WebRequestRedirectToEmptyDocumentAction::CreateDelta( |
| } |
| // |
| +// WebRequestRedirectByRegExAction |
| +// |
| + |
| +WebRequestRedirectByRegExAction::WebRequestRedirectByRegExAction( |
| + scoped_ptr<icu::RegexPattern> from_pattern, |
| + const std::string& to_pattern) |
| + : from_pattern_(from_pattern.Pass()), |
| + 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.
|
| + |
| +WebRequestRedirectByRegExAction::~WebRequestRedirectByRegExAction() {} |
| + |
| +int WebRequestRedirectByRegExAction::GetStages() const { |
| + return ON_BEFORE_REQUEST; |
| +} |
| + |
| +WebRequestAction::Type WebRequestRedirectByRegExAction::GetType() const { |
| + return WebRequestAction::ACTION_REDIRECT_BY_REGEX_DOCUMENT; |
| +} |
| + |
| +LinkedPtrEventResponseDelta WebRequestRedirectByRegExAction::CreateDelta( |
| + net::URLRequest* request, |
| + RequestStages request_stage, |
| + const WebRequestRule::OptionalRequestData& optional_request_data, |
| + const std::string& extension_id, |
| + const base::Time& extension_install_time) const { |
| + CHECK(request_stage & GetStages()); |
| + CHECK(from_pattern_.get()); |
| + |
| + UErrorCode status = U_ZERO_ERROR; |
| + const std::string& old_url = request->url().spec(); |
| + icu::UnicodeString old_url_unicode(old_url.c_str(), old_url.size()); |
| + |
| + scoped_ptr<icu::RegexMatcher> matcher( |
| + from_pattern_->matcher(old_url_unicode, status)); |
| + if (U_FAILURE(status) || !matcher.get()) |
| + return LinkedPtrEventResponseDelta(NULL); |
| + |
| + icu::UnicodeString new_url = matcher->replaceAll(to_pattern_, status); |
| + if (U_FAILURE(status)) |
| + return LinkedPtrEventResponseDelta(NULL); |
| + |
| + std::string new_url_utf8; |
| + UTF16ToUTF8(new_url.getBuffer(), new_url.length(), &new_url_utf8); |
| + |
| + if (new_url_utf8 == request->url().spec()) |
| + return LinkedPtrEventResponseDelta(NULL); |
| + |
| + LinkedPtrEventResponseDelta result( |
| + new extension_web_request_api_helpers::EventResponseDelta( |
| + extension_id, extension_install_time)); |
| + result->new_url = GURL(new_url_utf8); |
| + return result; |
| +} |
| + |
| +// |
| // WebRequestSetRequestHeaderAction |
| // |
| @@ -485,19 +565,18 @@ WebRequestAddResponseHeaderAction::CreateDelta( |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const { |
| CHECK(request_stage & GetStages()); |
| - LinkedPtrEventResponseDelta result( |
| - new extension_web_request_api_helpers::EventResponseDelta( |
| - extension_id, extension_install_time)); |
| - |
| net::HttpResponseHeaders* headers = |
| optional_request_data.original_response_headers; |
| if (!headers) |
| - return result; |
| + return LinkedPtrEventResponseDelta(NULL); |
| // Don't generate the header if it exists already. |
| if (headers->HasHeaderValue(name_, value_)) |
| - return result; |
| + return LinkedPtrEventResponseDelta(NULL); |
| + LinkedPtrEventResponseDelta result( |
| + new extension_web_request_api_helpers::EventResponseDelta( |
| + extension_id, extension_install_time)); |
| result->added_response_headers.push_back(make_pair(name_, value_)); |
| return result; |
| } |
| @@ -534,13 +613,14 @@ WebRequestRemoveResponseHeaderAction::CreateDelta( |
| const std::string& extension_id, |
| const base::Time& extension_install_time) const { |
| CHECK(request_stage & GetStages()); |
| - LinkedPtrEventResponseDelta result( |
| - new extension_web_request_api_helpers::EventResponseDelta( |
| - extension_id, extension_install_time)); |
| net::HttpResponseHeaders* headers = |
| optional_request_data.original_response_headers; |
| if (!headers) |
| - return result; |
| + return LinkedPtrEventResponseDelta(NULL); |
| + |
| + LinkedPtrEventResponseDelta result( |
| + new extension_web_request_api_helpers::EventResponseDelta( |
| + extension_id, extension_install_time)); |
| void* iter = NULL; |
| std::string current_value; |
| while (headers->EnumerateHeader(&iter, name_, ¤t_value)) { |