Chromium Code Reviews| Index: chrome/browser/extensions/api/web_request/web_request_api.cc |
| diff --git a/chrome/browser/extensions/api/web_request/web_request_api.cc b/chrome/browser/extensions/api/web_request/web_request_api.cc |
| index add3163d50af425b05dd7f48563cfdf616a1888e..2c46bc76043e60031114ffb9cde8b8af64ef287e 100644 |
| --- a/chrome/browser/extensions/api/web_request/web_request_api.cc |
| +++ b/chrome/browser/extensions/api/web_request/web_request_api.cc |
| @@ -19,6 +19,7 @@ |
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rule.h" |
| #include "chrome/browser/extensions/api/declarative_webrequest/webrequest_rules_registry.h" |
| #include "chrome/browser/extensions/api/web_navigation/web_navigation_api_helpers.h" |
| +#include "chrome/browser/extensions/api/web_request/upload_data_presenter.h" |
| #include "chrome/browser/extensions/api/web_request/web_request_api_constants.h" |
| #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h" |
| #include "chrome/browser/extensions/api/web_request/web_request_time_tracker.h" |
| @@ -36,6 +37,7 @@ |
| #include "chrome/common/extensions/extension_constants.h" |
| #include "chrome/common/extensions/extension_error_utils.h" |
| #include "chrome/common/extensions/extension_messages.h" |
| +#include "chrome/common/extensions/features/feature.h" |
| #include "chrome/common/extensions/url_pattern.h" |
| #include "chrome/common/url_constants.h" |
| #include "content/public/browser/browser_message_filter.h" |
| @@ -50,10 +52,15 @@ |
| #include "net/url_request/url_request.h" |
| #include "ui/base/l10n/l10n_util.h" |
| +using base::DictionaryValue; |
| +using base::ListValue; |
| +using base::StringValue; |
| +using chrome::VersionInfo; |
| using content::BrowserMessageFilter; |
| using content::BrowserThread; |
| using content::ResourceRequestInfo; |
| using extensions::Extension; |
| +using extensions::Feature; |
| using extensions::web_navigation_api_helpers::GetFrameId; |
| @@ -63,7 +70,7 @@ namespace keys = extension_web_request_api_constants; |
| namespace { |
| // List of all the webRequest events. |
| -static const char* const kWebRequestEvents[] = { |
| +const char* const kWebRequestEvents[] = { |
| keys::kOnBeforeRedirect, |
| keys::kOnBeforeRequest, |
| keys::kOnBeforeSendHeaders, |
| @@ -77,6 +84,13 @@ static const char* const kWebRequestEvents[] = { |
| #define ARRAYEND(array) (array + arraysize(array)) |
| +// Access to request body (crbug.com/91191/) is currently only enabled in dev |
| +// and canary channels. This function caches the release channel info from |
| +// chrome::VersionInfo. Don't use this outside IO thread. |
| +bool IsWebRequestBodyDataAccessEnabled() { |
| + return Feature::GetCurrentChannel() <= VersionInfo::CHANNEL_DEV; |
| +} |
| + |
| bool IsWebRequestEvent(const std::string& event_name) { |
| return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), |
| event_name) != ARRAYEND(kWebRequestEvents); |
| @@ -157,6 +171,49 @@ void ExtractRequestInfo(net::URLRequest* request, DictionaryValue* out) { |
| out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); |
| } |
| +// Extracts the body from |request| and writes the data into |out|. |
| +void ExtractRequestInfoBody(const net::URLRequest* request, |
| + DictionaryValue* out) { |
| + if (request->method() != "POST" && request->method() != "PUT") |
| + return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" . |
| + |
| + DictionaryValue* requestBody = new DictionaryValue(); |
| + out->Set(keys::kRequestBodyKey, requestBody); |
| + |
| + // Get the data presenters, ordered by being interesting. |
| + extensions::ChunkedErrorPresenter chunked_error_presenter(request); |
| + extensions::RawDataPresenter raw_data_presenter; |
| + extensions::ParsedDataPresenter parsed_data_presenter(request); |
| + extensions::UploadDataPresenter* const presenters[] = { |
| + &chunked_error_presenter, // First -- any errors? |
| + &parsed_data_presenter, // Second -- any parseable forms? |
| + &raw_data_presenter // Third -- any data at all? |
| + }; |
| + // Keys for the results of the corresponding presenters. |
| + static const char* const kKeys[] = { |
| + keys::kRequestBodyErrorKey, |
| + keys::kRequestBodyFormDataKey, |
| + keys::kRequestBodyRawKey |
| + }; |
| + |
| + const std::vector<net::UploadData::Element>* elements = |
| + request->get_upload()->elements(); |
| + bool some_succeeded = false; |
| + for (size_t i = 0; !some_succeeded && i < arraysize(presenters); ++i) { |
| + std::vector<net::UploadData::Element>::const_iterator element; |
| + for (element = elements->begin(); element != elements->end(); ++element) { |
| + presenters[i]->FeedNext(*element); |
| + } |
|
battre
2012/08/16 19:18:03
nit: no {}
vabr (Chromium)
2012/08/17 18:29:57
Done.
|
| + if (presenters[i]->Succeeded()) { |
|
battre
2012/08/16 19:18:03
This looks wrong to me. Most presenters call Abort
vabr (Chromium)
2012/08/17 18:29:57
This is by design, all the elements together repre
battre
2012/08/20 12:09:38
Nevermind, you are right. I misunderstood the loop
|
| + requestBody->Set(kKeys[i], presenters[i]->Result().release()); |
| + some_succeeded = true; |
| + } |
| + } |
| + if (!some_succeeded) { |
| + requestBody->SetString(keys::kRequestBodyErrorKey, "Unknown error."); |
| + } |
|
battre
2012/08/16 19:18:03
nit: no {}
vabr (Chromium)
2012/08/17 18:29:57
Done.
|
| +} |
| + |
| // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns |
| // true if successful. |
| bool FromHeaderDictionary(const DictionaryValue* header_value, |
| @@ -409,6 +466,9 @@ bool ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
| *extra_info_spec |= BLOCKING; |
| else if (str == "asyncBlocking") |
| *extra_info_spec |= ASYNC_BLOCKING; |
| + else if (str == "requestBody") |
| + *extra_info_spec |= |
| + IsWebRequestBodyDataAccessEnabled() ? REQUEST_BODY : 0; |
| else |
| return false; |
| @@ -498,6 +558,8 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest( |
| ListValue args; |
| DictionaryValue* dict = new DictionaryValue(); |
| ExtractRequestInfo(request, dict); |
| + if (extra_info_spec & ExtraInfoSpec::REQUEST_BODY) |
| + ExtractRequestInfoBody(request, dict); |
| args.Append(dict); |
| initialize_blocked_requests |= |