| Index: chrome/browser/extensions/extension_webrequest_api.cc
|
| diff --git a/chrome/browser/extensions/extension_webrequest_api.cc b/chrome/browser/extensions/extension_webrequest_api.cc
|
| index 56a464d10bba16848a01ed2c4a8d0c52690d08ab..08c7066baa5e526e3f5c44243b4f35871b80a609 100644
|
| --- a/chrome/browser/extensions/extension_webrequest_api.cc
|
| +++ b/chrome/browser/extensions/extension_webrequest_api.cc
|
| @@ -17,6 +17,7 @@
|
| #include "chrome/common/extensions/extension.h"
|
| #include "chrome/common/extensions/extension_extent.h"
|
| #include "chrome/common/extensions/url_pattern.h"
|
| +#include "chrome/common/url_constants.h"
|
| #include "content/browser/browser_thread.h"
|
| #include "content/browser/renderer_host/resource_dispatcher_host.h"
|
| #include "content/browser/renderer_host/resource_dispatcher_host_request_info.h"
|
| @@ -32,6 +33,7 @@ namespace {
|
| static const char *kWebRequestEvents[] = {
|
| keys::kOnBeforeRedirect,
|
| keys::kOnBeforeRequest,
|
| + keys::kOnBeforeSendHeaders,
|
| keys::kOnCompleted,
|
| keys::kOnErrorOccurred,
|
| keys::kOnHeadersReceived,
|
| @@ -155,7 +157,7 @@ struct ExtensionWebRequestEventRouter::ExtraInfoSpec {
|
| RESPONSE_HEADERS = 1<<3,
|
| REDIRECT_REQUEST_LINE = 1<<4,
|
| REDIRECT_REQUEST_HEADERS = 1<<5,
|
| - BLOCKING = 1<<5,
|
| + BLOCKING = 1<<6,
|
| };
|
|
|
| static bool InitFromValue(const ListValue& value, int* extra_info_spec);
|
| @@ -300,6 +302,13 @@ bool ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| if (listeners.empty())
|
| return false;
|
|
|
| + // If this is an HTTP request, keep track of it. HTTP-specific events only
|
| + // have the request ID, so we'll need to look up the URLRequest from that.
|
| + if (request->url().SchemeIs(chrome::kHttpScheme) ||
|
| + request->url().SchemeIs(chrome::kHttpsScheme)) {
|
| + http_requests_[request->identifier()] = request;
|
| + }
|
| +
|
| ListValue args;
|
| DictionaryValue* dict = new DictionaryValue();
|
| dict->SetString(keys::kRequestIdKey,
|
| @@ -312,18 +321,65 @@ bool ExtensionWebRequestEventRouter::OnBeforeRequest(
|
| request->request_time().ToDoubleT() * 1000);
|
| args.Append(dict);
|
|
|
| + return DispatchEvent(profile_id, event_router, request, callback, listeners,
|
| + args);
|
| +}
|
| +
|
| +bool ExtensionWebRequestEventRouter::OnBeforeSendHeaders(
|
| + ProfileId profile_id,
|
| + ExtensionEventRouterForwarder* event_router,
|
| + uint64 request_id,
|
| + net::HttpRequestHeaders* headers,
|
| + net::CompletionCallback* callback) {
|
| + // TODO(jochen): Figure out what to do with events from the system context.
|
| + if (profile_id == Profile::kInvalidProfileId)
|
| + return false;
|
| +
|
| + HttpRequestMap::iterator iter = http_requests_.find(request_id);
|
| + if (iter == http_requests_.end())
|
| + return false;
|
| +
|
| + net::URLRequest* request = iter->second;
|
| + http_requests_.erase(iter);
|
| +
|
| + std::vector<const EventListener*> listeners =
|
| + GetMatchingListeners(profile_id, keys::kOnBeforeSendHeaders, request);
|
| + if (listeners.empty())
|
| + return false;
|
| +
|
| + ListValue args;
|
| + DictionaryValue* dict = new DictionaryValue();
|
| + dict->SetString(keys::kUrlKey, request->url().spec());
|
| + dict->SetDouble(keys::kTimeStampKey, base::Time::Now().ToDoubleT() * 1000);
|
| + // TODO(mpcomplete): request headers.
|
| + return DispatchEvent(profile_id, event_router, request, callback, listeners,
|
| + args);
|
| +}
|
| +
|
| +void ExtensionWebRequestEventRouter::OnURLRequestDestroyed(
|
| + ProfileId profile_id, net::URLRequest* request) {
|
| + http_requests_.erase(request->identifier());
|
| +}
|
| +
|
| +bool ExtensionWebRequestEventRouter::DispatchEvent(
|
| + ProfileId profile_id,
|
| + ExtensionEventRouterForwarder* event_router,
|
| + net::URLRequest* request,
|
| + net::CompletionCallback* callback,
|
| + const std::vector<const EventListener*>& listeners,
|
| + const ListValue& args) {
|
| std::string json_args;
|
| base::JSONWriter::Write(&args, false, &json_args);
|
|
|
| // TODO(mpcomplete): Consider consolidating common (extension_id,json_args)
|
| // pairs into a single message sent to a list of sub_event_names.
|
| int num_handlers_blocking = 0;
|
| - for (std::vector<const EventListener*>::iterator it = listeners.begin();
|
| + for (std::vector<const EventListener*>::const_iterator it = listeners.begin();
|
| it != listeners.end(); ++it) {
|
| event_router->DispatchEventToExtension(
|
| (*it)->extension_id, (*it)->sub_event_name, json_args,
|
| profile_id, true, GURL());
|
| - if ((*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
|
| + if (callback && (*it)->extra_info_spec & ExtraInfoSpec::BLOCKING) {
|
| (*it)->blocked_requests.insert(request->identifier());
|
| ++num_handlers_blocking;
|
| }
|
| @@ -444,6 +500,20 @@ ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| return matching_listeners;
|
| }
|
|
|
| +std::vector<const ExtensionWebRequestEventRouter::EventListener*>
|
| +ExtensionWebRequestEventRouter::GetMatchingListeners(
|
| + ProfileId profile_id,
|
| + const std::string& event_name,
|
| + net::URLRequest* request) {
|
| + int tab_id = -1;
|
| + int window_id = -1;
|
| + ResourceType::Type resource_type = ResourceType::LAST_TYPE;
|
| + ExtractRequestInfo(request, &tab_id, &window_id, &resource_type);
|
| +
|
| + return GetMatchingListeners(
|
| + profile_id, event_name, request->url(), tab_id, window_id, resource_type);
|
| +}
|
| +
|
| void ExtensionWebRequestEventRouter::DecrementBlockCount(uint64 request_id,
|
| bool cancel) {
|
| // It's possible that this request was already cancelled by a previous event
|
|
|