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 CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_
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/web_request/web_request_api_helpers.h"
20 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
21 #include "content/public/common/resource_type.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"
31 class ExtensionWebRequestTimeTracker;
35 class DictionaryValue;
42 class RenderProcessHost;
46 class AuthCredentials;
47 class AuthChallengeInfo;
48 class HttpRequestHeaders;
49 class HttpResponseHeaders;
53 namespace extensions {
56 class WebRequestRulesRegistry;
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 {
65 explicit WebRequestAPI(content::BrowserContext* context);
66 virtual ~WebRequestAPI();
68 // BrowserContextKeyedAPI support:
69 static BrowserContextKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance();
71 // EventRouter::Observer overrides:
72 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE;
75 friend class BrowserContextKeyedAPIFactory<WebRequestAPI>;
77 // BrowserContextKeyedAPI support:
78 static const char* service_name() { return "WebRequestAPI"; }
79 static const bool kServiceRedirectedInIncognito = true;
80 static const bool kServiceIsNULLWhileTesting = true;
82 content::BrowserContext* browser_context_;
84 DISALLOW_COPY_AND_ASSIGN(WebRequestAPI);
87 } // namespace extensions
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> {
95 struct BlockedRequest;
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 {
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
119 bool InitFromValue(const base::DictionaryValue& value, std::string* error);
121 extensions::URLPatternSet urls;
122 std::vector<content::ResourceType> types;
127 // Internal representation of the extraInfoSpec parameter on webRequest
128 // events, used to specify extra information to be included with network
130 struct ExtraInfoSpec {
132 REQUEST_HEADERS = 1<<0,
133 RESPONSE_HEADERS = 1<<1,
135 ASYNC_BLOCKING = 1<<3,
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);
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
155 base::Time extension_install_time;
157 // Response values. These are mutually exclusive.
160 scoped_ptr<net::HttpRequestHeaders> request_headers;
161 scoped_ptr<extension_web_request_api_helpers::ResponseHeaders>
164 scoped_ptr<net::AuthCredentials> auth_credentials;
166 DISALLOW_COPY_AND_ASSIGN(EventResponse);
169 static ExtensionWebRequestEventRouter* GetInstance();
171 // Registers a rule registry. Pass null for |rules_registry| to unregister
172 // the rule registry for |profile|.
173 void RegisterRulesRegistry(
175 const extensions::RulesRegistryService::WebViewKey& webview_key,
176 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry);
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,
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
191 int OnBeforeSendHeaders(void* profile,
192 extensions::InfoMap* extension_info_map,
193 net::URLRequest* request,
194 const net::CompletionCallback& callback,
195 net::HttpRequestHeaders* headers);
197 // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
199 void OnSendHeaders(void* profile,
200 extensions::InfoMap* extension_info_map,
201 net::URLRequest* request,
202 const net::HttpRequestHeaders& headers);
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(
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);
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
227 net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
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);
235 // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
237 void OnBeforeRedirect(void* profile,
238 extensions::InfoMap* extension_info_map,
239 net::URLRequest* request,
240 const GURL& new_location);
242 // Dispatches the onResponseStarted event indicating that the first bytes of
243 // the response have arrived.
244 void OnResponseStarted(void* profile,
245 extensions::InfoMap* extension_info_map,
246 net::URLRequest* request);
248 // Dispatches the onComplete event.
249 void OnCompleted(void* profile,
250 extensions::InfoMap* extension_info_map,
251 net::URLRequest* request);
253 // Dispatches an onErrorOccurred event.
254 void OnErrorOccurred(void* profile,
255 extensions::InfoMap* extension_info_map,
256 net::URLRequest* request,
259 // Notifications when objects are going away.
260 void OnURLRequestDestroyed(void* profile, net::URLRequest* request);
262 // Called when an event listener handles a blocking event and responds.
265 const std::string& extension_id,
266 const std::string& event_name,
267 const std::string& sub_event_name,
269 EventResponse* response);
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(
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,
283 int embedder_process_id,
284 int web_view_instance_id,
285 base::WeakPtr<IPC::Sender> ipc_sender);
287 // Removes the listener for the given sub-event.
288 void RemoveEventListener(
290 const std::string& extension_id,
291 const std::string& sub_event_name);
293 // Removes the listeners for a given <webview>.
294 void RemoveWebViewEventListeners(
296 const std::string& extension_id,
297 int embedder_process_id,
298 int web_view_instance_id);
300 // Called when an incognito profile is created or destroyed.
301 void OnOTRProfileCreated(void* original_profile,
303 void OnOTRProfileDestroyed(void* original_profile,
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);
311 friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
313 struct EventListener;
314 typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile;
315 typedef std::map<void*, ListenerMapForProfile> ListenerMap;
316 typedef std::map<uint64, BlockedRequest> BlockedRequestMap;
317 // Map of request_id -> bit vector of EventTypes already signaled
318 typedef std::map<uint64, int> SignaledRequestMap;
319 // For each profile: a bool indicating whether it is an incognito profile,
320 // and a pointer to the corresponding (non-)incognito profile.
321 typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap;
322 typedef std::list<base::Closure> CallbacksForPageLoad;
324 ExtensionWebRequestEventRouter();
325 ~ExtensionWebRequestEventRouter();
327 // Ensures that future callbacks for |request| are ignored so that it can be
329 void ClearPendingCallbacks(net::URLRequest* request);
333 net::URLRequest* request,
334 const std::vector<const EventListener*>& listeners,
335 const base::ListValue& args);
337 // Returns a list of event listeners that care about the given event, based
338 // on their filter parameters. |extra_info_spec| will contain the combined
339 // set of extra_info_spec flags that every matching listener asked for.
340 std::vector<const EventListener*> GetMatchingListeners(
342 extensions::InfoMap* extension_info_map,
343 const std::string& event_name,
344 net::URLRequest* request,
345 int* extra_info_spec);
347 // Helper for the above functions. This is called twice: once for the profile
348 // of the event, the next time for the "cross" profile (i.e. the incognito
349 // profile if the event is originally for the normal profile, or vice versa).
350 void GetMatchingListenersImpl(
352 extensions::InfoMap* extension_info_map,
353 bool crosses_incognito,
354 const std::string& event_name,
358 int render_process_host_id,
360 content::ResourceType resource_type,
361 bool is_async_request,
362 bool is_request_from_extension,
363 int* extra_info_spec,
364 std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
367 // Decrements the count of event handlers blocking the given request. When the
368 // count reaches 0, we stop blocking the request and proceed it using the
369 // method requested by the extension with the highest precedence. Precedence
370 // is decided by extension install time. If |response| is non-NULL, this
371 // method assumes ownership.
372 void DecrementBlockCount(
374 const std::string& extension_id,
375 const std::string& event_name,
377 EventResponse* response);
379 // Processes the generated deltas from blocked_requests_ on the specified
380 // request. If |call_back| is true, the callback registered in
381 // |blocked_requests_| is called.
382 // The function returns the error code for the network request. This is
383 // mostly relevant in case the caller passes |call_callback| = false
384 // and wants to return the correct network error code himself.
385 int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback);
387 // Evaluates the rules of the declarative webrequest API and stores
388 // modifications to the request that result from WebRequestActions as
389 // deltas in |blocked_requests_|. |original_response_headers| should only be
390 // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any
391 // deltas were generated.
392 bool ProcessDeclarativeRules(
394 extensions::InfoMap* extension_info_map,
395 const std::string& event_name,
396 net::URLRequest* request,
397 extensions::RequestStage request_stage,
398 const net::HttpResponseHeaders* original_response_headers);
400 // If the BlockedRequest contains messages_to_extension entries in the event
401 // deltas, we send them to subscribers of
402 // chrome.declarativeWebRequest.onMessage.
403 void SendMessages(void* profile, const BlockedRequest& blocked_request);
405 // Called when the RulesRegistry is ready to unblock a request that was
406 // waiting for said event.
407 void OnRulesRegistryReady(
409 const std::string& event_name,
411 extensions::RequestStage request_stage);
413 // Sets the flag that |event_type| has been signaled for |request_id|.
414 // Returns the value of the flag before setting it.
415 bool GetAndSetSignaled(uint64 request_id, EventTypes event_type);
417 // Clears the flag that |event_type| has been signaled for |request_id|.
418 void ClearSignaled(uint64 request_id, EventTypes event_type);
420 // Returns whether |request| represents a top level window navigation.
421 bool IsPageLoad(net::URLRequest* request) const;
423 // Called on a page load to process all registered callbacks.
424 void NotifyPageLoad();
426 // Returns the matching cross profile (the regular profile if |profile| is
427 // OTR and vice versa).
428 void* GetCrossProfile(void* profile) const;
430 // Determines whether the specified profile is an incognito profile (based on
431 // the contents of the cross-profile table and without dereferencing the
433 bool IsIncognitoProfile(void* profile) const;
435 // Returns true if |request| was already signaled to some event handlers.
436 bool WasSignaled(const net::URLRequest& request) const;
438 // A map for each profile that maps an event name to a set of extensions that
439 // are listening to that event.
440 ListenerMap listeners_;
442 // A map of network requests that are waiting for at least one event handler
444 BlockedRequestMap blocked_requests_;
446 // A map of request ids to a bitvector indicating which events have been
447 // signaled and should not be sent again.
448 SignaledRequestMap signaled_requests_;
450 // A map of original profile -> corresponding incognito profile (and vice
452 CrossProfileMap cross_profile_map_;
454 // Keeps track of time spent waiting on extensions using the blocking
456 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
458 CallbacksForPageLoad callbacks_for_page_load_;
460 typedef std::pair<void*, extensions::RulesRegistryService::WebViewKey>
462 // Maps each profile (and OTRProfile) and a webview key to its respective
464 std::map<RulesRegistryKey,
465 scoped_refptr<extensions::WebRequestRulesRegistry> > rules_registries_;
467 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
470 class WebRequestInternalAddEventListenerFunction
471 : public SyncIOThreadExtensionFunction {
473 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
474 WEBREQUESTINTERNAL_ADDEVENTLISTENER)
477 virtual ~WebRequestInternalAddEventListenerFunction() {}
479 // ExtensionFunction:
480 virtual bool RunSync() OVERRIDE;
483 class WebRequestInternalEventHandledFunction
484 : public SyncIOThreadExtensionFunction {
486 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
487 WEBREQUESTINTERNAL_EVENTHANDLED)
490 virtual ~WebRequestInternalEventHandledFunction() {}
492 // Unblocks the network request and sets |error_| such that the developer
493 // console will show the respective error message. Use this function to handle
494 // incorrect requests from the extension that cannot be detected by the schema
496 void RespondWithError(
497 const std::string& event_name,
498 const std::string& sub_event_name,
500 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response,
501 const std::string& error);
503 // ExtensionFunction:
504 virtual bool RunSync() OVERRIDE;
507 class WebRequestHandlerBehaviorChangedFunction
508 : public SyncIOThreadExtensionFunction {
510 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
511 WEBREQUEST_HANDLERBEHAVIORCHANGED)
514 virtual ~WebRequestHandlerBehaviorChangedFunction() {}
516 // ExtensionFunction:
517 virtual void GetQuotaLimitHeuristics(
518 extensions::QuotaLimitHeuristics* heuristics) const OVERRIDE;
519 // Handle quota exceeded gracefully: Only warn the user but still execute the
521 virtual void OnQuotaExceeded(const std::string& error) OVERRIDE;
522 virtual bool RunSync() OVERRIDE;
525 // Send updates to |host| with information about what webRequest-related
526 // extensions are installed.
527 void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host);
529 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_