OLD | NEW |
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 "extensions/browser/api/web_request/web_request_api.h" | 5 #include "extensions/browser/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 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
451 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does | 451 // NOTE(benjhayden) New APIs should not use this sub_event_name trick! It does |
452 // not play well with event pages. See downloads.onDeterminingFilename and | 452 // not play well with event pages. See downloads.onDeterminingFilename and |
453 // ExtensionDownloadsEventRouter for an alternative approach. | 453 // ExtensionDownloadsEventRouter for an alternative approach. |
454 struct ExtensionWebRequestEventRouter::EventListener { | 454 struct ExtensionWebRequestEventRouter::EventListener { |
455 std::string extension_id; | 455 std::string extension_id; |
456 std::string extension_name; | 456 std::string extension_name; |
457 std::string sub_event_name; | 457 std::string sub_event_name; |
458 RequestFilter filter; | 458 RequestFilter filter; |
459 int extra_info_spec; | 459 int extra_info_spec; |
460 int embedder_process_id; | 460 int embedder_process_id; |
461 int webview_instance_id; | 461 int web_view_instance_id; |
462 base::WeakPtr<IPC::Sender> ipc_sender; | 462 base::WeakPtr<IPC::Sender> ipc_sender; |
463 mutable std::set<uint64> blocked_requests; | 463 mutable std::set<uint64> blocked_requests; |
464 | 464 |
465 // Comparator to work with std::set. | 465 // Comparator to work with std::set. |
466 bool operator<(const EventListener& that) const { | 466 bool operator<(const EventListener& that) const { |
467 if (extension_id < that.extension_id) | 467 if (extension_id != that.extension_id) |
468 return true; | 468 return extension_id < that.extension_id; |
469 if (extension_id == that.extension_id && | 469 |
470 sub_event_name < that.sub_event_name) | 470 if (sub_event_name != that.sub_event_name) |
471 return true; | 471 return sub_event_name < that.sub_event_name; |
| 472 |
| 473 if (embedder_process_id != that.embedder_process_id) |
| 474 return embedder_process_id < that.embedder_process_id; |
| 475 |
| 476 if (web_view_instance_id != that.web_view_instance_id) |
| 477 return web_view_instance_id < that.web_view_instance_id; |
| 478 |
472 return false; | 479 return false; |
473 } | 480 } |
474 | 481 |
475 EventListener() : extra_info_spec(0) {} | 482 EventListener() : |
| 483 extra_info_spec(0), |
| 484 embedder_process_id(0), |
| 485 web_view_instance_id(0) {} |
476 }; | 486 }; |
477 | 487 |
478 // Contains info about requests that are blocked waiting for a response from | 488 // Contains info about requests that are blocked waiting for a response from |
479 // an extension. | 489 // an extension. |
480 struct ExtensionWebRequestEventRouter::BlockedRequest { | 490 struct ExtensionWebRequestEventRouter::BlockedRequest { |
481 // The request that is being blocked. | 491 // The request that is being blocked. |
482 net::URLRequest* request; | 492 net::URLRequest* request; |
483 | 493 |
484 // Whether the request originates from an incognito tab. | 494 // Whether the request originates from an incognito tab. |
485 bool is_incognito; | 495 bool is_incognito; |
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1272 | 1282 |
1273 bool ExtensionWebRequestEventRouter::AddEventListener( | 1283 bool ExtensionWebRequestEventRouter::AddEventListener( |
1274 void* browser_context, | 1284 void* browser_context, |
1275 const std::string& extension_id, | 1285 const std::string& extension_id, |
1276 const std::string& extension_name, | 1286 const std::string& extension_name, |
1277 const std::string& event_name, | 1287 const std::string& event_name, |
1278 const std::string& sub_event_name, | 1288 const std::string& sub_event_name, |
1279 const RequestFilter& filter, | 1289 const RequestFilter& filter, |
1280 int extra_info_spec, | 1290 int extra_info_spec, |
1281 int embedder_process_id, | 1291 int embedder_process_id, |
1282 int webview_instance_id, | 1292 int web_view_instance_id, |
1283 base::WeakPtr<IPC::Sender> ipc_sender) { | 1293 base::WeakPtr<IPC::Sender> ipc_sender) { |
1284 if (!IsWebRequestEvent(event_name)) | 1294 if (!IsWebRequestEvent(event_name)) |
1285 return false; | 1295 return false; |
1286 | 1296 |
1287 EventListener listener; | 1297 EventListener listener; |
1288 listener.extension_id = extension_id; | 1298 listener.extension_id = extension_id; |
1289 listener.extension_name = extension_name; | 1299 listener.extension_name = extension_name; |
1290 listener.sub_event_name = sub_event_name; | 1300 listener.sub_event_name = sub_event_name; |
1291 listener.filter = filter; | 1301 listener.filter = filter; |
1292 listener.extra_info_spec = extra_info_spec; | 1302 listener.extra_info_spec = extra_info_spec; |
1293 listener.ipc_sender = ipc_sender; | 1303 listener.ipc_sender = ipc_sender; |
1294 listener.embedder_process_id = embedder_process_id; | 1304 listener.embedder_process_id = embedder_process_id; |
1295 listener.webview_instance_id = webview_instance_id; | 1305 listener.web_view_instance_id = web_view_instance_id; |
1296 if (listener.webview_instance_id) { | 1306 if (listener.web_view_instance_id) { |
1297 content::RecordAction( | 1307 content::RecordAction( |
1298 base::UserMetricsAction("WebView.WebRequest.AddListener")); | 1308 base::UserMetricsAction("WebView.WebRequest.AddListener")); |
1299 } | 1309 } |
1300 | 1310 |
1301 if (listeners_[browser_context][event_name].count(listener) != 0u) { | 1311 if (listeners_[browser_context][event_name].count(listener) != 0u) { |
1302 // This is likely an abuse of the API by a malicious extension. | 1312 // This is likely an abuse of the API by a malicious extension. |
1303 return false; | 1313 return false; |
1304 } | 1314 } |
1305 listeners_[browser_context][event_name].insert(listener); | 1315 listeners_[browser_context][event_name].insert(listener); |
1306 return true; | 1316 return true; |
(...skipping 30 matching lines...) Expand all Loading... |
1337 | 1347 |
1338 listeners_[browser_context][event_name].erase(listener); | 1348 listeners_[browser_context][event_name].erase(listener); |
1339 | 1349 |
1340 helpers::ClearCacheOnNavigation(); | 1350 helpers::ClearCacheOnNavigation(); |
1341 } | 1351 } |
1342 | 1352 |
1343 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( | 1353 void ExtensionWebRequestEventRouter::RemoveWebViewEventListeners( |
1344 void* browser_context, | 1354 void* browser_context, |
1345 const std::string& extension_id, | 1355 const std::string& extension_id, |
1346 int embedder_process_id, | 1356 int embedder_process_id, |
1347 int webview_instance_id) { | 1357 int web_view_instance_id) { |
1348 // Iterate over all listeners of all WebRequest events to delete | 1358 // Iterate over all listeners of all WebRequest events to delete |
1349 // any listeners that belong to the provided <webview>. | 1359 // any listeners that belong to the provided <webview>. |
1350 ListenerMapForBrowserContext& map_for_browser_context = | 1360 ListenerMapForBrowserContext& map_for_browser_context = |
1351 listeners_[browser_context]; | 1361 listeners_[browser_context]; |
1352 for (ListenerMapForBrowserContext::iterator event_iter = | 1362 for (ListenerMapForBrowserContext::iterator event_iter = |
1353 map_for_browser_context.begin(); | 1363 map_for_browser_context.begin(); |
1354 event_iter != map_for_browser_context.end(); ++event_iter) { | 1364 event_iter != map_for_browser_context.end(); ++event_iter) { |
1355 std::vector<EventListener> listeners_to_delete; | 1365 std::vector<EventListener> listeners_to_delete; |
1356 std::set<EventListener>& listeners = event_iter->second; | 1366 std::set<EventListener>& listeners = event_iter->second; |
1357 for (std::set<EventListener>::iterator listener_iter = listeners.begin(); | 1367 for (std::set<EventListener>::iterator listener_iter = listeners.begin(); |
1358 listener_iter != listeners.end(); ++listener_iter) { | 1368 listener_iter != listeners.end(); ++listener_iter) { |
1359 const EventListener& listener = *listener_iter; | 1369 const EventListener& listener = *listener_iter; |
1360 if (listener.embedder_process_id == embedder_process_id && | 1370 if (listener.embedder_process_id == embedder_process_id && |
1361 listener.webview_instance_id == webview_instance_id) | 1371 listener.web_view_instance_id == web_view_instance_id) |
1362 listeners_to_delete.push_back(listener); | 1372 listeners_to_delete.push_back(listener); |
1363 } | 1373 } |
1364 for (size_t i = 0; i < listeners_to_delete.size(); ++i) { | 1374 for (size_t i = 0; i < listeners_to_delete.size(); ++i) { |
1365 EventListener& listener = listeners_to_delete[i]; | 1375 EventListener& listener = listeners_to_delete[i]; |
1366 content::BrowserThread::PostTask( | 1376 content::BrowserThread::PostTask( |
1367 content::BrowserThread::UI, | 1377 content::BrowserThread::UI, |
1368 FROM_HERE, | 1378 FROM_HERE, |
1369 base::Bind(&RemoveEventListenerOnUI, | 1379 base::Bind(&RemoveEventListenerOnUI, |
1370 browser_context, | 1380 browser_context, |
1371 listener.sub_event_name, | 1381 listener.sub_event_name, |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1475 for (std::set<EventListener>::iterator it = listeners.begin(); | 1485 for (std::set<EventListener>::iterator it = listeners.begin(); |
1476 it != listeners.end(); ++it) { | 1486 it != listeners.end(); ++it) { |
1477 if (!it->ipc_sender.get()) { | 1487 if (!it->ipc_sender.get()) { |
1478 // The IPC sender has been deleted. This listener will be removed soon | 1488 // The IPC sender has been deleted. This listener will be removed soon |
1479 // via a call to RemoveEventListener. For now, just skip it. | 1489 // via a call to RemoveEventListener. For now, just skip it. |
1480 continue; | 1490 continue; |
1481 } | 1491 } |
1482 | 1492 |
1483 if (is_web_view_guest && | 1493 if (is_web_view_guest && |
1484 (it->embedder_process_id != web_view_info.embedder_process_id || | 1494 (it->embedder_process_id != web_view_info.embedder_process_id || |
1485 it->webview_instance_id != web_view_info.instance_id)) | 1495 it->web_view_instance_id != web_view_info.instance_id)) |
1486 continue; | 1496 continue; |
1487 | 1497 |
1488 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) | 1498 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) |
1489 continue; | 1499 continue; |
1490 if (web_request_event_router_delegate_ && | 1500 if (web_request_event_router_delegate_ && |
1491 web_request_event_router_delegate_->OnGetMatchingListenersImplCheck( | 1501 web_request_event_router_delegate_->OnGetMatchingListenersImplCheck( |
1492 it->filter.tab_id, it->filter.window_id, request)) | 1502 it->filter.tab_id, it->filter.window_id, request)) |
1493 continue; | 1503 continue; |
1494 if (!it->filter.types.empty() && | 1504 if (!it->filter.types.empty() && |
1495 std::find(it->filter.types.begin(), it->filter.types.end(), | 1505 std::find(it->filter.types.begin(), it->filter.types.end(), |
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2198 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( | 2208 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
2199 *value, &extra_info_spec)); | 2209 *value, &extra_info_spec)); |
2200 } | 2210 } |
2201 | 2211 |
2202 std::string event_name; | 2212 std::string event_name; |
2203 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); | 2213 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); |
2204 | 2214 |
2205 std::string sub_event_name; | 2215 std::string sub_event_name; |
2206 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); | 2216 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); |
2207 | 2217 |
2208 int webview_instance_id = 0; | 2218 int web_view_instance_id = 0; |
2209 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &webview_instance_id)); | 2219 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(5, &web_view_instance_id)); |
2210 | 2220 |
2211 base::WeakPtr<extensions::ExtensionMessageFilter> ipc_sender = | 2221 base::WeakPtr<extensions::ExtensionMessageFilter> ipc_sender = |
2212 ipc_sender_weak(); | 2222 ipc_sender_weak(); |
2213 int embedder_process_id = | 2223 int embedder_process_id = |
2214 ipc_sender.get() ? ipc_sender->render_process_id() : -1; | 2224 ipc_sender.get() && web_view_instance_id > 0 ? |
| 2225 ipc_sender->render_process_id() : 0; |
2215 | 2226 |
2216 const Extension* extension = | 2227 const Extension* extension = |
2217 extension_info_map()->extensions().GetByID(extension_id_safe()); | 2228 extension_info_map()->extensions().GetByID(extension_id_safe()); |
2218 std::string extension_name = | 2229 std::string extension_name = |
2219 extension ? extension->name() : extension_id_safe(); | 2230 extension ? extension->name() : extension_id_safe(); |
2220 | 2231 |
2221 if (webview_instance_id == 0) { | 2232 if (!web_view_instance_id) { |
2222 // We check automatically whether the extension has the 'webRequest' | 2233 // We check automatically whether the extension has the 'webRequest' |
2223 // permission. For blocking calls we require the additional permission | 2234 // permission. For blocking calls we require the additional permission |
2224 // 'webRequestBlocking'. | 2235 // 'webRequestBlocking'. |
2225 if ((extra_info_spec & | 2236 if ((extra_info_spec & |
2226 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | | 2237 (ExtensionWebRequestEventRouter::ExtraInfoSpec::BLOCKING | |
2227 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && | 2238 ExtensionWebRequestEventRouter::ExtraInfoSpec::ASYNC_BLOCKING)) && |
2228 !extension->permissions_data()->HasAPIPermission( | 2239 !extension->permissions_data()->HasAPIPermission( |
2229 extensions::APIPermission::kWebRequestBlocking)) { | 2240 extensions::APIPermission::kWebRequestBlocking)) { |
2230 error_ = keys::kBlockingPermissionRequired; | 2241 error_ = keys::kBlockingPermissionRequired; |
2231 return false; | 2242 return false; |
(...skipping 10 matching lines...) Expand all Loading... |
2242 .is_empty()) { | 2253 .is_empty()) { |
2243 error_ = keys::kHostPermissionsRequired; | 2254 error_ = keys::kHostPermissionsRequired; |
2244 return false; | 2255 return false; |
2245 } | 2256 } |
2246 } | 2257 } |
2247 | 2258 |
2248 bool success = | 2259 bool success = |
2249 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | 2260 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
2250 profile_id(), extension_id_safe(), extension_name, | 2261 profile_id(), extension_id_safe(), extension_name, |
2251 event_name, sub_event_name, filter, extra_info_spec, | 2262 event_name, sub_event_name, filter, extra_info_spec, |
2252 embedder_process_id, webview_instance_id, ipc_sender_weak()); | 2263 embedder_process_id, web_view_instance_id, ipc_sender_weak()); |
2253 EXTENSION_FUNCTION_VALIDATE(success); | 2264 EXTENSION_FUNCTION_VALIDATE(success); |
2254 | 2265 |
2255 helpers::ClearCacheOnNavigation(); | 2266 helpers::ClearCacheOnNavigation(); |
2256 | 2267 |
2257 if (!extension_id_safe().empty()) { | 2268 if (!extension_id_safe().empty()) { |
2258 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 2269 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
2259 base::Bind(&helpers::NotifyWebRequestAPIUsed, | 2270 base::Bind(&helpers::NotifyWebRequestAPIUsed, |
2260 profile_id(), extension_id_safe())); | 2271 profile_id(), extension_id_safe())); |
2261 } | 2272 } |
2262 | 2273 |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2455 base::Bind(&WarningService::NotifyWarningsOnUI, profile_id(), warnings)); | 2466 base::Bind(&WarningService::NotifyWarningsOnUI, profile_id(), warnings)); |
2456 | 2467 |
2457 // Continue gracefully. | 2468 // Continue gracefully. |
2458 RunSync(); | 2469 RunSync(); |
2459 } | 2470 } |
2460 | 2471 |
2461 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { | 2472 bool WebRequestHandlerBehaviorChangedFunction::RunSync() { |
2462 helpers::ClearCacheOnNavigation(); | 2473 helpers::ClearCacheOnNavigation(); |
2463 return true; | 2474 return true; |
2464 } | 2475 } |
OLD | NEW |