OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_webrequest_api.h" | 5 #include "chrome/browser/extensions/extension_webrequest_api.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "base/json/json_writer.h" | 9 #include "base/json/json_writer.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/string_number_conversions.h" | 11 #include "base/string_number_conversions.h" |
12 #include "base/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 Loading... |
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 Loading... |
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 Loading... |
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(profile_id, extension_info_map, |
| 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(profile_id, extension_info_map, |
| 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(profile_id, extension_info_map, |
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(profile_id, extension_info_map, |
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(profile_id, extension_info_map, |
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(profile_id, extension_info_map, |
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(profile_id, extension_info_map, |
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 Loading... |
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 Loading... |
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( |
793 ProfileId profile_id, | 788 ProfileId profile_id, |
| 789 ExtensionInfoMap* extension_info_map, |
| 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 ProfileId profile_id, |
| 838 ExtensionInfoMap* extension_info_map, |
| 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 profile_id, extension_info_map, 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 cross_profile_id->second, extension_info_map, 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( |
827 ProfileId profile_id, | 868 ProfileId profile_id, |
| 869 ExtensionInfoMap* extension_info_map, |
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 profile_id, extension_info_map, 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 Loading... |
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 Loading... |
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 } |
OLD | NEW |