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