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