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 EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ 6 #define EXTENSIONS_BROWSER_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 "content/public/common/resource_type.h" 18 #include "extensions/browser/api/declarative/rules_registry.h" 19 #include "extensions/browser/api/declarative_webrequest/request_stage.h" 20 #include "extensions/browser/api/web_request/web_request_api_helpers.h" 21 #include "extensions/browser/api/web_request/web_request_permissions.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" 30 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 BrowserContext; 42 } 43 44 namespace net { 45 class AuthCredentials; 46 class AuthChallengeInfo; 47 class HttpRequestHeaders; 48 class HttpResponseHeaders; 49 class URLRequest; 50 } 51 52 namespace extensions { 53 54 class InfoMap; 55 class WebRequestRulesRegistry; 56 class WebRequestEventRouterDelegate; 57 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 { 64 public: 65 explicit WebRequestAPI(content::BrowserContext* context); 66 virtual ~WebRequestAPI(); 67 68 // BrowserContextKeyedAPI support: 69 static BrowserContextKeyedAPIFactory<WebRequestAPI>* GetFactoryInstance(); 70 71 // EventRouter::Observer overrides: 72 virtual void OnListenerRemoved(const EventListenerInfo& details) OVERRIDE; 73 74 private: 75 friend class BrowserContextKeyedAPIFactory<WebRequestAPI>; 76 77 // BrowserContextKeyedAPI support: 78 static const char* service_name() { return "WebRequestAPI"; } 79 static const bool kServiceRedirectedInIncognito = true; 80 static const bool kServiceIsNULLWhileTesting = true; 81 82 content::BrowserContext* browser_context_; 83 84 DISALLOW_COPY_AND_ASSIGN(WebRequestAPI); 85 }; 86 87 } // namespace extensions 88 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; 96 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, 108 }; 109 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(); 115 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); 120 121 extensions::URLPatternSet urls; 122 std::vector<content::ResourceType> types; 123 int tab_id; 124 int window_id; 125 }; 126 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, 137 }; 138 139 static bool InitFromValue(const base::ListValue& value, 140 int* extra_info_spec); 141 }; 142 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(); 148 149 // ID of the extension that sent this response. 150 std::string extension_id; 151 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; 156 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; 163 164 scoped_ptr<net::AuthCredentials> auth_credentials; 165 166 DISALLOW_COPY_AND_ASSIGN(EventResponse); 167 }; 168 169 static ExtensionWebRequestEventRouter* GetInstance(); 170 171 // Registers a rule registry. Pass null for |rules_registry| to unregister 172 // the rule registry for |browser_context|. 173 void RegisterRulesRegistry( 174 void* browser_context, 175 const extensions::RulesRegistry::WebViewKey& webview_key, 176 scoped_refptr<extensions::WebRequestRulesRegistry> rules_registry); 177 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* browser_context, 182 extensions::InfoMap* extension_info_map, 183 net::URLRequest* request, 184 const net::CompletionCallback& callback, 185 GURL* new_url); 186 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 190 // otherwise. 191 int OnBeforeSendHeaders(void* browser_context, 192 extensions::InfoMap* extension_info_map, 193 net::URLRequest* request, 194 const net::CompletionCallback& callback, 195 net::HttpRequestHeaders* headers); 196 197 // Dispatches the onSendHeaders event. This is fired for HTTP(s) requests 198 // only. 199 void OnSendHeaders(void* browser_context, 200 extensions::InfoMap* extension_info_map, 201 net::URLRequest* request, 202 const net::HttpRequestHeaders& headers); 203 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( 214 void* browser_context, 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); 221 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 226 // invoked later. 227 net::NetworkDelegate::AuthRequiredResponse OnAuthRequired( 228 void* browser_context, 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); 234 235 // Dispatches the onBeforeRedirect event. This is fired for HTTP(s) requests 236 // only. 237 void OnBeforeRedirect(void* browser_context, 238 extensions::InfoMap* extension_info_map, 239 net::URLRequest* request, 240 const GURL& new_location); 241 242 // Dispatches the onResponseStarted event indicating that the first bytes of 243 // the response have arrived. 244 void OnResponseStarted(void* browser_context, 245 extensions::InfoMap* extension_info_map, 246 net::URLRequest* request); 247 248 // Dispatches the onComplete event. 249 void OnCompleted(void* browser_context, 250 extensions::InfoMap* extension_info_map, 251 net::URLRequest* request); 252 253 // Dispatches an onErrorOccurred event. 254 void OnErrorOccurred(void* browser_context, 255 extensions::InfoMap* extension_info_map, 256 net::URLRequest* request, 257 bool started); 258 259 // Notifications when objects are going away. 260 void OnURLRequestDestroyed(void* browser_context, net::URLRequest* request); 261 262 // Called when an event listener handles a blocking event and responds. 263 void OnEventHandled( 264 void* browser_context, 265 const std::string& extension_id, 266 const std::string& event_name, 267 const std::string& sub_event_name, 268 uint64 request_id, 269 EventResponse* response); 270 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( 276 void* browser_context, 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, 282 int extra_info_spec, 283 int embedder_process_id, 284 int web_view_instance_id, 285 base::WeakPtr<IPC::Sender> ipc_sender); 286 287 // Removes the listener for the given sub-event. 288 void RemoveEventListener( 289 void* browser_context, 290 const std::string& extension_id, 291 const std::string& sub_event_name); 292 293 // Removes the listeners for a given <webview>. 294 void RemoveWebViewEventListeners( 295 void* browser_context, 296 const std::string& extension_id, 297 int embedder_process_id, 298 int web_view_instance_id); 299 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); 305 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); 309 310 private: 311 friend struct DefaultSingletonTraits<ExtensionWebRequestEventRouter>; 312 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; 325 326 ExtensionWebRequestEventRouter(); 327 ~ExtensionWebRequestEventRouter(); 328 329 // Ensures that future callbacks for |request| are ignored so that it can be 330 // destroyed safely. 331 void ClearPendingCallbacks(net::URLRequest* request); 332 333 bool DispatchEvent( 334 void* browser_context, 335 net::URLRequest* request, 336 const std::vector<const EventListener*>& listeners, 337 const base::ListValue& args); 338 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); 348 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); 368 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); 380 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); 389 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); 398 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); 411 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); 417 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); 425 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); 430 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); 434 435 // Clears the flag that |event_type| has been signaled for |request_id|. 436 void ClearSignaled(uint64 request_id, EventTypes event_type); 437 438 // Returns whether |request| represents a top level window navigation. 439 bool IsPageLoad(net::URLRequest* request) const; 440 441 // Called on a page load to process all registered callbacks. 442 void NotifyPageLoad(); 443 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; 447 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; 452 453 // Returns true if |request| was already signaled to some event handlers. 454 bool WasSignaled(const net::URLRequest& request) const; 455 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_; 459 460 // A map of network requests that are waiting for at least one event handler 461 // to respond. 462 BlockedRequestMap blocked_requests_; 463 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_; 467 468 // A map of original browser_context -> corresponding incognito 469 // browser_context (and vice versa). 470 CrossBrowserContextMap cross_browser_context_map_; 471 472 // Keeps track of time spent waiting on extensions using the blocking 473 // webRequest API. 474 scoped_ptr<ExtensionWebRequestTimeTracker> request_time_tracker_; 475 476 CallbacksForPageLoad callbacks_for_page_load_; 477 478 typedef std::pair<void*, extensions::RulesRegistry::WebViewKey> 479 RulesRegistryKey; 480 // Maps each browser_context (and OTRBrowserContext) and a webview key to its 481 // respective rules registry. 482 std::map<RulesRegistryKey, 483 scoped_refptr<extensions::WebRequestRulesRegistry> > rules_registries_; 484 485 scoped_ptr<extensions::WebRequestEventRouterDelegate> 486 web_request_event_router_delegate_; 487 488 DISALLOW_COPY_AND_ASSIGN(ExtensionWebRequestEventRouter); 489 }; 490 491 class WebRequestInternalAddEventListenerFunction 492 : public SyncIOThreadExtensionFunction { 493 public: 494 DECLARE_EXTENSION_FUNCTION("webRequestInternal.addEventListener", 495 WEBREQUESTINTERNAL_ADDEVENTLISTENER) 496 497 protected: 498 virtual ~WebRequestInternalAddEventListenerFunction() {} 499 500 // ExtensionFunction: 501 virtual bool RunSync() OVERRIDE; 502 }; 503 504 class WebRequestInternalEventHandledFunction 505 : public SyncIOThreadExtensionFunction { 506 public: 507 DECLARE_EXTENSION_FUNCTION("webRequestInternal.eventHandled", 508 WEBREQUESTINTERNAL_EVENTHANDLED) 509 510 protected: 511 virtual ~WebRequestInternalEventHandledFunction() {} 512 513 // Unblocks the network request and sets |error_| such that the developer 514 // console will show the respective error message. Use this function to handle 515 // incorrect requests from the extension that cannot be detected by the schema 516 // validator. 517 void RespondWithError( 518 const std::string& event_name, 519 const std::string& sub_event_name, 520 uint64 request_id, 521 scoped_ptr<ExtensionWebRequestEventRouter::EventResponse> response, 522 const std::string& error); 523 524 // ExtensionFunction: 525 virtual bool RunSync() OVERRIDE; 526 }; 527 528 class WebRequestHandlerBehaviorChangedFunction 529 : public SyncIOThreadExtensionFunction { 530 public: 531 DECLARE_EXTENSION_FUNCTION("webRequest.handlerBehaviorChanged", 532 WEBREQUEST_HANDLERBEHAVIORCHANGED) 533 534 protected: 535 virtual ~WebRequestHandlerBehaviorChangedFunction() {} 536 537 // ExtensionFunction: 538 virtual void GetQuotaLimitHeuristics( 539 extensions::QuotaLimitHeuristics* heuristics) const OVERRIDE; 540 // Handle quota exceeded gracefully: Only warn the user but still execute the 541 // function. 542 virtual void OnQuotaExceeded(const std::string& error) OVERRIDE; 543 virtual bool RunSync() OVERRIDE; 544 }; 545 546 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ 547