Revert 222090 "<webview>: Cleanup WebRequest event listeners whe..."
[chromium-blink-merge.git] / chrome / browser / extensions / api / web_request / web_request_api.h
blobfba59b040925fa09cad821534ce12233b55c0466
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_
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/time/time.h"
17 #include "chrome/browser/extensions/api/declarative_webrequest/request_stage.h"
18 #include "chrome/browser/extensions/api/web_request/web_request_api_helpers.h"
19 #include "chrome/browser/extensions/api/web_request/web_request_permissions.h"
20 #include "chrome/browser/extensions/extension_function.h"
21 #include "chrome/browser/profiles/profile.h"
22 #include "chrome/common/chrome_version_info.h"
23 #include "extensions/common/url_pattern_set.h"
24 #include "ipc/ipc_sender.h"
25 #include "net/base/completion_callback.h"
26 #include "net/base/network_delegate.h"
27 #include "net/http/http_request_headers.h"
28 #include "webkit/common/resource_type.h"
30 class ExtensionInfoMap;
31 class ExtensionWebRequestTimeTracker;
32 class GURL;
34 namespace base {
35 class DictionaryValue;
36 class ListValue;
37 class StringValue;
40 namespace content {
41 class RenderProcessHost;
44 namespace extensions {
45 class WebRequestRulesRegistry;
48 namespace net {
49 class AuthCredentials;
50 class AuthChallengeInfo;
51 class HttpRequestHeaders;
52 class HttpResponseHeaders;
53 class URLRequest;
56 // This class observes network events and routes them to the appropriate
57 // extensions listening to those events. All methods must be called on the IO
58 // thread unless otherwise specified.
59 class ExtensionWebRequestEventRouter
60 : public base::SupportsWeakPtr<ExtensionWebRequestEventRouter> {
61 public:
62 struct BlockedRequest;
64 enum EventTypes {
65 kInvalidEvent = 0,
66 kOnBeforeRequest = 1 << 0,
67 kOnBeforeSendHeaders = 1 << 1,
68 kOnSendHeaders = 1 << 2,
69 kOnHeadersReceived = 1 << 3,
70 kOnBeforeRedirect = 1 << 4,
71 kOnAuthRequired = 1 << 5,
72 kOnResponseStarted = 1 << 6,
73 kOnErrorOccurred = 1 << 7,
74 kOnCompleted = 1 << 8,
77 // Internal representation of the webRequest.RequestFilter type, used to
78 // filter what network events an extension cares about.
79 struct RequestFilter {
80 RequestFilter();
81 ~RequestFilter();
83 // Returns false if there was an error initializing. If it is a user error,
84 // an error message is provided, otherwise the error is internal (and
85 // unexpected).
86 bool InitFromValue(const base::DictionaryValue& value, std::string* error);
88 extensions::URLPatternSet urls;
89 std::vector<ResourceType::Type> types;
90 int tab_id;
91 int window_id;
94 // Internal representation of the extraInfoSpec parameter on webRequest
95 // events, used to specify extra information to be included with network
96 // events.
97 struct ExtraInfoSpec {
98 enum Flags {
99 REQUEST_HEADERS = 1<<0,
100 RESPONSE_HEADERS = 1<<1,
101 BLOCKING = 1<<2,
102 ASYNC_BLOCKING = 1<<3,
103 REQUEST_BODY = 1<<4,
106 static bool InitFromValue(const base::ListValue& value,
107 int* extra_info_spec);
110 // Contains an extension's response to a blocking event.
111 struct EventResponse {
112 EventResponse(const std::string& extension_id,
113 const base::Time& extension_install_time);
114 ~EventResponse();
116 // ID of the extension that sent this response.
117 std::string extension_id;
119 // The time that the extension was installed. Used for deciding order of
120 // precedence in case multiple extensions respond with conflicting
121 // decisions.
122 base::Time extension_install_time;
124 // Response values. These are mutually exclusive.
125 bool cancel;
126 GURL new_url;
127 scoped_ptr<net::HttpRequestHeaders> request_headers;
128 scoped_ptr<extension_web_request_api_helpers::ResponseHeaders>
129 response_headers;
131 scoped_ptr<net::AuthCredentials> auth_credentials;
133 DISALLOW_COPY_AND_ASSIGN(EventResponse);
136 static ExtensionWebRequestEventRouter* GetInstance();
138 // Registers a rule registry. Pass null for |rules_registry| to unregister
139 // the rule registry for |profile|.
140 void RegisterRulesRegistry(
141 void* profile,
142 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry);
144 // Dispatches the OnBeforeRequest event to any extensions whose filters match
145 // the given request. Returns net::ERR_IO_PENDING if an extension is
146 // intercepting the request, OK otherwise.
147 int OnBeforeRequest(void* profile,
148 ExtensionInfoMap* extension_info_map,
149 net::URLRequest* request,
150 const net::CompletionCallback& callback,
151 GURL* new_url);
153 // Dispatches the onBeforeSendHeaders event. This is fired for HTTP(s)
154 // requests only, and allows modification of the outgoing request headers.
155 // Returns net::ERR_IO_PENDING if an extension is intercepting the request, OK
156 // otherwise.
157 int OnBeforeSendHeaders(void* profile,
158 ExtensionInfoMap* extension_info_map,
159 net::URLRequest* request,
160 const net::CompletionCallback& callback,
161 net::HttpRequestHeaders* headers);
163 // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests
164 // only.
165 void OnSendHeaders(void* profile,
166 ExtensionInfoMap* extension_info_map,
167 net::URLRequest* request,
168 const net::HttpRequestHeaders& headers);
170 // Dispatches the onHeadersReceived event. This is fired for HTTP(s)
171 // requests only, and allows modification of incoming response headers.
172 // Returns net::ERR_IO_PENDING if an extension is intercepting the request,
173 // OK otherwise. |original_response_headers| is reference counted. |callback|
174 // and |override_response_headers| are owned by a URLRequestJob. They are
175 // guaranteed to be valid until |callback| is called or OnURLRequestDestroyed
176 // is called (whatever comes first).
177 // Do not modify |original_response_headers| directly but write new ones
178 // into |override_response_headers|.
179 int OnHeadersReceived(
180 void* profile,
181 ExtensionInfoMap* extension_info_map,
182 net::URLRequest* request,
183 const net::CompletionCallback& callback,
184 const net::HttpResponseHeaders* original_response_headers,
185 scoped_refptr<net::HttpResponseHeaders>* override_response_headers);
187 // Dispatches the OnAuthRequired event to any extensions whose filters match
188 // the given request. If the listener is not registered as "blocking", then
189 // AUTH_REQUIRED_RESPONSE_OK is returned. Otherwise,
190 // AUTH_REQUIRED_RESPONSE_IO_PENDING is returned and |callback| will be
191 // invoked later.
192 net::NetworkDelegate::AuthRequiredResponse OnAuthRequired(
193 void* profile,
194 ExtensionInfoMap* extension_info_map,
195 net::URLRequest* request,
196 const net::AuthChallengeInfo& auth_info,
197 const net::NetworkDelegate::AuthCallback& callback,
198 net::AuthCredentials* credentials);
200 // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests
201 // only.
202 void OnBeforeRedirect(void* profile,
203 ExtensionInfoMap* extension_info_map,
204 net::URLRequest* request,
205 const GURL& new_location);
207 // Dispatches the onResponseStarted event indicating that the first bytes of
208 // the response have arrived.
209 void OnResponseStarted(void* profile,
210 ExtensionInfoMap* extension_info_map,
211 net::URLRequest* request);
213 // Dispatches the onComplete event.
214 void OnCompleted(void* profile,
215 ExtensionInfoMap* extension_info_map,
216 net::URLRequest* request);
218 // Dispatches an onErrorOccurred event.
219 void OnErrorOccurred(void* profile,
220 ExtensionInfoMap* extension_info_map,
221 net::URLRequest* request,
222 bool started);
224 // Notifications when objects are going away.
225 void OnURLRequestDestroyed(void* profile, net::URLRequest* request);
227 // Called when an event listener handles a blocking event and responds.
228 void OnEventHandled(
229 void* profile,
230 const std::string& extension_id,
231 const std::string& event_name,
232 const std::string& sub_event_name,
233 uint64 request_id,
234 EventResponse* response);
236 // Adds a listener to the given event. |event_name| specifies the event being
237 // listened to. |sub_event_name| is an internal event uniquely generated in
238 // the extension process to correspond to the given filter and
239 // extra_info_spec. It returns true on success, false on failure.
240 bool AddEventListener(
241 void* profile,
242 const std::string& extension_id,
243 const std::string& extension_name,
244 const std::string& event_name,
245 const std::string& sub_event_name,
246 const RequestFilter& filter,
247 int extra_info_spec,
248 int embedder_process_id,
249 int embedder_routing_id,
250 int web_view_instance_id,
251 base::WeakPtr<IPC::Sender> ipc_sender);
253 // Removes the listener for the given sub-event.
254 void RemoveEventListener(
255 void* profile,
256 const std::string& extension_id,
257 const std::string& sub_event_name);
259 // Removes the listeners for a given <webview>.
260 void RemoveWebViewEventListeners(
261 void* profile,
262 const std::string& extension_id,
263 int embedder_process_id,
264 int embedder_routing_id,
265 int web_view_instance_id);
267 // Called when an incognito profile is created or destroyed.
268 void OnOTRProfileCreated(void* original_profile,
269 void* otr_profile);
270 void OnOTRProfileDestroyed(void* original_profile,
271 void* otr_profile);
273 // Registers a |callback| that is executed when the next page load happens.
274 // The callback is then deleted.
275 void AddCallbackForPageLoad(const base::Closure& callback);
277 private:
278 friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>;
280 struct EventListener;
281 typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile;
282 typedef std::map<void*, ListenerMapForProfile> ListenerMap;
283 typedef std::map<uint64, BlockedRequest> BlockedRequestMap;
284 // Map of request_id -> bit vector of EventTypes already signaled
285 typedef std::map<uint64, int> SignaledRequestMap;
286 // For each profile: a bool indicating whether it is an incognito profile,
287 // and a pointer to the corresponding (non-)incognito profile.
288 typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap;
289 typedef std::list<base::Closure> CallbacksForPageLoad;
291 ExtensionWebRequestEventRouter();
292 ~ExtensionWebRequestEventRouter();
294 // Ensures that future callbacks for |request| are ignored so that it can be
295 // destroyed safely.
296 void ClearPendingCallbacks(net::URLRequest* request);
298 bool DispatchEvent(
299 void* profile,
300 net::URLRequest* request,
301 const std::vector<const EventListener*>& listeners,
302 const base::ListValue& args);
304 // Returns a list of event listeners that care about the given event, based
305 // on their filter parameters. |extra_info_spec| will contain the combined
306 // set of extra_info_spec flags that every matching listener asked for.
307 std::vector<const EventListener*> GetMatchingListeners(
308 void* profile,
309 ExtensionInfoMap* extension_info_map,
310 const std::string& event_name,
311 net::URLRequest* request,
312 int* extra_info_spec);
314 // Helper for the above functions. This is called twice: once for the profile
315 // of the event, the next time for the "cross" profile (i.e. the incognito
316 // profile if the event is originally for the normal profile, or vice versa).
317 void GetMatchingListenersImpl(
318 void* profile,
319 ExtensionInfoMap* extension_info_map,
320 bool crosses_incognito,
321 const std::string& event_name,
322 const GURL& url,
323 int tab_id,
324 int window_id,
325 int render_process_host_id,
326 int routing_id,
327 ResourceType::Type resource_type,
328 bool is_async_request,
329 bool is_request_from_extension,
330 int* extra_info_spec,
331 std::vector<const ExtensionWebRequestEventRouter::EventListener*>*
332 matching_listeners);
334 // Decrements the count of event handlers blocking the given request. When the
335 // count reaches 0, we stop blocking the request and proceed it using the
336 // method requested by the extension with the highest precedence. Precedence
337 // is decided by extension install time. If |response| is non-NULL, this
338 // method assumes ownership.
339 void DecrementBlockCount(
340 void* profile,
341 const std::string& extension_id,
342 const std::string& event_name,
343 uint64 request_id,
344 EventResponse* response);
346 // Processes the generated deltas from blocked_requests_ on the specified
347 // request. If |call_back| is true, the callback registered in
348 // |blocked_requests_| is called.
349 // The function returns the error code for the network request. This is
350 // mostly relevant in case the caller passes |call_callback| = false
351 // and wants to return the correct network error code himself.
352 int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback);
354 // Evaluates the rules of the declarative webrequest API and stores
355 // modifications to the request that result from WebRequestActions as
356 // deltas in |blocked_requests_|. |original_response_headers| should only be
357 // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any
358 // deltas were generated.
359 bool ProcessDeclarativeRules(
360 void* profile,
361 ExtensionInfoMap* extension_info_map,
362 const std::string& event_name,
363 net::URLRequest* request,
364 extensions::RequestStage request_stage,
365 const net::HttpResponseHeaders* original_response_headers);
367 // If the BlockedRequest contains messages_to_extension entries in the event
368 // deltas, we send them to subscribers of
369 // chrome.declarativeWebRequest.onMessage.
370 void SendMessages(void* profile, const BlockedRequest& blocked_request);
372 // Called when the RulesRegistry is ready to unblock a request that was
373 // waiting for said event.
374 void OnRulesRegistryReady(
375 void* profile,
376 const std::string& event_name,
377 uint64 request_id,
378 extensions::RequestStage request_stage);
380 // Sets the flag that |event_type| has been signaled for |request_id|.
381 // Returns the value of the flag before setting it.
382 bool GetAndSetSignaled(uint64 request_id, EventTypes event_type);
384 // Clears the flag that |event_type| has been signaled for |request_id|.
385 void ClearSignaled(uint64 request_id, EventTypes event_type);
387 // Returns whether |request| represents a top level window navigation.
388 bool IsPageLoad(net::URLRequest* request) const;
390 // Called on a page load to process all registered callbacks.
391 void NotifyPageLoad();
393 // Returns the matching cross profile (the regular profile if |profile| is
394 // OTR and vice versa).
395 void* GetCrossProfile(void* profile) const;
397 // Determines whether the specified profile is an incognito profile (based on
398 // the contents of the cross-profile table and without dereferencing the
399 // profile pointer).
400 bool IsIncognitoProfile(void* profile) const;
402 // Returns true if |request| was already signaled to some event handlers.
403 bool WasSignaled(const net::URLRequest& request) const;
405 // A map for each profile that maps an event name to a set of extensions that
406 // are listening to that event.
407 ListenerMap listeners_;
409 // A map of network requests that are waiting for at least one event handler
410 // to respond.
411 BlockedRequestMap blocked_requests_;
413 // A map of request ids to a bitvector indicating which events have been
414 // signaled and should not be sent again.
415 SignaledRequestMap signaled_requests_;
417 // A map of original profile -> corresponding incognito profile (and vice
418 // versa).
419 CrossProfileMap cross_profile_map_;
421 // Keeps track of time spent waiting on extensions using the blocking
422 // webRequest API.
423 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_;
425 CallbacksForPageLoad callbacks_for_page_load_;
427 // Maps each profile (and OTRProfile) to its respective rules registry.
428 std::map<void*, scoped_refptr<extensions::WebRequestRulesRegistry> >
429 rules_registries_;
431 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter);
434 class WebRequestAddEventListener : public SyncIOThreadExtensionFunction {
435 public:
436 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener",
437 WEBREQUESTINTERNAL_ADDEVENTLISTENER)
439 protected:
440 virtual ~WebRequestAddEventListener() {}
442 // ExtensionFunction:
443 virtual bool RunImpl() OVERRIDE;
446 class WebRequestEventHandled : public SyncIOThreadExtensionFunction {
447 public:
448 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled",
449 WEBREQUESTINTERNAL_EVENTHANDLED)
451 protected:
452 virtual ~WebRequestEventHandled() {}
454 // ExtensionFunction:
455 virtual bool RunImpl() OVERRIDE;
458 class WebRequestHandlerBehaviorChangedFunction
459 : public SyncIOThreadExtensionFunction {
460 public:
461 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged",
462 WEBREQUEST_HANDLERBEHAVIORCHANGED)
464 protected:
465 virtual ~WebRequestHandlerBehaviorChangedFunction() {}
467 // ExtensionFunction:
468 virtual void GetQuotaLimitHeuristics(
469 QuotaLimitHeuristics* heuristics) const OVERRIDE;
470 // Handle quota exceeded gracefully: Only warn the user but still execute the
471 // function.
472 virtual void OnQuotaExceeded(const std::string& error) OVERRIDE;
473 virtual bool RunImpl() OVERRIDE;
476 // Send updates to |host| with information about what webRequest-related
477 // extensions are installed.
478 // TODO(mpcomplete): remove. http://crbug.com/100411
479 void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host);
481 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_