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. |
| 332 // TODO(rdevlin.cronin): There are two types of EventListeners - those |
| 333 // associated with WebViews and those that are not. The ones associated with |
| 334 // WebViews are always identified by all five properties. The other ones |
| 335 // will always have web_view_instance_id = 0. Unfortunately, the |
| 336 // callbacks/interfaces for these ones don't specify embedder_process_id. |
| 337 // This is why we need the LooselyMatches method, and the need for a |
| 338 // |strict| argument on RemoveEventListener. |
| 339 struct ID { |
| 340 ID(void* browser_context, |
| 341 const std::string& extension_id, |
| 342 const std::string& sub_event_name, |
| 343 int embedder_process_id, |
| 344 int web_view_instance_id); |
| 345 |
| 346 // If web_view_instance_id is 0, then ignore embedder_process_id. |
| 347 // TODO(rdevlin.cronin): In a more sane world, LooselyMatches wouldn't be |
| 348 // necessary. |
| 349 bool LooselyMatches(const ID& that) const; |
| 350 |
| 351 bool operator==(const ID& that) const; |
| 352 void* browser_context; |
| 353 std::string extension_id; |
| 354 std::string sub_event_name; |
| 355 int embedder_process_id; |
| 356 int web_view_instance_id; |
| 357 }; |
| 358 |
| 359 EventListener(ID id); |
| 360 ~EventListener(); |
| 361 |
| 362 const ID id; |
| 363 std::string extension_name; |
| 364 events::HistogramValue histogram_value = events::UNKNOWN; |
| 365 RequestFilter filter; |
| 366 int extra_info_spec = 0; |
| 367 base::WeakPtr<IPC::Sender> ipc_sender; |
| 368 std::unordered_set<uint64_t> blocked_requests; |
| 369 |
| 370 private: |
| 371 DISALLOW_COPY_AND_ASSIGN(EventListener); |
| 372 }; |
| 373 |
321 friend struct base::DefaultSingletonTraits<ExtensionWebRequestEventRouter>; | 374 friend struct base::DefaultSingletonTraits<ExtensionWebRequestEventRouter>; |
322 | 375 |
323 struct EventListener; | 376 using RawListeners = std::vector<EventListener*>; |
324 using EventListeners = std::vector<const EventListener*>; | 377 using ListenerIDs = std::vector<EventListener::ID>; |
325 using ListenerMapForBrowserContext = | 378 using Listeners = std::vector<std::unique_ptr<EventListener>>; |
326 std::map<std::string, std::set<EventListener>>; | 379 using ListenerMapForBrowserContext = std::map<std::string, Listeners>; |
327 using ListenerMap = std::map<void*, ListenerMapForBrowserContext>; | 380 using ListenerMap = std::map<void*, ListenerMapForBrowserContext>; |
328 using BlockedRequestMap = std::map<uint64_t, BlockedRequest>; | 381 using BlockedRequestMap = std::map<uint64_t, BlockedRequest>; |
329 // Map of request_id -> bit vector of EventTypes already signaled | 382 // Map of request_id -> bit vector of EventTypes already signaled |
330 using SignaledRequestMap = std::map<uint64_t, int>; | 383 using SignaledRequestMap = std::map<uint64_t, int>; |
331 // For each browser_context: a bool indicating whether it is an incognito | 384 // For each browser_context: a bool indicating whether it is an incognito |
332 // browser_context, and a pointer to the corresponding (non-)incognito | 385 // browser_context, and a pointer to the corresponding (non-)incognito |
333 // browser_context. | 386 // browser_context. |
334 using CrossBrowserContextMap = std::map<void*, std::pair<bool, void*>>; | 387 using CrossBrowserContextMap = std::map<void*, std::pair<bool, void*>>; |
335 using CallbacksForPageLoad = std::list<base::Closure>; | 388 using CallbacksForPageLoad = std::list<base::Closure>; |
336 | 389 |
337 ExtensionWebRequestEventRouter(); | 390 ExtensionWebRequestEventRouter(); |
338 ~ExtensionWebRequestEventRouter(); | 391 ~ExtensionWebRequestEventRouter(); |
339 | 392 |
| 393 // Returns the EventListener with the given |id|, or nullptr. Must be called |
| 394 // from the IO thread. |
| 395 EventListener* FindEventListener(const EventListener::ID& id); |
| 396 |
| 397 // Returns the EventListener with the given |id| from |listeners|. |
| 398 EventListener* FindEventListenerInContainer(const EventListener::ID& id, |
| 399 Listeners& listeners); |
| 400 |
| 401 // Removes the listener for the given sub-event. Must be called from the IO |
| 402 // thread. |
| 403 void RemoveEventListener(const EventListener::ID& id, bool strict); |
| 404 |
340 // Ensures that future callbacks for |request| are ignored so that it can be | 405 // Ensures that future callbacks for |request| are ignored so that it can be |
341 // destroyed safely. | 406 // destroyed safely. |
342 void ClearPendingCallbacks(const net::URLRequest* request); | 407 void ClearPendingCallbacks(const net::URLRequest* request); |
343 | 408 |
344 bool DispatchEvent(void* browser_context, | 409 bool DispatchEvent(void* browser_context, |
345 net::URLRequest* request, | 410 net::URLRequest* request, |
346 const std::vector<const EventListener*>& listeners, | 411 const RawListeners& listener_ids, |
347 std::unique_ptr<WebRequestEventDetails> event_details); | 412 std::unique_ptr<WebRequestEventDetails> event_details); |
348 | 413 |
349 void DispatchEventToListeners( | 414 void DispatchEventToListeners( |
350 void* browser_context, | 415 void* browser_context, |
351 std::unique_ptr<std::vector<EventListener>> listeners, | 416 std::unique_ptr<ListenerIDs> listener_ids, |
352 std::unique_ptr<WebRequestEventDetails> event_details); | 417 std::unique_ptr<WebRequestEventDetails> event_details); |
353 | 418 |
354 // Returns a list of event listeners that care about the given event, based | 419 // 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 | 420 // on their filter parameters. |extra_info_spec| will contain the combined |
356 // set of extra_info_spec flags that every matching listener asked for. | 421 // set of extra_info_spec flags that every matching listener asked for. |
357 std::vector<const EventListener*> GetMatchingListeners( | 422 RawListeners GetMatchingListeners( |
358 void* browser_context, | 423 void* browser_context, |
359 const extensions::InfoMap* extension_info_map, | 424 const extensions::InfoMap* extension_info_map, |
360 const std::string& event_name, | 425 const std::string& event_name, |
361 const net::URLRequest* request, | 426 const net::URLRequest* request, |
362 int* extra_info_spec); | 427 int* extra_info_spec); |
363 | 428 |
364 // Helper for the above functions. This is called twice: once for the | 429 // 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 | 430 // 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 | 431 // (i.e. the incognito browser_context if the event is originally for the |
367 // normal browser_context, or vice versa). | 432 // normal browser_context, or vice versa). |
368 void GetMatchingListenersImpl( | 433 void GetMatchingListenersImpl(void* browser_context, |
369 void* browser_context, | 434 const net::URLRequest* request, |
370 const net::URLRequest* request, | 435 const extensions::InfoMap* extension_info_map, |
371 const extensions::InfoMap* extension_info_map, | 436 bool crosses_incognito, |
372 bool crosses_incognito, | 437 const std::string& event_name, |
373 const std::string& event_name, | 438 const GURL& url, |
374 const GURL& url, | 439 int render_process_host_id, |
375 int render_process_host_id, | 440 int routing_id, |
376 int routing_id, | 441 content::ResourceType resource_type, |
377 content::ResourceType resource_type, | 442 bool is_async_request, |
378 bool is_async_request, | 443 bool is_request_from_extension, |
379 bool is_request_from_extension, | 444 int* extra_info_spec, |
380 int* extra_info_spec, | 445 RawListeners* matching_listeners); |
381 std::vector<const EventListener*>* matching_listeners); | |
382 | 446 |
383 // Decrements the count of event handlers blocking the given request. When the | 447 // 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 | 448 // count reaches 0, we stop blocking the request and proceed it using the |
385 // method requested by the extension with the highest precedence. Precedence | 449 // method requested by the extension with the highest precedence. Precedence |
386 // is decided by extension install time. If |response| is non-NULL, this | 450 // is decided by extension install time. If |response| is non-NULL, this |
387 // method assumes ownership. | 451 // method assumes ownership. |
388 void DecrementBlockCount(void* browser_context, | 452 void DecrementBlockCount(void* browser_context, |
389 const std::string& extension_id, | 453 const std::string& extension_id, |
390 const std::string& event_name, | 454 const std::string& event_name, |
391 uint64_t request_id, | 455 uint64_t request_id, |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
450 void* GetCrossBrowserContext(void* browser_context) const; | 514 void* GetCrossBrowserContext(void* browser_context) const; |
451 | 515 |
452 // Determines whether the specified browser_context is an incognito | 516 // Determines whether the specified browser_context is an incognito |
453 // browser_context (based on the contents of the cross-browser_context table | 517 // browser_context (based on the contents of the cross-browser_context table |
454 // and without dereferencing the browser_context pointer). | 518 // and without dereferencing the browser_context pointer). |
455 bool IsIncognitoBrowserContext(void* browser_context) const; | 519 bool IsIncognitoBrowserContext(void* browser_context) const; |
456 | 520 |
457 // Returns true if |request| was already signaled to some event handlers. | 521 // Returns true if |request| was already signaled to some event handlers. |
458 bool WasSignaled(const net::URLRequest& request) const; | 522 bool WasSignaled(const net::URLRequest& request) const; |
459 | 523 |
| 524 // Get the number of listeners - for testing only. |
| 525 size_t GetListenerCountForTesting(void* browser_context, |
| 526 const std::string& event_name); |
| 527 |
460 // A map for each browser_context that maps an event name to a set of | 528 // A map for each browser_context that maps an event name to a set of |
461 // extensions that are listening to that event. | 529 // extensions that are listening to that event. |
462 ListenerMap listeners_; | 530 ListenerMap listeners_; |
463 | 531 |
464 // A map of network requests that are waiting for at least one event handler | 532 // A map of network requests that are waiting for at least one event handler |
465 // to respond. | 533 // to respond. |
466 BlockedRequestMap blocked_requests_; | 534 BlockedRequestMap blocked_requests_; |
467 | 535 |
468 // A map of request ids to a bitvector indicating which events have been | 536 // A map of request ids to a bitvector indicating which events have been |
469 // signaled and should not be sent again. | 537 // 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; | 621 extensions::QuotaLimitHeuristics* heuristics) const override; |
554 // Handle quota exceeded gracefully: Only warn the user but still execute the | 622 // Handle quota exceeded gracefully: Only warn the user but still execute the |
555 // function. | 623 // function. |
556 void OnQuotaExceeded(const std::string& error) override; | 624 void OnQuotaExceeded(const std::string& error) override; |
557 ResponseAction Run() override; | 625 ResponseAction Run() override; |
558 }; | 626 }; |
559 | 627 |
560 } // namespace extensions | 628 } // namespace extensions |
561 | 629 |
562 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ | 630 #endif // EXTENSIONS_BROWSER_API_WEB_REQUEST_WEB_REQUEST_API_H_ |
OLD | NEW |