| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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/extension_webrequest_api.h" | 5 #include "chrome/browser/extensions/extension_webrequest_api.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
| 10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
| (...skipping 15 matching lines...) Expand all Loading... |
| 26 #include "content/browser/browser_message_filter.h" | 26 #include "content/browser/browser_message_filter.h" |
| 27 #include "content/browser/browser_thread.h" | 27 #include "content/browser/browser_thread.h" |
| 28 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 28 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
| 29 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" | 29 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" |
| 30 #include "net/base/auth.h" | 30 #include "net/base/auth.h" |
| 31 #include "net/base/net_errors.h" | 31 #include "net/base/net_errors.h" |
| 32 #include "net/base/net_log.h" | 32 #include "net/base/net_log.h" |
| 33 #include "net/http/http_response_headers.h" | 33 #include "net/http/http_response_headers.h" |
| 34 #include "net/url_request/url_request.h" | 34 #include "net/url_request/url_request.h" |
| 35 #include "googleurl/src/gurl.h" | 35 #include "googleurl/src/gurl.h" |
| 36 #include "grit/generated_resources.h" |
| 37 #include "ui/base/l10n/l10n_util.h" |
| 36 | 38 |
| 37 namespace keys = extension_webrequest_api_constants; | 39 namespace keys = extension_webrequest_api_constants; |
| 38 | 40 |
| 39 namespace { | 41 namespace { |
| 40 | 42 |
| 41 // List of all the webRequest events. | 43 // List of all the webRequest events. |
| 42 static const char* const kWebRequestEvents[] = { | 44 static const char* const kWebRequestEvents[] = { |
| 43 keys::kOnBeforeRedirect, | 45 keys::kOnBeforeRedirect, |
| 44 keys::kOnBeforeRequest, | 46 keys::kOnBeforeRequest, |
| 45 keys::kOnBeforeSendHeaders, | 47 keys::kOnBeforeSendHeaders, |
| (...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 246 return a->extension_install_time > b->extension_install_time; | 248 return a->extension_install_time > b->extension_install_time; |
| 247 } | 249 } |
| 248 | 250 |
| 249 } // namespace | 251 } // namespace |
| 250 | 252 |
| 251 // Represents a single unique listener to an event, along with whatever filter | 253 // Represents a single unique listener to an event, along with whatever filter |
| 252 // parameters and extra_info_spec were specified at the time the listener was | 254 // parameters and extra_info_spec were specified at the time the listener was |
| 253 // added. | 255 // added. |
| 254 struct ExtensionWebRequestEventRouter::EventListener { | 256 struct ExtensionWebRequestEventRouter::EventListener { |
| 255 std::string extension_id; | 257 std::string extension_id; |
| 258 std::string extension_name; |
| 256 std::string sub_event_name; | 259 std::string sub_event_name; |
| 257 RequestFilter filter; | 260 RequestFilter filter; |
| 258 int extra_info_spec; | 261 int extra_info_spec; |
| 259 base::WeakPtr<IPC::Message::Sender> ipc_sender; | 262 base::WeakPtr<IPC::Message::Sender> ipc_sender; |
| 260 mutable std::set<uint64> blocked_requests; | 263 mutable std::set<uint64> blocked_requests; |
| 261 | 264 |
| 262 // Comparator to work with std::set. | 265 // Comparator to work with std::set. |
| 263 bool operator<(const EventListener& that) const { | 266 bool operator<(const EventListener& that) const { |
| 264 if (extension_id < that.extension_id) | 267 if (extension_id < that.extension_id) |
| 265 return true; | 268 return true; |
| 266 if (extension_id == that.extension_id && | 269 if (extension_id == that.extension_id && |
| 267 sub_event_name < that.sub_event_name) | 270 sub_event_name < that.sub_event_name) |
| 268 return true; | 271 return true; |
| 269 return false; | 272 return false; |
| 270 } | 273 } |
| 271 | 274 |
| 272 EventListener() : extra_info_spec(0) {} | 275 EventListener() : extra_info_spec(0) {} |
| 273 }; | 276 }; |
| 274 | 277 |
| 275 // Contains info about requests that are blocked waiting for a response from | 278 // Contains info about requests that are blocked waiting for a response from |
| 276 // an extension. | 279 // an extension. |
| 277 struct ExtensionWebRequestEventRouter::BlockedRequest { | 280 struct ExtensionWebRequestEventRouter::BlockedRequest { |
| 281 // The request that is being blocked. |
| 282 net::URLRequest* request; |
| 283 |
| 278 // The event that we're currently blocked on. | 284 // The event that we're currently blocked on. |
| 279 EventTypes event; | 285 EventTypes event; |
| 280 | 286 |
| 281 // The number of event handlers that we are awaiting a response from. | 287 // The number of event handlers that we are awaiting a response from. |
| 282 int num_handlers_blocking; | 288 int num_handlers_blocking; |
| 283 | 289 |
| 284 // Pointer to NetLog to report significant changes to the request for | 290 // Pointer to NetLog to report significant changes to the request for |
| 285 // debugging. | 291 // debugging. |
| 286 const net::BoundNetLog* net_log; | 292 const net::BoundNetLog* net_log; |
| 287 | 293 |
| 288 // The callback to call when we get a response from all event handlers. | 294 // The callback to call when we get a response from all event handlers. |
| 289 net::CompletionCallback* callback; | 295 net::CompletionCallback* callback; |
| 290 | 296 |
| 291 // If non-empty, this contains the new URL that the request will redirect to. | 297 // If non-empty, this contains the new URL that the request will redirect to. |
| 292 // Only valid for OnBeforeRequest. | 298 // Only valid for OnBeforeRequest. |
| 293 GURL* new_url; | 299 GURL* new_url; |
| 294 | 300 |
| 295 // The request headers that will be issued along with this request. Only valid | 301 // The request headers that will be issued along with this request. Only valid |
| 296 // for OnBeforeSendHeaders. | 302 // for OnBeforeSendHeaders. |
| 297 net::HttpRequestHeaders* request_headers; | 303 net::HttpRequestHeaders* request_headers; |
| 298 | 304 |
| 299 // Time the request was paused. Used for logging purposes. | 305 // Time the request was paused. Used for logging purposes. |
| 300 base::Time blocking_time; | 306 base::Time blocking_time; |
| 301 | 307 |
| 302 // Changes requested by extensions. | 308 // Changes requested by extensions. |
| 303 EventResponseDeltas response_deltas; | 309 EventResponseDeltas response_deltas; |
| 304 | 310 |
| 305 BlockedRequest() | 311 BlockedRequest() |
| 306 : event(kInvalidEvent), | 312 : request(NULL), |
| 313 event(kInvalidEvent), |
| 307 num_handlers_blocking(0), | 314 num_handlers_blocking(0), |
| 308 net_log(NULL), | 315 net_log(NULL), |
| 309 callback(NULL), | 316 callback(NULL), |
| 310 new_url(NULL), | 317 new_url(NULL), |
| 311 request_headers(NULL) {} | 318 request_headers(NULL) {} |
| 312 }; | 319 }; |
| 313 | 320 |
| 314 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( | 321 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( |
| 315 const DictionaryValue& value, std::string* error) { | 322 const DictionaryValue& value, std::string* error) { |
| 316 for (DictionaryValue::key_iterator key = value.begin_keys(); | 323 for (DictionaryValue::key_iterator key = value.begin_keys(); |
| (...skipping 523 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 840 dict->Remove(keys::kStatusLineKey, NULL); | 847 dict->Remove(keys::kStatusLineKey, NULL); |
| 841 | 848 |
| 842 base::JSONWriter::Write(args_filtered.get(), false, &json_args); | 849 base::JSONWriter::Write(args_filtered.get(), false, &json_args); |
| 843 | 850 |
| 844 ExtensionEventRouter::DispatchEvent( | 851 ExtensionEventRouter::DispatchEvent( |
| 845 (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name, | 852 (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name, |
| 846 json_args, GURL()); | 853 json_args, GURL()); |
| 847 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { | 854 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { |
| 848 (*it)->blocked_requests.insert(request->identifier()); | 855 (*it)->blocked_requests.insert(request->identifier()); |
| 849 ++num_handlers_blocking; | 856 ++num_handlers_blocking; |
| 857 |
| 858 request->SetLoadStateParam( |
| 859 l10n_util::GetStringFUTF16(IDS_LOAD_STATE_PARAMETER_EXTENSION, |
| 860 UTF8ToUTF16((*it)->extension_name))); |
| 850 } | 861 } |
| 851 } | 862 } |
| 852 | 863 |
| 853 if (num_handlers_blocking > 0) { | 864 if (num_handlers_blocking > 0) { |
| 854 CHECK(blocked_requests_.find(request->identifier()) == | 865 CHECK(blocked_requests_.find(request->identifier()) == |
| 855 blocked_requests_.end()); | 866 blocked_requests_.end()); |
| 867 blocked_requests_[request->identifier()].request = request; |
| 856 blocked_requests_[request->identifier()].num_handlers_blocking = | 868 blocked_requests_[request->identifier()].num_handlers_blocking = |
| 857 num_handlers_blocking; | 869 num_handlers_blocking; |
| 858 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); | 870 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); |
| 859 | 871 |
| 860 return true; | 872 return true; |
| 861 } | 873 } |
| 862 | 874 |
| 863 return false; | 875 return false; |
| 864 } | 876 } |
| 865 | 877 |
| 866 void ExtensionWebRequestEventRouter::OnEventHandled( | 878 void ExtensionWebRequestEventRouter::OnEventHandled( |
| 867 void* profile, | 879 void* profile, |
| 868 const std::string& extension_id, | 880 const std::string& extension_id, |
| 869 const std::string& event_name, | 881 const std::string& event_name, |
| 870 const std::string& sub_event_name, | 882 const std::string& sub_event_name, |
| 871 uint64 request_id, | 883 uint64 request_id, |
| 872 EventResponse* response) { | 884 EventResponse* response) { |
| 873 EventListener listener; | 885 EventListener listener; |
| 874 listener.extension_id = extension_id; | 886 listener.extension_id = extension_id; |
| 875 listener.sub_event_name = sub_event_name; | 887 listener.sub_event_name = sub_event_name; |
| 876 | 888 |
| 877 // The listener may have been removed (e.g. due to the process going away) | 889 // The listener may have been removed (e.g. due to the process going away) |
| 878 // before we got here. | 890 // before we got here. |
| 879 std::set<EventListener>::iterator found = | 891 std::set<EventListener>::iterator found = |
| 880 listeners_[profile][event_name].find(listener); | 892 listeners_[profile][event_name].find(listener); |
| 881 if (found != listeners_[profile][event_name].end()) | 893 if (found != listeners_[profile][event_name].end()) |
| 882 found->blocked_requests.erase(request_id); | 894 found->blocked_requests.erase(request_id); |
| 883 | 895 |
| 884 DecrementBlockCount(request_id, response); | 896 DecrementBlockCount(profile, event_name, request_id, response); |
| 885 } | 897 } |
| 886 | 898 |
| 887 void ExtensionWebRequestEventRouter::AddEventListener( | 899 void ExtensionWebRequestEventRouter::AddEventListener( |
| 888 void* profile, | 900 void* profile, |
| 889 const std::string& extension_id, | 901 const std::string& extension_id, |
| 902 const std::string& extension_name, |
| 890 const std::string& event_name, | 903 const std::string& event_name, |
| 891 const std::string& sub_event_name, | 904 const std::string& sub_event_name, |
| 892 const RequestFilter& filter, | 905 const RequestFilter& filter, |
| 893 int extra_info_spec, | 906 int extra_info_spec, |
| 894 base::WeakPtr<IPC::Message::Sender> ipc_sender) { | 907 base::WeakPtr<IPC::Message::Sender> ipc_sender) { |
| 895 if (!IsWebRequestEvent(event_name)) | 908 if (!IsWebRequestEvent(event_name)) |
| 896 return; | 909 return; |
| 897 | 910 |
| 898 EventListener listener; | 911 EventListener listener; |
| 899 listener.extension_id = extension_id; | 912 listener.extension_id = extension_id; |
| 913 listener.extension_name = extension_name; |
| 900 listener.sub_event_name = sub_event_name; | 914 listener.sub_event_name = sub_event_name; |
| 901 listener.filter = filter; | 915 listener.filter = filter; |
| 902 listener.extra_info_spec = extra_info_spec; | 916 listener.extra_info_spec = extra_info_spec; |
| 903 listener.ipc_sender = ipc_sender; | 917 listener.ipc_sender = ipc_sender; |
| 904 | 918 |
| 905 CHECK_EQ(listeners_[profile][event_name].count(listener), 0u) << | 919 CHECK_EQ(listeners_[profile][event_name].count(listener), 0u) << |
| 906 "extension=" << extension_id << " event=" << event_name; | 920 "extension=" << extension_id << " event=" << event_name; |
| 907 listeners_[profile][event_name].insert(listener); | 921 listeners_[profile][event_name].insert(listener); |
| 908 } | 922 } |
| 909 | 923 |
| (...skipping 18 matching lines...) Expand all Loading... |
| 928 listeners_[profile][event_name].find(listener); | 942 listeners_[profile][event_name].find(listener); |
| 929 if (found == listeners_[profile][event_name].end()) | 943 if (found == listeners_[profile][event_name].end()) |
| 930 return; | 944 return; |
| 931 | 945 |
| 932 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << | 946 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << |
| 933 "extension=" << extension_id << " event=" << event_name; | 947 "extension=" << extension_id << " event=" << event_name; |
| 934 | 948 |
| 935 // Unblock any request that this event listener may have been blocking. | 949 // Unblock any request that this event listener may have been blocking. |
| 936 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); | 950 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); |
| 937 it != found->blocked_requests.end(); ++it) { | 951 it != found->blocked_requests.end(); ++it) { |
| 938 DecrementBlockCount(*it, NULL); | 952 DecrementBlockCount(profile, event_name, *it, NULL); |
| 939 } | 953 } |
| 940 | 954 |
| 941 listeners_[profile][event_name].erase(listener); | 955 listeners_[profile][event_name].erase(listener); |
| 942 } | 956 } |
| 943 | 957 |
| 944 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( | 958 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( |
| 945 void* original_profile, void* otr_profile) { | 959 void* original_profile, void* otr_profile) { |
| 946 cross_profile_map_[original_profile] = otr_profile; | 960 cross_profile_map_[original_profile] = otr_profile; |
| 947 cross_profile_map_[otr_profile] = original_profile; | 961 cross_profile_map_[otr_profile] = original_profile; |
| 948 } | 962 } |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1215 conflicting_extensions->push_back((*delta)->extension_id); | 1229 conflicting_extensions->push_back((*delta)->extension_id); |
| 1216 request->net_log->AddEvent( | 1230 request->net_log->AddEvent( |
| 1217 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 1231 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
| 1218 make_scoped_refptr( | 1232 make_scoped_refptr( |
| 1219 new NetLogExtensionIdParameter((*delta)->extension_id))); | 1233 new NetLogExtensionIdParameter((*delta)->extension_id))); |
| 1220 } | 1234 } |
| 1221 } | 1235 } |
| 1222 } | 1236 } |
| 1223 | 1237 |
| 1224 void ExtensionWebRequestEventRouter::DecrementBlockCount( | 1238 void ExtensionWebRequestEventRouter::DecrementBlockCount( |
| 1239 void* profile, |
| 1240 const std::string& event_name, |
| 1225 uint64 request_id, | 1241 uint64 request_id, |
| 1226 EventResponse* response) { | 1242 EventResponse* response) { |
| 1227 scoped_ptr<EventResponse> response_scoped(response); | 1243 scoped_ptr<EventResponse> response_scoped(response); |
| 1228 | 1244 |
| 1229 // It's possible that this request was deleted, or cancelled by a previous | 1245 // It's possible that this request was deleted, or cancelled by a previous |
| 1230 // event handler. If so, ignore this response. | 1246 // event handler. If so, ignore this response. |
| 1231 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1247 if (blocked_requests_.find(request_id) == blocked_requests_.end()) |
| 1232 return; | 1248 return; |
| 1233 | 1249 |
| 1234 BlockedRequest& blocked_request = blocked_requests_[request_id]; | 1250 BlockedRequest& blocked_request = blocked_requests_[request_id]; |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1290 if (blocked_request.callback) { | 1306 if (blocked_request.callback) { |
| 1291 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK; | 1307 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK; |
| 1292 net::CompletionCallback* callback = blocked_request.callback; | 1308 net::CompletionCallback* callback = blocked_request.callback; |
| 1293 // Ensure that request is removed before callback because the callback | 1309 // Ensure that request is removed before callback because the callback |
| 1294 // might trigger the next event. | 1310 // might trigger the next event. |
| 1295 blocked_requests_.erase(request_id); | 1311 blocked_requests_.erase(request_id); |
| 1296 callback->Run(rv); | 1312 callback->Run(rv); |
| 1297 } else { | 1313 } else { |
| 1298 blocked_requests_.erase(request_id); | 1314 blocked_requests_.erase(request_id); |
| 1299 } | 1315 } |
| 1316 } else { |
| 1317 // Update the URLRequest to indicate it is now blocked on a different |
| 1318 // extension. |
| 1319 std::set<EventListener>& listeners = listeners_[profile][event_name]; |
| 1320 |
| 1321 for (std::set<EventListener>::iterator it = listeners.begin(); |
| 1322 it != listeners.end(); ++it) { |
| 1323 if (it->blocked_requests.count(request_id)) { |
| 1324 blocked_request.request->SetLoadStateParam( |
| 1325 l10n_util::GetStringFUTF16(IDS_LOAD_STATE_PARAMETER_EXTENSION, |
| 1326 UTF8ToUTF16(it->extension_name))); |
| 1327 break; |
| 1328 } |
| 1329 } |
| 1300 } | 1330 } |
| 1301 } | 1331 } |
| 1302 | 1332 |
| 1303 bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, | 1333 bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, |
| 1304 EventTypes event_type) { | 1334 EventTypes event_type) { |
| 1305 SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); | 1335 SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); |
| 1306 if (iter == signaled_requests_.end()) { | 1336 if (iter == signaled_requests_.end()) { |
| 1307 signaled_requests_[request_id] = event_type; | 1337 signaled_requests_[request_id] = event_type; |
| 1308 return false; | 1338 return false; |
| 1309 } | 1339 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1343 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( | 1373 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
| 1344 *value, &extra_info_spec)); | 1374 *value, &extra_info_spec)); |
| 1345 } | 1375 } |
| 1346 | 1376 |
| 1347 std::string event_name; | 1377 std::string event_name; |
| 1348 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); | 1378 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); |
| 1349 | 1379 |
| 1350 std::string sub_event_name; | 1380 std::string sub_event_name; |
| 1351 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); | 1381 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); |
| 1352 | 1382 |
| 1383 const Extension* extension = |
| 1384 extension_info_map()->extensions().GetByID(extension_id()); |
| 1385 std::string extension_name = extension ? extension->name() : extension_id(); |
| 1386 |
| 1353 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | 1387 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
| 1354 profile(), extension_id(), event_name, sub_event_name, filter, | 1388 profile(), extension_id(), extension_name, |
| 1389 event_name, sub_event_name, filter, |
| 1355 extra_info_spec, ipc_sender_weak()); | 1390 extra_info_spec, ipc_sender_weak()); |
| 1356 | 1391 |
| 1357 return true; | 1392 return true; |
| 1358 } | 1393 } |
| 1359 | 1394 |
| 1360 bool WebRequestEventHandled::RunImpl() { | 1395 bool WebRequestEventHandled::RunImpl() { |
| 1361 std::string event_name; | 1396 std::string event_name; |
| 1362 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); | 1397 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); |
| 1363 | 1398 |
| 1364 std::string sub_event_name; | 1399 std::string sub_event_name; |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1426 } | 1461 } |
| 1427 } | 1462 } |
| 1428 } | 1463 } |
| 1429 | 1464 |
| 1430 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( | 1465 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( |
| 1431 profile(), extension_id(), event_name, sub_event_name, request_id, | 1466 profile(), extension_id(), event_name, sub_event_name, request_id, |
| 1432 response.release()); | 1467 response.release()); |
| 1433 | 1468 |
| 1434 return true; | 1469 return true; |
| 1435 } | 1470 } |
| OLD | NEW |