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

Side by Side 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: Merge with ToT + cleanup Created 7 years, 7 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 unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "chrome/browser/extensions/api/web_request/web_request_api.h" 5 #include "chrome/browser/extensions/api/web_request/web_request_api.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/bind_helpers.h" 10 #include "base/bind_helpers.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 using extensions::web_navigation_api_helpers::GetFrameId; 76 using extensions::web_navigation_api_helpers::GetFrameId;
77 77
78 namespace helpers = extension_web_request_api_helpers; 78 namespace helpers = extension_web_request_api_helpers;
79 namespace keys = extension_web_request_api_constants; 79 namespace keys = extension_web_request_api_constants;
80 namespace web_request = extensions::api::web_request; 80 namespace web_request = extensions::api::web_request;
81 namespace declarative_keys = extensions::declarative_webrequest_constants; 81 namespace declarative_keys = extensions::declarative_webrequest_constants;
82 namespace activitylog = activity_log_web_request_constants; 82 namespace activitylog = activity_log_web_request_constants;
83 83
84 namespace { 84 namespace {
85 85
86 const char kWebRequest[] = "webRequest";
87 const char kWebView[] = "webview";
88
86 // List of all the webRequest events. 89 // List of all the webRequest events.
87 const char* const kWebRequestEvents[] = { 90 const char* const kWebRequestEvents[] = {
88 keys::kOnBeforeRedirectEvent, 91 keys::kOnBeforeRedirectEvent,
89 keys::kOnBeforeRequestEvent, 92 keys::kOnBeforeRequestEvent,
90 keys::kOnBeforeSendHeadersEvent, 93 keys::kOnBeforeSendHeadersEvent,
91 keys::kOnCompletedEvent, 94 keys::kOnCompletedEvent,
92 keys::kOnErrorOccurredEvent, 95 keys::kOnErrorOccurredEvent,
93 keys::kOnSendHeadersEvent, 96 keys::kOnSendHeadersEvent,
94 keys::kOnAuthRequiredEvent, 97 keys::kOnAuthRequiredEvent,
95 keys::kOnResponseStartedEvent, 98 keys::kOnResponseStartedEvent,
(...skipping 24 matching lines...) Expand all
120 case ExtensionWebRequestEventRouter::kOnErrorOccurred: 123 case ExtensionWebRequestEventRouter::kOnErrorOccurred:
121 return keys::kOnErrorOccurred; 124 return keys::kOnErrorOccurred;
122 case ExtensionWebRequestEventRouter::kOnCompleted: 125 case ExtensionWebRequestEventRouter::kOnCompleted:
123 return keys::kOnCompleted; 126 return keys::kOnCompleted;
124 } 127 }
125 NOTREACHED(); 128 NOTREACHED();
126 return "Not reached"; 129 return "Not reached";
127 } 130 }
128 131
129 bool IsWebRequestEvent(const std::string& event_name) { 132 bool IsWebRequestEvent(const std::string& event_name) {
133 std::string web_request_event_name(event_name);
134 if (web_request_event_name.find(kWebView) != std::string::npos)
135 web_request_event_name.replace(0, sizeof(kWebView) - 1, kWebRequest);
130 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents), 136 return std::find(kWebRequestEvents, ARRAYEND(kWebRequestEvents),
131 event_name) != ARRAYEND(kWebRequestEvents); 137 web_request_event_name) != ARRAYEND(kWebRequestEvents);
132 } 138 }
133 139
134 // Returns whether |request| has been triggered by an extension in 140 // Returns whether |request| has been triggered by an extension in
135 // |extension_info_map|. 141 // |extension_info_map|.
136 bool IsRequestFromExtension(const net::URLRequest* request, 142 bool IsRequestFromExtension(const net::URLRequest* request,
137 const ExtensionInfoMap* extension_info_map) { 143 const ExtensionInfoMap* extension_info_map) {
138 // |extension_info_map| is NULL for system-level requests. 144 // |extension_info_map| is NULL for system-level requests.
139 if (!extension_info_map) 145 if (!extension_info_map)
140 return false; 146 return false;
141 147
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after
355 // added. 361 // added.
356 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does 362 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does
357 // not play well with event pages. See downloads.onDeterminingFilename and 363 // not play well with event pages. See downloads.onDeterminingFilename and
358 // ExtensionDownloadsEventRouter for an alternative approach. 364 // ExtensionDownloadsEventRouter for an alternative approach.
359 struct ExtensionWebRequestEventRouter::EventListener { 365 struct ExtensionWebRequestEventRouter::EventListener {
360 std::string extension_id; 366 std::string extension_id;
361 std::string extension_name; 367 std::string extension_name;
362 std::string sub_event_name; 368 std::string sub_event_name;
363 RequestFilter filter; 369 RequestFilter filter;
364 int extra_info_spec; 370 int extra_info_spec;
365 int target_process_id; 371 int embedder_process_id;
366 int target_route_id; 372 int web_view_instance_id;
367 base::WeakPtr<IPC::Sender> ipc_sender; 373 base::WeakPtr<IPC::Sender> ipc_sender;
368 mutable std::set<uint64> blocked_requests; 374 mutable std::set<uint64> blocked_requests;
369 375
370 // Comparator to work with std::set. 376 // Comparator to work with std::set.
371 bool operator<(const EventListener& that) const { 377 bool operator<(const EventListener& that) const {
372 if (extension_id < that.extension_id) 378 if (extension_id < that.extension_id)
373 return true; 379 return true;
374 if (extension_id == that.extension_id && 380 if (extension_id == that.extension_id &&
375 sub_event_name < that.sub_event_name) 381 sub_event_name < that.sub_event_name)
376 return true; 382 return true;
(...skipping 739 matching lines...) Expand 10 before | Expand all | Expand 10 after
1116 } 1122 }
1117 1123
1118 bool ExtensionWebRequestEventRouter::AddEventListener( 1124 bool ExtensionWebRequestEventRouter::AddEventListener(
1119 void* profile, 1125 void* profile,
1120 const std::string& extension_id, 1126 const std::string& extension_id,
1121 const std::string& extension_name, 1127 const std::string& extension_name,
1122 const std::string& event_name, 1128 const std::string& event_name,
1123 const std::string& sub_event_name, 1129 const std::string& sub_event_name,
1124 const RequestFilter& filter, 1130 const RequestFilter& filter,
1125 int extra_info_spec, 1131 int extra_info_spec,
1126 int target_process_id, 1132 int embedder_process_id,
1127 int target_route_id, 1133 int web_view_instance_id,
1128 base::WeakPtr<IPC::Sender> ipc_sender) { 1134 base::WeakPtr<IPC::Sender> ipc_sender) {
1135
1129 if (!IsWebRequestEvent(event_name)) 1136 if (!IsWebRequestEvent(event_name))
1130 return false; 1137 return false;
1131 1138
1132 EventListener listener; 1139 EventListener listener;
1133 listener.extension_id = extension_id; 1140 listener.extension_id = extension_id;
1134 listener.extension_name = extension_name; 1141 listener.extension_name = extension_name;
1135 listener.sub_event_name = sub_event_name; 1142 listener.sub_event_name = sub_event_name;
1136 listener.filter = filter; 1143 listener.filter = filter;
1137 listener.extra_info_spec = extra_info_spec; 1144 listener.extra_info_spec = extra_info_spec;
1138 listener.ipc_sender = ipc_sender; 1145 listener.ipc_sender = ipc_sender;
1139 listener.target_process_id = target_process_id; 1146 listener.embedder_process_id = embedder_process_id;
1140 listener.target_route_id = target_route_id; 1147 listener.web_view_instance_id = web_view_instance_id;
1141 1148
1142 if (listeners_[profile][event_name].count(listener) != 0u) { 1149 if (listeners_[profile][event_name].count(listener) != 0u) {
1143 // This is likely an abuse of the API by a malicious extension. 1150 // This is likely an abuse of the API by a malicious extension.
1144 return false; 1151 return false;
1145 } 1152 }
1146 listeners_[profile][event_name].insert(listener); 1153 listeners_[profile][event_name].insert(listener);
1147 return true; 1154 return true;
1148 } 1155 }
1149 1156
1150 void ExtensionWebRequestEventRouter::RemoveEventListener( 1157 void ExtensionWebRequestEventRouter::RemoveEventListener(
(...skipping 25 matching lines...) Expand all
1176 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 1183 for (std::set<uint64>::iterator it = found->blocked_requests.begin();
1177 it != found->blocked_requests.end(); ++it) { 1184 it != found->blocked_requests.end(); ++it) {
1178 DecrementBlockCount(profile, extension_id, event_name, *it, NULL); 1185 DecrementBlockCount(profile, extension_id, event_name, *it, NULL);
1179 } 1186 }
1180 1187
1181 listeners_[profile][event_name].erase(listener); 1188 listeners_[profile][event_name].erase(listener);
1182 1189
1183 helpers::ClearCacheOnNavigation(); 1190 helpers::ClearCacheOnNavigation();
1184 } 1191 }
1185 1192
1193 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners(
1194 void* profile,
1195 const std::string& extension_id,
1196 int embedder_process_id,
1197 int web_view_instance_id) {
1198 // Iterate over all listeners of all WebRequest events to delete
1199 // any listeners that belong to the provided <webview>.
1200 bool found_listeners = false;
1201 ListenerMapForProfile& map_for_profile = listeners_[profile];
1202 for (ListenerMapForProfile::iterator event_iter = map_for_profile.begin();
1203 event_iter != map_for_profile.end(); ++event_iter) {
1204 std::vector<EventListener> listeners_to_delete;
1205 const std::string& event_name = event_iter->first;
1206 std::set<EventListener>& listeners = event_iter->second;
1207 for (std::set<EventListener>::iterator listener_iter = listeners.begin();
1208 listener_iter != listeners.end(); ++listener_iter) {
1209 const EventListener& listener = *listener_iter;
1210 if (listener.embedder_process_id == embedder_process_id &&
1211 listener.web_view_instance_id == web_view_instance_id)
1212 listeners_to_delete.push_back(listener);
1213 }
1214 for (size_t i = 0; i < listeners_to_delete.size(); ++i) {
1215 found_listeners = true;
1216 EventListener& listener = listeners_to_delete[i];
1217 listeners.erase(listeners_to_delete[i]);
1218 // Unblock any request that this event listener may have been blocking.
1219 for (std::set<uint64>::iterator it = listener.blocked_requests.begin();
1220 it != listener.blocked_requests.end(); ++it) {
1221 DecrementBlockCount(profile, extension_id, event_name, *it, NULL);
1222 }
1223 }
1224 }
1225 if (found_listeners)
1226 helpers::ClearCacheOnNavigation();
1227 }
1228
1186 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( 1229 void ExtensionWebRequestEventRouter::OnOTRProfileCreated(
1187 void* original_profile, void* otr_profile) { 1230 void* original_profile, void* otr_profile) {
1188 cross_profile_map_[original_profile] = otr_profile; 1231 cross_profile_map_[original_profile] = otr_profile;
1189 cross_profile_map_[otr_profile] = original_profile; 1232 cross_profile_map_[otr_profile] = original_profile;
1190 } 1233 }
1191 1234
1192 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed( 1235 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed(
1193 void* original_profile, void* otr_profile) { 1236 void* original_profile, void* otr_profile) {
1194 cross_profile_map_.erase(otr_profile); 1237 cross_profile_map_.erase(otr_profile);
1195 cross_profile_map_.erase(original_profile); 1238 cross_profile_map_.erase(original_profile);
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1253 int tab_id, 1296 int tab_id,
1254 int window_id, 1297 int window_id,
1255 int render_process_host_id, 1298 int render_process_host_id,
1256 int routing_id, 1299 int routing_id,
1257 ResourceType::Type resource_type, 1300 ResourceType::Type resource_type,
1258 bool is_async_request, 1301 bool is_async_request,
1259 bool is_request_from_extension, 1302 bool is_request_from_extension,
1260 int* extra_info_spec, 1303 int* extra_info_spec,
1261 std::vector<const ExtensionWebRequestEventRouter::EventListener*>* 1304 std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
1262 matching_listeners) { 1305 matching_listeners) {
1306 std::string web_request_event_name(event_name);
1263 ExtensionRendererState::WebViewInfo web_view_info; 1307 ExtensionRendererState::WebViewInfo web_view_info;
1264 bool is_guest = ExtensionRendererState::GetInstance()-> 1308 bool is_guest = ExtensionRendererState::GetInstance()->
1265 GetWebViewInfo(render_process_host_id, routing_id, &web_view_info); 1309 GetWebViewInfo(render_process_host_id, routing_id, &web_view_info);
1266 std::set<EventListener>& listeners = listeners_[profile][event_name]; 1310 if (is_guest)
1311 web_request_event_name.replace(0, sizeof(kWebRequest) - 1, kWebView);
1312
1313 std::set<EventListener>& listeners =
1314 listeners_[profile][web_request_event_name];
1267 for (std::set<EventListener>::iterator it = listeners.begin(); 1315 for (std::set<EventListener>::iterator it = listeners.begin();
1268 it != listeners.end(); ++it) { 1316 it != listeners.end(); ++it) {
1269 if (!it->ipc_sender.get()) { 1317 if (!it->ipc_sender.get()) {
1270 // The IPC sender has been deleted. This listener will be removed soon 1318 // The IPC sender has been deleted. This listener will be removed soon
1271 // via a call to RemoveEventListener. For now, just skip it. 1319 // via a call to RemoveEventListener. For now, just skip it.
1272 continue; 1320 continue;
1273 } 1321 }
1274 1322
1275 if (is_guest && (it->target_process_id != render_process_host_id|| 1323 if (is_guest &&
1276 it->target_route_id != routing_id)) 1324 (it->embedder_process_id != web_view_info.embedder_process_id ||
1325 it->web_view_instance_id != web_view_info.web_view_instance_id))
1277 continue; 1326 continue;
1278 1327
1279 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) 1328 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url))
1280 continue; 1329 continue;
1281 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) 1330 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id)
1282 continue; 1331 continue;
1283 if (it->filter.window_id != -1 && window_id != it->filter.window_id) 1332 if (it->filter.window_id != -1 && window_id != it->filter.window_id)
1284 continue; 1333 continue;
1285 if (!it->filter.types.empty() && 1334 if (!it->filter.types.empty() &&
1286 std::find(it->filter.types.begin(), it->filter.types.end(), 1335 std::find(it->filter.types.begin(), it->filter.types.end(),
1287 resource_type) == it->filter.types.end()) 1336 resource_type) == it->filter.types.end())
1288 continue; 1337 continue;
1289 1338
1290 if (!WebRequestPermissions::CanExtensionAccessURL( 1339 if (!is_guest && !WebRequestPermissions::CanExtensionAccessURL(
1291 extension_info_map, it->extension_id, url, crosses_incognito, 1340 extension_info_map, it->extension_id, url, crosses_incognito,
1292 WebRequestPermissions::REQUIRE_HOST_PERMISSION)) 1341 WebRequestPermissions::REQUIRE_HOST_PERMISSION))
1293 continue; 1342 continue;
1294 1343
1295 bool blocking_listener = 1344 bool blocking_listener =
1296 (it->extra_info_spec & 1345 (it->extra_info_spec &
1297 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0; 1346 (ExtraInfoSpec::BLOCKING | ExtraInfoSpec::ASYNC_BLOCKING)) != 0;
1298 1347
1299 // We do not want to notify extensions about XHR requests that are 1348 // We do not want to notify extensions about XHR requests that are
1300 // triggered by themselves. This is a workaround to prevent deadlocks 1349 // triggered by themselves. This is a workaround to prevent deadlocks
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
1968 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 2017 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
1969 *value, &extra_info_spec)); 2018 *value, &extra_info_spec));
1970 } 2019 }
1971 2020
1972 std::string event_name; 2021 std::string event_name;
1973 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); 2022 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name));
1974 2023
1975 std::string sub_event_name; 2024 std::string sub_event_name;
1976 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); 2025 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name));
1977 2026
2027 int web_view_instance_id = 0;
2028 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id));
2029
2030 base::WeakPtr<ChromeRenderMessageFilter> ipc_sender = ipc_sender_weak();
2031
2032 int embedder_process_id =
2033 ipc_sender.get() ? ipc_sender->render_process_id() : -1;
2034
1978 const Extension* extension = 2035 const Extension* extension =
1979 extension_info_map()->extensions().GetByID(extension_id()); 2036 extension_info_map()->extensions().GetByID(extension_id());
1980 std::string extension_name = extension ? extension->name() : extension_id(); 2037 std::string extension_name = extension ? extension->name() : extension_id();
1981 2038
2039 bool is_guest = web_view_instance_id != 0;
1982 // We check automatically whether the extension has the 'webRequest' 2040 // We check automatically whether the extension has the 'webRequest'
1983 // permission. For blocking calls we require the additional permission 2041 // permission. For blocking calls we require the additional permission
1984 // 'webRequestBlocking'. 2042 // 'webRequestBlocking'.
1985 if ((extra_info_spec & 2043 if ((!is_guest && extra_info_spec &
1986 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | 2044 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING |
1987 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && 2045 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) &&
1988 !extension->HasAPIPermission( 2046 !extension->HasAPIPermission(
1989 extensions::APIPermission::kWebRequestBlocking)) { 2047 extensions::APIPermission::kWebRequestBlocking)) {
1990 error_ = keys::kBlockingPermissionRequired; 2048 error_ = keys::kBlockingPermissionRequired;
1991 return false; 2049 return false;
1992 } 2050 }
1993 2051
1994 // We allow to subscribe to patterns that are broader than the host 2052 // We allow to subscribe to patterns that are broader than the host
1995 // permissions. E.g., we could subscribe to http://www.example.com/* 2053 // permissions. E.g., we could subscribe to http://www.example.com/*
1996 // while having host permissions for http://www.example.com/foo/* and 2054 // while having host permissions for http://www.example.com/foo/* and
1997 // http://www.example.com/bar/*. 2055 // http://www.example.com/bar/*.
1998 // For this reason we do only a coarse check here to warn the extension 2056 // For this reason we do only a coarse check here to warn the extension
1999 // developer if he does something obviously wrong. 2057 // developer if he does something obviously wrong.
2000 if (extension->GetEffectiveHostPermissions().is_empty()) { 2058 if (!is_guest && extension->GetEffectiveHostPermissions().is_empty()) {
2001 error_ = keys::kHostPermissionsRequired; 2059 error_ = keys::kHostPermissionsRequired;
2002 return false; 2060 return false;
2003 } 2061 }
2004 2062
2005 bool success = 2063 bool success =
2006 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( 2064 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
2007 profile_id(), extension_id(), extension_name, 2065 profile_id(), extension_id(), extension_name,
2008 event_name, sub_event_name, filter, 2066 event_name, sub_event_name, filter, extra_info_spec,
2009 extra_info_spec, -1, -1, ipc_sender_weak()); 2067 embedder_process_id, web_view_instance_id, ipc_sender_weak());
2010 EXTENSION_FUNCTION_VALIDATE(success); 2068 EXTENSION_FUNCTION_VALIDATE(success);
2011 2069
2012 helpers::ClearCacheOnNavigation(); 2070 helpers::ClearCacheOnNavigation();
2013 2071
2014 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind( 2072 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, base::Bind(
2015 &helpers::NotifyWebRequestAPIUsed, 2073 &helpers::NotifyWebRequestAPIUsed,
2016 profile_id(), make_scoped_refptr(GetExtension()))); 2074 profile_id(), make_scoped_refptr(GetExtension())));
2017 2075
2018 return true; 2076 return true;
2019 } 2077 }
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
2179 } else if ((*it)->name().find("AdBlock") != std::string::npos) { 2237 } else if ((*it)->name().find("AdBlock") != std::string::npos) {
2180 adblock = true; 2238 adblock = true;
2181 } else { 2239 } else {
2182 other = true; 2240 other = true;
2183 } 2241 }
2184 } 2242 }
2185 } 2243 }
2186 2244
2187 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other)); 2245 host->Send(new ExtensionMsg_UsingWebRequestAPI(adblock, adblock_plus, other));
2188 } 2246 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698