cookie_change_dispatcher.h 6.4 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_CHANGE_DISPATCHER_H_
  5. #define NET_COOKIES_COOKIE_CHANGE_DISPATCHER_H_
  6. #include <memory>
  7. #include <string>
  8. #include "base/callback.h"
  9. #include "net/base/net_export.h"
  10. #include "net/cookies/canonical_cookie.h"
  11. #include "net/cookies/cookie_access_result.h"
  12. class GURL;
  13. namespace net {
  14. class CanonicalCookie;
  15. // The publicly relevant reasons a cookie might be changed.
  16. enum class CookieChangeCause {
  17. // The cookie was inserted.
  18. INSERTED,
  19. // The cookie was changed directly by a consumer's action.
  20. EXPLICIT,
  21. // The cookie was deleted, but no more details are known.
  22. UNKNOWN_DELETION,
  23. // The cookie was automatically removed due to an insert operation that
  24. // overwrote it.
  25. OVERWRITE,
  26. // The cookie was automatically removed as it expired.
  27. EXPIRED,
  28. // The cookie was automatically evicted during garbage collection.
  29. EVICTED,
  30. // The cookie was overwritten with an already-expired expiration date.
  31. EXPIRED_OVERWRITE
  32. };
  33. struct NET_EXPORT CookieChangeInfo {
  34. CookieChangeInfo();
  35. CookieChangeInfo(const CanonicalCookie& cookie,
  36. CookieAccessResult access_result,
  37. CookieChangeCause cause);
  38. ~CookieChangeInfo();
  39. // The cookie that changed.
  40. CanonicalCookie cookie;
  41. // The access result of the cookie at the time of the change.
  42. CookieAccessResult access_result;
  43. // The reason for the change.
  44. CookieChangeCause cause = CookieChangeCause::EXPLICIT;
  45. };
  46. // Return a string corresponding to the change cause. For debugging/logging.
  47. NET_EXPORT const char* CookieChangeCauseToString(CookieChangeCause cause);
  48. // Returns whether |cause| is one that could be a reason for deleting a cookie.
  49. // This function assumes that ChangeCause::EXPLICIT is a reason for deletion.
  50. NET_EXPORT bool CookieChangeCauseIsDeletion(CookieChangeCause cause);
  51. // Called when a cookie is changed in a CookieStore.
  52. //
  53. // Receives the CanonicalCookie which was added to or removed from the store,
  54. // the CookieAccessSemantics of the cookie at the time of the change event,
  55. // and a CookieStore::ChangeCause indicating if the cookie was added, updated,
  56. // or removed.
  57. //
  58. // Note that the callback is called twice when a cookie is updated: the first
  59. // call communicates the removal of the existing cookie, and the second call
  60. // expresses the addition of the new cookie.
  61. //
  62. // The callback must not synchronously modify any cookie in the CookieStore
  63. // whose change it is observing.
  64. using CookieChangeCallback =
  65. base::RepeatingCallback<void(const CookieChangeInfo&)>;
  66. // Records a listener's interest in CookieStore changes.
  67. //
  68. // Each call to CookieChangeDispatcher::Add*() is a listener expressing an
  69. // interest in observing CookieStore changes. Each call creates a
  70. // CookieChangeSubscription instance whose ownership is passed to the listener.
  71. //
  72. // When the listener's interest disappears (usually at destruction time), the
  73. // listener must communicate this by destroying the CookieChangeSubscription
  74. // instance. The callback passed to the Add*() method will not to be called
  75. // after the returned handle is destroyed.
  76. //
  77. // CookieChangeSubscription instances do not keep the observed CookieStores
  78. // alive.
  79. //
  80. // Instances of this class are not thread-safe, and must be destroyed on the
  81. // same thread that they were obtained on.
  82. class CookieChangeSubscription {
  83. public:
  84. CookieChangeSubscription() = default;
  85. CookieChangeSubscription(const CookieChangeSubscription&) = delete;
  86. CookieChangeSubscription& operator=(const CookieChangeSubscription&) = delete;
  87. virtual ~CookieChangeSubscription() = default;
  88. };
  89. // Exposes changes to a CookieStore's contents.
  90. //
  91. // A component that wishes to react to changes in a CookieStore (the listener)
  92. // must register its interest (subscribe) by calling one of the Add*() methods
  93. // exposed by this interface.
  94. //
  95. // CookieChangeDispatch instances are intended to be embedded in CookieStore
  96. // implementations, so they are not intended to be created as standalone objects
  97. // on the heap.
  98. //
  99. // At the time of this writing (Q1 2018), using this interface has non-trivial
  100. // performance implications on all implementations. This issue should be fixed
  101. // by the end of 2018, at which point this warning should go away. Until then,
  102. // please understand and reason about the performance impact of your change if
  103. // you're adding uses of this to the codebase.
  104. class CookieChangeDispatcher {
  105. public:
  106. CookieChangeDispatcher() = default;
  107. CookieChangeDispatcher(const CookieChangeDispatcher&) = delete;
  108. CookieChangeDispatcher& operator=(const CookieChangeDispatcher&) = delete;
  109. virtual ~CookieChangeDispatcher() = default;
  110. // Observe changes to all cookies named `name` that would be sent in a
  111. // request to `url`.
  112. //
  113. // If `cookie_partition_key` is nullopt, then we ignore all change events for
  114. // partitioned cookies. Otherwise it only subscribes to change events for
  115. // partitioned cookies with the same provided key.
  116. // Unpartitioned cookies are not affected by the `cookie_partition_key`
  117. // parameter.
  118. [[nodiscard]] virtual std::unique_ptr<CookieChangeSubscription>
  119. AddCallbackForCookie(
  120. const GURL& url,
  121. const std::string& name,
  122. const absl::optional<CookiePartitionKey>& cookie_partition_key,
  123. CookieChangeCallback callback) = 0;
  124. // Observe changes to the cookies that would be sent for a request to `url`.
  125. //
  126. // If `cookie_partition_key` is nullopt, then we ignore all change events for
  127. // partitioned cookies. Otherwise it only subscribes to change events for
  128. // partitioned cookies with the same provided key.
  129. // Unpartitioned cookies are not affected by the `cookie_partition_key`
  130. // parameter.
  131. [[nodiscard]] virtual std::unique_ptr<CookieChangeSubscription>
  132. AddCallbackForUrl(
  133. const GURL& url,
  134. const absl::optional<CookiePartitionKey>& cookie_partition_key,
  135. CookieChangeCallback callback) = 0;
  136. // Observe all the CookieStore's changes.
  137. //
  138. // The callback will not observe a few bookkeeping changes.
  139. // See kChangeCauseMapping in cookie_monster.cc for details.
  140. // TODO(crbug.com/1225444): Add support for Partitioned cookies.
  141. [[nodiscard]] virtual std::unique_ptr<CookieChangeSubscription>
  142. AddCallbackForAllChanges(CookieChangeCallback callback) = 0;
  143. };
  144. } // namespace net
  145. #endif // NET_COOKIES_COOKIE_CHANGE_DISPATCHER_H_