Home | History | Annotate | Download | only in web_request
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #ifndef CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
      6 #define CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
      7 
      8 #include <list>
      9 #include <map>
     10 #include <set>
     11 #include <string>
     12 #include <vector>
     13 
     14 #include "base/memory/singleton.h"
     15 #include "base/memory/weak_ptr.h"
     16 #include "base/time/time.h"
     17 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
     18 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
     19 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
     20 #include "chrome/browser/extensions/extension_function.h"
     21 #include "chrome/browser/profiles/profile.h"
     22 #include "chrome/common/chrome_version_info.h"
     23 #include "extensions/common/url_pattern_set.h"
     24 #include "ipc/ipc_sender.h"
     25 #include "net/base/completion_callback.h"
     26 #include "net/base/network_delegate.h"
     27 #include "net/http/http_request_headers.h"
     28 #include "webkit/common/resource_type.h"
     29 
     30 class ExtensionInfoMap;
     31 class ExtensionWebRequestTimeTracker;
     32 class GURL;
     33 
     34 namespace base {
     35 class DictionaryValue;
     36 class ListValue;
     37 class StringValue;
     38 }
     39 
     40 namespace content {
     41 class RenderProcessHost;
     42 }
     43 
     44 namespace extensions {
     45 class WebRequestRulesRegistry;
     46 }
     47 
     48 namespace net {
     49 class AuthCredentials;
     50 class AuthChallengeInfo;
     51 class HttpRequestHeaders;
     52 class HttpResponseHeaders;
     53 class URLRequest;
     54 }
     55 
     56 // This class observes network events and routes them to the appropriate
     57 // extensions listening to those events. All methods must be called on the IO
     58 // thread unless otherwise specified.
     59 class ExtensionWebRequestEventRouter
     60     : public base::SupportsWeakPtr<ExtensionWebRequestEventRouter> {
     61  public:
     62   struct BlockedRequest;
     63 
     64   enum EventTypes {
     65     kInvalidEvent = 0,
     66     kOnBeforeRequest = 1 << 0,
     67     kOnBeforeSendHeaders = 1 << 1,
     68     kOnSendHeaders = 1 << 2,
     69     kOnHeadersReceived = 1 << 3,
     70     kOnBeforeRedirect = 1 << 4,
     71     kOnAuthRequired = 1 << 5,
     72     kOnResponseStarted = 1 << 6,
     73     kOnErrorOccurred = 1 << 7,
     74     kOnCompleted = 1 << 8,
     75   };
     76 
     77   // Internal representation of the webRequest.RequestFilter type, used to
     78   // filter what network events an extension cares about.
     79   struct RequestFilter {
     80     RequestFilter();
     81     ~RequestFilter();
     82 
     83     // Returns false if there was an error initializing. If it is a user error,
     84     // an error message is provided, otherwise the error is internal (and
     85     // unexpected).
     86     bool InitFromValue(const base::DictionaryValue& value, std::string* error);
     87 
     88     extensions::URLPatternSet urls;
     89     std::vector<ResourceType::Type> types;
     90     int tab_id;
     91     int window_id;
     92   };
     93 
     94   // Internal representation of the extraInfoSpec parameter on webRequest
     95   // events, used to specify extra information to be included with network
     96   // events.
     97   struct ExtraInfoSpec {
     98     enum Flags {
     99       REQUEST_HEADERS = 1<<0,
    100       RESPONSE_HEADERS = 1<<1,
    101       BLOCKING = 1<<2,
    102       ASYNC_BLOCKING = 1<<3,
    103       REQUEST_BODY = 1<<4,
    104     };
    105 
    106     static bool InitFromValue(const base::ListValue& value,
    107                               int* extra_info_spec);
    108   };
    109 
    110   // Contains an extension's response to a blocking event.
    111   struct EventResponse {
    112     EventResponse(const std::string& extension_id,
    113                   const base::Time& extension_install_time);
    114     ~EventResponse();
    115 
    116     // ID of the extension that sent this response.
    117     std::string extension_id;
    118 
    119     // The time that the extension was installed. Used for deciding order of
    120     // precedence in case multiple extensions respond with conflicting
    121     // decisions.
    122     base::Time extension_install_time;
    123 
    124     // Response values. These are mutually exclusive.
    125     bool cancel;
    126     GURL new_url;
    127     scoped_ptr<net::HttpRequestHeaders> request_headers;
    128     scoped_ptr<extension_web_request_api_helpers::ResponseHeaders>
    129         response_headers;
    130 
    131     scoped_ptr<net::AuthCredentials> auth_credentials;
    132 
    133     DISALLOW_COPY_AND_ASSIGN(EventResponse);
    134   };
    135 
    136   static ExtensionWebRequestEventRouter* GetInstance();
    137 
    138   // Registers a rule registry. Pass null for |rules_registry| to unregister
    139   // the rule registry for |profile|.
    140   void RegisterRulesRegistry(
    141       void* profile,
    142       scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry);
    143 
    144   // Dispatches the OnBeforeRequest event to any extensions whose filters match
    145   // the given request. Returns net::ERR_IO_PENDING if an extension is
    146   // intercepting the request, OK otherwise.
    147   int OnBeforeRequest(void* profile,
    148                       ExtensionInfoMap* extension_info_map,
    149                       net::URLRequest* request,
    150                       const net::CompletionCallback& callback,
    151                       GURL* new_url);
    152 
    153   // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s)
    154   // requests only, and allows modification of the outgoing request headers.
    155   // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK
    156   // otherwise.
    157   int OnBeforeSendHeaders(void* profile,
    158                           ExtensionInfoMap* extension_info_map,
    159                           net::URLRequest* request,
    160                           const net::CompletionCallback& callback,
    161                           net::HttpRequestHeaders* headers);
    162 
    163   // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
    164   // only.
    165   void OnSendHeaders(void* profile,
    166                      ExtensionInfoMap* extension_info_map,
    167                      net::URLRequest* request,
    168                      const net::HttpRequestHeaders& headers);
    169 
    170   // Dispatches the onHeadersReceived event. This is fired for HTTP(s)
    171   // requests only, and allows modification of incoming response headers.
    172   // Returns net::ERR_IO_PENDING if an extension is intercepting the request,
    173   // OK otherwise. |original_response_headers| is reference counted. |callback|
    174   // and |override_response_headers| are owned by a URLRequestJob. They are
    175   // guaranteed to be valid until |callback| is called or OnURLRequestDestroyed
    176   // is called (whatever comes first).
    177   // Do not modify |original_response_headers| directly but write new ones
    178   // into |override_response_headers|.
    179   int OnHeadersReceived(
    180       void* profile,
    181       ExtensionInfoMap* extension_info_map,
    182       net::URLRequest* request,
    183       const net::CompletionCallback& callback,
    184       const net::HttpResponseHeaders* original_response_headers,
    185       scoped_refptr<net::HttpResponseHeaders>* override_response_headers);
    186 
    187   // Dispatches the OnAuthRequired event to any extensions whose filters match
    188   // the given request. If the listener is not registered as "blocking", then
    189   // AUTH_REQUIRED_RESPONSE_OK is returned. Otherwise,
    190   // AUTH_REQUIRED_RESPONSE_IO_PENDING is returned and |callback| will be
    191   // invoked later.
    192   net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
    193                      void* profile,
    194                      ExtensionInfoMap* extension_info_map,
    195                      net::URLRequest* request,
    196                      const net::AuthChallengeInfo& auth_info,
    197                      const net::NetworkDelegate::AuthCallback& callback,
    198                      net::AuthCredentials* credentials);
    199 
    200   // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
    201   // only.
    202   void OnBeforeRedirect(void* profile,
    203                         ExtensionInfoMap* extension_info_map,
    204                         net::URLRequest* request,
    205                         const GURL& new_location);
    206 
    207   // Dispatches the onResponseStarted event indicating that the first bytes of
    208   // the response have arrived.
    209   void OnResponseStarted(void* profile,
    210                          ExtensionInfoMap* extension_info_map,
    211                          net::URLRequest* request);
    212 
    213   // Dispatches the onComplete event.
    214   void OnCompleted(void* profile,
    215                    ExtensionInfoMap* extension_info_map,
    216                    net::URLRequest* request);
    217 
    218   // Dispatches an onErrorOccurred event.
    219   void OnErrorOccurred(void* profile,
    220                       ExtensionInfoMap* extension_info_map,
    221                       net::URLRequest* request,
    222                       bool started);
    223 
    224   // Notifications when objects are going away.
    225   void OnURLRequestDestroyed(void* profile, net::URLRequest* request);
    226 
    227   // Called when an event listener handles a blocking event and responds.
    228   void OnEventHandled(
    229       void* profile,
    230       const std::string& extension_id,
    231       const std::string& event_name,
    232       const std::string& sub_event_name,
    233       uint64 request_id,
    234       EventResponse* response);
    235 
    236   // Adds a listener to the given event. |event_name| specifies the event being
    237   // listened to. |sub_event_name| is an internal event uniquely generated in
    238   // the extension process to correspond to the given filter and
    239   // extra_info_spec. It returns true on success, false on failure.
    240   bool AddEventListener(
    241       void* profile,
    242       const std::string& extension_id,
    243       const std::string& extension_name,
    244       const std::string& event_name,
    245       const std::string& sub_event_name,
    246       const RequestFilter& filter,
    247       int extra_info_spec,
    248       int embedder_process_id,
    249       int embedder_routing_id,
    250       int web_view_instance_id,
    251       base::WeakPtr<IPC::Sender> ipc_sender);
    252 
    253   // Removes the listener for the given sub-event.
    254   void RemoveEventListener(
    255       void* profile,
    256       const std::string& extension_id,
    257       const std::string& sub_event_name);
    258 
    259   // Removes the listeners for a given <webview>.
    260   void RemoveWebViewEventListeners(
    261       void* profile,
    262       const std::string& extension_id,
    263       int embedder_process_id,
    264       int web_view_instance_id);
    265 
    266   // Called when an incognito profile is created or destroyed.
    267   void OnOTRProfileCreated(void* original_profile,
    268                            void* otr_profile);
    269   void OnOTRProfileDestroyed(void* original_profile,
    270                              void* otr_profile);
    271 
    272   // Registers a |callback| that is executed when the next page load happens.
    273   // The callback is then deleted.
    274   void AddCallbackForPageLoad(const base::Closure& callback);
    275 
    276  private:
    277   friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
    278 
    279   struct EventListener;
    280   typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile;
    281   typedef std::map<void*, ListenerMapForProfile> ListenerMap;
    282   typedef std::map<uint64, BlockedRequest> BlockedRequestMap;
    283   // Map of request_id -> bit vector of EventTypes already signaled
    284   typedef std::map<uint64, int> SignaledRequestMap;
    285   // For each profile: a bool indicating whether it is an incognito profile,
    286   // and a pointer to the corresponding (non-)incognito profile.
    287   typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap;
    288   typedef std::list<base::Closure> CallbacksForPageLoad;
    289 
    290   ExtensionWebRequestEventRouter();
    291   ~ExtensionWebRequestEventRouter();
    292 
    293   // Ensures that future callbacks for |request| are ignored so that it can be
    294   // destroyed safely.
    295   void ClearPendingCallbacks(net::URLRequest* request);
    296 
    297   bool DispatchEvent(
    298       void* profile,
    299       net::URLRequest* request,
    300       const std::vector<const EventListener*>& listeners,
    301       const base::ListValue& args);
    302 
    303   // Returns a list of event listeners that care about the given event, based
    304   // on their filter parameters. |extra_info_spec| will contain the combined
    305   // set of extra_info_spec flags that every matching listener asked for.
    306   std::vector<const EventListener*> GetMatchingListeners(
    307       void* profile,
    308       ExtensionInfoMap* extension_info_map,
    309       const std::string& event_name,
    310       net::URLRequest* request,
    311       int* extra_info_spec);
    312 
    313   // Helper for the above functions. This is called twice: once for the profile
    314   // of the event, the next time for the "cross" profile (i.e. the incognito
    315   // profile if the event is originally for the normal profile, or vice versa).
    316   void GetMatchingListenersImpl(
    317       void* profile,
    318       ExtensionInfoMap* extension_info_map,
    319       bool crosses_incognito,
    320       const std::string& event_name,
    321       const GURL& url,
    322       int tab_id,
    323       int window_id,
    324       int render_process_host_id,
    325       int routing_id,
    326       ResourceType::Type resource_type,
    327       bool is_async_request,
    328       bool is_request_from_extension,
    329       int* extra_info_spec,
    330       std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
    331           matching_listeners);
    332 
    333   // Decrements the count of event handlers blocking the given request. When the
    334   // count reaches 0, we stop blocking the request and proceed it using the
    335   // method requested by the extension with the highest precedence. Precedence
    336   // is decided by extension install time. If |response| is non-NULL, this
    337   // method assumes ownership.
    338   void DecrementBlockCount(
    339       void* profile,
    340       const std::string& extension_id,
    341       const std::string& event_name,
    342       uint64 request_id,
    343       EventResponse* response);
    344 
    345   // Processes the generated deltas from blocked_requests_ on the specified
    346   // request. If |call_back| is true, the callback registered in
    347   // |blocked_requests_| is called.
    348   // The function returns the error code for the network request. This is
    349   // mostly relevant in case the caller passes |call_callback| = false
    350   // and wants to return the correct network error code himself.
    351   int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback);
    352 
    353   // Evaluates the rules of the declarative webrequest API and stores
    354   // modifications to the request that result from WebRequestActions as
    355   // deltas in |blocked_requests_|. |original_response_headers| should only be
    356   // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any
    357   // deltas were generated.
    358   bool ProcessDeclarativeRules(
    359       void* profile,
    360       ExtensionInfoMap* extension_info_map,
    361       const std::string& event_name,
    362       net::URLRequest* request,
    363       extensions::RequestStage request_stage,
    364       const net::HttpResponseHeaders* original_response_headers);
    365 
    366   // If the BlockedRequest contains messages_to_extension entries in the event
    367   // deltas, we send them to subscribers of
    368   // chrome.declarativeWebRequest.onMessage.
    369   void SendMessages(void* profile, const BlockedRequest& blocked_request);
    370 
    371   // Called when the RulesRegistry is ready to unblock a request that was
    372   // waiting for said event.
    373   void OnRulesRegistryReady(
    374       void* profile,
    375       const std::string& event_name,
    376       uint64 request_id,
    377       extensions::RequestStage request_stage);
    378 
    379   // Sets the flag that |event_type| has been signaled for |request_id|.
    380   // Returns the value of the flag before setting it.
    381   bool GetAndSetSignaled(uint64 request_id, EventTypes event_type);
    382 
    383   // Clears the flag that |event_type| has been signaled for |request_id|.
    384   void ClearSignaled(uint64 request_id, EventTypes event_type);
    385 
    386   // Returns whether |request| represents a top level window navigation.
    387   bool IsPageLoad(net::URLRequest* request) const;
    388 
    389   // Called on a page load to process all registered callbacks.
    390   void NotifyPageLoad();
    391 
    392   // Returns the matching cross profile (the regular profile if |profile| is
    393   // OTR and vice versa).
    394   void* GetCrossProfile(void* profile) const;
    395 
    396   // Determines whether the specified profile is an incognito profile (based on
    397   // the contents of the cross-profile table and without dereferencing the
    398   // profile pointer).
    399   bool IsIncognitoProfile(void* profile) const;
    400 
    401   // Returns true if |request| was already signaled to some event handlers.
    402   bool WasSignaled(const net::URLRequest& request) const;
    403 
    404   // A map for each profile that maps an event name to a set of extensions that
    405   // are listening to that event.
    406   ListenerMap listeners_;
    407 
    408   // A map of network requests that are waiting for at least one event handler
    409   // to respond.
    410   BlockedRequestMap blocked_requests_;
    411 
    412   // A map of request ids to a bitvector indicating which events have been
    413   // signaled and should not be sent again.
    414   SignaledRequestMap signaled_requests_;
    415 
    416   // A map of original profile -> corresponding incognito profile (and vice
    417   // versa).
    418   CrossProfileMap cross_profile_map_;
    419 
    420   // Keeps track of time spent waiting on extensions using the blocking
    421   // webRequest API.
    422   scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
    423 
    424   CallbacksForPageLoad callbacks_for_page_load_;
    425 
    426   // Maps each profile (and OTRProfile) to its respective rules registry.
    427   std::map<void*, scoped_refptr<extensions::WebRequestRulesRegistry> >
    428       rules_registries_;
    429 
    430   DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
    431 };
    432 
    433 class WebRequestAddEventListener : public SyncIOThreadExtensionFunction {
    434  public:
    435   DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
    436                              WEBREQUESTINTERNAL_ADDEVENTLISTENER)
    437 
    438  protected:
    439   virtual ~WebRequestAddEventListener() {}
    440 
    441   // ExtensionFunction:
    442   virtual bool RunImpl() OVERRIDE;
    443 };
    444 
    445 class WebRequestEventHandled : public SyncIOThreadExtensionFunction {
    446  public:
    447   DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
    448                              WEBREQUESTINTERNAL_EVENTHANDLED)
    449 
    450  protected:
    451   virtual ~WebRequestEventHandled() {}
    452 
    453   // ExtensionFunction:
    454   virtual bool RunImpl() OVERRIDE;
    455 };
    456 
    457 class WebRequestHandlerBehaviorChangedFunction
    458     : public SyncIOThreadExtensionFunction {
    459  public:
    460   DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
    461                              WEBREQUEST_HANDLERBEHAVIORCHANGED)
    462 
    463  protected:
    464   virtual ~WebRequestHandlerBehaviorChangedFunction() {}
    465 
    466   // ExtensionFunction:
    467   virtual void GetQuotaLimitHeuristics(
    468       QuotaLimitHeuristics* heuristics) const OVERRIDE;
    469   // Handle quota exceeded gracefully: Only warn the user but still execute the
    470   // function.
    471   virtual void OnQuotaExceeded(const std::string& error) OVERRIDE;
    472   virtual bool RunImpl() OVERRIDE;
    473 };
    474 
    475 // Send updates to |host| with information about what webRequest-related
    476 // extensions are installed.
    477 // TODO(mpcomplete): remove. http://crbug.com/100411
    478 void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host);
    479 
    480 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
    481