Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #ifndef EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ | 5 #ifndef EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ |
| 6 #define EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ | 6 #define EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ |
| 7 | 7 |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <list> | 10 #include <list> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <set> | 12 #include <set> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/gtest_prod_util.h" | |
| 17 #include "base/macros.h" | 18 #include "base/macros.h" |
| 18 #include "base/memory/singleton.h" | 19 #include "base/memory/singleton.h" |
| 19 #include "base/memory/weak_ptr.h" | 20 #include "base/memory/weak_ptr.h" |
| 20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 21 #include "base/time/time.h" | 22 #include "base/time/time.h" |
| 22 #include "content/public/common/resource_type.h" | 23 #include "content/public/common/resource_type.h" |
| 23 #include "extensions/browser/api/declarative/rules_registry.h" | 24 #include "extensions/browser/api/declarative/rules_registry.h" |
| 24 #include "extensions/browser/api/declarative_webrequest/request_stage.h" | 25 #include "extensions/browser/api/declarative_webrequest/request_stage.h" |
| 25 #include "extensions/browser/api/web_request/web_request_api_helpers.h" | 26 #include "extensions/browser/api/web_request/web_request_api_helpers.h" |
| 26 #include "extensions/browser/api/web_request/web_request_permissions.h" | 27 #include "extensions/browser/api/web_request/web_request_permissions.h" |
| (...skipping 259 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 286 const std::string& extension_name, | 287 const std::string& extension_name, |
| 287 events::HistogramValue histogram_value, | 288 events::HistogramValue histogram_value, |
| 288 const std::string& event_name, | 289 const std::string& event_name, |
| 289 const std::string& sub_event_name, | 290 const std::string& sub_event_name, |
| 290 const RequestFilter& filter, | 291 const RequestFilter& filter, |
| 291 int extra_info_spec, | 292 int extra_info_spec, |
| 292 int embedder_process_id, | 293 int embedder_process_id, |
| 293 int web_view_instance_id, | 294 int web_view_instance_id, |
| 294 base::WeakPtr<IPC::Sender> ipc_sender); | 295 base::WeakPtr<IPC::Sender> ipc_sender); |
| 295 | 296 |
| 296 // Removes the listener for the given sub-event. | |
| 297 void RemoveEventListener( | |
| 298 void* browser_context, | |
| 299 const std::string& extension_id, | |
| 300 const std::string& sub_event_name, | |
| 301 int embedder_process_id, | |
| 302 int web_view_instance_id); | |
| 303 | |
| 304 // Removes the listeners for a given <webview>. | 297 // Removes the listeners for a given <webview>. |
| 305 void RemoveWebViewEventListeners( | 298 void RemoveWebViewEventListeners( |
| 306 void* browser_context, | 299 void* browser_context, |
| 307 int embedder_process_id, | 300 int embedder_process_id, |
| 308 int web_view_instance_id); | 301 int web_view_instance_id); |
| 309 | 302 |
| 310 // Called when an incognito browser_context is created or destroyed. | 303 // Called when an incognito browser_context is created or destroyed. |
| 311 void OnOTRBrowserContextCreated(void* original_browser_context, | 304 void OnOTRBrowserContextCreated(void* original_browser_context, |
| 312 void* otr_browser_context); | 305 void* otr_browser_context); |
| 313 void OnOTRBrowserContextDestroyed(void* original_browser_context, | 306 void OnOTRBrowserContextDestroyed(void* original_browser_context, |
| 314 void* otr_browser_context); | 307 void* otr_browser_context); |
| 315 | 308 |
| 316 // Registers a |callback| that is executed when the next page load happens. | 309 // Registers a |callback| that is executed when the next page load happens. |
| 317 // The callback is then deleted. | 310 // The callback is then deleted. |
| 318 void AddCallbackForPageLoad(const base::Closure& callback); | 311 void AddCallbackForPageLoad(const base::Closure& callback); |
| 319 | 312 |
| 320 private: | 313 private: |
| 314 friend class WebRequestAPI; | |
| 315 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, | |
| 316 BlockingEventPrecedenceRedirect); | |
| 317 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, | |
| 318 BlockingEventPrecedenceCancel); | |
| 319 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, | |
| 320 SimulateChancelWhileBlocked); | |
| 321 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, AccessRequestBodyData); | |
| 322 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, | |
| 323 MinimalAccessRequestBodyData); | |
| 324 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, NoAccessRequestBodyData); | |
| 325 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, AddAndRemoveListeners); | |
| 326 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestTest, BlockedRequestsAreRemoved); | |
| 327 FRIEND_TEST_ALL_PREFIXES(ExtensionWebRequestHeaderModificationTest, | |
| 328 TestModifications); | |
| 329 | |
| 330 struct EventListener { | |
| 331 // An EventListener is uniquely defined by five properties. | |
|
Devlin
2016/09/07 19:18:00
This isn't strictly true, right? We potentially h
erikchen
2016/09/07 22:07:43
Two responses:
1) This comment was based on my int
Devlin
2016/09/08 17:33:12
Yep, that and others are why I was scared. :)
erikchen
2016/09/08 18:34:41
I added a long TODO & comment. We still need to us
| |
| 332 struct Identifier { | |
| 333 Identifier(void* browser_context, | |
| 334 const std::string& extension_id, | |
| 335 const std::string& sub_event_name, | |
| 336 int embedder_process_id, | |
| 337 int web_view_instance_id) | |
| 338 : browser_context(browser_context), | |
|
Devlin
2016/09/07 19:18:00
nit: these methods should probably be defined in t
erikchen
2016/09/07 22:07:43
Done.
| |
| 339 extension_id(extension_id), | |
| 340 sub_event_name(sub_event_name), | |
| 341 embedder_process_id(embedder_process_id), | |
| 342 web_view_instance_id(web_view_instance_id) {} | |
| 343 | |
| 344 // If web_view_instance_id is 0, then ignore embedder_process_id. | |
| 345 bool LooselyMatches(const Identifier& that) const { | |
|
Devlin
2016/09/07 19:18:00
Is there a time we don't want to do this? i.e., w
erikchen
2016/09/07 22:07:43
We can't use operator== everywhere because we aren
Devlin
2016/09/08 17:33:12
Ah, I see. This is annoying. Can we add another
erikchen
2016/09/08 18:34:42
Added a TODO.
| |
| 346 if (web_view_instance_id == 0 && that.web_view_instance_id == 0) { | |
| 347 // Since EventListeners are segmented by browser_context, check that | |
| 348 // last, as it is exceedingly unlikely to be different. | |
| 349 return extension_id == that.extension_id && | |
| 350 sub_event_name == that.sub_event_name && | |
| 351 browser_context == that.browser_context; | |
| 352 } | |
| 353 | |
| 354 return *this == that; | |
| 355 } | |
| 356 | |
| 357 bool operator==(const Identifier& that) const { | |
| 358 // Since EventListeners are segmented by browser_context, check that | |
| 359 // last, as it is exceedingly unlikely to be different. | |
| 360 return extension_id == that.extension_id && | |
| 361 sub_event_name == that.sub_event_name && | |
| 362 web_view_instance_id == that.web_view_instance_id && | |
| 363 embedder_process_id == that.embedder_process_id && | |
| 364 browser_context == that.browser_context; | |
| 365 } | |
| 366 | |
| 367 void* browser_context; | |
| 368 std::string extension_id; | |
| 369 std::string sub_event_name; | |
| 370 int embedder_process_id; | |
| 371 int web_view_instance_id; | |
| 372 }; | |
| 373 | |
| 374 EventListener(Identifier id); | |
| 375 ~EventListener(); | |
| 376 | |
| 377 const Identifier id; | |
| 378 std::string extension_name; | |
| 379 events::HistogramValue histogram_value = events::UNKNOWN; | |
| 380 RequestFilter filter; | |
| 381 int extra_info_spec = 0; | |
| 382 base::WeakPtr<IPC::Sender> ipc_sender; | |
| 383 std::unordered_set<uint64_t> blocked_requests; | |
| 384 | |
| 385 private: | |
| 386 friend class WebRequestAPI; | |
|
Devlin
2016/09/07 19:18:00
Why does the WebRequestAPI need to be able to copy
erikchen
2016/09/07 22:07:43
Removed.
| |
| 387 DISALLOW_COPY_AND_ASSIGN(EventListener); | |
| 388 }; | |
| 389 | |
| 321 friend struct base::DefaultSingletonTraits<ExtensionWebRequestEventRouter>; | 390 friend struct base::DefaultSingletonTraits<ExtensionWebRequestEventRouter>; |
| 322 | 391 |
| 323 struct EventListener; | 392 using ListenerIdentifiers = std::vector<EventListener::Identifier>; |
| 324 using EventListeners = std::vector<const EventListener*>; | 393 using Listeners = std::vector<std::unique_ptr<EventListener>>; |
| 325 using ListenerMapForBrowserContext = | 394 using ListenerMapForBrowserContext = std::map<std::string, Listeners>; |
| 326 std::map<std::string, std::set<EventListener>>; | |
| 327 using ListenerMap = std::map<void*, ListenerMapForBrowserContext>; | 395 using ListenerMap = std::map<void*, ListenerMapForBrowserContext>; |
| 328 using BlockedRequestMap = std::map<uint64_t, BlockedRequest>; | 396 using BlockedRequestMap = std::map<uint64_t, BlockedRequest>; |
| 329 // Map of request_id -> bit vector of EventTypes already signaled | 397 // Map of request_id -> bit vector of EventTypes already signaled |
| 330 using SignaledRequestMap = std::map<uint64_t, int>; | 398 using SignaledRequestMap = std::map<uint64_t, int>; |
| 331 // For each browser_context: a bool indicating whether it is an incognito | 399 // For each browser_context: a bool indicating whether it is an incognito |
| 332 // browser_context, and a pointer to the corresponding (non-)incognito | 400 // browser_context, and a pointer to the corresponding (non-)incognito |
| 333 // browser_context. | 401 // browser_context. |
| 334 using CrossBrowserContextMap = std::map<void*, std::pair<bool, void*>>; | 402 using CrossBrowserContextMap = std::map<void*, std::pair<bool, void*>>; |
| 335 using CallbacksForPageLoad = std::list<base::Closure>; | 403 using CallbacksForPageLoad = std::list<base::Closure>; |
| 336 | 404 |
| 337 ExtensionWebRequestEventRouter(); | 405 ExtensionWebRequestEventRouter(); |
| 338 ~ExtensionWebRequestEventRouter(); | 406 ~ExtensionWebRequestEventRouter(); |
| 339 | 407 |
| 408 // Returns the EventListener with the given |id|, or nullptr. Must be called | |
| 409 // from the IO thread. | |
| 410 EventListener* FindEventListener(const EventListener::Identifier& id); | |
| 411 | |
| 412 // Removes the listener for the given sub-event. Must be called from the IO | |
| 413 // thread. | |
| 414 void RemoveEventListener(const EventListener::Identifier& id); | |
| 415 | |
| 340 // Ensures that future callbacks for |request| are ignored so that it can be | 416 // Ensures that future callbacks for |request| are ignored so that it can be |
| 341 // destroyed safely. | 417 // destroyed safely. |
| 342 void ClearPendingCallbacks(const net::URLRequest* request); | 418 void ClearPendingCallbacks(const net::URLRequest* request); |
| 343 | 419 |
| 344 bool DispatchEvent(void* browser_context, | 420 bool DispatchEvent(void* browser_context, |
| 345 net::URLRequest* request, | 421 net::URLRequest* request, |
| 346 const std::vector<const EventListener*>& listeners, | 422 const ListenerIdentifiers& listener_ids, |
| 347 std::unique_ptr<WebRequestEventDetails> event_details); | 423 std::unique_ptr<WebRequestEventDetails> event_details); |
| 348 | 424 |
| 349 void DispatchEventToListeners( | 425 void DispatchEventToListeners( |
| 350 void* browser_context, | 426 void* browser_context, |
| 351 std::unique_ptr<std::vector<EventListener>> listeners, | 427 const ListenerIdentifiers& listener_ids, |
| 352 std::unique_ptr<WebRequestEventDetails> event_details); | 428 std::unique_ptr<WebRequestEventDetails> event_details); |
| 353 | 429 |
| 354 // Returns a list of event listeners that care about the given event, based | 430 // Returns a list of event listeners that care about the given event, based |
| 355 // on their filter parameters. |extra_info_spec| will contain the combined | 431 // on their filter parameters. |extra_info_spec| will contain the combined |
| 356 // set of extra_info_spec flags that every matching listener asked for. | 432 // set of extra_info_spec flags that every matching listener asked for. |
| 357 std::vector<const EventListener*> GetMatchingListeners( | 433 ListenerIdentifiers GetMatchingListeners( |
| 358 void* browser_context, | 434 void* browser_context, |
| 359 const extensions::InfoMap* extension_info_map, | 435 const extensions::InfoMap* extension_info_map, |
| 360 const std::string& event_name, | 436 const std::string& event_name, |
| 361 const net::URLRequest* request, | 437 const net::URLRequest* request, |
| 362 int* extra_info_spec); | 438 int* extra_info_spec); |
| 363 | 439 |
| 364 // Helper for the above functions. This is called twice: once for the | 440 // Helper for the above functions. This is called twice: once for the |
| 365 // browser_context of the event, the next time for the "cross" browser_context | 441 // browser_context of the event, the next time for the "cross" browser_context |
| 366 // (i.e. the incognito browser_context if the event is originally for the | 442 // (i.e. the incognito browser_context if the event is originally for the |
| 367 // normal browser_context, or vice versa). | 443 // normal browser_context, or vice versa). |
| 368 void GetMatchingListenersImpl( | 444 void GetMatchingListenersImpl(void* browser_context, |
| 369 void* browser_context, | 445 const net::URLRequest* request, |
| 370 const net::URLRequest* request, | 446 const extensions::InfoMap* extension_info_map, |
| 371 const extensions::InfoMap* extension_info_map, | 447 bool crosses_incognito, |
| 372 bool crosses_incognito, | 448 const std::string& event_name, |
| 373 const std::string& event_name, | 449 const GURL& url, |
| 374 const GURL& url, | 450 int render_process_host_id, |
| 375 int render_process_host_id, | 451 int routing_id, |
| 376 int routing_id, | 452 content::ResourceType resource_type, |
| 377 content::ResourceType resource_type, | 453 bool is_async_request, |
| 378 bool is_async_request, | 454 bool is_request_from_extension, |
| 379 bool is_request_from_extension, | 455 int* extra_info_spec, |
| 380 int* extra_info_spec, | 456 ListenerIdentifiers* matching_listeners); |
| 381 std::vector<const EventListener*>* matching_listeners); | |
| 382 | 457 |
| 383 // Decrements the count of event handlers blocking the given request. When the | 458 // Decrements the count of event handlers blocking the given request. When the |
| 384 // count reaches 0, we stop blocking the request and proceed it using the | 459 // count reaches 0, we stop blocking the request and proceed it using the |
| 385 // method requested by the extension with the highest precedence. Precedence | 460 // method requested by the extension with the highest precedence. Precedence |
| 386 // is decided by extension install time. If |response| is non-NULL, this | 461 // is decided by extension install time. If |response| is non-NULL, this |
| 387 // method assumes ownership. | 462 // method assumes ownership. |
| 388 void DecrementBlockCount(void* browser_context, | 463 void DecrementBlockCount(void* browser_context, |
| 389 const std::string& extension_id, | 464 const std::string& extension_id, |
| 390 const std::string& event_name, | 465 const std::string& event_name, |
| 391 uint64_t request_id, | 466 uint64_t request_id, |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 450 void* GetCrossBrowserContext(void* browser_context) const; | 525 void* GetCrossBrowserContext(void* browser_context) const; |
| 451 | 526 |
| 452 // Determines whether the specified browser_context is an incognito | 527 // Determines whether the specified browser_context is an incognito |
| 453 // browser_context (based on the contents of the cross-browser_context table | 528 // browser_context (based on the contents of the cross-browser_context table |
| 454 // and without dereferencing the browser_context pointer). | 529 // and without dereferencing the browser_context pointer). |
| 455 bool IsIncognitoBrowserContext(void* browser_context) const; | 530 bool IsIncognitoBrowserContext(void* browser_context) const; |
| 456 | 531 |
| 457 // Returns true if |request| was already signaled to some event handlers. | 532 // Returns true if |request| was already signaled to some event handlers. |
| 458 bool WasSignaled(const net::URLRequest& request) const; | 533 bool WasSignaled(const net::URLRequest& request) const; |
| 459 | 534 |
| 535 // Get the number of listeners - for testing only. | |
| 536 size_t GetListenerCountForTesting(void* browser_context, | |
| 537 const std::string& event_name); | |
| 538 | |
| 460 // A map for each browser_context that maps an event name to a set of | 539 // A map for each browser_context that maps an event name to a set of |
| 461 // extensions that are listening to that event. | 540 // extensions that are listening to that event. |
| 462 ListenerMap listeners_; | 541 ListenerMap listeners_; |
| 463 | 542 |
| 464 // A map of network requests that are waiting for at least one event handler | 543 // A map of network requests that are waiting for at least one event handler |
| 465 // to respond. | 544 // to respond. |
| 466 BlockedRequestMap blocked_requests_; | 545 BlockedRequestMap blocked_requests_; |
| 467 | 546 |
| 468 // A map of request ids to a bitvector indicating which events have been | 547 // A map of request ids to a bitvector indicating which events have been |
| 469 // signaled and should not be sent again. | 548 // signaled and should not be sent again. |
| (...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 553 extensions::QuotaLimitHeuristics* heuristics) const override; | 632 extensions::QuotaLimitHeuristics* heuristics) const override; |
| 554 // Handle quota exceeded gracefully: Only warn the user but still execute the | 633 // Handle quota exceeded gracefully: Only warn the user but still execute the |
| 555 // function. | 634 // function. |
| 556 void OnQuotaExceeded(const std::string& error) override; | 635 void OnQuotaExceeded(const std::string& error) override; |
| 557 ResponseAction Run() override; | 636 ResponseAction Run() override; |
| 558 }; | 637 }; |
| 559 | 638 |
| 560 } // namespace extensions | 639 } // namespace extensions |
| 561 | 640 |
| 562 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ | 641 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ |
| OLD | NEW |