blob: c05a6db5d335862a8ae173b43b74fb4ffb7c400c [file] [log] [blame]
// Copyright 2018 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef NET_COOKIES_COOKIE_CHANGE_DISPATCHER_H_
#define NET_COOKIES_COOKIE_CHANGE_DISPATCHER_H_
#include <memory>
#include <string>
#include "base/callback.h"
#include "base/compiler_specific.h"
#include "net/base/net_export.h"
#include "net/cookies/canonical_cookie.h"
class GURL;
namespace net {
class CanonicalCookie;
// The publicly relevant reasons a cookie might be changed.
enum class CookieChangeCause {
// The cookie was inserted.
INSERTED,
// The cookie was changed directly by a consumer's action.
EXPLICIT,
// The cookie was deleted, but no more details are known.
UNKNOWN_DELETION,
// The cookie was automatically removed due to an insert operation that
// overwrote it.
OVERWRITE,
// The cookie was automatically removed as it expired.
EXPIRED,
// The cookie was automatically evicted during garbage collection.
EVICTED,
// The cookie was overwritten with an already-expired expiration date.
EXPIRED_OVERWRITE
};
// Return a string corresponding to the change cause. For debugging/logging.
NET_EXPORT const char* CookieChangeCauseToString(CookieChangeCause cause);
// Returns whether |cause| is one that could be a reason for deleting a cookie.
// This function assumes that ChangeCause::EXPLICIT is a reason for deletion.
NET_EXPORT bool CookieChangeCauseIsDeletion(CookieChangeCause cause);
// Called when a cookie is changed in a CookieStore.
//
// Receives the CanonicalCookie which was added to or removed from the store,
// and a CookieStore::ChangeCause indicating if the cookie was added, updated,
// or removed.
//
// Note that the callback is called twice when a cookie is updated: the first
// call communicates the removal of the existing cookie, and the second call
// expresses the addition of the new cookie.
//
// The callback must not synchronously modify any cookie in the CookieStore
// whose change it is observing.
using CookieChangeCallback =
base::RepeatingCallback<void(const CanonicalCookie& cookie,
CookieChangeCause cause)>;
// Records a listener's interest in CookieStore changes.
//
// Each call to CookieChangeDispatcher::Add*() is a listener expressing an
// interest in observing CookieStore changes. Each call creates a
// CookieChangeSubscription instance whose ownership is passed to the listener.
//
// When the listener's interest disappears (usually at destruction time), the
// listener must communicate this by destroying the CookieChangeSubscription
// instance. The callback passed to the Add*() method will not to be called
// after the returned handle is destroyed.
//
// CookieChangeSubscription instances do not keep the observed CookieStores
// alive.
//
// Instances of this class are not thread-safe, and must be destroyed on the
// same thread that they were obtained on.
class CookieChangeSubscription {
public:
CookieChangeSubscription() = default;
virtual ~CookieChangeSubscription() = default;
private:
DISALLOW_COPY_AND_ASSIGN(CookieChangeSubscription);
};
// Exposes changes to a CookieStore's contents.
//
// A component that wishes to react to changes in a CookieStore (the listener)
// must register its interest (subscribe) by calling one of the Add*() methods
// exposed by this interface.
//
// CookieChangeDispatch instances are intended to be embedded in CookieStore
// implementations, so they are not intended to be created as standalone objects
// on the heap.
//
// At the time of this writing (Q1 2018), using this interface has non-trivial
// performance implications on all implementations. This issue should be fixed
// by the end of 2018, at which point this warning should go away. Until then,
// please understand and reason about the performance impact of your change if
// you're adding uses of this to the codebase.
class CookieChangeDispatcher {
public:
CookieChangeDispatcher() = default;
virtual ~CookieChangeDispatcher() = default;
// Observe changes to all cookies named |name| that would be sent in a
// request to |url|.
virtual std::unique_ptr<CookieChangeSubscription> AddCallbackForCookie(
const GURL& url,
const std::string& name,
CookieChangeCallback callback) WARN_UNUSED_RESULT = 0;
// Observe changes to the cookies that would be sent for a request to |url|.
virtual std::unique_ptr<CookieChangeSubscription> AddCallbackForUrl(
const GURL& url,
CookieChangeCallback callback) WARN_UNUSED_RESULT = 0;
// Observe all the CookieStore's changes.
//
// The callback will not observe a few bookkeeping changes.
// See kChangeCauseMapping in cookie_monster.cc for details.
virtual std::unique_ptr<CookieChangeSubscription> AddCallbackForAllChanges(
CookieChangeCallback callback) WARN_UNUSED_RESULT = 0;
private:
DISALLOW_COPY_AND_ASSIGN(CookieChangeDispatcher);
};
} // namespace net
#endif // NET_COOKIES_COOKIE_CHANGE_DISPATCHER_H_