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 2019494bf36a5895d66edded30aa55dcd85545d1..e75f20dca271be69aef1dbe2dbaefae0469b8e35 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/post_data_parser.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" |
@@ -45,6 +46,7 @@ |
#include "grit/generated_resources.h" |
#include "net/base/auth.h" |
#include "net/base/net_errors.h" |
+#include "net/base/upload_data.h" |
#include "net/http/http_response_headers.h" |
#include "net/url_request/url_request.h" |
#include "ui/base/l10n/l10n_util.h" |
@@ -76,6 +78,15 @@ static const char* const kWebRequestEvents[] = { |
#define ARRAYEND(array) (array + arraysize(array)) |
+// Returns the frame ID as it will be passed to the extension: |
+// 0 if the navigation happens in the main frame, or the frame ID |
+// modulo 32 bits otherwise. |
+// Keep this in sync with the GetFrameId() function in |
+// extension_webnavigation_api.cc. |
+int GetFrameId(bool is_main_frame, int64 frame_id) { |
+ return is_main_frame ? 0 : static_cast<int>(frame_id); |
+} |
+ |
bool IsWebRequestEvent(const std::string& event_name) { |
return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), |
event_name) != ARRAYEND(kWebRequestEvents); |
@@ -156,6 +167,54 @@ void ExtractRequestInfo(net::URLRequest* request, DictionaryValue* out) { |
out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); |
} |
+// Takes |dictionary| of <string, list of strings> pairs, and gets the list |
+// for |key|, creating it if necessary. |
+ListValue* GetOrCreateList(DictionaryValue* dictionary, |
+ const std::string& key) { |
+ ListValue* list = NULL; |
+ if (!dictionary->GetList(key, &list)) { |
+ list = new ListValue(); |
+ dictionary->Set(key, list); |
+ } |
+ return list; |
+} |
+ |
+// Extracts the POST data from |request| and writes the data into |out|. |
+// This can be expensive, so it's separated from ExtractRequestInfo(). |
+// Contract: request->method() == "POST" |
+void ExtractRequestInfoPost(net::URLRequest* request, DictionaryValue* out) { |
+ const std::vector<net::UploadData::Element>* elements = |
+ request->get_upload()->elements(); |
+ scoped_ptr<extensions::PostDataParser> parser = |
+ extensions::PostDataParser::CreatePostDataParser(request); |
+ if (parser.get() == NULL) { |
+ // No parser means most probably unsupported form encoding. |
+ return; |
+ } |
+ scoped_ptr<DictionaryValue> post_data(new DictionaryValue()); |
Matt Perry
2012/07/23 21:19:01
The rest of this function seems like it should be
vabr (Chromium)
2012/07/30 16:05:57
Fair point, I tried to move as much as I felt is i
|
+ scoped_ptr<DictionaryValue> form_data(new DictionaryValue()); |
+ std::vector<net::UploadData::Element>::const_iterator element; |
+ bool data_valid = true; |
+ for (element = elements->begin(); |
+ data_valid && element != elements->end(); ++element) { |
+ if (element->type() != net::UploadData::TYPE_BYTES) { |
+ // We do not handle data including blobs or chunks. |
+ if (element->type() != net::UploadData::TYPE_FILE) |
+ data_valid = false; |
+ continue; |
+ } |
+ if (!parser->SetSource(&(element->bytes()))) continue; |
+ extensions::PostDataParser::Result result; |
+ while (parser->GetNextPair(&result)) { |
+ GetOrCreateList(form_data.get(), result.get_key())->Append( |
+ new StringValue(result.get_val())); |
+ } |
+ } |
+ if (data_valid && parser->AllDataReadOK()) |
+ post_data->Set(keys::kFormDataKey, form_data.release()); |
+ out->Set(keys::kPostDataKey, post_data.release()); |
+} |
+ |
// Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns |
// true if successful. |
bool FromHeaderDictionary(const DictionaryValue* header_value, |
@@ -408,6 +467,8 @@ bool ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
*extra_info_spec |= BLOCKING; |
else if (str == "asyncBlocking") |
*extra_info_spec |= ASYNC_BLOCKING; |
+ else if (str == "requestPostData") |
+ *extra_info_spec |= REQUEST_POST_DATA; |
else |
return false; |
@@ -493,6 +554,9 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest( |
ListValue args; |
DictionaryValue* dict = new DictionaryValue(); |
ExtractRequestInfo(request, dict); |
+ if (extra_info_spec & ExtraInfoSpec::REQUEST_POST_DATA && |
+ request->method() == "POST") |
+ ExtractRequestInfoPost(request, dict); |
args.Append(dict); |
initialize_blocked_requests |= |