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 CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_ 6 #define CHROME_BROWSER_EXTENSIONS_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/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" 29 30 class ExtensionInfoMap; 31 class ExtensionWebRequestTimeTracker; 32 class GURL; 33 34 namespace base { 35 class DictionaryValue; 36 class ListValue; 37 class StringValue; 38 } 39 40 namespace content { 41 class RenderProcessHost; 42 } 43 44 namespace extensions { 45 class WebRequestRulesRegistry; 46 } 47 48 namespace net { 49 class AuthCredentials; 50 class AuthChallengeInfo; 51 class HttpRequestHeaders; 52 class HttpResponseHeaders; 53 class URLRequest; 54 } 55 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; 63 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, 75 }; 76 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(); 82 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); 87 88 extensions::URLPatternSet urls; 89 std::vector<ResourceType::Type> types; 90 int tab_id; 91 int window_id; 92 }; 93 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, 104 }; 105 106 static bool InitFromValue(const base::ListValue& value, 107 int* extra_info_spec); 108 }; 109 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(); 115 116 // ID of the extension that sent this response. 117 std::string extension_id; 118 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; 123 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; 130 131 scoped_ptr<net::AuthCredentials> auth_credentials; 132 133 DISALLOW_COPY_AND_ASSIGN(EventResponse); 134 }; 135 136 static ExtensionWebRequestEventRouter* GetInstance(); 137 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); 143 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); 152 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); 162 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); 169 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); 186 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); 199 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); 206 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); 212 213 // Dispatches the onComplete event. 214 void OnCompleted(void* profile, 215 ExtensionInfoMap* extension_info_map, 216 net::URLRequest* request); 217 218 // Dispatches an onErrorOccurred event. 219 void OnErrorOccurred(void* profile, 220 ExtensionInfoMap* extension_info_map, 221 net::URLRequest* request, 222 bool started); 223 224 // Notifications when objects are going away. 225 void OnURLRequestDestroyed(void* profile, net::URLRequest* request); 226 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); 235 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); 252 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); 258 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 web_view_instance_id); 265 266 // Called when an incognito profile is created or destroyed. 267 void OnOTRProfileCreated(void* original_profile, 268 void* otr_profile); 269 void OnOTRProfileDestroyed(void* original_profile, 270 void* otr_profile); 271 272 // Registers a |callback| that is executed when the next page load happens. 273 // The callback is then deleted. 274 void AddCallbackForPageLoad(const base::Closure& callback); 275 276 private: 277 friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>; 278 279 struct EventListener; 280 typedef std::map<std::string, std::set<EventListener> > ListenerMapForProfile; 281 typedef std::map<void*, ListenerMapForProfile> ListenerMap; 282 typedef std::map<uint64, BlockedRequest> BlockedRequestMap; 283 // Map of request_id -> bit vector of EventTypes already signaled 284 typedef std::map<uint64, int> SignaledRequestMap; 285 // For each profile: a bool indicating whether it is an incognito profile, 286 // and a pointer to the corresponding (non-)incognito profile. 287 typedef std::map<void*, std::pair<bool, void*> > CrossProfileMap; 288 typedef std::list<base::Closure> CallbacksForPageLoad; 289 290 ExtensionWebRequestEventRouter(); 291 ~ExtensionWebRequestEventRouter(); 292 293 // Ensures that future callbacks for |request| are ignored so that it can be 294 // destroyed safely. 295 void ClearPendingCallbacks(net::URLRequest* request); 296 297 bool DispatchEvent( 298 void* profile, 299 net::URLRequest* request, 300 const std::vector<const EventListener*>& listeners, 301 const base::ListValue& args); 302 303 // Returns a list of event listeners that care about the given event, based 304 // on their filter parameters. |extra_info_spec| will contain the combined 305 // set of extra_info_spec flags that every matching listener asked for. 306 std::vector<const EventListener*> GetMatchingListeners( 307 void* profile, 308 ExtensionInfoMap* extension_info_map, 309 const std::string& event_name, 310 net::URLRequest* request, 311 int* extra_info_spec); 312 313 // Helper for the above functions. This is called twice: once for the profile 314 // of the event, the next time for the "cross" profile (i.e. the incognito 315 // profile if the event is originally for the normal profile, or vice versa). 316 void GetMatchingListenersImpl( 317 void* profile, 318 ExtensionInfoMap* extension_info_map, 319 bool crosses_incognito, 320 const std::string& event_name, 321 const GURL& url, 322 int tab_id, 323 int window_id, 324 int render_process_host_id, 325 int routing_id, 326 ResourceType::Type resource_type, 327 bool is_async_request, 328 bool is_request_from_extension, 329 int* extra_info_spec, 330 std::vector<const ExtensionWebRequestEventRouter::EventListener*>* 331 matching_listeners); 332 333 // Decrements the count of event handlers blocking the given request. When the 334 // count reaches 0, we stop blocking the request and proceed it using the 335 // method requested by the extension with the highest precedence. Precedence 336 // is decided by extension install time. If |response| is non-NULL, this 337 // method assumes ownership. 338 void DecrementBlockCount( 339 void* profile, 340 const std::string& extension_id, 341 const std::string& event_name, 342 uint64 request_id, 343 EventResponse* response); 344 345 // Processes the generated deltas from blocked_requests_ on the specified 346 // request. If |call_back| is true, the callback registered in 347 // |blocked_requests_| is called. 348 // The function returns the error code for the network request. This is 349 // mostly relevant in case the caller passes |call_callback| = false 350 // and wants to return the correct network error code himself. 351 int ExecuteDeltas(void* profile, uint64 request_id, bool call_callback); 352 353 // Evaluates the rules of the declarative webrequest API and stores 354 // modifications to the request that result from WebRequestActions as 355 // deltas in |blocked_requests_|. |original_response_headers| should only be 356 // set for the OnHeadersReceived stage and NULL otherwise. Returns whether any 357 // deltas were generated. 358 bool ProcessDeclarativeRules( 359 void* profile, 360 ExtensionInfoMap* extension_info_map, 361 const std::string& event_name, 362 net::URLRequest* request, 363 extensions::RequestStage request_stage, 364 const net::HttpResponseHeaders* original_response_headers); 365 366 // If the BlockedRequest contains messages_to_extension entries in the event 367 // deltas, we send them to subscribers of 368 // chrome.declarativeWebRequest.onMessage. 369 void SendMessages(void* profile, const BlockedRequest& blocked_request); 370 371 // Called when the RulesRegistry is ready to unblock a request that was 372 // waiting for said event. 373 void OnRulesRegistryReady( 374 void* profile, 375 const std::string& event_name, 376 uint64 request_id, 377 extensions::RequestStage request_stage); 378 379 // Sets the flag that |event_type| has been signaled for |request_id|. 380 // Returns the value of the flag before setting it. 381 bool GetAndSetSignaled(uint64 request_id, EventTypes event_type); 382 383 // Clears the flag that |event_type| has been signaled for |request_id|. 384 void ClearSignaled(uint64 request_id, EventTypes event_type); 385 386 // Returns whether |request| represents a top level window navigation. 387 bool IsPageLoad(net::URLRequest* request) const; 388 389 // Called on a page load to process all registered callbacks. 390 void NotifyPageLoad(); 391 392 // Returns the matching cross profile (the regular profile if |profile| is 393 // OTR and vice versa). 394 void* GetCrossProfile(void* profile) const; 395 396 // Determines whether the specified profile is an incognito profile (based on 397 // the contents of the cross-profile table and without dereferencing the 398 // profile pointer). 399 bool IsIncognitoProfile(void* profile) const; 400 401 // Returns true if |request| was already signaled to some event handlers. 402 bool WasSignaled(const net::URLRequest& request) const; 403 404 // A map for each profile that maps an event name to a set of extensions that 405 // are listening to that event. 406 ListenerMap listeners_; 407 408 // A map of network requests that are waiting for at least one event handler 409 // to respond. 410 BlockedRequestMap blocked_requests_; 411 412 // A map of request ids to a bitvector indicating which events have been 413 // signaled and should not be sent again. 414 SignaledRequestMap signaled_requests_; 415 416 // A map of original profile -> corresponding incognito profile (and vice 417 // versa). 418 CrossProfileMap cross_profile_map_; 419 420 // Keeps track of time spent waiting on extensions using the blocking 421 // webRequest API. 422 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_; 423 424 CallbacksForPageLoad callbacks_for_page_load_; 425 426 // Maps each profile (and OTRProfile) to its respective rules registry. 427 std::map<void*, scoped_refptr<extensions::WebRequestRulesRegistry> > 428 rules_registries_; 429 430 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter); 431 }; 432 433 class WebRequestAddEventListener : public SyncIOThreadExtensionFunction { 434 public: 435 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener", 436 WEBREQUESTINTERNAL_ADDEVENTLISTENER) 437 438 protected: 439 virtual ~WebRequestAddEventListener() {} 440 441 // ExtensionFunction: 442 virtual bool RunImpl() OVERRIDE; 443 }; 444 445 class WebRequestEventHandled : public SyncIOThreadExtensionFunction { 446 public: 447 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled", 448 WEBREQUESTINTERNAL_EVENTHANDLED) 449 450 protected: 451 virtual ~WebRequestEventHandled() {} 452 453 // ExtensionFunction: 454 virtual bool RunImpl() OVERRIDE; 455 }; 456 457 class WebRequestHandlerBehaviorChangedFunction 458 : public SyncIOThreadExtensionFunction { 459 public: 460 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged", 461 WEBREQUEST_HANDLERBEHAVIORCHANGED) 462 463 protected: 464 virtual ~WebRequestHandlerBehaviorChangedFunction() {} 465 466 // ExtensionFunction: 467 virtual void GetQuotaLimitHeuristics( 468 QuotaLimitHeuristics* heuristics) const OVERRIDE; 469 // Handle quota exceeded gracefully: Only warn the user but still execute the 470 // function. 471 virtual void OnQuotaExceeded(const std::string& error) OVERRIDE; 472 virtual bool RunImpl() OVERRIDE; 473 }; 474 475 // Send updates to |host| with information about what webRequest-related 476 // extensions are installed. 477 // TODO(mpcomplete): remove. http://crbug.com/100411 478 void SendExtensionWebRequestStatusToHost(content::RenderProcessHost* host); 479 480 #endif // CHROME_BROWSER_EXTENSIONS_API_WEB_REQUEST_WEB_REQUEST_API_H_ 481