summaryrefslogtreecommitdiffstats
path: root/extensions/browser/api/web_request/web_request_api.cc
diff options
context:
space:
mode:
Diffstat (limited to 'extensions/browser/api/web_request/web_request_api.cc')
-rw-r--r--extensions/browser/api/web_request/web_request_api.cc489
1 files changed, 102 insertions, 387 deletions
diff --git a/extensions/browser/api/web_request/web_request_api.cc b/extensions/browser/api/web_request/web_request_api.cc
index b3855a3..76db07f 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;