| 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());
|
| + 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 |=
|
|
|