172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Use of this source code is governed by a BSD-style license that can be 372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// found in the LICENSE file. 472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#ifndef CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ 672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#define CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ 772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#pragma once 872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <map> 1072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <set> 1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <string> 1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include <vector> 1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/singleton.h" 1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "chrome/browser/extensions/extension_function.h" 16dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen#include "chrome/browser/profiles/profile.h" 17ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "ipc/ipc_message.h" 18ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/base/completion_callback.h" 19ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "webkit/glue/resource_type.h" 2072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 21dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenclass ExtensionEventRouterForwarder; 2272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass GURL; 2372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 24ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsennamespace net { 25ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass HttpRequestHeaders; 26ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass URLRequest; 27ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen} 28ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 2972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// This class observes network events and routes them to the appropriate 3072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// extensions listening to those events. All methods must be called on the IO 3172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// thread unless otherwise specified. 3272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass ExtensionWebRequestEventRouter { 3372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 3472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct RequestFilter; 3572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct ExtraInfoSpec; 3672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 3772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen static ExtensionWebRequestEventRouter* GetInstance(); 3872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 39ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Dispatches the OnBeforeRequest event to any extensions whose filters match 40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // the given request. Returns net::ERR_IO_PENDING if an extension is 41ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // intercepting the request, OK otherwise. 42ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int OnBeforeRequest(ProfileId profile_id, 43ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionEventRouterForwarder* event_router, 44ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::URLRequest* request, 45ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::CompletionCallback* callback, 46ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen GURL* new_url); 47ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 48ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s) 49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // requests only, and allows modification of the outgoing request headers. 50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK 51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // otherwise. 52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int OnBeforeSendHeaders(ProfileId profile_id, 53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionEventRouterForwarder* event_router, 54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen uint64 request_id, 55ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::CompletionCallback* callback, 56ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::HttpRequestHeaders* headers); 57ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void OnURLRequestDestroyed(ProfileId profile_id, net::URLRequest* request); 59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 60ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Called when an event listener handles a blocking event and responds. 61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // TODO(mpcomplete): modify request 62ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void OnEventHandled( 63dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen ProfileId profile_id, 64ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& extension_id, 65ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& event_name, 66ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& sub_event_name, 67ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen uint64 request_id, 68ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool cancel, 69ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& new_url); 7072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 7172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Adds a listener to the given event. |event_name| specifies the event being 7272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // listened to. |sub_event_name| is an internal event uniquely generated in 7372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // the extension process to correspond to the given filter and 7472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // extra_info_spec. 7572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void AddEventListener( 76ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileId profile_id, 7772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& extension_id, 7872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& event_name, 7972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& sub_event_name, 8072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const RequestFilter& filter, 8172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen int extra_info_spec); 8272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Removes the listener for the given sub-event. 8472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen void RemoveEventListener( 85ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileId profile_id, 8672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& extension_id, 8772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen const std::string& sub_event_name); 8872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 8972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen private: 9072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>; 9172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen struct EventListener; 92ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen struct BlockedRequest; 93ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile; 94ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<ProfileId, ListenerMapForProfile> ListenerMap; 95ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<uint64, BlockedRequest> BlockedRequestMap; 96ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen typedef std::map<uint64, net::URLRequest*> HttpRequestMap; 9772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 9872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ExtensionWebRequestEventRouter(); 9972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ~ExtensionWebRequestEventRouter(); 10072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 101ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen bool DispatchEvent( 102ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileId profile_id, 103ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ExtensionEventRouterForwarder* event_router, 104ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::URLRequest* request, 105ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::CompletionCallback* callback, 106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::vector<const EventListener*>& listeners, 107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const ListValue& args); 108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 10972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // Returns a list of event listeners that care about the given event, based 11072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen // on their filter parameters. 11172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen std::vector<const EventListener*> GetMatchingListeners( 112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileId profile_id, 113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& event_name, 114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const GURL& url, 115ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int tab_id, 116ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen int window_id, 117ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ResourceType::Type resource_type); 118ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 119ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Same as above, but retrieves the filter parameters from the request. 120ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen std::vector<const EventListener*> GetMatchingListeners( 121ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen ProfileId profile_id, 122ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen const std::string& event_name, 123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen net::URLRequest* request); 124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // Decrements the count of event handlers blocking the given request. When the 126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // count reaches 0 (or immediately if the request is being cancelled), we 127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // stop blocking the request and either resume or cancel it. 128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void DecrementBlockCount(uint64 request_id, bool cancel, const GURL& new_url); 12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 130ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen void OnRequestDeleted(net::URLRequest* request); 131ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 132ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A map for each profile that maps an event name to a set of extensions that 133ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // are listening to that event. 13472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen ListenerMap listeners_; 13572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A map of network requests that are waiting for at least one event handler 137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // to respond. 138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen BlockedRequestMap blocked_requests_; 139ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 140ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // A map of HTTP(s) network requests. We use this to look up the URLRequest 141ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen // from the request ID given to us for HTTP-specific events. 142ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen HttpRequestMap http_requests_; 143ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 14472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter); 14572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 14672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 14772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenclass WebRequestAddEventListener : public SyncExtensionFunction { 14872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen public: 14972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen virtual bool RunImpl(); 15072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.addEventListener"); 15172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}; 15272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen 153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenclass WebRequestEventHandled : public SyncExtensionFunction { 154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen public: 155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen virtual bool RunImpl(); 156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen DECLARE_EXTENSION_FUNCTION_NAME("experimental.webRequest.eventHandled"); 157ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}; 158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen 15972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_WEBREQUEST_API_H_ 160