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

Side by Side Diff: chrome/browser/extensions/extension_webrequest_api.cc

Issue 7523042: Add a status message "Waiting for extension Foo..." when there's a request (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: comments Created 9 years, 4 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) 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
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
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
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
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
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698