cookie_monster_change_dispatcher.h 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. // Copyright 2018 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. #ifndef NET_COOKIES_COOKIE_MONSTER_CHANGE_DISPATCHER_H_
  5. #define NET_COOKIES_COOKIE_MONSTER_CHANGE_DISPATCHER_H_
  6. #include <map>
  7. #include <memory>
  8. #include <string>
  9. #include "base/callback.h"
  10. #include "base/callback_list.h"
  11. #include "base/containers/linked_list.h"
  12. #include "base/memory/raw_ptr.h"
  13. #include "base/memory/scoped_refptr.h"
  14. #include "base/memory/weak_ptr.h"
  15. #include "base/task/single_thread_task_runner.h"
  16. #include "base/threading/thread_checker.h"
  17. #include "net/cookies/cookie_change_dispatcher.h"
  18. #include "url/gurl.h"
  19. namespace net {
  20. class CookieAccessDelegate;
  21. class CookieMonster;
  22. // CookieChangeDispatcher implementation used by CookieMonster.
  23. class CookieMonsterChangeDispatcher : public CookieChangeDispatcher {
  24. public:
  25. using CookieChangeCallbackList =
  26. base::RepeatingCallbackList<void(const CookieChangeInfo&)>;
  27. // Expects |cookie_monster| to outlive this.
  28. CookieMonsterChangeDispatcher(const CookieMonster* cookie_monster,
  29. bool first_party_sets_enabled);
  30. CookieMonsterChangeDispatcher(const CookieMonsterChangeDispatcher&) = delete;
  31. CookieMonsterChangeDispatcher& operator=(
  32. const CookieMonsterChangeDispatcher&) = delete;
  33. ~CookieMonsterChangeDispatcher() override;
  34. // The key in CookieNameMap for a cookie name.
  35. static std::string NameKey(std::string name);
  36. // The key in CookieDomainName for a cookie domain.
  37. static std::string DomainKey(const std::string& domain);
  38. // The key in CookieDomainName for a listener URL.
  39. static std::string DomainKey(const GURL& url);
  40. // net::CookieChangeDispatcher
  41. [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForCookie(
  42. const GURL& url,
  43. const std::string& name,
  44. const absl::optional<CookiePartitionKey>& cookie_partition_key,
  45. CookieChangeCallback callback) override;
  46. [[nodiscard]] std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
  47. const GURL& url,
  48. const absl::optional<CookiePartitionKey>& cookie_partition_key,
  49. CookieChangeCallback callback) override;
  50. [[nodiscard]] std::unique_ptr<CookieChangeSubscription>
  51. AddCallbackForAllChanges(CookieChangeCallback callback) override;
  52. // |notify_global_hooks| is true if the function should run the
  53. // global hooks in addition to the per-cookie hooks.
  54. //
  55. // TODO(pwnall): Remove |notify_global_hooks| and fix consumers.
  56. void DispatchChange(const CookieChangeInfo& change, bool notify_global_hooks);
  57. private:
  58. class Subscription : public base::LinkNode<Subscription>,
  59. public CookieChangeSubscription {
  60. public:
  61. Subscription(base::WeakPtr<CookieMonsterChangeDispatcher> change_dispatcher,
  62. std::string domain_key,
  63. std::string name_key,
  64. GURL url,
  65. absl::optional<CookiePartitionKey> cookie_partition_key,
  66. const bool first_party_sets_enabled,
  67. net::CookieChangeCallback callback);
  68. Subscription(const Subscription&) = delete;
  69. Subscription& operator=(const Subscription&) = delete;
  70. ~Subscription() override;
  71. // The lookup key used in the domain subscription map.
  72. //
  73. // The empty string means no domain filtering.
  74. const std::string& domain_key() const { return domain_key_; }
  75. // The lookup key used in the name subscription map.
  76. //
  77. // The empty string means no name filtering.
  78. const std::string& name_key() const { return name_key_; }
  79. // Dispatches a cookie change notification if the listener is interested.
  80. void DispatchChange(const CookieChangeInfo& change,
  81. const CookieAccessDelegate* cookie_access_delegate);
  82. private:
  83. base::WeakPtr<CookieMonsterChangeDispatcher> change_dispatcher_;
  84. const std::string domain_key_; // kGlobalDomainKey means no filtering.
  85. const std::string name_key_; // kGlobalNameKey means no filtering.
  86. const GURL url_; // empty() means no URL-based filtering.
  87. // nullopt means all Partitioned cookies will be ignored.
  88. const absl::optional<CookiePartitionKey> cookie_partition_key_;
  89. const net::CookieChangeCallback callback_;
  90. const bool first_party_sets_enabled_;
  91. void DoDispatchChange(const CookieChangeInfo& change) const;
  92. // Used to post DoDispatchChange() calls to this subscription's thread.
  93. scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
  94. THREAD_CHECKER(thread_checker_);
  95. // Used to cancel delayed calls to DoDispatchChange() when the subscription
  96. // gets destroyed.
  97. base::WeakPtrFactory<Subscription> weak_ptr_factory_{this};
  98. };
  99. // The last level of the subscription data structures.
  100. using SubscriptionList = base::LinkedList<Subscription>;
  101. // Buckets subscriptions according to cookie names.
  102. //
  103. // Map keys are cookie names, as we only support exact name matching.
  104. using CookieNameMap = std::map<std::string, SubscriptionList>;
  105. // Buckets subscriptions according to cookie domains.
  106. //
  107. // Map keys are the eTLD+1 of cookie domains. Cookies are either host-locked,
  108. // or visible to all the subdomain of a given domain. A cookie's scope cannot
  109. // exceed eTLD+1, so we stop there.
  110. using CookieDomainMap = std::map<std::string, CookieNameMap>;
  111. void DispatchChangeToDomainKey(const CookieChangeInfo& change,
  112. const std::string& domain_key);
  113. void DispatchChangeToNameKey(const CookieChangeInfo& change,
  114. CookieNameMap& name_map,
  115. const std::string& name_key);
  116. // Inserts a subscription into the map.
  117. //
  118. // Called by the AddCallback* methods, after creating the Subscription.
  119. void LinkSubscription(Subscription* subscription);
  120. // Removes a subscription from the map.
  121. //
  122. // Called by the Subscription destructor.
  123. void UnlinkSubscription(Subscription* subscription);
  124. raw_ptr<const CookieMonster> cookie_monster_;
  125. CookieDomainMap cookie_domain_map_;
  126. const bool first_party_sets_enabled_;
  127. THREAD_CHECKER(thread_checker_);
  128. // Vends weak pointers to subscriptions.
  129. base::WeakPtrFactory<CookieMonsterChangeDispatcher> weak_ptr_factory_{this};
  130. };
  131. } // namespace net
  132. #endif // NET_COOKIES_COOKIE_MONSTER_CHANGE_DISPATCHER_H_