• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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/rules_registry_service.h"
18 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
19 #include "chrome/browser/extensions/api/profile_keyed_api_factory.h"
20 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
21 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
22 #include "extensions/browser/event_router.h"
23 #include "extensions/browser/extension_function.h"
24 #include "extensions/common/url_pattern_set.h"
25 #include "ipc/ipc_sender.h"
26 #include "net/base/completion_callback.h"
27 #include "net/base/network_delegate.h"
28 #include "net/http/http_request_headers.h"
29 #include "webkit/common/resource_type.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 class RenderProcessHost;
43 }
44 
45 namespace net {
46 class AuthCredentials;
47 class AuthChallengeInfo;
48 class HttpRequestHeaders;
49 class HttpResponseHeaders;
50 class URLRequest;
51 }
52 
53 namespace extensions {
54 
55 class InfoMap;
56 class WebRequestRulesRegistry;
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 // extension::EventRouter to deal with event listeners. There is one instance
61 // per BrowserContext which is shared with incognito.
62 class WebRequestAPI : public ProfileKeyedAPI,
63                       public EventRouter::Observer {
64  public:
65   explicit WebRequestAPI(content::BrowserContext* context);
66   virtual ~WebRequestAPI();
67 
68   // ProfileKeyedAPI support:
69   static ProfileKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance();
70 
71   // EventRouter::Observer overrides:
72   virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
73 
74  private:
75   friend class ProfileKeyedAPIFactory<WebRequestAPI>;
76 
77   // ProfileKeyedAPI support:
service_name()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<ResourceType::Type> 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 |profile|.
173   void RegisterRulesRegistry(
174       void* profile,
175       const extensions::RulesRegistryService::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* profile,
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* profile,
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* profile,
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   // and |override_response_headers| are owned by a URLRequestJob. They are
209   // guaranteed to be valid until |callback| is called or OnURLRequestDestroyed
210   // 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* profile,
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 
221   // Dispatches the OnAuthRequired event to any extensions whose filters match
222   // the given request. If the listener is not registered as "blocking", then
223   // AUTH_REQUIRED_RESPONSE_OK is returned. Otherwise,
224   // AUTH_REQUIRED_RESPONSE_IO_PENDING is returned and |callback| will be
225   // invoked later.
226   net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
227       void* profile,
228       extensions::InfoMap* extension_info_map,
229       net::URLRequest* request,
230       const net::AuthChallengeInfo& auth_info,
231       const net::NetworkDelegate::AuthCallback& callback,
232       net::AuthCredentials* credentials);
233 
234   // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
235   // only.
236   void OnBeforeRedirect(void* profile,
237                         extensions::InfoMap* extension_info_map,
238                         net::URLRequest* request,
239                         const GURL& new_location);
240 
241   // Dispatches the onResponseStarted event indicating that the first bytes of
242   // the response have arrived.
243   void OnResponseStarted(void* profile,
244                          extensions::InfoMap* extension_info_map,
245                          net::URLRequest* request);
246 
247   // Dispatches the onComplete event.
248   void OnCompleted(void* profile,
249                    extensions::InfoMap* extension_info_map,
250                    net::URLRequest* request);
251 
252   // Dispatches an onErrorOccurred event.
253   void OnErrorOccurred(void* profile,
254                        extensions::InfoMap* extension_info_map,
255                        net::URLRequest* request,
256                        bool started);
257 
258   // Notifications when objects are going away.
259   void OnURLRequestDestroyed(void* profile, net::URLRequest* request);
260 
261   // Called when an event listener handles a blocking event and responds.
262   void OnEventHandled(
263       void* profile,
264       const std::string& extension_id,
265       const std::string& event_name,
266       const std::string& sub_event_name,
267       uint64 request_id,
268       EventResponse* response);
269 
270   // Adds a listener to the given event. |event_name| specifies the event being
271   // listened to. |sub_event_name| is an internal event uniquely generated in
272   // the extension process to correspond to the given filter and
273   // extra_info_spec. It returns true on success, false on failure.
274   bool AddEventListener(
275       void* profile,
276       const std::string& extension_id,
277       const std::string& extension_name,
278       const std::string& event_name,
279       const std::string& sub_event_name,
280       const RequestFilter& filter,
281       int extra_info_spec,
282       int embedder_process_id,
283       int web_view_instance_id,
284       base::WeakPtr<IPC::Sender> ipc_sender);
285 
286   // Removes the listener for the given sub-event.
287   void RemoveEventListener(
288       void* profile,
289       const std::string& extension_id,
290       const std::string& sub_event_name);
291 
292   // Removes the listeners for a given <webview>.
293   void RemoveWebViewEventListeners(
294       void* profile,
295       const std::string& extension_id,
296       int embedder_process_id,
297       int web_view_instance_id);
298 
299   // Called when an incognito profile is created or destroyed.
300   void OnOTRProfileCreated(void* original_profile,
301                            void* otr_profile);
302   void OnOTRProfileDestroyed(void* original_profile,
303                              void* otr_profile);
304 
305   // Registers a |callback| that is executed when the next page load happens.
306   // The callback is then deleted.
307   void AddCallbackForPageLoad(const base::Closure& callback);
308 
309  private:
310   friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
311 
312   struct EventListener;
313   typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile;
314   typedef std::map<void*, ListenerMapForProfile> ListenerMap;
315   typedef std::map<uint64, BlockedRequest> BlockedRequestMap;
316   // Map of request_id -> bit vector of EventTypes already signaled
317   typedef std::map<uint64, int> SignaledRequestMap;
318   // For each profile: a bool indicating whether it is an incognito profile,
319   // and a pointer to the corresponding (non-)incognito profile.
320   typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap;
321   typedef std::list<base::Closure> CallbacksForPageLoad;
322 
323   ExtensionWebRequestEventRouter();
324   ~ExtensionWebRequestEventRouter();
325 
326   // Ensures that future callbacks for |request| are ignored so that it can be
327   // destroyed safely.
328   void ClearPendingCallbacks(net::URLRequest* request);
329 
330   bool DispatchEvent(
331       void* profile,
332       net::URLRequest* request,
333       const std::vector<const EventListener*>& listeners,
334       const base::ListValue& args);
335 
336   // Returns a list of event listeners that care about the given event, based
337   // on their filter parameters. |extra_info_spec| will contain the combined
338   // set of extra_info_spec flags that every matching listener asked for.
339   std::vector<const EventListener*> GetMatchingListeners(
340       void* profile,
341       extensions::InfoMap* extension_info_map,
342       const std::string& event_name,
343       net::URLRequest* request,
344       int* extra_info_spec);
345 
346   // Helper for the above functions. This is called twice: once for the profile
347   // of the event, the next time for the "cross" profile (i.e. the incognito
348   // profile if the event is originally for the normal profile, or vice versa).
349   void GetMatchingListenersImpl(
350       void* profile,
351       extensions::InfoMap* extension_info_map,
352       bool crosses_incognito,
353       const std::string& event_name,
354       const GURL& url,
355       int tab_id,
356       int window_id,
357       int render_process_host_id,
358       int routing_id,
359       ResourceType::Type resource_type,
360       bool is_async_request,
361       bool is_request_from_extension,
362       int* extra_info_spec,
363       std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
364           matching_listeners);
365 
366   // Decrements the count of event handlers blocking the given request. When the
367   // count reaches 0, we stop blocking the request and proceed it using the
368   // method requested by the extension with the highest precedence. Precedence
369   // is decided by extension install time. If |response| is non-NULL, this
370   // method assumes ownership.
371   void DecrementBlockCount(
372       void* profile,
373       const std::string& extension_id,
374       const std::string& event_name,
375       uint64 request_id,
376       EventResponse* response);
377 
378   // Processes the generated deltas from blocked_requests_ on the specified
379   // request. If |call_back| is true, the callback registered in
380   // |blocked_requests_| is called.
381   // The function returns the error code for the network request. This is
382   // mostly relevant in case the caller passes |call_callback| = false
383   // and wants to return the correct network error code himself.
384   int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback);
385 
386   // Evaluates the rules of the declarative webrequest API and stores
387   // modifications to the request that result from WebRequestActions as
388   // deltas in |blocked_requests_|. |original_response_headers| should only be
389   // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any
390   // deltas were generated.
391   bool ProcessDeclarativeRules(
392       void* profile,
393       extensions::InfoMap* extension_info_map,
394       const std::string& event_name,
395       net::URLRequest* request,
396       extensions::RequestStage request_stage,
397       const net::HttpResponseHeaders* original_response_headers);
398 
399   // If the BlockedRequest contains messages_to_extension entries in the event
400   // deltas, we send them to subscribers of
401   // chrome.declarativeWebRequest.onMessage.
402   void SendMessages(void* profile, const BlockedRequest& blocked_request);
403 
404   // Called when the RulesRegistry is ready to unblock a request that was
405   // waiting for said event.
406   void OnRulesRegistryReady(
407       void* profile,
408       const std::string& event_name,
409       uint64 request_id,
410       extensions::RequestStage request_stage);
411 
412   // Sets the flag that |event_type| has been signaled for |request_id|.
413   // Returns the value of the flag before setting it.
414   bool GetAndSetSignaled(uint64 request_id, EventTypes event_type);
415 
416   // Clears the flag that |event_type| has been signaled for |request_id|.
417   void ClearSignaled(uint64 request_id, EventTypes event_type);
418 
419   // Returns whether |request| represents a top level window navigation.
420   bool IsPageLoad(net::URLRequest* request) const;
421 
422   // Called on a page load to process all registered callbacks.
423   void NotifyPageLoad();
424 
425   // Returns the matching cross profile (the regular profile if |profile| is
426   // OTR and vice versa).
427   void* GetCrossProfile(void* profile) const;
428 
429   // Determines whether the specified profile is an incognito profile (based on
430   // the contents of the cross-profile table and without dereferencing the
431   // profile pointer).
432   bool IsIncognitoProfile(void* profile) const;
433 
434   // Returns true if |request| was already signaled to some event handlers.
435   bool WasSignaled(const net::URLRequest& request) const;
436 
437   // A map for each profile that maps an event name to a set of extensions that
438   // are listening to that event.
439   ListenerMap listeners_;
440 
441   // A map of network requests that are waiting for at least one event handler
442   // to respond.
443   BlockedRequestMap blocked_requests_;
444 
445   // A map of request ids to a bitvector indicating which events have been
446   // signaled and should not be sent again.
447   SignaledRequestMap signaled_requests_;
448 
449   // A map of original profile -> corresponding incognito profile (and vice
450   // versa).
451   CrossProfileMap cross_profile_map_;
452 
453   // Keeps track of time spent waiting on extensions using the blocking
454   // webRequest API.
455   scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
456 
457   CallbacksForPageLoad callbacks_for_page_load_;
458 
459   typedef std::pair<void*, extensions::RulesRegistryService::WebViewKey>
460       RulesRegistryKey;
461   // Maps each profile (and OTRProfile) and a webview key to its respective
462   // rules registry.
463   std::map<RulesRegistryKey,
464       scoped_refptr<extensions::WebRequestRulesRegistry> > rules_registries_;
465 
466   DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
467 };
468 
469 class WebRequestAddEventListener : public SyncIOThreadExtensionFunction {
470  public:
471   DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
472                              WEBREQUESTINTERNAL_ADDEVENTLISTENER)
473 
474  protected:
475   virtual ~WebRequestAddEventListener() {}
476 
477   // ExtensionFunction:
478   virtual bool RunImpl() OVERRIDE;
479 };
480 
481 class WebRequestEventHandled : public SyncIOThreadExtensionFunction {
482  public:
483   DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
484                              WEBREQUESTINTERNAL_EVENTHANDLED)
485 
486  protected:
487   virtual ~WebRequestEventHandled() {}
488 
489   // ExtensionFunction:
490   virtual bool RunImpl() OVERRIDE;
491 };
492 
493 class WebRequestHandlerBehaviorChangedFunction
494     : public SyncIOThreadExtensionFunction {
495  public:
496   DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
497                              WEBREQUEST_HANDLERBEHAVIORCHANGED)
498 
499  protected:
500   virtual ~WebRequestHandlerBehaviorChangedFunction() {}
501 
502   // ExtensionFunction:
503   virtual void GetQuotaLimitHeuristics(
504       extensions::QuotaLimitHeuristics* heuristics) const OVERRIDE;
505   // Handle quota exceeded gracefully: Only warn the user but still execute the
506   // function.
507   virtual void OnQuotaExceeded(const std::string& error) OVERRIDE;
508   virtual bool RunImpl() OVERRIDE;
509 };
510 
511 // Send updates to |host| with information about what webRequest-related
512 // extensions are installed.
513 // TODO(mpcomplete): remove. http://crbug.com/100411
514 void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host);
515 
516 #endif  // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
517