Chromium Code Reviews| 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 d1da6838450407fe8b53c19c763247235d140591..1e312d8f44b17e00e64376b8a4f2c791e273de3e 100644 |
| --- a/chrome/browser/extensions/api/web_request/web_request_api.cc |
| +++ b/chrome/browser/extensions/api/web_request/web_request_api.cc |
| @@ -80,6 +80,9 @@ namespace declarative_keys = extensions::declarative_webrequest_constants; |
| namespace { |
| +const char kWebRequest[] = "webRequest"; |
| +const char kWebView[] = "webview"; |
| + |
| // List of all the webRequest events. |
| const char* const kWebRequestEvents[] = { |
| keys::kOnBeforeRedirectEvent, |
| @@ -124,8 +127,11 @@ const char* GetRequestStageAsString( |
| } |
| bool IsWebRequestEvent(const std::string& event_name) { |
| + std::string web_request_event_name(event_name); |
| + if (web_request_event_name.find(kWebView) != std::string::npos) |
| + web_request_event_name.replace(0, sizeof(kWebView) - 1, kWebRequest); |
| return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), |
| - event_name) != ARRAYEND(kWebRequestEvents); |
| + web_request_event_name) != ARRAYEND(kWebRequestEvents); |
| } |
| // Returns whether |request| has been triggered by an extension in |
| @@ -375,8 +381,9 @@ struct ExtensionWebRequestEventRouter::EventListener { |
| std::string sub_event_name; |
| RequestFilter filter; |
| int extra_info_spec; |
| - int target_process_id; |
| - int target_route_id; |
| + int caller_process_id; |
|
Matt Perry
2013/02/06 22:40:24
nit: embedder_process_id
Fady Samuel
2013/05/15 21:58:53
Done.
|
| + int caller_routing_id; |
| + int web_view_instance_id; |
| base::WeakPtr<IPC::Sender> ipc_sender; |
| mutable std::set<uint64> blocked_requests; |
| @@ -1137,9 +1144,11 @@ bool ExtensionWebRequestEventRouter::AddEventListener( |
| const std::string& sub_event_name, |
| const RequestFilter& filter, |
| int extra_info_spec, |
| - int target_process_id, |
| - int target_route_id, |
| + int caller_process_id, |
| + int caller_routing_id, |
| + int web_view_instance_id, |
| base::WeakPtr<IPC::Sender> ipc_sender) { |
| + |
| if (!IsWebRequestEvent(event_name)) |
| return false; |
| @@ -1150,8 +1159,9 @@ bool ExtensionWebRequestEventRouter::AddEventListener( |
| listener.filter = filter; |
| listener.extra_info_spec = extra_info_spec; |
| listener.ipc_sender = ipc_sender; |
| - listener.target_process_id = target_process_id; |
| - listener.target_route_id = target_route_id; |
| + listener.caller_process_id = caller_process_id; |
| + listener.caller_routing_id = caller_routing_id; |
| + listener.web_view_instance_id = web_view_instance_id; |
| if (listeners_[profile][event_name].count(listener) != 0u) { |
| // This is likely an abuse of the API by a malicious extension. |
| @@ -1197,6 +1207,44 @@ void ExtensionWebRequestEventRouter::RemoveEventListener( |
| helpers::ClearCacheOnNavigation(); |
| } |
| +void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( |
|
Matt Perry
2013/02/06 22:40:24
Are you sure this is necessary? When a context goe
Fady Samuel
2013/05/15 21:58:53
Yes, this is necessary because the listeners a <we
Matt Perry
2013/05/16 21:16:38
I don't understand what you mean.
To clarify my c
|
| + void* profile, |
| + const std::string& extension_id, |
| + int embedder_process_id, |
| + int embedder_routing_id, |
| + int web_view_instance_id) { |
| + // Iterate over all listeners of all WebRequest events to delete |
| + // any listeners that belong to the provided <webview>. |
| + bool found_listeners = false; |
| + ListenerMapForProfile& map_for_profile = listeners_[profile]; |
| + for (ListenerMapForProfile::iterator event_iter = map_for_profile.begin(); |
| + event_iter != map_for_profile.end(); ++event_iter) { |
| + std::vector<EventListener> listeners_to_delete; |
| + const std::string& event_name = event_iter->first; |
| + std::set<EventListener>& listeners = event_iter->second; |
| + for (std::set<EventListener>::iterator listener_iter = listeners.begin(); |
| + listener_iter != listeners.end(); ++listener_iter) { |
| + const EventListener& listener = *listener_iter; |
| + if (listener.caller_process_id == embedder_process_id && |
| + listener.caller_routing_id == embedder_routing_id && |
| + listener.web_view_instance_id == web_view_instance_id) |
| + listeners_to_delete.push_back(listener); |
| + } |
| + for (size_t i = 0; i < listeners_to_delete.size(); ++i) { |
| + found_listeners = true; |
| + EventListener& listener = listeners_to_delete[i]; |
| + listeners.erase(listeners_to_delete[i]); |
| + // Unblock any request that this event listener may have been blocking. |
| + for (std::set<uint64>::iterator it = listener.blocked_requests.begin(); |
| + it != listener.blocked_requests.end(); ++it) { |
| + DecrementBlockCount(profile, extension_id, event_name, *it, NULL); |
| + } |
| + } |
| + } |
| + if (found_listeners) |
| + helpers::ClearCacheOnNavigation(); |
| +} |
| + |
| void ExtensionWebRequestEventRouter::OnOTRProfileCreated( |
| void* original_profile, void* otr_profile) { |
| cross_profile_map_[original_profile] = otr_profile; |
| @@ -1274,10 +1322,15 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
| int* extra_info_spec, |
| std::vector<const ExtensionWebRequestEventRouter::EventListener*>* |
| matching_listeners) { |
| + std::string web_request_event_name(event_name); |
| ExtensionRendererState::WebViewInfo web_view_info; |
| bool is_guest = ExtensionRendererState::GetInstance()-> |
| GetWebViewInfo(render_process_host_id, routing_id, &web_view_info); |
| - std::set<EventListener>& listeners = listeners_[profile][event_name]; |
| + if (is_guest) |
| + web_request_event_name.replace(0, sizeof(kWebRequest) - 1, kWebView); |
| + |
| + std::set<EventListener>& listeners = |
| + listeners_[profile][web_request_event_name]; |
| for (std::set<EventListener>::iterator it = listeners.begin(); |
| it != listeners.end(); ++it) { |
| if (!it->ipc_sender.get()) { |
| @@ -1286,8 +1339,10 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
| continue; |
| } |
| - if (is_guest && (it->target_process_id != render_process_host_id|| |
| - it->target_route_id != routing_id)) |
| + if (is_guest && |
| + (it->caller_process_id != web_view_info.embedder_process_id || |
| + it->caller_routing_id != web_view_info.embedder_routing_id || |
| + it->web_view_instance_id != web_view_info.web_view_instance_id)) |
| continue; |
| if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) |
| @@ -1301,7 +1356,7 @@ void ExtensionWebRequestEventRouter::GetMatchingListenersImpl( |
| resource_type) == it->filter.types.end()) |
| continue; |
| - if (!WebRequestPermissions::CanExtensionAccessURL( |
| + if (!is_guest && !WebRequestPermissions::CanExtensionAccessURL( |
| extension_info_map, it->extension_id, url, crosses_incognito, true)) |
| continue; |
| @@ -1826,14 +1881,21 @@ bool WebRequestAddEventListener::RunImpl() { |
| std::string sub_event_name; |
| EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); |
| + int web_view_instance_id = 0; |
| + EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id)); |
| + |
| + int caller_process_id = ipc_sender()->render_process_id(); |
| + int caller_routing_id = routing_id(); |
| + |
| const Extension* extension = |
| extension_info_map()->extensions().GetByID(extension_id()); |
| std::string extension_name = extension ? extension->name() : extension_id(); |
| + bool is_guest = web_view_instance_id != 0; |
| // We check automatically whether the extension has the 'webRequest' |
| // permission. For blocking calls we require the additional permission |
| // 'webRequestBlocking'. |
| - if ((extra_info_spec & |
| + if ((!is_guest && extra_info_spec & |
| (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | |
| ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && |
| !extension->HasAPIPermission( |
| @@ -1848,7 +1910,7 @@ bool WebRequestAddEventListener::RunImpl() { |
| // http://www.example.com/bar/*. |
| // For this reason we do only a coarse check here to warn the extension |
| // developer if he does something obviously wrong. |
| - if (extension->GetEffectiveHostPermissions().is_empty()) { |
| + if (!is_guest && extension->GetEffectiveHostPermissions().is_empty()) { |
| error_ = keys::kHostPermissionsRequired; |
| return false; |
| } |
| @@ -1856,8 +1918,9 @@ bool WebRequestAddEventListener::RunImpl() { |
| bool success = |
| ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
| profile_id(), extension_id(), extension_name, |
| - event_name, sub_event_name, filter, |
| - extra_info_spec, -1, -1, ipc_sender_weak()); |
| + event_name, sub_event_name, filter, extra_info_spec, |
| + caller_process_id, caller_routing_id, web_view_instance_id, |
| + ipc_sender_weak()); |
| EXTENSION_FUNCTION_VALIDATE(success); |
| helpers::ClearCacheOnNavigation(); |