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