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 |