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