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