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 229e5534a3f0d044ba02014896c90f250ffb816d..c2fc061ae7ce0028c48157a4be845fcf6ba6efc4 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" |
@@ -46,14 +48,21 @@ |
#include "grit/generated_resources.h" |
#include "net/base/auth.h" |
#include "net/base/net_errors.h" |
+#include "net/base/upload_data.h" |
+#include "net/base/upload_element.h" |
#include "net/http/http_response_headers.h" |
#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; |
@@ -64,7 +73,7 @@ namespace web_request = extensions::api::web_request; |
namespace { |
// List of all the webRequest events. |
-static const char* const kWebRequestEvents[] = { |
+const char* const kWebRequestEvents[] = { |
keys::kOnBeforeRedirect, |
keys::kOnBeforeRequest, |
keys::kOnBeforeSendHeaders, |
@@ -78,6 +87,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. |
battre
2012/09/09 22:08:35
where is this caching? I don't understand why we c
vabr (Chromium)
2012/09/12 11:18:08
Thanks for catching that. The comment was obsolete
|
+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); |
@@ -158,6 +174,44 @@ 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. |
battre
2012/09/09 22:08:35
"ordered by being interesting"? grammar and what d
vabr (Chromium)
2012/09/12 11:18:08
I refined that comment, and also corrected the two
|
+ extensions::RawDataPresenter raw_data_presenter; |
+ extensions::ParsedDataPresenter parsed_data_presenter(request); |
battre
2012/09/09 22:08:35
nit: swap previous two lines?
vabr (Chromium)
2012/09/12 11:18:08
Done.
|
+ extensions::UploadDataPresenter* const presenters[] = { |
+ &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::kRequestBodyFormDataKey, |
+ keys::kRequestBodyRawKey |
+ }; |
+ |
+ const std::vector<net::UploadElement>* elements = |
+ request->get_upload()->elements(); |
+ bool some_succeeded = false; |
+ for (size_t i = 0; !some_succeeded && i < arraysize(presenters); ++i) { |
+ std::vector<net::UploadElement>::const_iterator element; |
+ for (element = elements->begin(); element != elements->end(); ++element) |
+ presenters[i]->FeedNext(*element); |
+ if (presenters[i]->Succeeded()) { |
+ requestBody->Set(kKeys[i], presenters[i]->Result().release()); |
+ some_succeeded = true; |
+ } |
+ } |
+ if (!some_succeeded) |
+ requestBody->SetString(keys::kRequestBodyErrorKey, "Unknown error."); |
+} |
+ |
// Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns |
// true if successful. |
bool FromHeaderDictionary(const DictionaryValue* header_value, |
@@ -406,6 +460,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; |
@@ -496,6 +553,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 |= |