Linux: Depend on liberation-fonts package for RPMs.
[chromium-blink-merge.git] / extensions / browser / api / web_request / web_request_api.h
blobc9caa65f7659fb0eb205c71df888ac145258de59
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.
5 #ifndef EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_
6 #define EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_
8 #include <list>
9 #include <map>
10 #include <set>
11 #include <string>
12 #include <utility>
13 #include <vector>
15 #include "base/memory/singleton.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/strings/string_util.h"
18 #include "base/time/time.h"
19 #include "content/public/common/resource_type.h"
20 #include "extensions/browser/api/declarative/rules_registry.h"
21 #include "extensions/browser/api/declarative_webrequest/request_stage.h"
22 #include "extensions/browser/api/web_request/web_request_api_helpers.h"
23 #include "extensions/browser/api/web_request/web_request_permissions.h"
24 #include "extensions/browser/browser_context_keyed_api_factory.h"
25 #include "extensions/browser/event_router.h"
26 #include "extensions/browser/extension_function.h"
27 #include "extensions/common/url_pattern_set.h"
28 #include "ipc/ipc_sender.h"
29 #include "net/base/completion_callback.h"
30 #include "net/base/network_delegate.h"
31 #include "net/http/http_request_headers.h"
33 class ExtensionWebRequestTimeTracker;
34 class GURL;
36 namespace base {
37 class DictionaryValue;
38 class ListValue;
39 class StringValue;
42 namespace content {
43 class BrowserContext;
46 namespace net {
47 class AuthChallengeInfo;
48 class AuthCredentials;
49 class HttpRequestHeaders;
50 class HttpResponseHeaders;
51 class URLRequest;
54 namespace extensions {
56 class InfoMap;
57 class WebRequestRulesRegistry;
58 class WebRequestEventRouterDelegate;
60 // Support class for the WebRequest API. Lives on the UI thread. Most of the
61 // work is done by ExtensionWebRequestEventRouter below. This class observes
62 // extensions::EventRouter to deal with event listeners. There is one instance
63 // per BrowserContext which is shared with incognito.
64 class WebRequestAPI : public BrowserContextKeyedAPI,
65 public EventRouter::Observer {
66 public:
67 explicit WebRequestAPI(content::BrowserContext* context);
68 ~WebRequestAPI() override;
70 // BrowserContextKeyedAPI support:
71 static BrowserContextKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance();
73 // EventRouter::Observer overrides:
74 void OnListenerRemoved(const EventListenerInfo& details) override;
76 private:
77 friend class BrowserContextKeyedAPIFactory<WebRequestAPI>;
79 // BrowserContextKeyedAPI support:
80 static const char* service_name() { return "WebRequestAPI"; }
81 static const bool kServiceRedirectedInIncognito = true;
82 static const bool kServiceIsNULLWhileTesting = true;
84 content::BrowserContext* browser_context_;
86 DISALLOW_COPY_AND_ASSIGN(WebRequestAPI);
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;
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,
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();
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);
121 extensions::URLPatternSet urls;
122 std::vector<content::ResourceType> types;
123 int tab_id;
124 int window_id;
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,
139 static bool InitFromValue(const base::ListValue& value,
140 int* extra_info_spec);
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();
149 // ID of the extension that sent this response.
150 std::string extension_id;
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;
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;
164 scoped_ptr<net::AuthCredentials> auth_credentials;
166 private:
167 DISALLOW_COPY_AND_ASSIGN(EventResponse);
170 static ExtensionWebRequestEventRouter* GetInstance();
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 int rules_registry_id,
177 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry);
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 const extensions::InfoMap* extension_info_map,
184 net::URLRequest* request,
185 const net::CompletionCallback& callback,
186 GURL* new_url);
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 const extensions::InfoMap* extension_info_map,
194 net::URLRequest* request,
195 const net::CompletionCallback& callback,
196 net::HttpRequestHeaders* headers);
198 // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
199 // only.
200 void OnSendHeaders(void* browser_context,
201 const extensions::InfoMap* extension_info_map,
202 net::URLRequest* request,
203 const net::HttpRequestHeaders& headers);
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 const 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);
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 const 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);
236 // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
237 // only.
238 void OnBeforeRedirect(void* browser_context,
239 const extensions::InfoMap* extension_info_map,
240 net::URLRequest* request,
241 const GURL& new_location);
243 // Dispatches the onResponseStarted event indicating that the first bytes of
244 // the response have arrived.
245 void OnResponseStarted(void* browser_context,
246 const extensions::InfoMap* extension_info_map,
247 net::URLRequest* request);
249 // Dispatches the onComplete event.
250 void OnCompleted(void* browser_context,
251 const extensions::InfoMap* extension_info_map,
252 net::URLRequest* request);
254 // Dispatches an onErrorOccurred event.
255 void OnErrorOccurred(void* browser_context,
256 const extensions::InfoMap* extension_info_map,
257 net::URLRequest* request,
258 bool started);
260 // Notifications when objects are going away.
261 void OnURLRequestDestroyed(void* browser_context,
262 const net::URLRequest* request);
264 // See https://crbug.com/289715.
265 void OnURLRequestJobOrphaned(void* browser_context,
266 const net::URLRequest* request);
268 // Called when an event listener handles a blocking event and responds.
269 void OnEventHandled(void* browser_context,
270 const std::string& extension_id,
271 const std::string& event_name,
272 const std::string& sub_event_name,
273 uint64_t request_id,
274 EventResponse* response);
276 // Adds a listener to the given event. |event_name| specifies the event being
277 // listened to. |sub_event_name| is an internal event uniquely generated in
278 // the extension process to correspond to the given filter and
279 // extra_info_spec. It returns true on success, false on failure.
280 bool AddEventListener(void* browser_context,
281 const std::string& extension_id,
282 const std::string& extension_name,
283 events::HistogramValue histogram_value,
284 const std::string& event_name,
285 const std::string& sub_event_name,
286 const RequestFilter& filter,
287 int extra_info_spec,
288 int embedder_process_id,
289 int web_view_instance_id,
290 base::WeakPtr<IPC::Sender> ipc_sender);
292 // Removes the listener for the given sub-event.
293 void RemoveEventListener(
294 void* browser_context,
295 const std::string& extension_id,
296 const std::string& sub_event_name,
297 int embedder_process_id,
298 int web_view_instance_id);
300 // Removes the listeners for a given <webview>.
301 void RemoveWebViewEventListeners(
302 void* browser_context,
303 int embedder_process_id,
304 int web_view_instance_id);
306 // Called when an incognito browser_context is created or destroyed.
307 void OnOTRBrowserContextCreated(void* original_browser_context,
308 void* otr_browser_context);
309 void OnOTRBrowserContextDestroyed(void* original_browser_context,
310 void* otr_browser_context);
312 // Registers a |callback| that is executed when the next page load happens.
313 // The callback is then deleted.
314 void AddCallbackForPageLoad(const base::Closure& callback);
316 private:
317 friend struct base::DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
319 struct EventListener;
320 using EventListeners = std::vector<const EventListener*>;
321 using ListenerMapForBrowserContext =
322 std::map<std::string, std::set<EventListener>>;
323 using ListenerMap = std::map<void*, ListenerMapForBrowserContext>;
324 using BlockedRequestMap = std::map<uint64_t, BlockedRequest>;
325 // Map of request_id -> bit vector of EventTypes already signaled
326 using SignaledRequestMap = std::map<uint64_t, int>;
327 // For each browser_context: a bool indicating whether it is an incognito
328 // browser_context, and a pointer to the corresponding (non-)incognito
329 // browser_context.
330 using CrossBrowserContextMap = std::map<void*, std::pair<bool, void*>>;
331 using CallbacksForPageLoad = std::list<base::Closure>;
333 ExtensionWebRequestEventRouter();
334 ~ExtensionWebRequestEventRouter();
336 // Ensures that future callbacks for |request| are ignored so that it can be
337 // destroyed safely.
338 void ClearPendingCallbacks(const net::URLRequest* request);
340 bool DispatchEvent(
341 void* browser_context,
342 net::URLRequest* request,
343 const std::vector<const EventListener*>& listeners,
344 const base::ListValue& args);
346 // Returns a list of event listeners that care about the given event, based
347 // on their filter parameters. |extra_info_spec| will contain the combined
348 // set of extra_info_spec flags that every matching listener asked for.
349 std::vector<const EventListener*> GetMatchingListeners(
350 void* browser_context,
351 const extensions::InfoMap* extension_info_map,
352 const std::string& event_name,
353 const net::URLRequest* request,
354 int* extra_info_spec);
356 // Helper for the above functions. This is called twice: once for the
357 // browser_context of the event, the next time for the "cross" browser_context
358 // (i.e. the incognito browser_context if the event is originally for the
359 // normal browser_context, or vice versa).
360 void GetMatchingListenersImpl(
361 void* browser_context,
362 const net::URLRequest* request,
363 const extensions::InfoMap* extension_info_map,
364 bool crosses_incognito,
365 const std::string& event_name,
366 const GURL& url,
367 int render_process_host_id,
368 int routing_id,
369 content::ResourceType resource_type,
370 bool is_async_request,
371 bool is_request_from_extension,
372 int* extra_info_spec,
373 std::vector<const EventListener*>* matching_listeners);
375 // Decrements the count of event handlers blocking the given request. When the
376 // count reaches 0, we stop blocking the request and proceed it using the
377 // method requested by the extension with the highest precedence. Precedence
378 // is decided by extension install time. If |response| is non-NULL, this
379 // method assumes ownership.
380 void DecrementBlockCount(void* browser_context,
381 const std::string& extension_id,
382 const std::string& event_name,
383 uint64_t request_id,
384 EventResponse* response);
386 // Logs an extension action.
387 void LogExtensionActivity(
388 void* browser_context_id,
389 bool is_incognito,
390 const std::string& extension_id,
391 const GURL& url,
392 const std::string& api_call,
393 scoped_ptr<base::DictionaryValue> details);
395 // Processes the generated deltas from blocked_requests_ on the specified
396 // request. If |call_back| is true, the callback registered in
397 // |blocked_requests_| is called.
398 // The function returns the error code for the network request. This is
399 // mostly relevant in case the caller passes |call_callback| = false
400 // and wants to return the correct network error code himself.
401 int ExecuteDeltas(void* browser_context,
402 uint64_t request_id,
403 bool call_callback);
405 // Evaluates the rules of the declarative webrequest API and stores
406 // modifications to the request that result from WebRequestActions as
407 // deltas in |blocked_requests_|. |original_response_headers| should only be
408 // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any
409 // deltas were generated.
410 bool ProcessDeclarativeRules(
411 void* browser_context,
412 const extensions::InfoMap* extension_info_map,
413 const std::string& event_name,
414 net::URLRequest* request,
415 extensions::RequestStage request_stage,
416 const net::HttpResponseHeaders* original_response_headers);
418 // If the BlockedRequest contains messages_to_extension entries in the event
419 // deltas, we send them to subscribers of
420 // chrome.declarativeWebRequest.onMessage.
421 void SendMessages(
422 void* browser_context, const BlockedRequest& blocked_request);
424 // Called when the RulesRegistry is ready to unblock a request that was
425 // waiting for said event.
426 void OnRulesRegistryReady(void* browser_context,
427 const std::string& event_name,
428 uint64_t request_id,
429 extensions::RequestStage request_stage);
431 // Extracts from |request| information for the keys requestId, url, method,
432 // frameId, tabId, type, and timeStamp and writes these into |out| to be
433 // passed on to extensions.
434 void ExtractRequestInfo(const net::URLRequest* request,
435 base::DictionaryValue* out);
437 // Sets the flag that |event_type| has been signaled for |request_id|.
438 // Returns the value of the flag before setting it.
439 bool GetAndSetSignaled(uint64_t request_id, EventTypes event_type);
441 // Clears the flag that |event_type| has been signaled for |request_id|.
442 void ClearSignaled(uint64_t request_id, EventTypes event_type);
444 // Returns whether |request| represents a top level window navigation.
445 bool IsPageLoad(const net::URLRequest* request) const;
447 // Called on a page load to process all registered callbacks.
448 void NotifyPageLoad();
450 // Returns the matching cross browser_context (the regular browser_context if
451 // |browser_context| is OTR and vice versa).
452 void* GetCrossBrowserContext(void* browser_context) const;
454 // Determines whether the specified browser_context is an incognito
455 // browser_context (based on the contents of the cross-browser_context table
456 // and without dereferencing the browser_context pointer).
457 bool IsIncognitoBrowserContext(void* browser_context) const;
459 // Returns true if |request| was already signaled to some event handlers.
460 bool WasSignaled(const net::URLRequest& request) const;
462 // A map for each browser_context that maps an event name to a set of
463 // extensions that are listening to that event.
464 ListenerMap listeners_;
466 // A map of network requests that are waiting for at least one event handler
467 // to respond.
468 BlockedRequestMap blocked_requests_;
470 // A map of request ids to a bitvector indicating which events have been
471 // signaled and should not be sent again.
472 SignaledRequestMap signaled_requests_;
474 // A map of original browser_context -> corresponding incognito
475 // browser_context (and vice versa).
476 CrossBrowserContextMap cross_browser_context_map_;
478 // Keeps track of time spent waiting on extensions using the blocking
479 // webRequest API.
480 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
482 CallbacksForPageLoad callbacks_for_page_load_;
484 typedef std::pair<void*, int> RulesRegistryKey;
485 // Maps each browser_context (and OTRBrowserContext) and a webview key to its
486 // respective rules registry.
487 std::map<RulesRegistryKey,
488 scoped_refptr<extensions::WebRequestRulesRegistry> > rules_registries_;
490 scoped_ptr<extensions::WebRequestEventRouterDelegate>
491 web_request_event_router_delegate_;
493 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
496 class WebRequestInternalFunction : public SyncIOThreadExtensionFunction {
497 public:
498 WebRequestInternalFunction() {}
500 protected:
501 ~WebRequestInternalFunction() override {}
503 const std::string& extension_id_safe() const {
504 return extension() ? extension_id() : base::EmptyString();
508 class WebRequestInternalAddEventListenerFunction
509 : public WebRequestInternalFunction {
510 public:
511 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
512 WEBREQUESTINTERNAL_ADDEVENTLISTENER)
514 protected:
515 ~WebRequestInternalAddEventListenerFunction() override {}
517 // ExtensionFunction:
518 bool RunSync() override;
521 class WebRequestInternalEventHandledFunction
522 : public WebRequestInternalFunction {
523 public:
524 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
525 WEBREQUESTINTERNAL_EVENTHANDLED)
527 protected:
528 ~WebRequestInternalEventHandledFunction() override {}
530 // Unblocks the network request and sets |error_| such that the developer
531 // console will show the respective error message. Use this function to handle
532 // incorrect requests from the extension that cannot be detected by the schema
533 // validator.
534 void RespondWithError(
535 const std::string& event_name,
536 const std::string& sub_event_name,
537 uint64_t request_id,
538 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response,
539 const std::string& error);
541 // ExtensionFunction:
542 bool RunSync() override;
545 class WebRequestHandlerBehaviorChangedFunction
546 : public WebRequestInternalFunction {
547 public:
548 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
549 WEBREQUEST_HANDLERBEHAVIORCHANGED)
551 protected:
552 ~WebRequestHandlerBehaviorChangedFunction() override {}
554 // ExtensionFunction:
555 void GetQuotaLimitHeuristics(
556 extensions::QuotaLimitHeuristics* heuristics) const override;
557 // Handle quota exceeded gracefully: Only warn the user but still execute the
558 // function.
559 void OnQuotaExceeded(const std::string& error) override;
560 bool RunSync() override;
563 } // namespace extensions
565 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_