Add ICU message format support
[chromium-blink-merge.git] / extensions / browser / api / web_request / web_request_api.h
blob49bed01b9de2d19c0439e3c446e44c956228f0bb
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 <vector>
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"
32 class ExtensionWebRequestTimeTracker;
33 class GURL;
35 namespace base {
36 class DictionaryValue;
37 class ListValue;
38 class StringValue;
41 namespace content {
42 class BrowserContext;
45 namespace net {
46 class AuthCredentials;
47 class AuthChallengeInfo;
48 class HttpRequestHeaders;
49 class HttpResponseHeaders;
50 class URLRequest;
53 namespace extensions {
55 class InfoMap;
56 class WebRequestRulesRegistry;
57 class WebRequestEventRouterDelegate;
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;
69 // BrowserContextKeyedAPI support:
70 static BrowserContextKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance();
72 // EventRouter::Observer overrides:
73 void OnListenerRemoved(const EventListenerInfo& details) override;
75 private:
76 friend class BrowserContextKeyedAPIFactory<WebRequestAPI>;
78 // BrowserContextKeyedAPI support:
79 static const char* service_name() { return "WebRequestAPI"; }
80 static const bool kServiceRedirectedInIncognito = true;
81 static const bool kServiceIsNULLWhileTesting = true;
83 content::BrowserContext* browser_context_;
85 DISALLOW_COPY_AND_ASSIGN(WebRequestAPI);
88 // This class observes network events and routes them to the appropriate
89 // extensions listening to those events. All methods must be called on the IO
90 // thread unless otherwise specified.
91 class ExtensionWebRequestEventRouter
92 : public base::SupportsWeakPtr<ExtensionWebRequestEventRouter> {
93 public:
94 struct BlockedRequest;
96 enum EventTypes {
97 kInvalidEvent = 0,
98 kOnBeforeRequest = 1 << 0,
99 kOnBeforeSendHeaders = 1 << 1,
100 kOnSendHeaders = 1 << 2,
101 kOnHeadersReceived = 1 << 3,
102 kOnBeforeRedirect = 1 << 4,
103 kOnAuthRequired = 1 << 5,
104 kOnResponseStarted = 1 << 6,
105 kOnErrorOccurred = 1 << 7,
106 kOnCompleted = 1 << 8,
109 // Internal representation of the webRequest.RequestFilter type, used to
110 // filter what network events an extension cares about.
111 struct RequestFilter {
112 RequestFilter();
113 ~RequestFilter();
115 // Returns false if there was an error initializing. If it is a user error,
116 // an error message is provided, otherwise the error is internal (and
117 // unexpected).
118 bool InitFromValue(const base::DictionaryValue& value, std::string* error);
120 extensions::URLPatternSet urls;
121 std::vector<content::ResourceType> types;
122 int tab_id;
123 int window_id;
126 // Internal representation of the extraInfoSpec parameter on webRequest
127 // events, used to specify extra information to be included with network
128 // events.
129 struct ExtraInfoSpec {
130 enum Flags {
131 REQUEST_HEADERS = 1<<0,
132 RESPONSE_HEADERS = 1<<1,
133 BLOCKING = 1<<2,
134 ASYNC_BLOCKING = 1<<3,
135 REQUEST_BODY = 1<<4,
138 static bool InitFromValue(const base::ListValue& value,
139 int* extra_info_spec);
142 // Contains an extension's response to a blocking event.
143 struct EventResponse {
144 EventResponse(const std::string& extension_id,
145 const base::Time& extension_install_time);
146 ~EventResponse();
148 // ID of the extension that sent this response.
149 std::string extension_id;
151 // The time that the extension was installed. Used for deciding order of
152 // precedence in case multiple extensions respond with conflicting
153 // decisions.
154 base::Time extension_install_time;
156 // Response values. These are mutually exclusive.
157 bool cancel;
158 GURL new_url;
159 scoped_ptr<net::HttpRequestHeaders> request_headers;
160 scoped_ptr<extension_web_request_api_helpers::ResponseHeaders>
161 response_headers;
163 scoped_ptr<net::AuthCredentials> auth_credentials;
165 DISALLOW_COPY_AND_ASSIGN(EventResponse);
168 static ExtensionWebRequestEventRouter* GetInstance();
170 // Registers a rule registry. Pass null for |rules_registry| to unregister
171 // the rule registry for |browser_context|.
172 void RegisterRulesRegistry(
173 void* browser_context,
174 int rules_registry_id,
175 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry);
177 // Dispatches the OnBeforeRequest event to any extensions whose filters match
178 // the given request. Returns net::ERR_IO_PENDING if an extension is
179 // intercepting the request, OK otherwise.
180 int OnBeforeRequest(void* browser_context,
181 extensions::InfoMap* extension_info_map,
182 net::URLRequest* request,
183 const net::CompletionCallback& callback,
184 GURL* new_url);
186 // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s)
187 // requests only, and allows modification of the outgoing request headers.
188 // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK
189 // otherwise.
190 int OnBeforeSendHeaders(void* browser_context,
191 extensions::InfoMap* extension_info_map,
192 net::URLRequest* request,
193 const net::CompletionCallback& callback,
194 net::HttpRequestHeaders* headers);
196 // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
197 // only.
198 void OnSendHeaders(void* browser_context,
199 extensions::InfoMap* extension_info_map,
200 net::URLRequest* request,
201 const net::HttpRequestHeaders& headers);
203 // Dispatches the onHeadersReceived event. This is fired for HTTP(s)
204 // requests only, and allows modification of incoming response headers.
205 // Returns net::ERR_IO_PENDING if an extension is intercepting the request,
206 // OK otherwise. |original_response_headers| is reference counted. |callback|
207 // |override_response_headers| and |allowed_unsafe_redirect_url| are owned by
208 // a URLRequestJob. They are guaranteed to be valid until |callback| is called
209 // or OnURLRequestDestroyed is called (whatever comes first).
210 // Do not modify |original_response_headers| directly but write new ones
211 // into |override_response_headers|.
212 int OnHeadersReceived(
213 void* browser_context,
214 extensions::InfoMap* extension_info_map,
215 net::URLRequest* request,
216 const net::CompletionCallback& callback,
217 const net::HttpResponseHeaders* original_response_headers,
218 scoped_refptr<net::HttpResponseHeaders>* override_response_headers,
219 GURL* allowed_unsafe_redirect_url);
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* browser_context,
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);
234 // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
235 // only.
236 void OnBeforeRedirect(void* browser_context,
237 extensions::InfoMap* extension_info_map,
238 net::URLRequest* request,
239 const GURL& new_location);
241 // Dispatches the onResponseStarted event indicating that the first bytes of
242 // the response have arrived.
243 void OnResponseStarted(void* browser_context,
244 extensions::InfoMap* extension_info_map,
245 net::URLRequest* request);
247 // Dispatches the onComplete event.
248 void OnCompleted(void* browser_context,
249 extensions::InfoMap* extension_info_map,
250 net::URLRequest* request);
252 // Dispatches an onErrorOccurred event.
253 void OnErrorOccurred(void* browser_context,
254 extensions::InfoMap* extension_info_map,
255 net::URLRequest* request,
256 bool started);
258 // Notifications when objects are going away.
259 void OnURLRequestDestroyed(void* browser_context, net::URLRequest* request);
261 // Called when an event listener handles a blocking event and responds.
262 void OnEventHandled(
263 void* browser_context,
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);
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* browser_context,
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);
286 // Removes the listener for the given sub-event.
287 void RemoveEventListener(
288 void* browser_context,
289 const std::string& extension_id,
290 const std::string& sub_event_name,
291 int embedder_process_id,
292 int web_view_instance_id);
294 // Removes the listeners for a given <webview>.
295 void RemoveWebViewEventListeners(
296 void* browser_context,
297 int embedder_process_id,
298 int web_view_instance_id);
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);
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);
310 private:
311 friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
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;
326 ExtensionWebRequestEventRouter();
327 ~ExtensionWebRequestEventRouter();
329 // Ensures that future callbacks for |request| are ignored so that it can be
330 // destroyed safely.
331 void ClearPendingCallbacks(net::URLRequest* request);
333 bool DispatchEvent(
334 void* browser_context,
335 net::URLRequest* request,
336 const std::vector<const EventListener*>& listeners,
337 const base::ListValue& args);
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);
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);
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);
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);
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);
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);
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);
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);
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);
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);
435 // Clears the flag that |event_type| has been signaled for |request_id|.
436 void ClearSignaled(uint64 request_id, EventTypes event_type);
438 // Returns whether |request| represents a top level window navigation.
439 bool IsPageLoad(net::URLRequest* request) const;
441 // Called on a page load to process all registered callbacks.
442 void NotifyPageLoad();
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;
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;
453 // Returns true if |request| was already signaled to some event handlers.
454 bool WasSignaled(const net::URLRequest& request) const;
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_;
460 // A map of network requests that are waiting for at least one event handler
461 // to respond.
462 BlockedRequestMap blocked_requests_;
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_;
468 // A map of original browser_context -> corresponding incognito
469 // browser_context (and vice versa).
470 CrossBrowserContextMap cross_browser_context_map_;
472 // Keeps track of time spent waiting on extensions using the blocking
473 // webRequest API.
474 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
476 CallbacksForPageLoad callbacks_for_page_load_;
478 typedef std::pair<void*, int> RulesRegistryKey;
479 // Maps each browser_context (and OTRBrowserContext) and a webview key to its
480 // respective rules registry.
481 std::map<RulesRegistryKey,
482 scoped_refptr<extensions::WebRequestRulesRegistry> > rules_registries_;
484 scoped_ptr<extensions::WebRequestEventRouterDelegate>
485 web_request_event_router_delegate_;
487 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
490 class WebRequestInternalFunction : public SyncIOThreadExtensionFunction {
491 public:
492 WebRequestInternalFunction() {}
494 protected:
495 ~WebRequestInternalFunction() override {}
497 const std::string& extension_id_safe() const {
498 return extension() ? extension_id() : base::EmptyString();
502 class WebRequestInternalAddEventListenerFunction
503 : public WebRequestInternalFunction {
504 public:
505 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
506 WEBREQUESTINTERNAL_ADDEVENTLISTENER)
508 protected:
509 ~WebRequestInternalAddEventListenerFunction() override {}
511 // ExtensionFunction:
512 bool RunSync() override;
515 class WebRequestInternalEventHandledFunction
516 : public WebRequestInternalFunction {
517 public:
518 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
519 WEBREQUESTINTERNAL_EVENTHANDLED)
521 protected:
522 ~WebRequestInternalEventHandledFunction() override {}
524 // Unblocks the network request and sets |error_| such that the developer
525 // console will show the respective error message. Use this function to handle
526 // incorrect requests from the extension that cannot be detected by the schema
527 // validator.
528 void RespondWithError(
529 const std::string& event_name,
530 const std::string& sub_event_name,
531 uint64 request_id,
532 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response,
533 const std::string& error);
535 // ExtensionFunction:
536 bool RunSync() override;
539 class WebRequestHandlerBehaviorChangedFunction
540 : public WebRequestInternalFunction {
541 public:
542 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
543 WEBREQUEST_HANDLERBEHAVIORCHANGED)
545 protected:
546 ~WebRequestHandlerBehaviorChangedFunction() override {}
548 // ExtensionFunction:
549 void GetQuotaLimitHeuristics(
550 extensions::QuotaLimitHeuristics* heuristics) const override;
551 // Handle quota exceeded gracefully: Only warn the user but still execute the
552 // function.
553 void OnQuotaExceeded(const std::string& error) override;
554 bool RunSync() override;
557 } // namespace extensions
559 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_