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

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

Issue 7024056: Handle extension webrequest API on the IO thread. This speeds up blocking event (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: fix broken test Created 9 years, 6 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/values.h" 12 #include "base/values.h"
13 #include "chrome/browser/extensions/extension_event_router_forwarder.h" 13 #include "chrome/browser/extensions/extension_event_router.h"
14 #include "chrome/browser/extensions/extension_info_map.h"
14 #include "chrome/browser/extensions/extension_prefs.h" 15 #include "chrome/browser/extensions/extension_prefs.h"
15 #include "chrome/browser/extensions/extension_service.h" 16 #include "chrome/browser/extensions/extension_service.h"
16 #include "chrome/browser/extensions/extension_tab_id_map.h" 17 #include "chrome/browser/extensions/extension_tab_id_map.h"
17 #include "chrome/browser/extensions/extension_webrequest_api_constants.h" 18 #include "chrome/browser/extensions/extension_webrequest_api_constants.h"
18 #include "chrome/browser/profiles/profile.h" 19 #include "chrome/browser/profiles/profile.h"
20 #include "chrome/browser/renderer_host/chrome_render_message_filter.h"
19 #include "chrome/common/extensions/extension.h" 21 #include "chrome/common/extensions/extension.h"
20 #include "chrome/common/extensions/extension_error_utils.h" 22 #include "chrome/common/extensions/extension_error_utils.h"
21 #include "chrome/common/extensions/url_pattern.h" 23 #include "chrome/common/extensions/url_pattern.h"
22 #include "chrome/common/url_constants.h" 24 #include "chrome/common/url_constants.h"
25 #include "content/browser/browser_message_filter.h"
23 #include "content/browser/browser_thread.h" 26 #include "content/browser/browser_thread.h"
24 #include "content/browser/renderer_host/resource_dispatcher_host.h" 27 #include "content/browser/renderer_host/resource_dispatcher_host.h"
25 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h" 28 #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
26 #include "net/base/net_errors.h" 29 #include "net/base/net_errors.h"
27 #include "net/http/http_response_headers.h" 30 #include "net/http/http_response_headers.h"
28 #include "net/url_request/url_request.h" 31 #include "net/url_request/url_request.h"
29 #include "googleurl/src/gurl.h" 32 #include "googleurl/src/gurl.h"
30 33
31 namespace keys = extension_webrequest_api_constants; 34 namespace keys = extension_webrequest_api_constants;
32 35
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
77 const char* ResourceTypeToString(ResourceType::Type type) { 80 const char* ResourceTypeToString(ResourceType::Type type) {
78 ResourceType::Type* iter = 81 ResourceType::Type* iter =
79 std::find(kResourceTypeValues, ARRAYEND(kResourceTypeValues), type); 82 std::find(kResourceTypeValues, ARRAYEND(kResourceTypeValues), type);
80 if (iter == ARRAYEND(kResourceTypeValues)) 83 if (iter == ARRAYEND(kResourceTypeValues))
81 return "other"; 84 return "other";
82 85
83 return kResourceTypeStrings[iter - kResourceTypeValues]; 86 return kResourceTypeStrings[iter - kResourceTypeValues];
84 } 87 }
85 88
86 bool ParseResourceType(const std::string& type_str, 89 bool ParseResourceType(const std::string& type_str,
87 ResourceType::Type* type) { 90 ResourceType::Type* type) {
88 const char** iter = 91 const char** iter =
89 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str); 92 std::find(kResourceTypeStrings, ARRAYEND(kResourceTypeStrings), type_str);
90 if (iter == ARRAYEND(kResourceTypeStrings)) 93 if (iter == ARRAYEND(kResourceTypeStrings))
91 return false; 94 return false;
92 *type = kResourceTypeValues[iter - kResourceTypeStrings]; 95 *type = kResourceTypeValues[iter - kResourceTypeStrings];
93 return true; 96 return true;
94 } 97 }
95 98
96 void ExtractRequestInfo(net::URLRequest* request, 99 void ExtractRequestInfo(net::URLRequest* request,
97 int* tab_id, 100 int* tab_id,
98 int* window_id, 101 int* window_id,
99 ResourceType::Type* resource_type) { 102 ResourceType::Type* resource_type) {
100 if (!request->GetUserData(NULL)) 103 if (!request->GetUserData(NULL))
101 return; 104 return;
102 105
103 ResourceDispatcherHostRequestInfo* info = 106 ResourceDispatcherHostRequestInfo* info =
104 ResourceDispatcherHost::InfoForRequest(request); 107 ResourceDispatcherHost::InfoForRequest(request);
105 ExtensionTabIdMap::GetInstance()->GetTabAndWindowId( 108 ExtensionTabIdMap::GetInstance()->GetTabAndWindowId(
106 info->child_id(), info->route_id(), tab_id, window_id); 109 info->child_id(), info->route_id(), tab_id, window_id);
107 110
108 // Restrict the resource type to the values we care about. 111 // Restrict the resource type to the values we care about.
109 ResourceType::Type* iter = 112 ResourceType::Type* iter =
110 std::find(kResourceTypeValues, ARRAYEND(kResourceTypeValues), 113 std::find(kResourceTypeValues, ARRAYEND(kResourceTypeValues),
111 info->resource_type()); 114 info->resource_type());
112 *resource_type = (iter != ARRAYEND(kResourceTypeValues)) ? 115 *resource_type = (iter != ARRAYEND(kResourceTypeValues)) ?
113 *iter : ResourceType::LAST_TYPE; 116 *iter : ResourceType::LAST_TYPE;
114 } 117 }
115 118
116 void AddEventListenerOnIOThread(
117 ProfileId profile_id,
118 const std::string& extension_id,
119 const std::string& event_name,
120 const std::string& sub_event_name,
121 const ExtensionWebRequestEventRouter::RequestFilter& filter,
122 int extra_info_spec) {
123 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
124 profile_id, extension_id, event_name, sub_event_name, filter,
125 extra_info_spec);
126 }
127
128 void EventHandledOnIOThread(
129 ProfileId profile_id,
130 const std::string& extension_id,
131 const std::string& event_name,
132 const std::string& sub_event_name,
133 uint64 request_id,
134 ExtensionWebRequestEventRouter::EventResponse* response) {
135 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
136 profile_id, extension_id, event_name, sub_event_name, request_id,
137 response);
138 }
139
140 // Creates a list of HttpHeaders (see extension_api.json). If |headers| is 119 // Creates a list of HttpHeaders (see extension_api.json). If |headers| is
141 // NULL, the list is empty. Ownership is passed to the caller. 120 // NULL, the list is empty. Ownership is passed to the caller.
142 ListValue* GetResponseHeadersList(const net::HttpResponseHeaders* headers) { 121 ListValue* GetResponseHeadersList(const net::HttpResponseHeaders* headers) {
143 ListValue* headers_value = new ListValue(); 122 ListValue* headers_value = new ListValue();
144 if (headers) { 123 if (headers) {
145 void* iter = NULL; 124 void* iter = NULL;
146 std::string name; 125 std::string name;
147 std::string value; 126 std::string value;
148 while (headers->EnumerateHeaderLines(&iter, &name, &value)) { 127 while (headers->EnumerateHeaderLines(&iter, &name, &value)) {
149 DictionaryValue* header = new DictionaryValue(); 128 DictionaryValue* header = new DictionaryValue();
(...skipping 27 matching lines...) Expand all
177 } // namespace 156 } // namespace
178 157
179 // Represents a single unique listener to an event, along with whatever filter 158 // Represents a single unique listener to an event, along with whatever filter
180 // parameters and extra_info_spec were specified at the time the listener was 159 // parameters and extra_info_spec were specified at the time the listener was
181 // added. 160 // added.
182 struct ExtensionWebRequestEventRouter::EventListener { 161 struct ExtensionWebRequestEventRouter::EventListener {
183 std::string extension_id; 162 std::string extension_id;
184 std::string sub_event_name; 163 std::string sub_event_name;
185 RequestFilter filter; 164 RequestFilter filter;
186 int extra_info_spec; 165 int extra_info_spec;
166 base::WeakPtr<IPC::Message::Sender> ipc_sender;
187 mutable std::set<uint64> blocked_requests; 167 mutable std::set<uint64> blocked_requests;
188 168
189 // Comparator to work with std::set. 169 // Comparator to work with std::set.
190 bool operator<(const EventListener& that) const { 170 bool operator<(const EventListener& that) const {
191 if (extension_id < that.extension_id) 171 if (extension_id < that.extension_id)
192 return true; 172 return true;
193 if (extension_id == that.extension_id && 173 if (extension_id == that.extension_id &&
194 sub_event_name < that.sub_event_name) 174 sub_event_name < that.sub_event_name)
195 return true; 175 return true;
196 return false; 176 return false;
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
334 } 314 }
335 315
336 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() { 316 ExtensionWebRequestEventRouter::ExtensionWebRequestEventRouter() {
337 } 317 }
338 318
339 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() { 319 ExtensionWebRequestEventRouter::~ExtensionWebRequestEventRouter() {
340 } 320 }
341 321
342 int ExtensionWebRequestEventRouter::OnBeforeRequest( 322 int ExtensionWebRequestEventRouter::OnBeforeRequest(
343 ProfileId profile_id, 323 ProfileId profile_id,
344 ExtensionEventRouterForwarder* event_router, 324 ExtensionInfoMap* extension_info_map,
345 net::URLRequest* request, 325 net::URLRequest* request,
346 net::CompletionCallback* callback, 326 net::CompletionCallback* callback,
347 GURL* new_url) { 327 GURL* new_url) {
348 // TODO(jochen): Figure out what to do with events from the system context. 328 // TODO(jochen): Figure out what to do with events from the system context.
349 if (profile_id == Profile::kInvalidProfileId) 329 if (profile_id == Profile::kInvalidProfileId)
350 return net::OK; 330 return net::OK;
351 331
352 // If this is an HTTP request, keep track of it. HTTP-specific events only 332 // If this is an HTTP request, keep track of it. HTTP-specific events only
353 // have the request ID, so we'll need to look up the URLRequest from that. 333 // have the request ID, so we'll need to look up the URLRequest from that.
354 // We need to do this even if no extension subscribes to OnBeforeRequest to 334 // We need to do this even if no extension subscribes to OnBeforeRequest to
355 // guarantee that |http_requests_| is populated if an extension subscribes 335 // guarantee that |http_requests_| is populated if an extension subscribes
356 // to OnBeforeSendHeaders or OnRequestSent. 336 // to OnBeforeSendHeaders or OnRequestSent.
357 if (request->url().SchemeIs(chrome::kHttpScheme) || 337 if (request->url().SchemeIs(chrome::kHttpScheme) ||
358 request->url().SchemeIs(chrome::kHttpsScheme)) { 338 request->url().SchemeIs(chrome::kHttpsScheme)) {
359 http_requests_[request->identifier()] = request; 339 http_requests_[request->identifier()] = request;
360 } 340 }
361 341
362 int tab_id = -1; 342 int tab_id = -1;
363 int window_id = -1; 343 int window_id = -1;
364 ResourceType::Type resource_type = ResourceType::LAST_TYPE; 344 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
365 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type); 345 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
366 346
367 int extra_info_spec = 0; 347 int extra_info_spec = 0;
368 std::vector<const EventListener*> listeners = 348 std::vector<const EventListener*> listeners =
369 GetMatchingListeners(profile_id, keys::kOnBeforeRequest, request->url(), 349 GetMatchingListeners(extension_info_map, profile_id,
Mihai Parparita -not on Chrome 2011/06/08 01:11:59 All of the functions in ExtensionWebRequestEventRo
350 keys::kOnBeforeRequest, request->url(),
370 tab_id, window_id, resource_type, &extra_info_spec); 351 tab_id, window_id, resource_type, &extra_info_spec);
371 if (listeners.empty()) 352 if (listeners.empty())
372 return net::OK; 353 return net::OK;
373 354
374 if (GetAndSetSignaled(request->identifier(), kOnBeforeRequest)) 355 if (GetAndSetSignaled(request->identifier(), kOnBeforeRequest))
375 return net::OK; 356 return net::OK;
376 357
377 ListValue args; 358 ListValue args;
378 DictionaryValue* dict = new DictionaryValue(); 359 DictionaryValue* dict = new DictionaryValue();
379 dict->SetString(keys::kRequestIdKey, 360 dict->SetString(keys::kRequestIdKey,
380 base::Uint64ToString(request->identifier())); 361 base::Uint64ToString(request->identifier()));
381 dict->SetString(keys::kUrlKey, request->url().spec()); 362 dict->SetString(keys::kUrlKey, request->url().spec());
382 dict->SetString(keys::kMethodKey, request->method()); 363 dict->SetString(keys::kMethodKey, request->method());
383 dict->SetInteger(keys::kTabIdKey, tab_id); 364 dict->SetInteger(keys::kTabIdKey, tab_id);
384 dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type)); 365 dict->SetString(keys::kTypeKey, ResourceTypeToString(resource_type));
385 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 366 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
386 args.Append(dict); 367 args.Append(dict);
387 368
388 if (DispatchEvent(profile_id, event_router, request, listeners, args)) { 369 if (DispatchEvent(profile_id, request, listeners, args)) {
389 blocked_requests_[request->identifier()].event = kOnBeforeRequest; 370 blocked_requests_[request->identifier()].event = kOnBeforeRequest;
390 blocked_requests_[request->identifier()].callback = callback; 371 blocked_requests_[request->identifier()].callback = callback;
391 blocked_requests_[request->identifier()].new_url = new_url; 372 blocked_requests_[request->identifier()].new_url = new_url;
392 return net::ERR_IO_PENDING; 373 return net::ERR_IO_PENDING;
393 } 374 }
394 return net::OK; 375 return net::OK;
395 } 376 }
396 377
397 int ExtensionWebRequestEventRouter::OnBeforeSendHeaders( 378 int ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
398 ProfileId profile_id, 379 ProfileId profile_id,
399 ExtensionEventRouterForwarder* event_router, 380 ExtensionInfoMap* extension_info_map,
400 uint64 request_id, 381 uint64 request_id,
401 net::CompletionCallback* callback, 382 net::CompletionCallback* callback,
402 net::HttpRequestHeaders* headers) { 383 net::HttpRequestHeaders* headers) {
403 // TODO(jochen): Figure out what to do with events from the system context. 384 // TODO(jochen): Figure out what to do with events from the system context.
404 if (profile_id == Profile::kInvalidProfileId) 385 if (profile_id == Profile::kInvalidProfileId)
405 return net::OK; 386 return net::OK;
406 387
407 HttpRequestMap::iterator iter = http_requests_.find(request_id); 388 HttpRequestMap::iterator iter = http_requests_.find(request_id);
408 if (iter == http_requests_.end()) 389 if (iter == http_requests_.end())
409 return net::OK; 390 return net::OK;
410 391
411 net::URLRequest* request = iter->second; 392 net::URLRequest* request = iter->second;
412 393
413 if (GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders)) 394 if (GetAndSetSignaled(request->identifier(), kOnBeforeSendHeaders))
414 return net::OK; 395 return net::OK;
415 396
416 int extra_info_spec = 0; 397 int extra_info_spec = 0;
417 std::vector<const EventListener*> listeners = 398 std::vector<const EventListener*> listeners =
418 GetMatchingListeners(profile_id, keys::kOnBeforeSendHeaders, request, 399 GetMatchingListeners(extension_info_map, profile_id,
400 keys::kOnBeforeSendHeaders, request,
419 &extra_info_spec); 401 &extra_info_spec);
420 if (listeners.empty()) 402 if (listeners.empty())
421 return net::OK; 403 return net::OK;
422 404
423 ListValue args; 405 ListValue args;
424 DictionaryValue* dict = new DictionaryValue(); 406 DictionaryValue* dict = new DictionaryValue();
425 dict->SetString(keys::kRequestIdKey, 407 dict->SetString(keys::kRequestIdKey,
426 base::Uint64ToString(request->identifier())); 408 base::Uint64ToString(request->identifier()));
427 dict->SetString(keys::kUrlKey, request->url().spec()); 409 dict->SetString(keys::kUrlKey, request->url().spec());
428 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000); 410 dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
429 411
430 if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 412 if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)
431 dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(headers)); 413 dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(headers));
432 // TODO(battre): implement request line. 414 // TODO(battre): implement request line.
433 415
434 args.Append(dict); 416 args.Append(dict);
435 417
436 if (DispatchEvent(profile_id, event_router, request, listeners, args)) { 418 if (DispatchEvent(profile_id, request, listeners, args)) {
437 blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders; 419 blocked_requests_[request->identifier()].event = kOnBeforeSendHeaders;
438 blocked_requests_[request->identifier()].callback = callback; 420 blocked_requests_[request->identifier()].callback = callback;
439 blocked_requests_[request->identifier()].request_headers = headers; 421 blocked_requests_[request->identifier()].request_headers = headers;
440 return net::ERR_IO_PENDING; 422 return net::ERR_IO_PENDING;
441 } 423 }
442 return net::OK; 424 return net::OK;
443 } 425 }
444 426
445 void ExtensionWebRequestEventRouter::OnRequestSent( 427 void ExtensionWebRequestEventRouter::OnRequestSent(
446 ProfileId profile_id, 428 ProfileId profile_id,
447 ExtensionEventRouterForwarder* event_router, 429 ExtensionInfoMap* extension_info_map,
448 uint64 request_id, 430 uint64 request_id,
449 const net::HostPortPair& socket_address, 431 const net::HostPortPair& socket_address,
450 const net::HttpRequestHeaders& headers) { 432 const net::HttpRequestHeaders& headers) {
451 if (profile_id == Profile::kInvalidProfileId) 433 if (profile_id == Profile::kInvalidProfileId)
452 return; 434 return;
453 base::Time time(base::Time::Now()); 435 base::Time time(base::Time::Now());
454 436
455 HttpRequestMap::iterator iter = http_requests_.find(request_id); 437 HttpRequestMap::iterator iter = http_requests_.find(request_id);
456 if (iter == http_requests_.end()) 438 if (iter == http_requests_.end())
457 return; 439 return;
458 440
459 net::URLRequest* request = iter->second; 441 net::URLRequest* request = iter->second;
460 442
461 if (GetAndSetSignaled(request->identifier(), kOnRequestSent)) 443 if (GetAndSetSignaled(request->identifier(), kOnRequestSent))
462 return; 444 return;
463 445
464 ClearSignaled(request->identifier(), kOnBeforeRedirect); 446 ClearSignaled(request->identifier(), kOnBeforeRedirect);
465 447
466 int extra_info_spec = 0; 448 int extra_info_spec = 0;
467 std::vector<const EventListener*> listeners = 449 std::vector<const EventListener*> listeners =
468 GetMatchingListeners(profile_id, keys::kOnRequestSent, request, 450 GetMatchingListeners(extension_info_map, profile_id,
469 &extra_info_spec); 451 keys::kOnRequestSent, request, &extra_info_spec);
470 if (listeners.empty()) 452 if (listeners.empty())
471 return; 453 return;
472 454
473 ListValue args; 455 ListValue args;
474 DictionaryValue* dict = new DictionaryValue(); 456 DictionaryValue* dict = new DictionaryValue();
475 dict->SetString(keys::kRequestIdKey, 457 dict->SetString(keys::kRequestIdKey,
476 base::Uint64ToString(request->identifier())); 458 base::Uint64ToString(request->identifier()));
477 dict->SetString(keys::kUrlKey, request->url().spec()); 459 dict->SetString(keys::kUrlKey, request->url().spec());
478 dict->SetString(keys::kIpKey, socket_address.host()); 460 dict->SetString(keys::kIpKey, socket_address.host());
479 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 461 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
480 if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS) 462 if (extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)
481 dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(&headers)); 463 dict->Set(keys::kRequestHeadersKey, GetRequestHeadersList(&headers));
482 // TODO(battre): support "request line". 464 // TODO(battre): support "request line".
483 args.Append(dict); 465 args.Append(dict);
484 466
485 DispatchEvent(profile_id, event_router, request, listeners, args); 467 DispatchEvent(profile_id, request, listeners, args);
486 } 468 }
487 469
488 void ExtensionWebRequestEventRouter::OnBeforeRedirect( 470 void ExtensionWebRequestEventRouter::OnBeforeRedirect(
489 ProfileId profile_id, 471 ProfileId profile_id,
490 ExtensionEventRouterForwarder* event_router, 472 ExtensionInfoMap* extension_info_map,
491 net::URLRequest* request, 473 net::URLRequest* request,
492 const GURL& new_location) { 474 const GURL& new_location) {
493 if (profile_id == Profile::kInvalidProfileId) 475 if (profile_id == Profile::kInvalidProfileId)
494 return; 476 return;
495 base::Time time(base::Time::Now()); 477 base::Time time(base::Time::Now());
496 478
497 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect)) 479 if (GetAndSetSignaled(request->identifier(), kOnBeforeRedirect))
498 return; 480 return;
499 481
500 ClearSignaled(request->identifier(), kOnBeforeRequest); 482 ClearSignaled(request->identifier(), kOnBeforeRequest);
501 ClearSignaled(request->identifier(), kOnBeforeSendHeaders); 483 ClearSignaled(request->identifier(), kOnBeforeSendHeaders);
502 ClearSignaled(request->identifier(), kOnRequestSent); 484 ClearSignaled(request->identifier(), kOnRequestSent);
503 485
504 int extra_info_spec = 0; 486 int extra_info_spec = 0;
505 std::vector<const EventListener*> listeners = 487 std::vector<const EventListener*> listeners =
506 GetMatchingListeners(profile_id, keys::kOnBeforeRedirect, request, 488 GetMatchingListeners(extension_info_map, profile_id,
507 &extra_info_spec); 489 keys::kOnBeforeRedirect, request, &extra_info_spec);
508 if (listeners.empty()) 490 if (listeners.empty())
509 return; 491 return;
510 492
511 int http_status_code = request->GetResponseCode(); 493 int http_status_code = request->GetResponseCode();
512 494
513 ListValue args; 495 ListValue args;
514 DictionaryValue* dict = new DictionaryValue(); 496 DictionaryValue* dict = new DictionaryValue();
515 dict->SetString(keys::kRequestIdKey, 497 dict->SetString(keys::kRequestIdKey,
516 base::Uint64ToString(request->identifier())); 498 base::Uint64ToString(request->identifier()));
517 dict->SetString(keys::kUrlKey, request->url().spec()); 499 dict->SetString(keys::kUrlKey, request->url().spec());
518 dict->SetString(keys::kRedirectUrlKey, new_location.spec()); 500 dict->SetString(keys::kRedirectUrlKey, new_location.spec());
519 dict->SetInteger(keys::kStatusCodeKey, http_status_code); 501 dict->SetInteger(keys::kStatusCodeKey, http_status_code);
520 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 502 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
521 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 503 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
522 dict->Set(keys::kResponseHeadersKey, 504 dict->Set(keys::kResponseHeadersKey,
523 GetResponseHeadersList(request->response_headers())); 505 GetResponseHeadersList(request->response_headers()));
524 } 506 }
525 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE) 507 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE)
526 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 508 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
527 args.Append(dict); 509 args.Append(dict);
528 510
529 DispatchEvent(profile_id, event_router, request, listeners, args); 511 DispatchEvent(profile_id, request, listeners, args);
530 } 512 }
531 513
532 void ExtensionWebRequestEventRouter::OnResponseStarted( 514 void ExtensionWebRequestEventRouter::OnResponseStarted(
533 ProfileId profile_id, 515 ProfileId profile_id,
534 ExtensionEventRouterForwarder* event_router, 516 ExtensionInfoMap* extension_info_map,
535 net::URLRequest* request) { 517 net::URLRequest* request) {
536 if (profile_id == Profile::kInvalidProfileId) 518 if (profile_id == Profile::kInvalidProfileId)
537 return; 519 return;
538 520
539 // OnResponseStarted is even triggered, when the request was cancelled. 521 // OnResponseStarted is even triggered, when the request was cancelled.
540 if (request->status().status() != net::URLRequestStatus::SUCCESS) 522 if (request->status().status() != net::URLRequestStatus::SUCCESS)
541 return; 523 return;
542 524
543 base::Time time(base::Time::Now()); 525 base::Time time(base::Time::Now());
544 526
545 int extra_info_spec = 0; 527 int extra_info_spec = 0;
546 std::vector<const EventListener*> listeners = 528 std::vector<const EventListener*> listeners =
547 GetMatchingListeners(profile_id, keys::kOnResponseStarted, request, 529 GetMatchingListeners(extension_info_map, profile_id,
548 &extra_info_spec); 530 keys::kOnResponseStarted, request, &extra_info_spec);
549 if (listeners.empty()) 531 if (listeners.empty())
550 return; 532 return;
551 533
552 // UrlRequestFileJobs do not send headers, so we simulate their behavior. 534 // UrlRequestFileJobs do not send headers, so we simulate their behavior.
553 int response_code = 200; 535 int response_code = 200;
554 if (request->response_headers()) 536 if (request->response_headers())
555 response_code = request->response_headers()->response_code(); 537 response_code = request->response_headers()->response_code();
556 538
557 ListValue args; 539 ListValue args;
558 DictionaryValue* dict = new DictionaryValue(); 540 DictionaryValue* dict = new DictionaryValue();
559 dict->SetString(keys::kRequestIdKey, 541 dict->SetString(keys::kRequestIdKey,
560 base::Uint64ToString(request->identifier())); 542 base::Uint64ToString(request->identifier()));
561 dict->SetString(keys::kUrlKey, request->url().spec()); 543 dict->SetString(keys::kUrlKey, request->url().spec());
562 dict->SetInteger(keys::kStatusCodeKey, response_code); 544 dict->SetInteger(keys::kStatusCodeKey, response_code);
563 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 545 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
564 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 546 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
565 dict->Set(keys::kResponseHeadersKey, 547 dict->Set(keys::kResponseHeadersKey,
566 GetResponseHeadersList(request->response_headers())); 548 GetResponseHeadersList(request->response_headers()));
567 } 549 }
568 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE) 550 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE)
569 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 551 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
570 args.Append(dict); 552 args.Append(dict);
571 553
572 DispatchEvent(profile_id, event_router, request, listeners, args); 554 DispatchEvent(profile_id, request, listeners, args);
573 } 555 }
574 556
575 void ExtensionWebRequestEventRouter::OnCompleted( 557 void ExtensionWebRequestEventRouter::OnCompleted(
576 ProfileId profile_id, 558 ProfileId profile_id,
577 ExtensionEventRouterForwarder* event_router, 559 ExtensionInfoMap* extension_info_map,
578 net::URLRequest* request) { 560 net::URLRequest* request) {
579 if (profile_id == Profile::kInvalidProfileId) 561 if (profile_id == Profile::kInvalidProfileId)
580 return; 562 return;
581 563
582 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS); 564 DCHECK(request->status().status() == net::URLRequestStatus::SUCCESS);
583 565
584 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted)); 566 DCHECK(!GetAndSetSignaled(request->identifier(), kOnCompleted));
585 567
586 base::Time time(base::Time::Now()); 568 base::Time time(base::Time::Now());
587 569
588 int extra_info_spec = 0; 570 int extra_info_spec = 0;
589 std::vector<const EventListener*> listeners = 571 std::vector<const EventListener*> listeners =
590 GetMatchingListeners(profile_id, keys::kOnCompleted, request, 572 GetMatchingListeners(extension_info_map, profile_id,
591 &extra_info_spec); 573 keys::kOnCompleted, request, &extra_info_spec);
592 if (listeners.empty()) 574 if (listeners.empty())
593 return; 575 return;
594 576
595 // UrlRequestFileJobs do not send headers, so we simulate their behavior. 577 // UrlRequestFileJobs do not send headers, so we simulate their behavior.
596 int response_code = 200; 578 int response_code = 200;
597 if (request->response_headers()) 579 if (request->response_headers())
598 response_code = request->response_headers()->response_code(); 580 response_code = request->response_headers()->response_code();
599 581
600 ListValue args; 582 ListValue args;
601 DictionaryValue* dict = new DictionaryValue(); 583 DictionaryValue* dict = new DictionaryValue();
602 dict->SetString(keys::kRequestIdKey, 584 dict->SetString(keys::kRequestIdKey,
603 base::Uint64ToString(request->identifier())); 585 base::Uint64ToString(request->identifier()));
604 dict->SetString(keys::kUrlKey, request->url().spec()); 586 dict->SetString(keys::kUrlKey, request->url().spec());
605 dict->SetInteger(keys::kStatusCodeKey, response_code); 587 dict->SetInteger(keys::kStatusCodeKey, response_code);
606 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 588 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
607 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) { 589 if (extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS) {
608 dict->Set(keys::kResponseHeadersKey, 590 dict->Set(keys::kResponseHeadersKey,
609 GetResponseHeadersList(request->response_headers())); 591 GetResponseHeadersList(request->response_headers()));
610 } 592 }
611 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE) 593 if (extra_info_spec & ExtraInfoSpec::STATUS_LINE)
612 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers())); 594 dict->Set(keys::kStatusLineKey, GetStatusLine(request->response_headers()));
613 args.Append(dict); 595 args.Append(dict);
614 596
615 DispatchEvent(profile_id, event_router, request, listeners, args); 597 DispatchEvent(profile_id, request, listeners, args);
616 } 598 }
617 599
618 void ExtensionWebRequestEventRouter::OnErrorOccurred( 600 void ExtensionWebRequestEventRouter::OnErrorOccurred(
619 ProfileId profile_id, 601 ProfileId profile_id,
620 ExtensionEventRouterForwarder* event_router, 602 ExtensionInfoMap* extension_info_map,
621 net::URLRequest* request) { 603 net::URLRequest* request) {
622 if (profile_id == Profile::kInvalidProfileId) 604 if (profile_id == Profile::kInvalidProfileId)
623 return; 605 return;
624 606
625 DCHECK(request->status().status() == net::URLRequestStatus::FAILED); 607 DCHECK(request->status().status() == net::URLRequestStatus::FAILED);
626 608
627 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred)); 609 DCHECK(!GetAndSetSignaled(request->identifier(), kOnErrorOccurred));
628 610
629 base::Time time(base::Time::Now()); 611 base::Time time(base::Time::Now());
630 612
631 int extra_info_spec = 0; 613 int extra_info_spec = 0;
632 std::vector<const EventListener*> listeners = 614 std::vector<const EventListener*> listeners =
633 GetMatchingListeners(profile_id, keys::kOnErrorOccurred, request, 615 GetMatchingListeners(extension_info_map, profile_id,
634 &extra_info_spec); 616 keys::kOnErrorOccurred, request, &extra_info_spec);
635 if (listeners.empty()) 617 if (listeners.empty())
636 return; 618 return;
637 619
638 ListValue args; 620 ListValue args;
639 DictionaryValue* dict = new DictionaryValue(); 621 DictionaryValue* dict = new DictionaryValue();
640 dict->SetString(keys::kRequestIdKey, 622 dict->SetString(keys::kRequestIdKey,
641 base::Uint64ToString(request->identifier())); 623 base::Uint64ToString(request->identifier()));
642 dict->SetString(keys::kUrlKey, request->url().spec()); 624 dict->SetString(keys::kUrlKey, request->url().spec());
643 dict->SetString(keys::kErrorKey, 625 dict->SetString(keys::kErrorKey,
644 net::ErrorToString(request->status().os_error())); 626 net::ErrorToString(request->status().os_error()));
645 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000); 627 dict->SetDouble(keys::kTimeStampKey, time.ToDoubleT() * 1000);
646 args.Append(dict); 628 args.Append(dict);
647 629
648 DispatchEvent(profile_id, event_router, request, listeners, args); 630 DispatchEvent(profile_id, request, listeners, args);
649 } 631 }
650 632
651 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed( 633 void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
652 ProfileId profile_id, net::URLRequest* request) { 634 ProfileId profile_id, net::URLRequest* request) {
653 blocked_requests_.erase(request->identifier()); 635 blocked_requests_.erase(request->identifier());
654 signaled_requests_.erase(request->identifier()); 636 signaled_requests_.erase(request->identifier());
655 http_requests_.erase(request->identifier()); 637 http_requests_.erase(request->identifier());
656 } 638 }
657 639
658 void ExtensionWebRequestEventRouter::OnHttpTransactionDestroyed( 640 void ExtensionWebRequestEventRouter::OnHttpTransactionDestroyed(
659 ProfileId profile_id, uint64 request_id) { 641 ProfileId profile_id, uint64 request_id) {
660 if (blocked_requests_.find(request_id) != blocked_requests_.end() && 642 if (blocked_requests_.find(request_id) != blocked_requests_.end() &&
661 blocked_requests_[request_id].event == kOnBeforeSendHeaders) { 643 blocked_requests_[request_id].event == kOnBeforeSendHeaders) {
662 // Ensure we don't call into the deleted HttpTransaction. 644 // Ensure we don't call into the deleted HttpTransaction.
663 blocked_requests_[request_id].callback = NULL; 645 blocked_requests_[request_id].callback = NULL;
664 blocked_requests_[request_id].request_headers = NULL; 646 blocked_requests_[request_id].request_headers = NULL;
665 } 647 }
666 } 648 }
667 649
668 bool ExtensionWebRequestEventRouter::DispatchEvent( 650 bool ExtensionWebRequestEventRouter::DispatchEvent(
669 ProfileId profile_id, 651 ProfileId profile_id,
670 ExtensionEventRouterForwarder* event_router,
671 net::URLRequest* request, 652 net::URLRequest* request,
672 const std::vector<const EventListener*>& listeners, 653 const std::vector<const EventListener*>& listeners,
673 const ListValue& args) { 654 const ListValue& args) {
674 std::string json_args; 655 std::string json_args;
675 656
676 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args) 657 // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
677 // pairs into a single message sent to a list of sub_event_names. 658 // pairs into a single message sent to a list of sub_event_names.
678 int num_handlers_blocking = 0; 659 int num_handlers_blocking = 0;
679 for (std::vector<const EventListener*>::const_iterator it = listeners.begin(); 660 for (std::vector<const EventListener*>::const_iterator it = listeners.begin();
680 it != listeners.end(); ++it) { 661 it != listeners.end(); ++it) {
681 // Filter out the optional keys that this listener didn't request. 662 // Filter out the optional keys that this listener didn't request.
682 scoped_ptr<ListValue> args_filtered(args.DeepCopy()); 663 scoped_ptr<ListValue> args_filtered(args.DeepCopy());
683 DictionaryValue* dict = NULL; 664 DictionaryValue* dict = NULL;
684 CHECK(args_filtered->GetDictionary(0, &dict) && dict); 665 CHECK(args_filtered->GetDictionary(0, &dict) && dict);
685 if (!((*it)->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS)) 666 if (!((*it)->extra_info_spec & ExtraInfoSpec::REQUEST_HEADERS))
686 dict->Remove(keys::kRequestHeadersKey, NULL); 667 dict->Remove(keys::kRequestHeadersKey, NULL);
687 if (!((*it)->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS)) 668 if (!((*it)->extra_info_spec & ExtraInfoSpec::RESPONSE_HEADERS))
688 dict->Remove(keys::kResponseHeadersKey, NULL); 669 dict->Remove(keys::kResponseHeadersKey, NULL);
689 if (!((*it)->extra_info_spec & ExtraInfoSpec::STATUS_LINE)) 670 if (!((*it)->extra_info_spec & ExtraInfoSpec::STATUS_LINE))
690 dict->Remove(keys::kStatusLineKey, NULL); 671 dict->Remove(keys::kStatusLineKey, NULL);
691 672
692 base::JSONWriter::Write(args_filtered.get(), false, &json_args); 673 base::JSONWriter::Write(args_filtered.get(), false, &json_args);
693 event_router->DispatchEventToExtension( 674
694 (*it)->extension_id, (*it)->sub_event_name, json_args, 675 ExtensionEventRouter::DispatchEvent(
695 profile_id, true, GURL()); 676 (*it)->ipc_sender.get(), (*it)->extension_id, (*it)->sub_event_name,
677 json_args, GURL());
696 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) { 678 if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
697 (*it)->blocked_requests.insert(request->identifier()); 679 (*it)->blocked_requests.insert(request->identifier());
698 ++num_handlers_blocking; 680 ++num_handlers_blocking;
699 } 681 }
700 } 682 }
701 683
702 if (num_handlers_blocking > 0) { 684 if (num_handlers_blocking > 0) {
703 CHECK(blocked_requests_.find(request->identifier()) == 685 CHECK(blocked_requests_.find(request->identifier()) ==
704 blocked_requests_.end()); 686 blocked_requests_.end());
705 blocked_requests_[request->identifier()].num_handlers_blocking = 687 blocked_requests_[request->identifier()].num_handlers_blocking =
(...skipping 26 matching lines...) Expand all
732 714
733 DecrementBlockCount(request_id, response); 715 DecrementBlockCount(request_id, response);
734 } 716 }
735 717
736 void ExtensionWebRequestEventRouter::AddEventListener( 718 void ExtensionWebRequestEventRouter::AddEventListener(
737 ProfileId profile_id, 719 ProfileId profile_id,
738 const std::string& extension_id, 720 const std::string& extension_id,
739 const std::string& event_name, 721 const std::string& event_name,
740 const std::string& sub_event_name, 722 const std::string& sub_event_name,
741 const RequestFilter& filter, 723 const RequestFilter& filter,
742 int extra_info_spec) { 724 int extra_info_spec,
725 base::WeakPtr<IPC::Message::Sender> ipc_sender) {
743 if (!IsWebRequestEvent(event_name)) 726 if (!IsWebRequestEvent(event_name))
744 return; 727 return;
745 728
746 EventListener listener; 729 EventListener listener;
747 listener.extension_id = extension_id; 730 listener.extension_id = extension_id;
748 listener.sub_event_name = sub_event_name; 731 listener.sub_event_name = sub_event_name;
749 listener.filter = filter; 732 listener.filter = filter;
750 listener.extra_info_spec = extra_info_spec; 733 listener.extra_info_spec = extra_info_spec;
734 listener.ipc_sender = ipc_sender;
751 735
752 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 0u) << 736 CHECK_EQ(listeners_[profile_id][event_name].count(listener), 0u) <<
753 "extension=" << extension_id << " event=" << event_name; 737 "extension=" << extension_id << " event=" << event_name;
754 listeners_[profile_id][event_name].insert(listener); 738 listeners_[profile_id][event_name].insert(listener);
755 } 739 }
756 740
757 void ExtensionWebRequestEventRouter::RemoveEventListener( 741 void ExtensionWebRequestEventRouter::RemoveEventListener(
758 ProfileId profile_id, 742 ProfileId profile_id,
759 const std::string& extension_id, 743 const std::string& extension_id,
760 const std::string& sub_event_name) { 744 const std::string& sub_event_name) {
(...skipping 20 matching lines...) Expand all
781 765
782 // Unblock any request that this event listener may have been blocking. 766 // Unblock any request that this event listener may have been blocking.
783 for (std::set<uint64>::iterator it = found->blocked_requests.begin(); 767 for (std::set<uint64>::iterator it = found->blocked_requests.begin();
784 it != found->blocked_requests.end(); ++it) { 768 it != found->blocked_requests.end(); ++it) {
785 DecrementBlockCount(*it, NULL); 769 DecrementBlockCount(*it, NULL);
786 } 770 }
787 771
788 listeners_[profile_id][event_name].erase(listener); 772 listeners_[profile_id][event_name].erase(listener);
789 } 773 }
790 774
791 std::vector<const ExtensionWebRequestEventRouter::EventListener*> 775 void ExtensionWebRequestEventRouter::OnOTRProfileCreated(
792 ExtensionWebRequestEventRouter::GetMatchingListeners( 776 ProfileId original_profile_id, ProfileId otr_profile_id) {
777 cross_profile_map_[original_profile_id] = otr_profile_id;
778 cross_profile_map_[otr_profile_id] = original_profile_id;
779 }
780
781 void ExtensionWebRequestEventRouter::OnOTRProfileDestroyed(
782 ProfileId original_profile_id, ProfileId otr_profile_id) {
783 cross_profile_map_.erase(otr_profile_id);
784 cross_profile_map_.erase(original_profile_id);
785 }
786
787 void ExtensionWebRequestEventRouter::GetMatchingListenersImpl(
788 ExtensionInfoMap* extension_info_map,
793 ProfileId profile_id, 789 ProfileId profile_id,
790 bool crosses_incognito,
794 const std::string& event_name, 791 const std::string& event_name,
795 const GURL& url, 792 const GURL& url,
796 int tab_id, 793 int tab_id,
797 int window_id, 794 int window_id,
798 ResourceType::Type resource_type, 795 ResourceType::Type resource_type,
799 int* extra_info_spec) { 796 int* extra_info_spec,
800 // TODO(mpcomplete): handle profile_id == invalid (should collect all 797 std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
801 // listeners). 798 matching_listeners) {
802 *extra_info_spec = 0;
803
804 std::vector<const EventListener*> matching_listeners;
805 std::set<EventListener>& listeners = listeners_[profile_id][event_name]; 799 std::set<EventListener>& listeners = listeners_[profile_id][event_name];
806 for (std::set<EventListener>::iterator it = listeners.begin(); 800 for (std::set<EventListener>::iterator it = listeners.begin();
807 it != listeners.end(); ++it) { 801 it != listeners.end(); ++it) {
802 if (!it->ipc_sender.get()) {
803 // The IPC sender has been deleted. This listener will be removed soon
804 // via a call to RemoveEventListener. For now, just skip it.
805 continue;
806 }
807
808 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url)) 808 if (!it->filter.urls.is_empty() && !it->filter.urls.MatchesURL(url))
809 continue; 809 continue;
810 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id) 810 if (it->filter.tab_id != -1 && tab_id != it->filter.tab_id)
811 continue; 811 continue;
812 if (it->filter.window_id != -1 && window_id != it->filter.window_id) 812 if (it->filter.window_id != -1 && window_id != it->filter.window_id)
813 continue; 813 continue;
814 if (!it->filter.types.empty() && 814 if (!it->filter.types.empty() &&
815 std::find(it->filter.types.begin(), it->filter.types.end(), 815 std::find(it->filter.types.begin(), it->filter.types.end(),
816 resource_type) == it->filter.types.end()) 816 resource_type) == it->filter.types.end())
817 continue; 817 continue;
818 818
819 matching_listeners.push_back(&(*it)); 819 // Check if this event crosses incognito boundaries when it shouldn't.
820 // extension_info_map can be NULL if this is a system-level request.
821 if (extension_info_map) {
822 const Extension* extension =
823 extension_info_map->extensions().GetByID(it->extension_id);
824 if (!extension ||
825 (crosses_incognito &&
826 !extension_info_map->CanCrossIncognito(extension)))
827 continue;
828 }
829
830 matching_listeners->push_back(&(*it));
820 *extra_info_spec |= it->extra_info_spec; 831 *extra_info_spec |= it->extra_info_spec;
821 } 832 }
833 }
834
835 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
836 ExtensionWebRequestEventRouter::GetMatchingListeners(
837 ExtensionInfoMap* extension_info_map,
838 ProfileId profile_id,
839 const std::string& event_name,
840 const GURL& url,
841 int tab_id,
842 int window_id,
843 ResourceType::Type resource_type,
844 int* extra_info_spec) {
845 // TODO(mpcomplete): handle profile_id == invalid (should collect all
846 // listeners).
847 *extra_info_spec = 0;
848
849 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
850 matching_listeners;
851
852 GetMatchingListenersImpl(
853 extension_info_map, profile_id, false, event_name, url,
854 tab_id, window_id, resource_type, extra_info_spec, &matching_listeners);
855 CrossProfileMap::const_iterator cross_profile_id =
856 cross_profile_map_.find(profile_id);
857 if (cross_profile_id != cross_profile_map_.end()) {
858 GetMatchingListenersImpl(
859 extension_info_map, cross_profile_id->second, true, event_name, url,
860 tab_id, window_id, resource_type, extra_info_spec, &matching_listeners);
861 }
862
822 return matching_listeners; 863 return matching_listeners;
823 } 864 }
824 865
825 std::vector<const ExtensionWebRequestEventRouter::EventListener*> 866 std::vector<const ExtensionWebRequestEventRouter::EventListener*>
826 ExtensionWebRequestEventRouter::GetMatchingListeners( 867 ExtensionWebRequestEventRouter::GetMatchingListeners(
868 ExtensionInfoMap* extension_info_map,
827 ProfileId profile_id, 869 ProfileId profile_id,
828 const std::string& event_name, 870 const std::string& event_name,
829 net::URLRequest* request, 871 net::URLRequest* request,
830 int* extra_info_spec) { 872 int* extra_info_spec) {
831 int tab_id = -1; 873 int tab_id = -1;
832 int window_id = -1; 874 int window_id = -1;
833 ResourceType::Type resource_type = ResourceType::LAST_TYPE; 875 ResourceType::Type resource_type = ResourceType::LAST_TYPE;
834 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type); 876 ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
835 877
836 return GetMatchingListeners( 878 return GetMatchingListeners(
837 profile_id, event_name, request->url(), tab_id, window_id, resource_type, 879 extension_info_map, profile_id, event_name, request->url(),
838 extra_info_spec); 880 tab_id, window_id, resource_type, extra_info_spec);
839 } 881 }
840 882
841 void ExtensionWebRequestEventRouter::DecrementBlockCount( 883 void ExtensionWebRequestEventRouter::DecrementBlockCount(
842 uint64 request_id, 884 uint64 request_id,
843 EventResponse* response) { 885 EventResponse* response) {
844 scoped_ptr<EventResponse> response_scoped(response); 886 scoped_ptr<EventResponse> response_scoped(response);
845 887
846 // It's possible that this request was deleted, or cancelled by a previous 888 // It's possible that this request was deleted, or cancelled by a previous
847 // event handler. If so, ignore this response. 889 // event handler. If so, ignore this response.
848 if (blocked_requests_.find(request_id) == blocked_requests_.end()) 890 if (blocked_requests_.find(request_id) == blocked_requests_.end())
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
948 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue( 990 ExtensionWebRequestEventRouter::ExtraInfoSpec::InitFromValue(
949 *value, &extra_info_spec)); 991 *value, &extra_info_spec));
950 } 992 }
951 993
952 std::string event_name; 994 std::string event_name;
953 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name)); 995 EXTENSION_FUNCTION_VALIDATE(args_->GetString(3, &event_name));
954 996
955 std::string sub_event_name; 997 std::string sub_event_name;
956 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name)); 998 EXTENSION_FUNCTION_VALIDATE(args_->GetString(4, &sub_event_name));
957 999
958 BrowserThread::PostTask( 1000 ExtensionWebRequestEventRouter::GetInstance()->AddEventListener(
959 BrowserThread::IO, FROM_HERE, 1001 profile_id(), extension_id(), event_name, sub_event_name, filter,
960 NewRunnableFunction( 1002 extra_info_spec, ipc_sender_weak());
961 &AddEventListenerOnIOThread,
962 profile()->GetRuntimeId(), extension_id(),
963 event_name, sub_event_name, filter, extra_info_spec));
964 1003
965 return true; 1004 return true;
966 } 1005 }
967 1006
968 bool WebRequestEventHandled::RunImpl() { 1007 bool WebRequestEventHandled::RunImpl() {
969 std::string event_name; 1008 std::string event_name;
970 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name)); 1009 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &event_name));
971 1010
972 std::string sub_event_name; 1011 std::string sub_event_name;
973 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &sub_event_name)); 1012 EXTENSION_FUNCTION_VALIDATE(args_->GetString(1, &sub_event_name));
974 1013
975 std::string request_id_str; 1014 std::string request_id_str;
976 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &request_id_str)); 1015 EXTENSION_FUNCTION_VALIDATE(args_->GetString(2, &request_id_str));
977 // TODO(mpcomplete): string-to-uint64? 1016 // TODO(mpcomplete): string-to-uint64?
978 int64 request_id; 1017 int64 request_id;
979 EXTENSION_FUNCTION_VALIDATE(base::StringToInt64(request_id_str, &request_id)); 1018 EXTENSION_FUNCTION_VALIDATE(base::StringToInt64(request_id_str, &request_id));
980 1019
981 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response; 1020 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response;
982 if (HasOptionalArgument(3)) { 1021 if (HasOptionalArgument(3)) {
983 DictionaryValue* value = NULL; 1022 DictionaryValue* value = NULL;
984 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(3, &value)); 1023 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(3, &value));
985 1024
986 if (!value->empty()) { 1025 if (!value->empty()) {
987 base::Time install_time = 1026 base::Time install_time =
988 profile()->GetExtensionService()->extension_prefs()-> 1027 extension_info_map()->GetInstallTime(extension_id());
989 GetInstallTime(extension_id());
990 response.reset(new ExtensionWebRequestEventRouter::EventResponse( 1028 response.reset(new ExtensionWebRequestEventRouter::EventResponse(
991 extension_id(), install_time)); 1029 extension_id(), install_time));
992 } 1030 }
993 1031
994 if (value->HasKey("cancel")) { 1032 if (value->HasKey("cancel")) {
995 // Don't allow cancel mixed with other keys. 1033 // Don't allow cancel mixed with other keys.
996 if (value->HasKey("redirectUrl") || value->HasKey("requestHeaders")) { 1034 if (value->HasKey("redirectUrl") || value->HasKey("requestHeaders")) {
997 error_ = keys::kInvalidBlockingResponse; 1035 error_ = keys::kInvalidBlockingResponse;
998 return false; 1036 return false;
999 } 1037 }
(...skipping 29 matching lines...) Expand all
1029 EXTENSION_FUNCTION_VALIDATE( 1067 EXTENSION_FUNCTION_VALIDATE(
1030 header_value->GetString(keys::kHeaderNameKey, &name)); 1068 header_value->GetString(keys::kHeaderNameKey, &name));
1031 EXTENSION_FUNCTION_VALIDATE( 1069 EXTENSION_FUNCTION_VALIDATE(
1032 header_value->GetString(keys::kHeaderValueKey, &value)); 1070 header_value->GetString(keys::kHeaderValueKey, &value));
1033 1071
1034 response->request_headers->SetHeader(name, value); 1072 response->request_headers->SetHeader(name, value);
1035 } 1073 }
1036 } 1074 }
1037 } 1075 }
1038 1076
1039 BrowserThread::PostTask( 1077 ExtensionWebRequestEventRouter::GetInstance()->OnEventHandled(
1040 BrowserThread::IO, FROM_HERE, 1078 profile_id(), extension_id(), event_name, sub_event_name, request_id,
1041 NewRunnableFunction( 1079 response.release());
1042 &EventHandledOnIOThread,
1043 profile()->GetRuntimeId(), extension_id(),
1044 event_name, sub_event_name, request_id, response.release()));
1045 1080
1046 return true; 1081 return true;
1047 } 1082 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698