Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1372)

Unified Diff: chrome/browser/extensions/api/web_request/web_request_api.cc

Issue 12189018: <webview>: Implement WebRequest API (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Diff from latest patch Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
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();

Powered by Google App Engine
This is Rietveld 408576698