Upstream version 10.39.225.0
[platform/framework/web/crosswalk.git] / src / extensions / browser / api / web_request / web_request_api.h
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_