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 |