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" |
11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
| 12 #include "base/utf_string_conversions.h" |
12 #include "base/values.h" | 13 #include "base/values.h" |
13 #include "chrome/browser/extensions/extension_event_router.h" | 14 #include "chrome/browser/extensions/extension_event_router.h" |
14 #include "chrome/browser/extensions/extension_info_map.h" | 15 #include "chrome/browser/extensions/extension_info_map.h" |
15 #include "chrome/browser/extensions/extension_prefs.h" | 16 #include "chrome/browser/extensions/extension_prefs.h" |
16 #include "chrome/browser/extensions/extension_service.h" | 17 #include "chrome/browser/extensions/extension_service.h" |
17 #include "chrome/browser/extensions/extension_tab_id_map.h" | 18 #include "chrome/browser/extensions/extension_tab_id_map.h" |
18 #include "chrome/browser/extensions/extension_webrequest_api_constants.h" | 19 #include "chrome/browser/extensions/extension_webrequest_api_constants.h" |
19 #include "chrome/browser/profiles/profile.h" | 20 #include "chrome/browser/profiles/profile.h" |
20 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" | 21 #include "chrome/browser/renderer_host/chrome_render_message_filter.h" |
21 #include "chrome/common/extensions/extension.h" | 22 #include "chrome/common/extensions/extension.h" |
22 #include "chrome/common/extensions/extension_error_utils.h" | 23 #include "chrome/common/extensions/extension_error_utils.h" |
23 #include "chrome/common/extensions/url_pattern.h" | 24 #include "chrome/common/extensions/url_pattern.h" |
24 #include "chrome/common/url_constants.h" | 25 #include "chrome/common/url_constants.h" |
25 #include "content/browser/browser_message_filter.h" | 26 #include "content/browser/browser_message_filter.h" |
26 #include "content/browser/browser_thread.h" | 27 #include "content/browser/browser_thread.h" |
27 #include "content/browser/renderer_host/resource_dispatcher_host.h" | 28 #include "content/browser/renderer_host/resource_dispatcher_host.h" |
28 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" | 29 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" |
29 #include "net/base/net_errors.h" | 30 #include "net/base/net_errors.h" |
30 #include "net/base/net_log.h" | 31 #include "net/base/net_log.h" |
31 #include "net/http/http_response_headers.h" | 32 #include "net/http/http_response_headers.h" |
32 #include "net/url_request/url_request.h" | 33 #include "net/url_request/url_request.h" |
33 #include "googleurl/src/gurl.h" | 34 #include "googleurl/src/gurl.h" |
| 35 #include "grit/generated_resources.h" |
| 36 #include "ui/base/l10n/l10n_util.h" |
34 | 37 |
35 namespace keys = extension_webrequest_api_constants; | 38 namespace keys = extension_webrequest_api_constants; |
36 | 39 |
37 namespace { | 40 namespace { |
38 | 41 |
39 // List of all the webRequest events. | 42 // List of all the webRequest events. |
40 static const char* const kWebRequestEvents[] = { | 43 static const char* const kWebRequestEvents[] = { |
41 keys::kOnBeforeRedirect, | 44 keys::kOnBeforeRedirect, |
42 keys::kOnBeforeRequest, | 45 keys::kOnBeforeRequest, |
43 keys::kOnBeforeSendHeaders, | 46 keys::kOnBeforeSendHeaders, |
(...skipping 190 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 return a->extension_install_time > b->extension_install_time; | 237 return a->extension_install_time > b->extension_install_time; |
235 } | 238 } |
236 | 239 |
237 } // namespace | 240 } // namespace |
238 | 241 |
239 // Represents a single unique listener to an event, along with whatever filter | 242 // Represents a single unique listener to an event, along with whatever filter |
240 // parameters and extra_info_spec were specified at the time the listener was | 243 // parameters and extra_info_spec were specified at the time the listener was |
241 // added. | 244 // added. |
242 struct ExtensionWebRequestEventRouter::EventListener { | 245 struct ExtensionWebRequestEventRouter::EventListener { |
243 std::string extension_id; | 246 std::string extension_id; |
| 247 std::string extension_name; |
244 std::string sub_event_name; | 248 std::string sub_event_name; |
245 RequestFilter filter; | 249 RequestFilter filter; |
246 int extra_info_spec; | 250 int extra_info_spec; |
247 base::WeakPtr<IPC::Message::Sender> ipc_sender; | 251 base::WeakPtr<IPC::Message::Sender> ipc_sender; |
248 mutable std::set<uint64> blocked_requests; | 252 mutable std::set<uint64> blocked_requests; |
249 | 253 |
250 // Comparator to work with std::set. | 254 // Comparator to work with std::set. |
251 bool operator<(const EventListener& that) const { | 255 bool operator<(const EventListener& that) const { |
252 if (extension_id < that.extension_id) | 256 if (extension_id < that.extension_id) |
253 return true; | 257 return true; |
254 if (extension_id == that.extension_id && | 258 if (extension_id == that.extension_id && |
255 sub_event_name < that.sub_event_name) | 259 sub_event_name < that.sub_event_name) |
256 return true; | 260 return true; |
257 return false; | 261 return false; |
258 } | 262 } |
259 | 263 |
260 EventListener() : extra_info_spec(0) {} | 264 EventListener() : extra_info_spec(0) {} |
261 }; | 265 }; |
262 | 266 |
263 // Contains info about requests that are blocked waiting for a response from | 267 // Contains info about requests that are blocked waiting for a response from |
264 // an extension. | 268 // an extension. |
265 struct ExtensionWebRequestEventRouter::BlockedRequest { | 269 struct ExtensionWebRequestEventRouter::BlockedRequest { |
| 270 // The request that is being blocked. |
| 271 net::URLRequest* request; |
| 272 |
266 // The event that we're currently blocked on. | 273 // The event that we're currently blocked on. |
267 EventTypes event; | 274 EventTypes event; |
268 | 275 |
269 // The number of event handlers that we are awaiting a response from. | 276 // The number of event handlers that we are awaiting a response from. |
270 int num_handlers_blocking; | 277 int num_handlers_blocking; |
271 | 278 |
272 // Pointer to NetLog to report significant changes to the request for | 279 // Pointer to NetLog to report significant changes to the request for |
273 // debugging. | 280 // debugging. |
274 const net::BoundNetLog* net_log; | 281 const net::BoundNetLog* net_log; |
275 | 282 |
276 // The callback to call when we get a response from all event handlers. | 283 // The callback to call when we get a response from all event handlers. |
277 net::CompletionCallback* callback; | 284 net::CompletionCallback* callback; |
278 | 285 |
279 // If non-empty, this contains the new URL that the request will redirect to. | 286 // If non-empty, this contains the new URL that the request will redirect to. |
280 // Only valid for OnBeforeRequest. | 287 // Only valid for OnBeforeRequest. |
281 GURL* new_url; | 288 GURL* new_url; |
282 | 289 |
283 // The request headers that will be issued along with this request. Only valid | 290 // The request headers that will be issued along with this request. Only valid |
284 // for OnBeforeSendHeaders. | 291 // for OnBeforeSendHeaders. |
285 net::HttpRequestHeaders* request_headers; | 292 net::HttpRequestHeaders* request_headers; |
286 | 293 |
287 // Time the request was paused. Used for logging purposes. | 294 // Time the request was paused. Used for logging purposes. |
288 base::Time blocking_time; | 295 base::Time blocking_time; |
289 | 296 |
290 // Changes requested by extensions. | 297 // Changes requested by extensions. |
291 EventResponseDeltas response_deltas; | 298 EventResponseDeltas response_deltas; |
292 | 299 |
293 BlockedRequest() | 300 BlockedRequest() |
294 : event(kInvalidEvent), | 301 : request(NULL), |
| 302 event(kInvalidEvent), |
295 num_handlers_blocking(0), | 303 num_handlers_blocking(0), |
296 net_log(NULL), | 304 net_log(NULL), |
297 callback(NULL), | 305 callback(NULL), |
298 new_url(NULL), | 306 new_url(NULL), |
299 request_headers(NULL) {} | 307 request_headers(NULL) {} |
300 }; | 308 }; |
301 | 309 |
302 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( | 310 bool ExtensionWebRequestEventRouter::RequestFilter::InitFromValue( |
303 const DictionaryValue& value, std::string* error) { | 311 const DictionaryValue& value, std::string* error) { |
304 for (DictionaryValue::key_iterator key = value.begin_keys(); | 312 for (DictionaryValue::key_iterator key = value.begin_keys(); |
(...skipping 482 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 dict->Remove(keys::kStatusLineKey, NULL); | 795 dict->Remove(keys::kStatusLineKey, NULL); |
788 | 796 |
789 base::JSONWriter::Write(args_filtered.get(), false, &json_args); | 797 base::JSONWriter::Write(args_filtered.get(), false, &json_args); |
790 | 798 |
791 ExtensionEventRouter::DispatchEvent( | 799 ExtensionEventRouter::DispatchEvent( |
792 (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name, | 800 (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name, |
793 json_args, GURL()); | 801 json_args, GURL()); |
794 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { | 802 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { |
795 (*it)->blocked_requests.insert(request->identifier()); | 803 (*it)->blocked_requests.insert(request->identifier()); |
796 ++num_handlers_blocking; | 804 ++num_handlers_blocking; |
| 805 |
| 806 request->SetLoadStateParam( |
| 807 l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, |
| 808 UTF8ToUTF16((*it)->extension_name))); |
797 } | 809 } |
798 } | 810 } |
799 | 811 |
800 if (num_handlers_blocking > 0) { | 812 if (num_handlers_blocking > 0) { |
801 CHECK(blocked_requests_.find(request->identifier()) == | 813 CHECK(blocked_requests_.find(request->identifier()) == |
802 blocked_requests_.end()); | 814 blocked_requests_.end()); |
| 815 blocked_requests_[request->identifier()].request = request; |
803 blocked_requests_[request->identifier()].num_handlers_blocking = | 816 blocked_requests_[request->identifier()].num_handlers_blocking = |
804 num_handlers_blocking; | 817 num_handlers_blocking; |
805 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); | 818 blocked_requests_[request->identifier()].blocking_time = base::Time::Now(); |
806 | 819 |
807 return true; | 820 return true; |
808 } | 821 } |
809 | 822 |
810 return false; | 823 return false; |
811 } | 824 } |
812 | 825 |
813 void ExtensionWebRequestEventRouter::OnEventHandled( | 826 void ExtensionWebRequestEventRouter::OnEventHandled( |
814 void* profile, | 827 void* profile, |
815 const std::string& extension_id, | 828 const std::string& extension_id, |
816 const std::string& event_name, | 829 const std::string& event_name, |
817 const std::string& sub_event_name, | 830 const std::string& sub_event_name, |
818 uint64 request_id, | 831 uint64 request_id, |
819 EventResponse* response) { | 832 EventResponse* response) { |
820 EventListener listener; | 833 EventListener listener; |
821 listener.extension_id = extension_id; | 834 listener.extension_id = extension_id; |
822 listener.sub_event_name = sub_event_name; | 835 listener.sub_event_name = sub_event_name; |
823 | 836 |
824 // The listener may have been removed (e.g. due to the process going away) | 837 // The listener may have been removed (e.g. due to the process going away) |
825 // before we got here. | 838 // before we got here. |
826 std::set<EventListener>::iterator found = | 839 std::set<EventListener>::iterator found = |
827 listeners_[profile][event_name].find(listener); | 840 listeners_[profile][event_name].find(listener); |
828 if (found != listeners_[profile][event_name].end()) | 841 if (found != listeners_[profile][event_name].end()) |
829 found->blocked_requests.erase(request_id); | 842 found->blocked_requests.erase(request_id); |
830 | 843 |
831 DecrementBlockCount(request_id, response); | 844 DecrementBlockCount(profile, event_name, request_id, response); |
832 } | 845 } |
833 | 846 |
834 void ExtensionWebRequestEventRouter::AddEventListener( | 847 void ExtensionWebRequestEventRouter::AddEventListener( |
835 void* profile, | 848 void* profile, |
836 const std::string& extension_id, | 849 const std::string& extension_id, |
| 850 const std::string& extension_name, |
837 const std::string& event_name, | 851 const std::string& event_name, |
838 const std::string& sub_event_name, | 852 const std::string& sub_event_name, |
839 const RequestFilter& filter, | 853 const RequestFilter& filter, |
840 int extra_info_spec, | 854 int extra_info_spec, |
841 base::WeakPtr<IPC::Message::Sender> ipc_sender) { | 855 base::WeakPtr<IPC::Message::Sender> ipc_sender) { |
842 if (!IsWebRequestEvent(event_name)) | 856 if (!IsWebRequestEvent(event_name)) |
843 return; | 857 return; |
844 | 858 |
845 EventListener listener; | 859 EventListener listener; |
846 listener.extension_id = extension_id; | 860 listener.extension_id = extension_id; |
| 861 listener.extension_name = extension_name; |
847 listener.sub_event_name = sub_event_name; | 862 listener.sub_event_name = sub_event_name; |
848 listener.filter = filter; | 863 listener.filter = filter; |
849 listener.extra_info_spec = extra_info_spec; | 864 listener.extra_info_spec = extra_info_spec; |
850 listener.ipc_sender = ipc_sender; | 865 listener.ipc_sender = ipc_sender; |
851 | 866 |
852 CHECK_EQ(listeners_[profile][event_name].count(listener), 0u) << | 867 CHECK_EQ(listeners_[profile][event_name].count(listener), 0u) << |
853 "extension=" << extension_id << " event=" << event_name; | 868 "extension=" << extension_id << " event=" << event_name; |
854 listeners_[profile][event_name].insert(listener); | 869 listeners_[profile][event_name].insert(listener); |
855 } | 870 } |
856 | 871 |
(...skipping 18 matching lines...) Expand all Loading... |
875 listeners_[profile][event_name].find(listener); | 890 listeners_[profile][event_name].find(listener); |
876 if (found == listeners_[profile][event_name].end()) | 891 if (found == listeners_[profile][event_name].end()) |
877 return; | 892 return; |
878 | 893 |
879 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << | 894 CHECK_EQ(listeners_[profile][event_name].count(listener), 1u) << |
880 "extension=" << extension_id << " event=" << event_name; | 895 "extension=" << extension_id << " event=" << event_name; |
881 | 896 |
882 // Unblock any request that this event listener may have been blocking. | 897 // Unblock any request that this event listener may have been blocking. |
883 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); | 898 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); |
884 it != found->blocked_requests.end(); ++it) { | 899 it != found->blocked_requests.end(); ++it) { |
885 DecrementBlockCount(*it, NULL); | 900 DecrementBlockCount(profile, event_name, *it, NULL); |
886 } | 901 } |
887 | 902 |
888 listeners_[profile][event_name].erase(listener); | 903 listeners_[profile][event_name].erase(listener); |
889 } | 904 } |
890 | 905 |
891 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( | 906 void ExtensionWebRequestEventRouter::OnOTRProfileCreated( |
892 void* original_profile, void* otr_profile) { | 907 void* original_profile, void* otr_profile) { |
893 cross_profile_map_[original_profile] = otr_profile; | 908 cross_profile_map_[original_profile] = otr_profile; |
894 cross_profile_map_[otr_profile] = original_profile; | 909 cross_profile_map_[otr_profile] = original_profile; |
895 } | 910 } |
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1162 conflicting_extensions->push_back((*delta)->extension_id); | 1177 conflicting_extensions->push_back((*delta)->extension_id); |
1163 request->net_log->AddEvent( | 1178 request->net_log->AddEvent( |
1164 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, | 1179 net::NetLog::TYPE_CHROME_EXTENSION_IGNORED_DUE_TO_CONFLICT, |
1165 make_scoped_refptr( | 1180 make_scoped_refptr( |
1166 new NetLogExtensionIdParameter((*delta)->extension_id))); | 1181 new NetLogExtensionIdParameter((*delta)->extension_id))); |
1167 } | 1182 } |
1168 } | 1183 } |
1169 } | 1184 } |
1170 | 1185 |
1171 void ExtensionWebRequestEventRouter::DecrementBlockCount( | 1186 void ExtensionWebRequestEventRouter::DecrementBlockCount( |
| 1187 void* profile, |
| 1188 const std::string& event_name, |
1172 uint64 request_id, | 1189 uint64 request_id, |
1173 EventResponse* response) { | 1190 EventResponse* response) { |
1174 scoped_ptr<EventResponse> response_scoped(response); | 1191 scoped_ptr<EventResponse> response_scoped(response); |
1175 | 1192 |
1176 // It's possible that this request was deleted, or cancelled by a previous | 1193 // It's possible that this request was deleted, or cancelled by a previous |
1177 // event handler. If so, ignore this response. | 1194 // event handler. If so, ignore this response. |
1178 if (blocked_requests_.find(request_id) == blocked_requests_.end()) | 1195 if (blocked_requests_.find(request_id) == blocked_requests_.end()) |
1179 return; | 1196 return; |
1180 | 1197 |
1181 BlockedRequest& blocked_request = blocked_requests_[request_id]; | 1198 BlockedRequest& blocked_request = blocked_requests_[request_id]; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1237 if (blocked_request.callback) { | 1254 if (blocked_request.callback) { |
1238 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK; | 1255 int rv = canceled ? net::ERR_EMPTY_RESPONSE : net::OK; |
1239 net::CompletionCallback* callback = blocked_request.callback; | 1256 net::CompletionCallback* callback = blocked_request.callback; |
1240 // Ensure that request is removed before callback because the callback | 1257 // Ensure that request is removed before callback because the callback |
1241 // might trigger the next event. | 1258 // might trigger the next event. |
1242 blocked_requests_.erase(request_id); | 1259 blocked_requests_.erase(request_id); |
1243 callback->Run(rv); | 1260 callback->Run(rv); |
1244 } else { | 1261 } else { |
1245 blocked_requests_.erase(request_id); | 1262 blocked_requests_.erase(request_id); |
1246 } | 1263 } |
| 1264 } else { |
| 1265 // Update the URLRequest to indicate it is now blocked on a different |
| 1266 // extension. |
| 1267 std::set<EventListener>& listeners = listeners_[profile][event_name]; |
| 1268 |
| 1269 for (std::set<EventListener>::iterator it = listeners.begin(); |
| 1270 it != listeners.end(); ++it) { |
| 1271 if (it->blocked_requests.count(request_id)) { |
| 1272 blocked_request.request->SetLoadStateParam( |
| 1273 l10n_util::GetStringFUTF8(IDS_LOAD_STATE_PARAMETER_EXTENSION, |
| 1274 UTF8ToUTF16(it->extension_name))); |
| 1275 break; |
| 1276 } |
| 1277 } |
1247 } | 1278 } |
1248 } | 1279 } |
1249 | 1280 |
1250 bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, | 1281 bool ExtensionWebRequestEventRouter::GetAndSetSignaled(uint64 request_id, |
1251 EventTypes event_type) { | 1282 EventTypes event_type) { |
1252 SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); | 1283 SignaledRequestMap::iterator iter = signaled_requests_.find(request_id); |
1253 if (iter == signaled_requests_.end()) { | 1284 if (iter == signaled_requests_.end()) { |
1254 signaled_requests_[request_id] = event_type; | 1285 signaled_requests_[request_id] = event_type; |
1255 return false; | 1286 return false; |
1256 } | 1287 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1290 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( | 1321 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( |
1291 *value, &extra_info_spec)); | 1322 *value, &extra_info_spec)); |
1292 } | 1323 } |
1293 | 1324 |
1294 std::string event_name; | 1325 std::string event_name; |
1295 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); | 1326 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); |
1296 | 1327 |
1297 std::string sub_event_name; | 1328 std::string sub_event_name; |
1298 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); | 1329 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); |
1299 | 1330 |
| 1331 const Extension* extension = |
| 1332 extension_info_map()->extensions().GetByID(extension_id()); |
| 1333 std::string extension_name = extension ? extension->name() : extension_id(); |
| 1334 |
1300 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( | 1335 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener( |
1301 profile(), extension_id(), event_name, sub_event_name, filter, | 1336 profile(), extension_id(), extension_name, |
| 1337 event_name, sub_event_name, filter, |
1302 extra_info_spec, ipc_sender_weak()); | 1338 extra_info_spec, ipc_sender_weak()); |
1303 | 1339 |
1304 return true; | 1340 return true; |
1305 } | 1341 } |
1306 | 1342 |
1307 bool WebRequestEventHandled::RunImpl() { | 1343 bool WebRequestEventHandled::RunImpl() { |
1308 std::string event_name; | 1344 std::string event_name; |
1309 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); | 1345 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); |
1310 | 1346 |
1311 std::string sub_event_name; | 1347 std::string sub_event_name; |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1373 } | 1409 } |
1374 } | 1410 } |
1375 } | 1411 } |
1376 | 1412 |
1377 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( | 1413 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled( |
1378 profile(), extension_id(), event_name, sub_event_name, request_id, | 1414 profile(), extension_id(), event_name, sub_event_name, request_id, |
1379 response.release()); | 1415 response.release()); |
1380 | 1416 |
1381 return true; | 1417 return true; |
1382 } | 1418 } |
OLD | NEW |