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

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: final 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"
(...skipping 15 matching lines...) Expand all
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
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
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
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
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
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
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
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 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_webrequest_api.h ('k') | chrome/browser/extensions/extension_webrequest_api_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698