// Copyright (c) 2011 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ #define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ #pragma once #include <map> #include <set> #include <string> #include <vector> #include "base/memory/singleton.h" #include "chrome/browser/extensions/extension_function.h" #include "chrome/browser/profiles/profile.h" #include "ipc/ipc_message.h" #include "net/base/completion_callback.h" #include "webkit/glue/resource_type.h" class ExtensionEventRouterForwarder; class GURL; namespace net { class HttpRequestHeaders; class URLRequest; } // This class observes network events and routes them to the appropriate // extensions listening to those events. All methods must be called on the IO // thread unless otherwise specified. class ExtensionWebRequestEventRouter { public: struct RequestFilter; struct ExtraInfoSpec; static ExtensionWebRequestEventRouter* GetInstance(); // Dispatches the OnBeforeRequest event to any extensions whose filters match // the given request. Returns net::ERR_IO_PENDING if an extension is // intercepting the request, OK otherwise. int OnBeforeRequest(ProfileId profile_id, ExtensionEventRouterForwarder* event_router, net::URLRequest* request, net::CompletionCallback* callback, GURL* new_url); // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s) // requests only, and allows modification of the outgoing request headers. // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK // otherwise. int OnBeforeSendHeaders(ProfileId profile_id, ExtensionEventRouterForwarder* event_router, uint64 request_id, net::CompletionCallback* callback, net::HttpRequestHeaders* headers); void OnURLRequestDestroyed(ProfileId profile_id, net::URLRequest* request); // Called when an event listener handles a blocking event and responds. // TODO(mpcomplete): modify request void OnEventHandled( ProfileId profile_id, const std::string& extension_id, const std::string& event_name, const std::string& sub_event_name, uint64 request_id, bool cancel, const GURL& new_url); // Adds a listener to the given event. |event_name| specifies the event being // listened to. |sub_event_name| is an internal event uniquely generated in // the extension process to correspond to the given filter and // extra_info_spec. void AddEventListener( ProfileId profile_id, const std::string& extension_id, const std::string& event_name, const std::string& sub_event_name, const RequestFilter& filter, int extra_info_spec); // Removes the listener for the given sub-event. void RemoveEventListener( ProfileId profile_id, const std::string& extension_id, const std::string& sub_event_name); private: friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>; struct EventListener; struct BlockedRequest; typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile; typedef std::map<ProfileId, ListenerMapForProfile> ListenerMap; typedef std::map<uint64, BlockedRequest> BlockedRequestMap; typedef std::map<uint64, net::URLRequest*> HttpRequestMap; ExtensionWebRequestEventRouter(); ~ExtensionWebRequestEventRouter(); bool DispatchEvent( ProfileId profile_id, ExtensionEventRouterForwarder* event_router, net::URLRequest* request, net::CompletionCallback* callback, const std::vector<const EventListener*>& listeners, const ListValue& args); // Returns a list of event listeners that care about the given event, based // on their filter parameters. std::vector<const EventListener*> GetMatchingListeners( ProfileId profile_id, const std::string& event_name, const GURL& url, int tab_id, int window_id, ResourceType::Type resource_type); // Same as above, but retrieves the filter parameters from the request. std::vector<const EventListener*> GetMatchingListeners( ProfileId profile_id, const std::string& event_name, net::URLRequest* request); // Decrements the count of event handlers blocking the given request. When the // count reaches 0 (or immediately if the request is being cancelled), we // stop blocking the request and either resume or cancel it. void DecrementBlockCount(uint64 request_id, bool cancel, const GURL& new_url); void OnRequestDeleted(net::URLRequest* request); // A map for each profile that maps an event name to a set of extensions that // are listening to that event. ListenerMap listeners_; // A map of network requests that are waiting for at least one event handler // to respond. BlockedRequestMap blocked_requests_; // A map of HTTP(s) network requests. We use this to look up the URLRequest // from the request ID given to us for HTTP-specific events. HttpRequestMap http_requests_; DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter); }; class WebRequestAddEventListener : public SyncExtensionFunction { public: virtual bool RunImpl(); DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.addEventListener"); }; class WebRequestEventHandled : public SyncExtensionFunction { public: virtual bool RunImpl(); DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.eventHandled"); }; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_