| Index: chrome/browser/extensions/extension_webrequest_api.cc
|
| diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc
|
| index 983bdfe0d0ac64916e150382717d5a6ee6573934..46929fe89f118324d6402c4fc5fbc98204062342 100644
|
| --- a/chrome/browser/extensions/extension_webrequest_api.cc
|
| +++ b/chrome/browser/extensions/extension_webrequest_api.cc
|
| @@ -10,16 +10,19 @@
|
| #include "base/metrics/histogram.h"
|
| #include "base/string_number_conversions.h"
|
| #include "base/values.h"
|
| -#include "chrome/browser/extensions/extension_event_router_forwarder.h"
|
| +#include "chrome/browser/extensions/extension_event_router.h"
|
| +#include "chrome/browser/extensions/extension_info_map.h"
|
| #include "chrome/browser/extensions/extension_prefs.h"
|
| #include "chrome/browser/extensions/extension_service.h"
|
| #include "chrome/browser/extensions/extension_tab_id_map.h"
|
| #include "chrome/browser/extensions/extension_webrequest_api_constants.h"
|
| #include "chrome/browser/profiles/profile.h"
|
| +#include "chrome/browser/renderer_host/chrome_render_message_filter.h"
|
| #include "chrome/common/extensions/extension.h"
|
| #include "chrome/common/extensions/extension_error_utils.h"
|
| #include "chrome/common/extensions/url_pattern.h"
|
| #include "chrome/common/url_constants.h"
|
| +#include "content/browser/browser_message_filter.h"
|
| #include "content/browser/browser_thread.h"
|
| #include "content/browser/renderer_host/resource_dispatcher_host.h"
|
| #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
|
| @@ -84,7 +87,7 @@ const char* ResourceTypeToString(ResourceType::Type type) {
|
| }
|
|
|
| bool ParseResourceType(const std::string& type_str,
|
| - ResourceType::Type* type) {
|
| + ResourceType::Type* type) {
|
| const char** iter =
|
| std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str);
|
| if (iter == ARRAYEND(kResourceTypeStrings))
|
| @@ -94,9 +97,9 @@ bool ParseResourceType(const std::string& type_str,
|
| }
|
|
|
| void ExtractRequestInfo(net::URLRequest* request,
|
| - int* tab_id,
|
| - int* window_id,
|
| - ResourceType::Type* resource_type) {
|
| + int* tab_id,
|
| + int* window_id,
|
| + ResourceType::Type* resource_type) {
|
| if (!request->GetUserData(NULL))
|
| return;
|
|
|
| @@ -113,30 +116,6 @@ void ExtractRequestInfo(net::URLRequest* request,
|
| *iter : ResourceType::LAST_TYPE;
|
| }
|
|
|
| -void AddEventListenerOnIOThread(
|
| - ProfileId profile_id,
|
| - const std::string& extension_id,
|
| - const std::string& event_name,
|
| - const std::string& sub_event_name,
|
| - const ExtensionWebRequestEventRouter::RequestFilter& filter,
|
| - int extra_info_spec) {
|
| - ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
|
| - profile_id, extension_id, event_name, sub_event_name, filter,
|
| - extra_info_spec);
|
| -}
|
| -
|
| -void EventHandledOnIOThread(
|
| - ProfileId profile_id,
|
| - const std::string& extension_id,
|
| - const std::string& event_name,
|
| - const std::string& sub_event_name,
|
| - uint64 request_id,
|
| - ExtensionWebRequestEventRouter::EventResponse* response) {
|
| - ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
|
| - profile_id, extension_id, event_name, sub_event_name, request_id,
|
| - response);
|
| -}
|
| -
|
| // Creates a list of HttpHeaders (see extension_api.json). If |headers| is
|
| // NULL, the list is empty. Ownership is passed to the caller.
|
| ListValue* GetResponseHeadersList(const net::HttpResponseHeaders* headers) {
|
| @@ -184,6 +163,7 @@ struct ExtensionWebRequestEventRouter::EventListener {
|
| std::string sub_event_name;
|
| RequestFilter filter;
|
| int extra_info_spec;
|
| + base::WeakPtr<IPC::Message::Sender> ipc_sender;
|
| mutable std::set<uint64> blocked_requests;
|
|
|
| // Comparator to work with std::set.
|
| @@ -341,7 +321,7 @@ ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() {
|
|
|
| int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request,
|
| net::CompletionCallback* callback,
|
| GURL* new_url) {
|
| @@ -366,7 +346,8 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnBeforeRequest, request->url(),
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnBeforeRequest, request->url(),
|
| tab_id, window_id, resource_type, &extra_info_spec);
|
| if (listeners.empty())
|
| return net::OK;
|
| @@ -385,7 +366,7 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
|
| args.Append(dict);
|
|
|
| - if (DispatchEvent(profile_id, event_router, request, listeners, args)) {
|
| + if (DispatchEvent(profile_id, request, listeners, args)) {
|
| blocked_requests_[request->identifier()].event = kOnBeforeRequest;
|
| blocked_requests_[request->identifier()].callback = callback;
|
| blocked_requests_[request->identifier()].new_url = new_url;
|
| @@ -396,7 +377,7 @@ int ExtensionWebRequestEventRouter::OnBeforeRequest(
|
|
|
| int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| uint64 request_id,
|
| net::CompletionCallback* callback,
|
| net::HttpRequestHeaders* headers) {
|
| @@ -415,7 +396,8 @@ int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnBeforeSendHeaders, request,
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnBeforeSendHeaders, request,
|
| &extra_info_spec);
|
| if (listeners.empty())
|
| return net::OK;
|
| @@ -433,7 +415,7 @@ int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
|
|
| args.Append(dict);
|
|
|
| - if (DispatchEvent(profile_id, event_router, request, listeners, args)) {
|
| + if (DispatchEvent(profile_id, request, listeners, args)) {
|
| blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders;
|
| blocked_requests_[request->identifier()].callback = callback;
|
| blocked_requests_[request->identifier()].request_headers = headers;
|
| @@ -444,7 +426,7 @@ int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
|
|
| void ExtensionWebRequestEventRouter::OnRequestSent(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| uint64 request_id,
|
| const net::HostPortPair& socket_address,
|
| const net::HttpRequestHeaders& headers) {
|
| @@ -465,8 +447,8 @@ void ExtensionWebRequestEventRouter::OnRequestSent(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnRequestSent, request,
|
| - &extra_info_spec);
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnRequestSent, request, &extra_info_spec);
|
| if (listeners.empty())
|
| return;
|
|
|
| @@ -482,12 +464,12 @@ void ExtensionWebRequestEventRouter::OnRequestSent(
|
| // TODO(battre): support "request line".
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile_id, event_router, request, listeners, args);
|
| + DispatchEvent(profile_id, request, listeners, args);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnBeforeRedirect(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request,
|
| const GURL& new_location) {
|
| if (profile_id == Profile::kInvalidProfileId)
|
| @@ -503,8 +485,8 @@ void ExtensionWebRequestEventRouter::OnBeforeRedirect(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnBeforeRedirect, request,
|
| - &extra_info_spec);
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnBeforeRedirect, request, &extra_info_spec);
|
| if (listeners.empty())
|
| return;
|
|
|
| @@ -526,12 +508,12 @@ void ExtensionWebRequestEventRouter::OnBeforeRedirect(
|
| dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile_id, event_router, request, listeners, args);
|
| + DispatchEvent(profile_id, request, listeners, args);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnResponseStarted(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request) {
|
| if (profile_id == Profile::kInvalidProfileId)
|
| return;
|
| @@ -544,8 +526,8 @@ void ExtensionWebRequestEventRouter::OnResponseStarted(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnResponseStarted, request,
|
| - &extra_info_spec);
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnResponseStarted, request, &extra_info_spec);
|
| if (listeners.empty())
|
| return;
|
|
|
| @@ -569,12 +551,12 @@ void ExtensionWebRequestEventRouter::OnResponseStarted(
|
| dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile_id, event_router, request, listeners, args);
|
| + DispatchEvent(profile_id, request, listeners, args);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnCompleted(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request) {
|
| if (profile_id == Profile::kInvalidProfileId)
|
| return;
|
| @@ -587,8 +569,8 @@ void ExtensionWebRequestEventRouter::OnCompleted(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnCompleted, request,
|
| - &extra_info_spec);
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnCompleted, request, &extra_info_spec);
|
| if (listeners.empty())
|
| return;
|
|
|
| @@ -612,12 +594,12 @@ void ExtensionWebRequestEventRouter::OnCompleted(
|
| dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile_id, event_router, request, listeners, args);
|
| + DispatchEvent(profile_id, request, listeners, args);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnErrorOccurred(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| + ExtensionInfoMap* extension_info_map,
|
| net::URLRequest* request) {
|
| if (profile_id == Profile::kInvalidProfileId)
|
| return;
|
| @@ -630,8 +612,8 @@ void ExtensionWebRequestEventRouter::OnErrorOccurred(
|
|
|
| int extra_info_spec = 0;
|
| std::vector<const EventListener*> listeners =
|
| - GetMatchingListeners(profile_id, keys::kOnErrorOccurred, request,
|
| - &extra_info_spec);
|
| + GetMatchingListeners(profile_id, extension_info_map,
|
| + keys::kOnErrorOccurred, request, &extra_info_spec);
|
| if (listeners.empty())
|
| return;
|
|
|
| @@ -645,7 +627,7 @@ void ExtensionWebRequestEventRouter::OnErrorOccurred(
|
| dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
|
| args.Append(dict);
|
|
|
| - DispatchEvent(profile_id, event_router, request, listeners, args);
|
| + DispatchEvent(profile_id, request, listeners, args);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
|
| @@ -667,7 +649,6 @@ void ExtensionWebRequestEventRouter::OnHttpTransactionDestroyed(
|
|
|
| bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| ProfileId profile_id,
|
| - ExtensionEventRouterForwarder* event_router,
|
| net::URLRequest* request,
|
| const std::vector<const EventListener*>& listeners,
|
| const ListValue& args) {
|
| @@ -690,9 +671,10 @@ bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| dict->Remove(keys::kStatusLineKey, NULL);
|
|
|
| base::JSONWriter::Write(args_filtered.get(), false, &json_args);
|
| - event_router->DispatchEventToExtension(
|
| - (*it)->extension_id, (*it)->sub_event_name, json_args,
|
| - profile_id, true, GURL());
|
| +
|
| + ExtensionEventRouter::DispatchEvent(
|
| + (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name,
|
| + json_args, GURL());
|
| if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
|
| (*it)->blocked_requests.insert(request->identifier());
|
| ++num_handlers_blocking;
|
| @@ -739,7 +721,8 @@ void ExtensionWebRequestEventRouter::AddEventListener(
|
| const std::string& event_name,
|
| const std::string& sub_event_name,
|
| const RequestFilter& filter,
|
| - int extra_info_spec) {
|
| + int extra_info_spec,
|
| + base::WeakPtr<IPC::Message::Sender> ipc_sender) {
|
| if (!IsWebRequestEvent(event_name))
|
| return;
|
|
|
| @@ -748,6 +731,7 @@ void ExtensionWebRequestEventRouter::AddEventListener(
|
| listener.sub_event_name = sub_event_name;
|
| listener.filter = filter;
|
| listener.extra_info_spec = extra_info_spec;
|
| + listener.ipc_sender = ipc_sender;
|
|
|
| CHECK_EQ(listeners_[profile_id][event_name].count(listener), 0u) <<
|
| "extension=" << extension_id << " event=" << event_name;
|
| @@ -788,23 +772,39 @@ void ExtensionWebRequestEventRouter::RemoveEventListener(
|
| listeners_[profile_id][event_name].erase(listener);
|
| }
|
|
|
| -std::vector<const ExtensionWebRequestEventRouter::EventListener*>
|
| -ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| +void ExtensionWebRequestEventRouter::OnOTRProfileCreated(
|
| + ProfileId original_profile_id, ProfileId otr_profile_id) {
|
| + cross_profile_map_[original_profile_id] = otr_profile_id;
|
| + cross_profile_map_[otr_profile_id] = original_profile_id;
|
| +}
|
| +
|
| +void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed(
|
| + ProfileId original_profile_id, ProfileId otr_profile_id) {
|
| + cross_profile_map_.erase(otr_profile_id);
|
| + cross_profile_map_.erase(original_profile_id);
|
| +}
|
| +
|
| +void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
|
| ProfileId profile_id,
|
| + ExtensionInfoMap* extension_info_map,
|
| + bool crosses_incognito,
|
| const std::string& event_name,
|
| const GURL& url,
|
| int tab_id,
|
| int window_id,
|
| ResourceType::Type resource_type,
|
| - int* extra_info_spec) {
|
| - // TODO(mpcomplete): handle profile_id == invalid (should collect all
|
| - // listeners).
|
| - *extra_info_spec = 0;
|
| -
|
| - std::vector<const EventListener*> matching_listeners;
|
| + int* extra_info_spec,
|
| + std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
|
| + matching_listeners) {
|
| std::set<EventListener>& listeners = listeners_[profile_id][event_name];
|
| for (std::set<EventListener>::iterator it = listeners.begin();
|
| it != listeners.end(); ++it) {
|
| + if (!it->ipc_sender.get()) {
|
| + // The IPC sender has been deleted. This listener will be removed soon
|
| + // via a call to RemoveEventListener. For now, just skip it.
|
| + continue;
|
| + }
|
| +
|
| if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url))
|
| continue;
|
| if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id)
|
| @@ -816,15 +816,57 @@ ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| resource_type) == it->filter.types.end())
|
| continue;
|
|
|
| - matching_listeners.push_back(&(*it));
|
| + // Check if this event crosses incognito boundaries when it shouldn't.
|
| + // extension_info_map can be NULL if this is a system-level request.
|
| + if (extension_info_map) {
|
| + const Extension* extension =
|
| + extension_info_map->extensions().GetByID(it->extension_id);
|
| + if (!extension ||
|
| + (crosses_incognito &&
|
| + !extension_info_map->CanCrossIncognito(extension)))
|
| + continue;
|
| + }
|
| +
|
| + matching_listeners->push_back(&(*it));
|
| *extra_info_spec |= it->extra_info_spec;
|
| }
|
| +}
|
| +
|
| +std::vector<const ExtensionWebRequestEventRouter::EventListener*>
|
| +ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| + ProfileId profile_id,
|
| + ExtensionInfoMap* extension_info_map,
|
| + const std::string& event_name,
|
| + const GURL& url,
|
| + int tab_id,
|
| + int window_id,
|
| + ResourceType::Type resource_type,
|
| + int* extra_info_spec) {
|
| + // TODO(mpcomplete): handle profile_id == invalid (should collect all
|
| + // listeners).
|
| + *extra_info_spec = 0;
|
| +
|
| + std::vector<const ExtensionWebRequestEventRouter::EventListener*>
|
| + matching_listeners;
|
| +
|
| + GetMatchingListenersImpl(
|
| + profile_id, extension_info_map, false, event_name, url,
|
| + tab_id, window_id, resource_type, extra_info_spec, &matching_listeners);
|
| + CrossProfileMap::const_iterator cross_profile_id =
|
| + cross_profile_map_.find(profile_id);
|
| + if (cross_profile_id != cross_profile_map_.end()) {
|
| + GetMatchingListenersImpl(
|
| + cross_profile_id->second, extension_info_map, true, event_name, url,
|
| + tab_id, window_id, resource_type, extra_info_spec, &matching_listeners);
|
| + }
|
| +
|
| return matching_listeners;
|
| }
|
|
|
| std::vector<const ExtensionWebRequestEventRouter::EventListener*>
|
| ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| ProfileId profile_id,
|
| + ExtensionInfoMap* extension_info_map,
|
| const std::string& event_name,
|
| net::URLRequest* request,
|
| int* extra_info_spec) {
|
| @@ -834,8 +876,8 @@ ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
|
|
|
| return GetMatchingListeners(
|
| - profile_id, event_name, request->url(), tab_id, window_id, resource_type,
|
| - extra_info_spec);
|
| + profile_id, extension_info_map, event_name, request->url(),
|
| + tab_id, window_id, resource_type, extra_info_spec);
|
| }
|
|
|
| void ExtensionWebRequestEventRouter::DecrementBlockCount(
|
| @@ -955,12 +997,9 @@ bool WebRequestAddEventListener::RunImpl() {
|
| std::string sub_event_name;
|
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name));
|
|
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - NewRunnableFunction(
|
| - &AddEventListenerOnIOThread,
|
| - profile()->GetRuntimeId(), extension_id(),
|
| - event_name, sub_event_name, filter, extra_info_spec));
|
| + ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
|
| + profile_id(), extension_id(), event_name, sub_event_name, filter,
|
| + extra_info_spec, ipc_sender_weak());
|
|
|
| return true;
|
| }
|
| @@ -985,8 +1024,7 @@ bool WebRequestEventHandled::RunImpl() {
|
|
|
| if (!value->empty()) {
|
| base::Time install_time =
|
| - profile()->GetExtensionService()->extension_prefs()->
|
| - GetInstallTime(extension_id());
|
| + extension_info_map()->GetInstallTime(extension_id());
|
| response.reset(new ExtensionWebRequestEventRouter::EventResponse(
|
| extension_id(), install_time));
|
| }
|
| @@ -1036,12 +1074,9 @@ bool WebRequestEventHandled::RunImpl() {
|
| }
|
| }
|
|
|
| - BrowserThread::PostTask(
|
| - BrowserThread::IO, FROM_HERE,
|
| - NewRunnableFunction(
|
| - &EventHandledOnIOThread,
|
| - profile()->GetRuntimeId(), extension_id(),
|
| - event_name, sub_event_name, request_id, response.release()));
|
| + ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
|
| + profile_id(), extension_id(), event_name, sub_event_name, request_id,
|
| + response.release());
|
|
|
| return true;
|
| }
|
|
|