| Index: extensions/browser/api/web_request/web_request_api.cc
|
| diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
|
| index b3855a303b61ae8f6ac8264661ec368839ca7564..76db07fe55227c27b68a4d37a37fc19722873318 100644
|
| --- a/extensions/browser/api/web_request/web_request_api.cc
|
| +++ b/extensions/browser/api/web_request/web_request_api.cc
|
| @@ -22,25 +22,22 @@
|
| #include "base/strings/utf_string_conversions.h"
|
| #include "base/time/time.h"
|
| #include "base/values.h"
|
| -#include "content/public/browser/browser_message_filter.h"
|
| #include "content/public/browser/browser_thread.h"
|
| -#include "content/public/browser/render_frame_host.h"
|
| -#include "content/public/browser/render_process_host.h"
|
| #include "content/public/browser/resource_request_info.h"
|
| #include "content/public/browser/user_metrics.h"
|
| +#include "content/public/common/child_process_host.h"
|
| #include "extensions/browser/api/activity_log/web_request_constants.h"
|
| #include "extensions/browser/api/declarative/rules_registry_service.h"
|
| #include "extensions/browser/api/declarative_webrequest/request_stage.h"
|
| #include "extensions/browser/api/declarative_webrequest/webrequest_constants.h"
|
| #include "extensions/browser/api/declarative_webrequest/webrequest_rules_registry.h"
|
| #include "extensions/browser/api/extensions_api_client.h"
|
| -#include "extensions/browser/api/web_request/upload_data_presenter.h"
|
| #include "extensions/browser/api/web_request/web_request_api_constants.h"
|
| #include "extensions/browser/api/web_request/web_request_api_helpers.h"
|
| +#include "extensions/browser/api/web_request/web_request_event_details.h"
|
| #include "extensions/browser/api/web_request/web_request_event_router_delegate.h"
|
| #include "extensions/browser/api/web_request/web_request_time_tracker.h"
|
| #include "extensions/browser/event_router.h"
|
| -#include "extensions/browser/extension_api_frame_id_map.h"
|
| #include "extensions/browser/extension_prefs.h"
|
| #include "extensions/browser/extension_registry.h"
|
| #include "extensions/browser/extension_system.h"
|
| @@ -63,20 +60,14 @@
|
| #include "extensions/strings/grit/extensions_strings.h"
|
| #include "net/base/auth.h"
|
| #include "net/base/net_errors.h"
|
| -#include "net/base/upload_data_stream.h"
|
| -#include "net/http/http_response_headers.h"
|
| #include "net/http/http_util.h"
|
| #include "net/url_request/url_request.h"
|
| #include "ui/base/l10n/l10n_util.h"
|
| #include "url/gurl.h"
|
|
|
| -using base::DictionaryValue;
|
| -using base::ListValue;
|
| -using base::StringValue;
|
| -using content::BrowserMessageFilter;
|
| using content::BrowserThread;
|
| using content::ResourceRequestInfo;
|
| -using content::ResourceType;
|
| +using extension_web_request_api_helpers::ExtraInfoSpec;
|
|
|
| namespace activity_log = activity_log_web_request_constants;
|
| namespace helpers = extension_web_request_api_helpers;
|
| @@ -200,86 +191,6 @@ bool GetWebViewInfo(const net::URLRequest* request,
|
| render_process_host_id, routing_id, web_view_info);
|
| }
|
|
|
| -void ExtractRequestInfoDetails(const net::URLRequest* request,
|
| - bool* is_main_frame,
|
| - int* render_frame_id,
|
| - int* render_process_host_id,
|
| - int* routing_id,
|
| - ResourceType* resource_type) {
|
| - const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
|
| - if (!info)
|
| - return;
|
| -
|
| - *render_frame_id = info->GetRenderFrameID();
|
| - *is_main_frame = info->IsMainFrame();
|
| - *render_process_host_id = info->GetChildID();
|
| - *routing_id = info->GetRouteID();
|
| -
|
| - // Restrict the resource type to the values we care about.
|
| - if (helpers::IsRelevantResourceType(info->GetResourceType()))
|
| - *resource_type = info->GetResourceType();
|
| - else
|
| - *resource_type = content::RESOURCE_TYPE_LAST_TYPE;
|
| -}
|
| -
|
| -// Extracts a pair of IDs to identify the RenderFrameHost. These IDs are used to
|
| -// get the frame ID and parent frame ID from ExtensionApiFrameIdMap, and then
|
| -// stored in |dict| by DispatchEventToListeners or SendOnMessageEventOnUI.
|
| -void ExtractRenderFrameInfo(base::DictionaryValue* dict,
|
| - int* render_process_id,
|
| - int* render_frame_id) {
|
| - if (!dict->GetInteger(keys::kFrameIdKey, render_frame_id) ||
|
| - !dict->GetInteger(keys::kProcessIdKey, render_process_id)) {
|
| - *render_process_id = -1;
|
| - *render_frame_id = -1;
|
| - }
|
| - // kFrameIdKey will be overwritten later, so it's not removed here.
|
| - dict->Remove(keys::kProcessIdKey, nullptr);
|
| -}
|
| -
|
| -// Extracts the body from |request| and writes the data into |out|.
|
| -void ExtractRequestInfoBody(const net::URLRequest* request,
|
| - base::DictionaryValue* out) {
|
| - const net::UploadDataStream* upload_data = request->get_upload();
|
| - if (!upload_data ||
|
| - (request->method() != "POST" && request->method() != "PUT")) {
|
| - return; // Need to exit without "out->Set(keys::kRequestBodyKey, ...);" .
|
| - }
|
| -
|
| - base::DictionaryValue* request_body = new base::DictionaryValue();
|
| - out->Set(keys::kRequestBodyKey, request_body);
|
| -
|
| - // Get the data presenters, ordered by how specific they are.
|
| - ParsedDataPresenter parsed_data_presenter(*request);
|
| - RawDataPresenter raw_data_presenter;
|
| - UploadDataPresenter* const presenters[] = {
|
| - &parsed_data_presenter, // 1: any parseable forms? (Specific to forms.)
|
| - &raw_data_presenter // 2: any data at all? (Non-specific.)
|
| - };
|
| - // Keys for the results of the corresponding presenters.
|
| - static const char* const kKeys[] = {
|
| - keys::kRequestBodyFormDataKey,
|
| - keys::kRequestBodyRawKey
|
| - };
|
| -
|
| - const std::vector<scoped_ptr<net::UploadElementReader>>* readers =
|
| - upload_data->GetElementReaders();
|
| - bool some_succeeded = false;
|
| - if (readers) {
|
| - for (size_t i = 0; i < arraysize(presenters); ++i) {
|
| - for (const auto& reader : *readers)
|
| - presenters[i]->FeedNext(*reader);
|
| - if (presenters[i]->Succeeded()) {
|
| - request_body->Set(kKeys[i], presenters[i]->Result().release());
|
| - some_succeeded = true;
|
| - break;
|
| - }
|
| - }
|
| - }
|
| - if (!some_succeeded)
|
| - request_body->SetString(keys::kRequestBodyErrorKey, "Unknown error.");
|
| -}
|
| -
|
| // Converts a HttpHeaders dictionary to a |name|, |value| pair. Returns
|
| // true if successful.
|
| bool FromHeaderDictionary(const base::DictionaryValue* header_value,
|
| @@ -310,43 +221,6 @@ bool FromHeaderDictionary(const base::DictionaryValue* header_value,
|
| return true;
|
| }
|
|
|
| -// Creates a list of HttpHeaders (see the extension API JSON). If |headers| is
|
| -// NULL, the list is empty. Ownership is passed to the caller.
|
| -base::ListValue* GetResponseHeadersList(
|
| - const net::HttpResponseHeaders* headers) {
|
| - base::ListValue* headers_value = new base::ListValue();
|
| - if (headers) {
|
| - void* iter = NULL;
|
| - std::string name;
|
| - std::string value;
|
| - while (headers->EnumerateHeaderLines(&iter, &name, &value))
|
| - headers_value->Append(helpers::CreateHeaderDictionary(name, value));
|
| - }
|
| - return headers_value;
|
| -}
|
| -
|
| -base::ListValue* GetRequestHeadersList(const net::HttpRequestHeaders& headers) {
|
| - base::ListValue* headers_value = new base::ListValue();
|
| - for (net::HttpRequestHeaders::Iterator it(headers); it.GetNext(); )
|
| - headers_value->Append(
|
| - helpers::CreateHeaderDictionary(it.name(), it.value()));
|
| - return headers_value;
|
| -}
|
| -
|
| -// Creates a base::StringValue with the status line of |headers|. If |headers|
|
| -// is NULL, an empty string is returned. Ownership is passed to the caller.
|
| -base::StringValue* GetStatusLine(net::HttpResponseHeaders* headers) {
|
| - return new base::StringValue(
|
| - headers ? headers->GetStatusLine() : std::string());
|
| -}
|
| -
|
| -// Returns the response code from the response headers, or 200 by default.
|
| -// |headers| may be NULL, e.g. UrlRequestFileJobs do not send headers, so
|
| -// simulate their behavior.
|
| -int GetResponseCodeWithDefault(net::HttpResponseHeaders* headers) {
|
| - return headers ? headers->response_code() : 200;
|
| -}
|
| -
|
| // Sends an event to subscribers of chrome.declarativeWebRequest.onMessage or
|
| // to subscribers of webview.onMessage if the action is being operated upon
|
| // a <webview> guest renderer.
|
| @@ -354,13 +228,13 @@ int GetResponseCodeWithDefault(net::HttpResponseHeaders* headers) {
|
| // |is_web_view_guest| indicates whether the action is for a <webview>.
|
| // |web_view_info| is a struct containing information about the <webview>
|
| // embedder.
|
| -// |event_argument| is passed to the event listener.
|
| +// |event_details| is passed to the event listener.
|
| void SendOnMessageEventOnUI(
|
| void* browser_context_id,
|
| const std::string& extension_id,
|
| bool is_web_view_guest,
|
| const WebViewRendererState::WebViewInfo& web_view_info,
|
| - scoped_ptr<base::DictionaryValue> event_argument) {
|
| + scoped_ptr<WebRequestEventDetails> event_details) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
|
|
| content::BrowserContext* browser_context =
|
| @@ -369,17 +243,8 @@ void SendOnMessageEventOnUI(
|
| return;
|
|
|
| scoped_ptr<base::ListValue> event_args(new base::ListValue);
|
| - int render_process_host_id = -1;
|
| - int render_frame_id = -1;
|
| - ExtractRenderFrameInfo(event_argument.get(), &render_process_host_id,
|
| - &render_frame_id);
|
| - content::RenderFrameHost* rfh =
|
| - content::RenderFrameHost::FromID(render_process_host_id, render_frame_id);
|
| - event_argument->SetInteger(keys::kFrameIdKey,
|
| - ExtensionApiFrameIdMap::GetFrameId(rfh));
|
| - event_argument->SetInteger(keys::kParentFrameIdKey,
|
| - ExtensionApiFrameIdMap::GetParentFrameId(rfh));
|
| - event_args->Append(event_argument.release());
|
| + event_details->DetermineFrameIdOnUI();
|
| + event_args->Append(event_details->GetAndClearDict());
|
|
|
| EventRouter* event_router = EventRouter::Get(browser_context);
|
|
|
| @@ -662,7 +527,7 @@ bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue(
|
| return false;
|
| for (size_t i = 0; i < types_value->GetSize(); ++i) {
|
| std::string type_str;
|
| - ResourceType type;
|
| + content::ResourceType type;
|
| if (!types_value->GetString(i, &type_str) ||
|
| !helpers::ParseResourceType(type_str, &type)) {
|
| return false;
|
| @@ -682,36 +547,6 @@ bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue(
|
| return true;
|
| }
|
|
|
| -// static
|
| -bool ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
|
| - const base::ListValue& value, int* extra_info_spec) {
|
| - *extra_info_spec = 0;
|
| - for (size_t i = 0; i < value.GetSize(); ++i) {
|
| - std::string str;
|
| - if (!value.GetString(i, &str))
|
| - return false;
|
| -
|
| - if (str == "requestHeaders")
|
| - *extra_info_spec |= REQUEST_HEADERS;
|
| - else if (str == "responseHeaders")
|
| - *extra_info_spec |= RESPONSE_HEADERS;
|
| - else if (str == "blocking")
|
| - *extra_info_spec |= BLOCKING;
|
| - else if (str == "asyncBlocking")
|
| - *extra_info_spec |= ASYNC_BLOCKING;
|
| - else if (str == "requestBody")
|
| - *extra_info_spec |= REQUEST_BODY;
|
| - else
|
| - return false;
|
| -
|
| - // BLOCKING and ASYNC_BLOCKING are mutually exclusive.
|
| - if ((*extra_info_spec & BLOCKING) && (*extra_info_spec & ASYNC_BLOCKING))
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -
|
| ExtensionWebRequestEventRouter::EventResponse::EventResponse(
|
| const std::string& extension_id, const base::Time& extension_install_time)
|
| : extension_id(extension_id),
|
| @@ -758,34 +593,18 @@ void ExtensionWebRequestEventRouter::RegisterRulesRegistry(
|
| rules_registries_.erase(key);
|
| }
|
|
|
| -void ExtensionWebRequestEventRouter::ExtractRequestInfo(
|
| +scoped_ptr<WebRequestEventDetails>
|
| +ExtensionWebRequestEventRouter::CreateEventDetails(
|
| const net::URLRequest* request,
|
| - base::DictionaryValue* out) {
|
| - bool is_main_frame = false;
|
| - int render_frame_id = -1;
|
| - int render_process_host_id = -1;
|
| - int routing_id = -1;
|
| - ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
|
| - ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id,
|
| - &render_process_host_id, &routing_id,
|
| - &resource_type);
|
| -
|
| - out->SetString(keys::kRequestIdKey,
|
| - base::Uint64ToString(request->identifier()));
|
| - out->SetString(keys::kUrlKey, request->url().spec());
|
| - out->SetString(keys::kMethodKey, request->method());
|
| - // Note: This (frameId, processId) pair is removed by ExtractRenderFrameInfo,
|
| - // and finally restored in DispatchEventToListeners or SendOnMessageEventOnUI.
|
| - // TODO(robwu): This is ugly. Create a proper data structure to separate these
|
| - // two IDs from the dictionary, so that kFrameIdKey has only one meaning.
|
| - out->SetInteger(keys::kFrameIdKey, render_frame_id);
|
| - out->SetInteger(keys::kProcessIdKey, render_process_host_id);
|
| - out->SetString(keys::kTypeKey, helpers::ResourceTypeToString(resource_type));
|
| - out->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
|
| + int extra_info_spec) {
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + new WebRequestEventDetails(request, extra_info_spec));
|
| +
|
| if (web_request_event_router_delegate_) {
|
| web_request_event_router_delegate_->ExtractExtraRequestDetails(
|
| - request, out);
|
| + request, event_details.get());
|
| }
|
| + return event_details;
|
| }
|
|
|
| int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| @@ -819,15 +638,12 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| web_request::OnBeforeRequest::kEventName, request, &extra_info_spec);
|
| if (!listeners.empty() &&
|
| !GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) {
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - if (extra_info_spec & ExtraInfoSpec::REQUEST_BODY)
|
| - ExtractRequestInfoBody(request, dict);
|
| - args.Append(dict);
|
| -
|
| - initialize_blocked_requests |=
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetRequestBody(request);
|
| +
|
| + initialize_blocked_requests |= DispatchEvent(
|
| + browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| if (!initialize_blocked_requests)
|
| @@ -871,15 +687,12 @@ int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
| request, &extra_info_spec);
|
| if (!listeners.empty() &&
|
| !GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) {
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)
|
| - dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(*headers));
|
| - args.Append(dict);
|
| -
|
| - initialize_blocked_requests |=
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetRequestHeaders(*headers);
|
| +
|
| + initialize_blocked_requests |= DispatchEvent(
|
| + browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| if (!initialize_blocked_requests)
|
| @@ -922,14 +735,11 @@ void ExtensionWebRequestEventRouter::OnSendHeaders(
|
| if (listeners.empty())
|
| return;
|
|
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)
|
| - dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(headers));
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetRequestHeaders(headers);
|
|
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + DispatchEvent(browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| int ExtensionWebRequestEventRouter::OnHeadersReceived(
|
| @@ -956,21 +766,12 @@ int ExtensionWebRequestEventRouter::OnHeadersReceived(
|
|
|
| if (!listeners.empty() &&
|
| !GetAndSetSignaled(request->identifier(), kOnHeadersReceived)) {
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - dict->SetString(keys::kStatusLineKey,
|
| - original_response_headers->GetStatusLine());
|
| - dict->SetInteger(keys::kStatusCodeKey,
|
| - original_response_headers->response_code());
|
| - if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
|
| - dict->Set(keys::kResponseHeadersKey,
|
| - GetResponseHeadersList(original_response_headers));
|
| - }
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetResponseHeaders(request, original_response_headers);
|
|
|
| - initialize_blocked_requests |=
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + initialize_blocked_requests |= DispatchEvent(
|
| + browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| if (!initialize_blocked_requests)
|
| @@ -1017,30 +818,13 @@ ExtensionWebRequestEventRouter::OnAuthRequired(
|
| if (listeners.empty())
|
| return net::NetworkDelegate::AUTH_REQUIRED_RESPONSE_NO_ACTION;
|
|
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - dict->SetBoolean(keys::kIsProxyKey, auth_info.is_proxy);
|
| - if (!auth_info.scheme.empty())
|
| - dict->SetString(keys::kSchemeKey, auth_info.scheme);
|
| - if (!auth_info.realm.empty())
|
| - dict->SetString(keys::kRealmKey, auth_info.realm);
|
| - base::DictionaryValue* challenger = new base::DictionaryValue();
|
| - challenger->SetString(keys::kHostKey, auth_info.challenger.host());
|
| - challenger->SetInteger(keys::kPortKey, auth_info.challenger.port());
|
| - dict->Set(keys::kChallengerKey, challenger);
|
| - dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| - if (request->response_headers()) {
|
| - dict->SetInteger(keys::kStatusCodeKey,
|
| - request->response_headers()->response_code());
|
| - }
|
| - if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
|
| - dict->Set(keys::kResponseHeadersKey,
|
| - GetResponseHeadersList(request->response_headers()));
|
| - }
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetResponseHeaders(request, request->response_headers());
|
| + event_details->SetAuthInfo(auth_info);
|
|
|
| - if (DispatchEvent(browser_context, request, listeners, args)) {
|
| + if (DispatchEvent(browser_context, request, listeners,
|
| + std::move(event_details))) {
|
| BlockedRequest& blocked_request = blocked_requests_[request->identifier()];
|
| blocked_request.event = kOnAuthRequired;
|
| blocked_request.is_incognito |= IsIncognitoBrowserContext(browser_context);
|
| @@ -1076,26 +860,13 @@ void ExtensionWebRequestEventRouter::OnBeforeRedirect(
|
| if (listeners.empty())
|
| return;
|
|
|
| - int http_status_code = request->GetResponseCode();
|
| -
|
| - std::string response_ip = request->GetSocketAddress().host();
|
| -
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - dict->SetString(keys::kRedirectUrlKey, new_location.spec());
|
| - dict->SetInteger(keys::kStatusCodeKey, http_status_code);
|
| - if (!response_ip.empty())
|
| - dict->SetString(keys::kIpKey, response_ip);
|
| - dict->SetBoolean(keys::kFromCache, request->was_cached());
|
| - dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| - if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
|
| - dict->Set(keys::kResponseHeadersKey,
|
| - GetResponseHeadersList(request->response_headers()));
|
| - }
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetResponseHeaders(request, request->response_headers());
|
| + event_details->SetResponseSource(request);
|
| + event_details->SetString(keys::kRedirectUrlKey, new_location.spec());
|
|
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + DispatchEvent(browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnResponseStarted(
|
| @@ -1116,24 +887,12 @@ void ExtensionWebRequestEventRouter::OnResponseStarted(
|
| if (listeners.empty())
|
| return;
|
|
|
| - std::string response_ip = request->GetSocketAddress().host();
|
| -
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - if (!response_ip.empty())
|
| - dict->SetString(keys::kIpKey, response_ip);
|
| - dict->SetBoolean(keys::kFromCache, request->was_cached());
|
| - dict->SetInteger(keys::kStatusCodeKey,
|
| - GetResponseCodeWithDefault(request->response_headers()));
|
| - dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| - if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
|
| - dict->Set(keys::kResponseHeadersKey,
|
| - GetResponseHeadersList(request->response_headers()));
|
| - }
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetResponseHeaders(request, request->response_headers());
|
| + event_details->SetResponseSource(request);
|
|
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + DispatchEvent(browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnCompleted(
|
| @@ -1166,24 +925,12 @@ void ExtensionWebRequestEventRouter::OnCompleted(
|
| if (listeners.empty())
|
| return;
|
|
|
| - std::string response_ip = request->GetSocketAddress().host();
|
| -
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - dict->SetInteger(keys::kStatusCodeKey,
|
| - GetResponseCodeWithDefault(request->response_headers()));
|
| - if (!response_ip.empty())
|
| - dict->SetString(keys::kIpKey, response_ip);
|
| - dict->SetBoolean(keys::kFromCache, request->was_cached());
|
| - dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| - if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
|
| - dict->Set(keys::kResponseHeadersKey,
|
| - GetResponseHeadersList(request->response_headers()));
|
| - }
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + event_details->SetResponseHeaders(request, request->response_headers());
|
| + event_details->SetResponseSource(request);
|
|
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + DispatchEvent(browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnErrorOccurred(
|
| @@ -1218,20 +965,16 @@ void ExtensionWebRequestEventRouter::OnErrorOccurred(
|
| if (listeners.empty())
|
| return;
|
|
|
| - base::ListValue args;
|
| - base::DictionaryValue* dict = new base::DictionaryValue();
|
| - ExtractRequestInfo(request, dict);
|
| - if (started) {
|
| - std::string response_ip = request->GetSocketAddress().host();
|
| - if (!response_ip.empty())
|
| - dict->SetString(keys::kIpKey, response_ip);
|
| - }
|
| - dict->SetBoolean(keys::kFromCache, request->was_cached());
|
| - dict->SetString(keys::kErrorKey,
|
| - net::ErrorToString(request->status().error()));
|
| - args.Append(dict);
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(request, extra_info_spec));
|
| + if (started)
|
| + event_details->SetResponseSource(request);
|
| + else
|
| + event_details->SetBoolean(keys::kFromCache, request->was_cached());
|
| + event_details->SetString(keys::kErrorKey,
|
| + net::ErrorToString(request->status().error()));
|
|
|
| - DispatchEvent(browser_context, request, listeners, args);
|
| + DispatchEvent(browser_context, request, listeners, std::move(event_details));
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
|
| @@ -1254,7 +997,7 @@ bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| void* browser_context,
|
| net::URLRequest* request,
|
| const std::vector<const EventListener*>& listeners,
|
| - const base::ListValue& args) {
|
| + scoped_ptr<WebRequestEventDetails> event_details) {
|
| // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
|
| // pairs into a single message sent to a list of sub_event_names.
|
| int num_handlers_blocking = 0;
|
| @@ -1281,21 +1024,9 @@ bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| }
|
| }
|
|
|
| - // TODO(robwu): Avoid unnecessary copy, by changing |args| to be a
|
| - // scoped_ptr<base::DictionaryValue> and transferring the ownership.
|
| - const base::DictionaryValue* dict = nullptr;
|
| - CHECK(args.GetDictionary(0, &dict) && dict);
|
| - base::DictionaryValue* args_copy = dict->DeepCopy();
|
| -
|
| - int render_process_host_id = -1;
|
| - int render_frame_id = -1;
|
| - ExtractRenderFrameInfo(args_copy, &render_process_host_id, &render_frame_id);
|
| -
|
| - ExtensionApiFrameIdMap::Get()->GetFrameIdOnIO(
|
| - render_process_host_id, render_frame_id,
|
| - base::Bind(&ExtensionWebRequestEventRouter::DispatchEventToListeners,
|
| - AsWeakPtr(), browser_context,
|
| - base::Passed(&listeners_to_dispatch), base::Owned(args_copy)));
|
| + event_details.release()->DetermineFrameIdOnIO(base::Bind(
|
| + &ExtensionWebRequestEventRouter::DispatchEventToListeners, AsWeakPtr(),
|
| + browser_context, base::Passed(&listeners_to_dispatch)));
|
|
|
| if (num_handlers_blocking > 0) {
|
| BlockedRequest& blocked_request = blocked_requests_[request->identifier()];
|
| @@ -1312,16 +1043,11 @@ bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| void ExtensionWebRequestEventRouter::DispatchEventToListeners(
|
| void* browser_context,
|
| scoped_ptr<std::vector<EventListener>> listeners,
|
| - base::DictionaryValue* dict,
|
| - int extension_api_frame_id,
|
| - int extension_api_parent_frame_id) {
|
| + scoped_ptr<WebRequestEventDetails> event_details) {
|
| DCHECK_CURRENTLY_ON(BrowserThread::IO);
|
| DCHECK(listeners.get());
|
| DCHECK_GT(listeners->size(), 0UL);
|
| - DCHECK(dict);
|
| -
|
| - dict->SetInteger(keys::kFrameIdKey, extension_api_frame_id);
|
| - dict->SetInteger(keys::kParentFrameIdKey, extension_api_parent_frame_id);
|
| + DCHECK(event_details.get());
|
|
|
| std::string event_name =
|
| EventRouter::GetBaseEventName((*listeners)[0].sub_event_name);
|
| @@ -1348,11 +1074,8 @@ void ExtensionWebRequestEventRouter::DispatchEventToListeners(
|
|
|
| // Filter out the optional keys that this listener didn't request.
|
| scoped_ptr<base::ListValue> args_filtered(new base::ListValue);
|
| - args_filtered->Append(dict->DeepCopy());
|
| - if (!(listener->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS))
|
| - dict->Remove(keys::kRequestHeadersKey, nullptr);
|
| - if (!(listener->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS))
|
| - dict->Remove(keys::kResponseHeadersKey, nullptr);
|
| + args_filtered->Append(
|
| + event_details->GetFilteredDict(listener->extra_info_spec));
|
|
|
| EventRouter::DispatchEventToSender(
|
| listener->ipc_sender.get(), browser_context, listener->extension_id,
|
| @@ -1514,17 +1237,11 @@ void ExtensionWebRequestEventRouter::AddCallbackForPageLoad(
|
|
|
| bool ExtensionWebRequestEventRouter::IsPageLoad(
|
| const net::URLRequest* request) const {
|
| - bool is_main_frame = false;
|
| - int render_frame_id = -1;
|
| - int render_process_host_id = -1;
|
| - int routing_id = -1;
|
| - ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
|
| -
|
| - ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id,
|
| - &render_process_host_id, &routing_id,
|
| - &resource_type);
|
| + const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
|
| + if (!info)
|
| + return false;
|
|
|
| - return resource_type == content::RESOURCE_TYPE_MAIN_FRAME;
|
| + return info->GetResourceType() == content::RESOURCE_TYPE_MAIN_FRAME;
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::NotifyPageLoad() {
|
| @@ -1567,7 +1284,7 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
|
| const GURL& url,
|
| int render_process_host_id,
|
| int routing_id,
|
| - ResourceType resource_type,
|
| + content::ResourceType resource_type,
|
| bool is_async_request,
|
| bool is_request_from_extension,
|
| int* extra_info_spec,
|
| @@ -1661,24 +1378,24 @@ ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| // listeners).
|
| *extra_info_spec = 0;
|
|
|
| - bool is_main_frame = false;
|
| - int render_frame_id = -1;
|
| - int render_process_host_id = -1;
|
| - int routing_id = -1;
|
| - ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
|
| const GURL& url = request->url();
|
| -
|
| - ExtractRequestInfoDetails(request, &is_main_frame, &render_frame_id,
|
| - &render_process_host_id, &routing_id,
|
| - &resource_type);
|
| -
|
| + int render_process_host_id = content::ChildProcessHost::kInvalidUniqueID;
|
| + int routing_id = MSG_ROUTING_NONE;
|
| + content::ResourceType resource_type = content::RESOURCE_TYPE_LAST_TYPE;
|
| + // We are conservative here and assume requests are asynchronous in case
|
| + // we don't have an info object. We don't want to risk a deadlock.
|
| + bool is_async_request = false;
|
| bool is_request_from_extension =
|
| IsRequestFromExtension(request, extension_info_map);
|
|
|
| const ResourceRequestInfo* info = ResourceRequestInfo::ForRequest(request);
|
| - // We are conservative here and assume requests are asynchronous in case
|
| - // we don't have an info object. We don't want to risk a deadlock.
|
| - bool is_async_request = !info || info->IsAsync();
|
| + if (info) {
|
| + is_async_request = info->IsAsync();
|
| + if (helpers::IsRelevantResourceType(info->GetResourceType()))
|
| + resource_type = info->GetResourceType();
|
| + render_process_host_id = info->GetChildID();
|
| + routing_id = info->GetRouteID();
|
| + }
|
|
|
| EventListeners matching_listeners;
|
| GetMatchingListenersImpl(
|
| @@ -1951,20 +1668,20 @@ void ExtensionWebRequestEventRouter::SendMessages(
|
| for (const auto& delta : deltas) {
|
| const std::set<std::string>& messages = delta->messages_to_extension;
|
| for (const std::string& message : messages) {
|
| - scoped_ptr<base::DictionaryValue> argument(new base::DictionaryValue);
|
| - ExtractRequestInfo(blocked_request.request, argument.get());
|
| + scoped_ptr<WebRequestEventDetails> event_details(
|
| + CreateEventDetails(blocked_request.request, /* extra_info_spec */ 0));
|
| WebViewRendererState::WebViewInfo web_view_info;
|
| bool is_web_view_guest = GetWebViewInfo(blocked_request.request,
|
| &web_view_info);
|
| - argument->SetString(keys::kMessageKey, message);
|
| - argument->SetString(keys::kStageKey,
|
| - GetRequestStageAsString(blocked_request.event));
|
| + event_details->SetString(keys::kMessageKey, message);
|
| + event_details->SetString(keys::kStageKey,
|
| + GetRequestStageAsString(blocked_request.event));
|
|
|
| BrowserThread::PostTask(
|
| BrowserThread::UI, FROM_HERE,
|
| base::Bind(&SendOnMessageEventOnUI, browser_context,
|
| delta->extension_id, is_web_view_guest, web_view_info,
|
| - base::Passed(&argument)));
|
| + base::Passed(&event_details)));
|
| }
|
| }
|
| }
|
| @@ -2294,8 +2011,7 @@ bool WebRequestInternalAddEventListenerFunction::RunSync() {
|
| base::ListValue* value = NULL;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetList(2, &value));
|
| EXTENSION_FUNCTION_VALIDATE(
|
| - ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
|
| - *value, &extra_info_spec));
|
| + ExtraInfoSpec::InitFromValue(*value, &extra_info_spec));
|
| }
|
|
|
| std::string event_name;
|
| @@ -2320,8 +2036,7 @@ bool WebRequestInternalAddEventListenerFunction::RunSync() {
|
| // permission. For blocking calls we require the additional permission
|
| // 'webRequestBlocking'.
|
| if ((extra_info_spec &
|
| - (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING |
|
| - ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) &&
|
| + (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) &&
|
| !extension->permissions_data()->HasAPIPermission(
|
| APIPermission::kWebRequestBlocking)) {
|
| error_ = keys::kBlockingPermissionRequired;
|
|
|