Chromium Code Reviews| 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(extension_info_map, profile_id, |
|
Mihai Parparita -not on Chrome
2011/06/09 18:37:24
Ping on this comment: "All of the functions in Ext
Matt Perry
2011/06/09 18:50:30
Sorry, I missed that comment. Done.
| |
| 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 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( | |
| 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 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 |