cookie_monster.h 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862
  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
  3. // found in the LICENSE file.
  4. // Brought to you by the letter D and the number 2.
  5. #ifndef NET_COOKIES_COOKIE_MONSTER_H_
  6. #define NET_COOKIES_COOKIE_MONSTER_H_
  7. #include <stddef.h>
  8. #include <stdint.h>
  9. #include <map>
  10. #include <memory>
  11. #include <set>
  12. #include <string>
  13. #include <vector>
  14. #include "base/callback_forward.h"
  15. #include "base/containers/circular_deque.h"
  16. #include "base/containers/flat_map.h"
  17. #include "base/gtest_prod_util.h"
  18. #include "base/memory/ref_counted.h"
  19. #include "base/memory/weak_ptr.h"
  20. #include "base/strings/string_piece.h"
  21. #include "base/threading/thread_checker.h"
  22. #include "base/time/time.h"
  23. #include "net/base/net_export.h"
  24. #include "net/base/schemeful_site.h"
  25. #include "net/cookies/canonical_cookie.h"
  26. #include "net/cookies/cookie_access_delegate.h"
  27. #include "net/cookies/cookie_constants.h"
  28. #include "net/cookies/cookie_inclusion_status.h"
  29. #include "net/cookies/cookie_monster_change_dispatcher.h"
  30. #include "net/cookies/cookie_store.h"
  31. #include "net/log/net_log_with_source.h"
  32. #include "third_party/abseil-cpp/absl/types/optional.h"
  33. #include "url/gurl.h"
  34. namespace net {
  35. class CookieChangeDispatcher;
  36. // The cookie monster is the system for storing and retrieving cookies. It has
  37. // an in-memory list of all cookies, and synchronizes non-session cookies to an
  38. // optional permanent storage that implements the PersistentCookieStore
  39. // interface.
  40. //
  41. // Tasks may be deferred if all affected cookies are not yet loaded from the
  42. // backing store. Otherwise, callbacks may be invoked immediately.
  43. //
  44. // A cookie task is either pending loading of the entire cookie store, or
  45. // loading of cookies for a specific domain key (GetKey(), roughly eTLD+1). In
  46. // the former case, the cookie callback will be queued in tasks_pending_ while
  47. // PersistentCookieStore chain loads the cookie store on DB thread. In the
  48. // latter case, the cookie callback will be queued in tasks_pending_for_key_
  49. // while PermanentCookieStore loads cookies for the specified domain key on DB
  50. // thread.
  51. class NET_EXPORT CookieMonster : public CookieStore {
  52. public:
  53. class PersistentCookieStore;
  54. // Terminology:
  55. // * The 'top level domain' (TLD) of an internet domain name is
  56. // the terminal "." free substring (e.g. "com" for google.com
  57. // or world.std.com).
  58. // * The 'effective top level domain' (eTLD) is the longest
  59. // "." initiated terminal substring of an internet domain name
  60. // that is controlled by a general domain registrar.
  61. // (e.g. "co.uk" for news.bbc.co.uk).
  62. // * The 'effective top level domain plus one' (eTLD+1) is the
  63. // shortest "." delimited terminal substring of an internet
  64. // domain name that is not controlled by a general domain
  65. // registrar (e.g. "bbc.co.uk" for news.bbc.co.uk, or
  66. // "google.com" for news.google.com). The general assumption
  67. // is that all hosts and domains under an eTLD+1 share some
  68. // administrative control.
  69. // CookieMap is the central data structure of the CookieMonster. It
  70. // is a map whose values are pointers to CanonicalCookie data
  71. // structures (the data structures are owned by the CookieMonster
  72. // and must be destroyed when removed from the map). The key is based on the
  73. // effective domain of the cookies. If the domain of the cookie has an
  74. // eTLD+1, that is the key for the map. If the domain of the cookie does not
  75. // have an eTLD+1, the key of the map is the host the cookie applies to (it is
  76. // not legal to have domain cookies without an eTLD+1). This rule
  77. // excludes cookies for, e.g, ".com", ".co.uk", or ".internalnetwork".
  78. // This behavior is the same as the behavior in Firefox v 3.6.10.
  79. // CookieMap does not store cookies that were set with the Partitioned
  80. // attribute, those are stored in PartitionedCookieMap.
  81. // NOTE(deanm):
  82. // I benchmarked hash_multimap vs multimap. We're going to be query-heavy
  83. // so it would seem like hashing would help. However they were very
  84. // close, with multimap being a tiny bit faster. I think this is because
  85. // our map is at max around 1000 entries, and the additional complexity
  86. // for the hashing might not overcome the O(log(1000)) for querying
  87. // a multimap. Also, multimap is standard, another reason to use it.
  88. // TODO(rdsmith): This benchmark should be re-done now that we're allowing
  89. // substantially more entries in the map.
  90. using CookieMap =
  91. std::multimap<std::string, std::unique_ptr<CanonicalCookie>>;
  92. using CookieMapItPair = std::pair<CookieMap::iterator, CookieMap::iterator>;
  93. using CookieItVector = std::vector<CookieMap::iterator>;
  94. // PartitionedCookieMap only stores cookies that were set with the Partitioned
  95. // attribute. The map is double-keyed on cookie's partition key and
  96. // the cookie's effective domain of the cookie (the key of CookieMap).
  97. // We store partitioned cookies in a separate map so that the queries for a
  98. // request's unpartitioned and partitioned cookies will both be more
  99. // efficient (since querying two smaller maps is more efficient that querying
  100. // one larger map twice).
  101. using PartitionedCookieMap =
  102. std::map<CookiePartitionKey, std::unique_ptr<CookieMap>>;
  103. using PartitionedCookieMapIterators =
  104. std::pair<PartitionedCookieMap::iterator, CookieMap::iterator>;
  105. // Cookie garbage collection thresholds. Based off of the Mozilla defaults.
  106. // When the number of cookies gets to k{Domain,}MaxCookies
  107. // purge down to k{Domain,}MaxCookies - k{Domain,}PurgeCookies.
  108. // It might seem scary to have a high purge value, but really it's not.
  109. // You just make sure that you increase the max to cover the increase
  110. // in purge, and we would have been purging the same number of cookies.
  111. // We're just going through the garbage collection process less often.
  112. // Note that the DOMAIN values are per eTLD+1; see comment for the
  113. // CookieMap typedef. So, e.g., the maximum number of cookies allowed for
  114. // google.com and all of its subdomains will be 150-180.
  115. //
  116. // Any cookies accessed more recently than kSafeFromGlobalPurgeDays will not
  117. // be evicted by global garbage collection, even if we have more than
  118. // kMaxCookies. This does not affect domain garbage collection.
  119. static const size_t kDomainMaxCookies;
  120. static const size_t kDomainPurgeCookies;
  121. static const size_t kMaxCookies;
  122. static const size_t kPurgeCookies;
  123. // Max number of keys to store for domains that have been purged.
  124. static const size_t kMaxDomainPurgedKeys;
  125. // Partitioned cookie garbage collection thresholds.
  126. static const size_t kPerPartitionDomainMaxCookies;
  127. // TODO(crbug.com/1225444): Add global limit to number of partitioned cookies.
  128. // Quota for cookies with {low, medium, high} priorities within a domain.
  129. static const size_t kDomainCookiesQuotaLow;
  130. static const size_t kDomainCookiesQuotaMedium;
  131. static const size_t kDomainCookiesQuotaHigh;
  132. // The number of days since last access that cookies will not be subject
  133. // to global garbage collection.
  134. static const int kSafeFromGlobalPurgeDays;
  135. // The store passed in should not have had Init() called on it yet. This
  136. // class will take care of initializing it. The backing store is NOT owned by
  137. // this class, but it must remain valid for the duration of the cookie
  138. // monster's existence. If |store| is NULL, then no backing store will be
  139. // updated. |net_log| must outlive the CookieMonster and can be null.
  140. CookieMonster(scoped_refptr<PersistentCookieStore> store,
  141. NetLog* net_log,
  142. bool first_party_sets_enabled);
  143. // Only used during unit testing.
  144. // |net_log| must outlive the CookieMonster.
  145. CookieMonster(scoped_refptr<PersistentCookieStore> store,
  146. base::TimeDelta last_access_threshold,
  147. NetLog* net_log,
  148. bool first_party_sets_enabled);
  149. CookieMonster(const CookieMonster&) = delete;
  150. CookieMonster& operator=(const CookieMonster&) = delete;
  151. ~CookieMonster() override;
  152. // Writes all the cookies in |list| into the store, replacing all cookies
  153. // currently present in store.
  154. // This method does not flush the backend.
  155. // TODO(rdsmith, mmenke): Do not use this function; it is deprecated
  156. // and should be removed.
  157. // See https://codereview.chromium.org/2882063002/#msg64.
  158. void SetAllCookiesAsync(const CookieList& list, SetCookiesCallback callback);
  159. // CookieStore implementation.
  160. void SetCanonicalCookieAsync(
  161. std::unique_ptr<CanonicalCookie> cookie,
  162. const GURL& source_url,
  163. const CookieOptions& options,
  164. SetCookiesCallback callback,
  165. absl::optional<CookieAccessResult> cookie_access_result =
  166. absl::nullopt) override;
  167. void GetCookieListWithOptionsAsync(const GURL& url,
  168. const CookieOptions& options,
  169. const CookiePartitionKeyCollection& s,
  170. GetCookieListCallback callback) override;
  171. void GetAllCookiesAsync(GetAllCookiesCallback callback) override;
  172. void GetAllCookiesWithAccessSemanticsAsync(
  173. GetAllCookiesWithAccessSemanticsCallback callback) override;
  174. void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
  175. DeleteCallback callback) override;
  176. void DeleteAllCreatedInTimeRangeAsync(
  177. const CookieDeletionInfo::TimeRange& creation_range,
  178. DeleteCallback callback) override;
  179. void DeleteAllMatchingInfoAsync(CookieDeletionInfo delete_info,
  180. DeleteCallback callback) override;
  181. void DeleteSessionCookiesAsync(DeleteCallback callback) override;
  182. void DeleteMatchingCookiesAsync(DeletePredicate predicate,
  183. DeleteCallback callback) override;
  184. void FlushStore(base::OnceClosure callback) override;
  185. void SetForceKeepSessionState() override;
  186. CookieChangeDispatcher& GetChangeDispatcher() override;
  187. void SetCookieableSchemes(const std::vector<std::string>& schemes,
  188. SetCookieableSchemesCallback callback) override;
  189. // Enables writing session cookies into the cookie database. If this this
  190. // method is called, it must be called before first use of the instance
  191. // (i.e. as part of the instance initialization process).
  192. void SetPersistSessionCookies(bool persist_session_cookies);
  193. // The default list of schemes the cookie monster can handle.
  194. static const char* const kDefaultCookieableSchemes[];
  195. static const int kDefaultCookieableSchemesCount;
  196. // Find a key based on the given domain, which will be used to find all
  197. // cookies potentially relevant to it. This is used for lookup in cookies_ as
  198. // well as for PersistentCookieStore::LoadCookiesForKey. See comment on keys
  199. // before the CookieMap typedef.
  200. static std::string GetKey(base::StringPiece domain);
  201. // Exposes the comparison function used when sorting cookies.
  202. static bool CookieSorter(const CanonicalCookie* cc1,
  203. const CanonicalCookie* cc2);
  204. // Triggers immediate recording of stats that are typically reported
  205. // periodically.
  206. bool DoRecordPeriodicStatsForTesting() { return DoRecordPeriodicStats(); }
  207. // Will convert a site's partitioned cookies into unpartitioned cookies. This
  208. // may result in multiple cookies which have the same (partition_key, name,
  209. // host_key, path), which violates the database's unique constraint. The
  210. // algorithm we use to coalesce the cookies into a single unpartitioned cookie
  211. // is the following:
  212. //
  213. // 1. If one of the cookies has no partition key (i.e. it is unpartitioned)
  214. // choose this cookie.
  215. //
  216. // 2. Choose the partitioned cookie with the most recent last_access_time.
  217. //
  218. // TODO(crbug.com/1296161): Delete this when the partitioned cookies Origin
  219. // Trial ends.
  220. void ConvertPartitionedCookiesToUnpartitioned(const GURL& url) override;
  221. private:
  222. // For garbage collection constants.
  223. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestHostGarbageCollection);
  224. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
  225. GarbageCollectWithSecureCookiesOnly);
  226. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestGCTimes);
  227. // For validation of key values.
  228. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestDomainTree);
  229. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestImport);
  230. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, GetKey);
  231. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestGetKey);
  232. // For FindCookiesForKey.
  233. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, ShortLivedSessionCookies);
  234. // For CookieSource histogram enum.
  235. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, CookieSourceHistogram);
  236. // For kSafeFromGlobalPurgeDays in CookieStore.
  237. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, EvictSecureCookies);
  238. // For CookieDeleteEquivalent histogram enum.
  239. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
  240. CookieDeleteEquivalentHistogramTest);
  241. // For CookieSentToSamePort enum.
  242. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
  243. CookiePortReadDiffersFromSetHistogram);
  244. FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, IsCookieSentToSamePortThatSetIt);
  245. // Internal reasons for deletion, used to populate informative histograms
  246. // and to provide a public cause for onCookieChange notifications.
  247. //
  248. // If you add or remove causes from this list, please be sure to also update
  249. // the CookieChangeCause mapping inside ChangeCauseMapping. New items (if
  250. // necessary) should be added at the end of the list, just before
  251. // DELETE_COOKIE_LAST_ENTRY.
  252. enum DeletionCause {
  253. DELETE_COOKIE_EXPLICIT = 0,
  254. DELETE_COOKIE_OVERWRITE = 1,
  255. DELETE_COOKIE_EXPIRED = 2,
  256. DELETE_COOKIE_EVICTED = 3,
  257. DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE = 4,
  258. DELETE_COOKIE_DONT_RECORD = 5, // For final cleanup after flush to store.
  259. // Cookies evicted during domain-level garbage collection.
  260. DELETE_COOKIE_EVICTED_DOMAIN = 6,
  261. // Cookies evicted during global garbage collection, which takes place after
  262. // domain-level garbage collection fails to bring the cookie store under
  263. // the overall quota.
  264. DELETE_COOKIE_EVICTED_GLOBAL = 7,
  265. // #8 was DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE
  266. // #9 was DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE
  267. // A common idiom is to remove a cookie by overwriting it with an
  268. // already-expired expiration date. This captures that case.
  269. DELETE_COOKIE_EXPIRED_OVERWRITE = 10,
  270. // Cookies are not allowed to contain control characters in the name or
  271. // value. However, we used to allow them, so we are now evicting any such
  272. // cookies as we load them. See http://crbug.com/238041.
  273. DELETE_COOKIE_CONTROL_CHAR = 11,
  274. // When strict secure cookies is enabled, non-secure cookies are evicted
  275. // right after expired cookies.
  276. DELETE_COOKIE_NON_SECURE = 12,
  277. // Partitioned cookies evicted during per-partition domain-level garbage
  278. // collection.
  279. DELETE_COOKIE_EVICTED_PER_PARTITION_DOMAIN = 13,
  280. DELETE_COOKIE_LAST_ENTRY = 14,
  281. };
  282. // This enum is used to generate a histogramed bitmask measureing the types
  283. // of stored cookies. Please do not reorder the list when adding new entries.
  284. // New items MUST be added at the end of the list, just before
  285. // COOKIE_TYPE_LAST_ENTRY;
  286. // There will be 2^COOKIE_TYPE_LAST_ENTRY buckets in the linear histogram.
  287. enum CookieType {
  288. COOKIE_TYPE_SAME_SITE = 0,
  289. COOKIE_TYPE_HTTPONLY,
  290. COOKIE_TYPE_SECURE,
  291. COOKIE_TYPE_LAST_ENTRY
  292. };
  293. // Used to populate a histogram containing information about the
  294. // sources of Secure and non-Secure cookies: that is, whether such
  295. // cookies are set by origins with cryptographic or non-cryptographic
  296. // schemes. Please do not reorder the list when adding new
  297. // entries. New items MUST be added at the end of the list, and kMaxValue
  298. // should be updated to the last value.
  299. //
  300. // CookieSource::k(Non)SecureCookie(Non)CryptographicScheme means
  301. // that a cookie was set or overwritten from a URL with the given type
  302. // of scheme. This enum should not be used when cookies are *cleared*,
  303. // because its purpose is to understand if Chrome can deprecate the
  304. // ability of HTTP urls to set/overwrite Secure cookies.
  305. enum class CookieSource : uint8_t {
  306. kSecureCookieCryptographicScheme = 0,
  307. kSecureCookieNoncryptographicScheme,
  308. kNonsecureCookieCryptographicScheme,
  309. kNonsecureCookieNoncryptographicScheme,
  310. kMaxValue = kNonsecureCookieNoncryptographicScheme
  311. };
  312. // Enum for collecting metrics on how frequently a cookie is sent to the same
  313. // port it was set by.
  314. //
  315. // kNoButDefault exists because we expect for cookies being sent between
  316. // schemes to have a port mismatch and want to separate those out from other,
  317. // more interesting, cases.
  318. //
  319. // Do not reorder or renumber. Used for metrics.
  320. enum class CookieSentToSamePort {
  321. kSourcePortUnspecified = 0, // Cookie's source port is unspecified, we
  322. // can't know if this is the same port or not.
  323. kInvalid = 1, // The source port was corrupted to be PORT_INVALID, we
  324. // can't know if this is the same port or not.
  325. kNo = 2, // Source port and destination port are different.
  326. kNoButDefault =
  327. 3, // Source and destination ports are different but they're
  328. // the defaults for their scheme. This can mean that an http
  329. // cookie was sent to a https origin or vice-versa.
  330. kYes = 4, // They're the same.
  331. kMaxValue = kYes
  332. };
  333. // Record statistics every kRecordStatisticsIntervalSeconds of uptime.
  334. static const int kRecordStatisticsIntervalSeconds = 10 * 60;
  335. // Sets a canonical cookie, deletes equivalents and performs garbage
  336. // collection. |source_url| indicates what URL the cookie is being set
  337. // from; secure cookies cannot be altered from insecure schemes, and some
  338. // schemes may not be authorized.
  339. //
  340. // |options| indicates if this setting operation is allowed
  341. // to affect http_only or same-site cookies.
  342. //
  343. // |cookie_access_result| is an optional input status, to allow for status
  344. // chaining from callers. It helps callers provide the status of a
  345. // canonical cookie that may have warnings associated with it.
  346. void SetCanonicalCookie(
  347. std::unique_ptr<CanonicalCookie> cookie,
  348. const GURL& source_url,
  349. const CookieOptions& options,
  350. SetCookiesCallback callback,
  351. absl::optional<CookieAccessResult> cookie_access_result = absl::nullopt);
  352. void GetAllCookies(GetAllCookiesCallback callback);
  353. void AttachAccessSemanticsListForCookieList(
  354. GetAllCookiesWithAccessSemanticsCallback callback,
  355. const CookieList& cookie_list);
  356. void GetCookieListWithOptions(
  357. const GURL& url,
  358. const CookieOptions& options,
  359. const CookiePartitionKeyCollection& cookie_partition_key_collection,
  360. GetCookieListCallback callback);
  361. void DeleteAllCreatedInTimeRange(
  362. const CookieDeletionInfo::TimeRange& creation_range,
  363. DeleteCallback callback);
  364. // Returns whether |cookie| matches |delete_info|.
  365. bool MatchCookieDeletionInfo(const CookieDeletionInfo& delete_info,
  366. const net::CanonicalCookie& cookie);
  367. void DeleteCanonicalCookie(const CanonicalCookie& cookie,
  368. DeleteCallback callback);
  369. void DeleteMatchingCookies(DeletePredicate predicate,
  370. DeletionCause cause,
  371. DeleteCallback callback);
  372. // The first access to the cookie store initializes it. This method should be
  373. // called before any access to the cookie store.
  374. void MarkCookieStoreAsInitialized();
  375. // Fetches all cookies if the backing store exists and they're not already
  376. // being fetched.
  377. void FetchAllCookiesIfNecessary();
  378. // Fetches all cookies from the backing store.
  379. void FetchAllCookies();
  380. // Whether all cookies should be fetched as soon as any is requested.
  381. bool ShouldFetchAllCookiesWhenFetchingAnyCookie();
  382. // Stores cookies loaded from the backing store and invokes any deferred
  383. // calls. |beginning_time| should be the moment PersistentCookieStore::Load
  384. // was invoked and is used for reporting histogram_time_blocked_on_load_.
  385. // See PersistentCookieStore::Load for details on the contents of cookies.
  386. void OnLoaded(base::TimeTicks beginning_time,
  387. std::vector<std::unique_ptr<CanonicalCookie>> cookies);
  388. // Stores cookies loaded from the backing store and invokes the deferred
  389. // task(s) pending loading of cookies associated with the domain key
  390. // (GetKey, roughly eTLD+1). Called when all cookies for the domain key have
  391. // been loaded from DB. See PersistentCookieStore::Load for details on the
  392. // contents of cookies.
  393. void OnKeyLoaded(const std::string& key,
  394. std::vector<std::unique_ptr<CanonicalCookie>> cookies);
  395. // Stores the loaded cookies.
  396. void StoreLoadedCookies(
  397. std::vector<std::unique_ptr<CanonicalCookie>> cookies);
  398. // Invokes deferred calls.
  399. void InvokeQueue();
  400. // Checks that |cookies_| matches our invariants, and tries to repair any
  401. // inconsistencies. (In other words, it does not have duplicate cookies).
  402. void EnsureCookiesMapIsValid();
  403. // Checks for any duplicate cookies for CookieMap key |key| which lie between
  404. // |begin| and |end|. If any are found, all but the most recent are deleted.
  405. //
  406. // If |cookie_partition_it| is not nullopt, then this function trims cookies
  407. // from the CookieMap in |partitioned_cookies_| at |cookie_partition_it|
  408. // instead of trimming cookies from |cookies_|.
  409. void TrimDuplicateCookiesForKey(
  410. const std::string& key,
  411. CookieMap::iterator begin,
  412. CookieMap::iterator end,
  413. absl::optional<PartitionedCookieMap::iterator> cookie_partition_it);
  414. void SetDefaultCookieableSchemes();
  415. std::vector<CanonicalCookie*> FindCookiesForRegistryControlledHost(
  416. const GURL& url,
  417. CookieMap* cookie_map = nullptr);
  418. std::vector<CanonicalCookie*> FindPartitionedCookiesForRegistryControlledHost(
  419. const CookiePartitionKey& cookie_partition_key,
  420. const GURL& url);
  421. void FilterCookiesWithOptions(const GURL url,
  422. const CookieOptions options,
  423. std::vector<CanonicalCookie*>* cookie_ptrs,
  424. CookieAccessResultList* included_cookies,
  425. CookieAccessResultList* excluded_cookies);
  426. // Possibly delete an existing cookie equivalent to |cookie_being_set| (same
  427. // path, domain, and name).
  428. //
  429. // |allowed_to_set_secure_cookie| indicates if the source may override
  430. // existing secure cookies. If the source is not trustworthy, and there is an
  431. // existing "equivalent" cookie that is Secure, that cookie will be preserved,
  432. // under "Leave Secure Cookies Alone" (see
  433. // https://tools.ietf.org/html/draft-ietf-httpbis-cookie-alone-01).
  434. // ("equivalent" here is in quotes because the equivalency check for the
  435. // purposes of preserving existing Secure cookies is slightly more inclusive.)
  436. //
  437. // If |skip_httponly| is true, httponly cookies will not be deleted even if
  438. // they are equivalent.
  439. // |key| is the key to find the cookie in cookies_; see the comment before the
  440. // CookieMap typedef for details.
  441. //
  442. // If a cookie is deleted, and its value matches |cookie_being_set|'s value,
  443. // then |creation_date_to_inherit| will be set to that cookie's creation date.
  444. //
  445. // The cookie will not be deleted if |*status| is not "include" when calling
  446. // the function. The function will update |*status| with exclusion reasons if
  447. // a secure cookie was skipped or an httponly cookie was skipped.
  448. //
  449. // If |cookie_partition_it| is nullopt, it will search |cookies_| for
  450. // duplicates of |cookie_being_set|. Otherwise, |cookie_partition_it|'s value
  451. // is the iterator of the CookieMap in |partitioned_cookies_| we should search
  452. // for duplicates.
  453. //
  454. // NOTE: There should never be more than a single matching equivalent cookie.
  455. void MaybeDeleteEquivalentCookieAndUpdateStatus(
  456. const std::string& key,
  457. const CanonicalCookie& cookie_being_set,
  458. bool allowed_to_set_secure_cookie,
  459. bool skip_httponly,
  460. bool already_expired,
  461. base::Time* creation_date_to_inherit,
  462. CookieInclusionStatus* status,
  463. absl::optional<PartitionedCookieMap::iterator> cookie_partition_it);
  464. // Inserts `cc` into cookies_. Returns an iterator that points to the inserted
  465. // cookie in `cookies_`. Guarantee: all iterators to `cookies_` remain valid.
  466. // Dispatches the change to `change_dispatcher_` iff `dispatch_change` is
  467. // true.
  468. CookieMap::iterator InternalInsertCookie(
  469. const std::string& key,
  470. std::unique_ptr<CanonicalCookie> cc,
  471. bool sync_to_store,
  472. const CookieAccessResult& access_result,
  473. bool dispatch_change = true);
  474. // Returns true if the cookie should be (or is already) synced to the store.
  475. // Used for cookies during insertion and deletion into the in-memory store.
  476. bool ShouldUpdatePersistentStore(CanonicalCookie* cc);
  477. void LogCookieTypeToUMA(CanonicalCookie* cc,
  478. const CookieAccessResult& access_result);
  479. // Inserts `cc` into partitioned_cookies_. Should only be used when
  480. // cc->IsPartitioned() is true.
  481. PartitionedCookieMapIterators InternalInsertPartitionedCookie(
  482. std::string key,
  483. std::unique_ptr<CanonicalCookie> cc,
  484. bool sync_to_store,
  485. const CookieAccessResult& access_result,
  486. bool dispatch_change = true);
  487. // Sets all cookies from |list| after deleting any equivalent cookie.
  488. // For data gathering purposes, this routine is treated as if it is
  489. // restoring saved cookies; some statistics are not gathered in this case.
  490. void SetAllCookies(CookieList list, SetCookiesCallback callback);
  491. void InternalUpdateCookieAccessTime(CanonicalCookie* cc,
  492. const base::Time& current_time);
  493. // |deletion_cause| argument is used for collecting statistics and choosing
  494. // the correct CookieChangeCause for OnCookieChange notifications. Guarantee:
  495. // All iterators to cookies_, except for the deleted entry, remain valid.
  496. void InternalDeleteCookie(CookieMap::iterator it,
  497. bool sync_to_store,
  498. DeletionCause deletion_cause);
  499. // Deletes a Partitioned cookie. Returns true if the deletion operation
  500. // resulted in the CookieMap the cookie was stored in was deleted.
  501. //
  502. // If the CookieMap which contains the deleted cookie only has one entry, then
  503. // this function will also delete the CookieMap from PartitionedCookieMap.
  504. // This may invalidate the |cookie_partition_it| argument.
  505. void InternalDeletePartitionedCookie(
  506. PartitionedCookieMap::iterator partition_it,
  507. CookieMap::iterator cookie_it,
  508. bool sync_to_store,
  509. DeletionCause deletion_cause);
  510. // If the number of cookies for CookieMap key |key|, or globally, are
  511. // over the preset maximums above, garbage collect, first for the host and
  512. // then globally. See comments above garbage collection threshold
  513. // constants for details. Also removes expired cookies.
  514. //
  515. // Returns the number of cookies deleted (useful for debugging).
  516. size_t GarbageCollect(const base::Time& current, const std::string& key);
  517. // Run garbage collection for PartitionedCookieMap keys |cookie_partition_key|
  518. // and |key|.
  519. //
  520. // Partitioned cookies are subject to different limits than unpartitioned
  521. // cookies in order to prevent leaking entropy about user behavior across
  522. // cookie partitions.
  523. size_t GarbageCollectPartitionedCookies(
  524. const base::Time& current,
  525. const CookiePartitionKey& cookie_partition_key,
  526. const std::string& key);
  527. // Helper for GarbageCollect(). Deletes up to |purge_goal| cookies with a
  528. // priority less than or equal to |priority| from |cookies|, while ensuring
  529. // that at least the |to_protect| most-recent cookies are retained.
  530. // |protected_secure_cookies| specifies whether or not secure cookies should
  531. // be protected from deletion.
  532. //
  533. // |cookies| must be sorted from least-recent to most-recent.
  534. //
  535. // Returns the number of cookies deleted.
  536. size_t PurgeLeastRecentMatches(CookieItVector* cookies,
  537. CookiePriority priority,
  538. size_t to_protect,
  539. size_t purge_goal,
  540. bool protect_secure_cookies);
  541. // Helper for GarbageCollect(); can be called directly as well. Deletes all
  542. // expired cookies in |itpair|. If |cookie_its| is non-NULL, all the
  543. // non-expired cookies from |itpair| are appended to |cookie_its|.
  544. //
  545. // Returns the number of cookies deleted.
  546. size_t GarbageCollectExpired(const base::Time& current,
  547. const CookieMapItPair& itpair,
  548. CookieItVector* cookie_its);
  549. // Deletes all expired cookies in the double-keyed PartitionedCookie map in
  550. // the CookieMap at |cookie_partition_it|. It deletes all cookies in that
  551. // CookieMap in |itpair|. If |cookie_its| is non-NULL, all non-expired cookies
  552. // from |itpair| are appended to |cookie_its|.
  553. //
  554. // Returns the number of cookies deleted.
  555. size_t GarbageCollectExpiredPartitionedCookies(
  556. const base::Time& current,
  557. const PartitionedCookieMap::iterator& cookie_partition_it,
  558. const CookieMapItPair& itpair,
  559. CookieItVector* cookie_its);
  560. // Helper function to garbage collect all expired cookies in
  561. // PartitionedCookieMap.
  562. void GarbageCollectAllExpiredPartitionedCookies(const base::Time& current);
  563. // Helper for GarbageCollect(). Deletes all cookies in the range specified by
  564. // [|it_begin|, |it_end|). Returns the number of cookies deleted.
  565. size_t GarbageCollectDeleteRange(const base::Time& current,
  566. DeletionCause cause,
  567. CookieItVector::iterator cookie_its_begin,
  568. CookieItVector::iterator cookie_its_end);
  569. // Helper for GarbageCollect(). Deletes cookies in |cookie_its| from least to
  570. // most recently used, but only before |safe_date|. Also will stop deleting
  571. // when the number of remaining cookies hits |purge_goal|.
  572. //
  573. // Sets |earliest_time| to be the earliest last access time of a cookie that
  574. // was not deleted, or base::Time() if no such cookie exists.
  575. size_t GarbageCollectLeastRecentlyAccessed(const base::Time& current,
  576. const base::Time& safe_date,
  577. size_t purge_goal,
  578. CookieItVector cookie_its,
  579. base::Time* earliest_time);
  580. bool HasCookieableScheme(const GURL& url);
  581. // Get the cookie's access semantics (LEGACY or NONLEGACY), by checking for a
  582. // value from the cookie access delegate, if it is non-null. Otherwise returns
  583. // UNKNOWN.
  584. CookieAccessSemantics GetAccessSemanticsForCookie(
  585. const CanonicalCookie& cookie) const;
  586. // Statistics support
  587. // This function should be called repeatedly, and will record
  588. // statistics if a sufficient time period has passed.
  589. void RecordPeriodicStats(const base::Time& current_time);
  590. // Records the aforementioned stats if we have already finished loading all
  591. // cookies. Returns whether stats were recorded.
  592. bool DoRecordPeriodicStats();
  593. // Records periodic stats related to First-Party Sets usage. Note that since
  594. // First-Party Sets presents a potentially asynchronous interface, these stats
  595. // may be collected asynchronously w.r.t. the rest of the stats collected by
  596. // `RecordPeriodicStats`.
  597. void RecordPeriodicFirstPartySetsStats(
  598. base::flat_map<SchemefulSite, FirstPartySetEntry> sets) const;
  599. // Defers the callback until the full coookie database has been loaded. If
  600. // it's already been loaded, runs the callback synchronously.
  601. void DoCookieCallback(base::OnceClosure callback);
  602. // Defers the callback until the cookies relevant to given URL have been
  603. // loaded. If they've already been loaded, runs the callback synchronously.
  604. void DoCookieCallbackForURL(base::OnceClosure callback, const GURL& url);
  605. // Defers the callback until the cookies relevant to given host or domain
  606. // have been loaded. If they've already been loaded, runs the callback
  607. // synchronously.
  608. void DoCookieCallbackForHostOrDomain(base::OnceClosure callback,
  609. base::StringPiece host_or_domain);
  610. // Checks to see if a cookie is being sent to the same port it was set by. For
  611. // metrics.
  612. //
  613. // This is in CookieMonster because only CookieMonster uses it. It's otherwise
  614. // a standalone utility function.
  615. static CookieSentToSamePort IsCookieSentToSamePortThatSetIt(
  616. const GURL& destination,
  617. int source_port,
  618. CookieSourceScheme source_scheme);
  619. // TODO(crbug.com/1296161): Delete this when the partitioned cookies Origin
  620. // Trial ends.
  621. void OnConvertPartitionedCookiesToUnpartitioned(const GURL& url);
  622. void ConvertPartitionedCookie(const net::CanonicalCookie& cookie,
  623. const GURL& url);
  624. // Set of keys (eTLD+1's) for which non-expired cookies have
  625. // been evicted for hitting the per-domain max. The size of this set is
  626. // histogrammed periodically. The size is limited to |kMaxDomainPurgedKeys|.
  627. std::set<std::string> domain_purged_keys_;
  628. // The number of distinct keys (eTLD+1's) currently present in the |cookies_|
  629. // multimap. This is histogrammed periodically.
  630. size_t num_keys_ = 0u;
  631. CookieMap cookies_;
  632. PartitionedCookieMap partitioned_cookies_;
  633. // Number of distinct partitioned cookies globally. This is used to enforce a
  634. // global maximum on the number of partitioned cookies.
  635. size_t num_partitioned_cookies_ = 0u;
  636. CookieMonsterChangeDispatcher change_dispatcher_;
  637. // Indicates whether the cookie store has been initialized.
  638. bool initialized_ = false;
  639. // Indicates whether the cookie store has started fetching all cookies.
  640. bool started_fetching_all_cookies_ = false;
  641. // Indicates whether the cookie store has finished fetching all cookies.
  642. bool finished_fetching_all_cookies_ = false;
  643. // List of domain keys that have been loaded from the DB.
  644. std::set<std::string> keys_loaded_;
  645. // Map of domain keys to their associated task queues. These tasks are blocked
  646. // until all cookies for the associated domain key eTLD+1 are loaded from the
  647. // backend store.
  648. std::map<std::string, base::circular_deque<base::OnceClosure>>
  649. tasks_pending_for_key_;
  650. // Queues tasks that are blocked until all cookies are loaded from the backend
  651. // store.
  652. base::circular_deque<base::OnceClosure> tasks_pending_;
  653. // Once a global cookie task has been seen, all per-key tasks must be put in
  654. // |tasks_pending_| instead of |tasks_pending_for_key_| to ensure a reasonable
  655. // view of the cookie store. This is more to ensure fancy cookie export/import
  656. // code has a consistent view of the CookieStore, rather than out of concern
  657. // for typical use.
  658. bool seen_global_task_ = false;
  659. NetLogWithSource net_log_;
  660. scoped_refptr<PersistentCookieStore> store_;
  661. // Minimum delay after updating a cookie's LastAccessDate before we will
  662. // update it again.
  663. const base::TimeDelta last_access_threshold_;
  664. // Approximate date of access time of least recently accessed cookie
  665. // in |cookies_|. Note that this is not guaranteed to be accurate, only a)
  666. // to be before or equal to the actual time, and b) to be accurate
  667. // immediately after a garbage collection that scans through all the cookies
  668. // (When garbage collection does not scan through all cookies, it may not be
  669. // updated). This value is used to determine whether global garbage collection
  670. // might find cookies to purge. Note: The default Time() constructor will
  671. // create a value that compares earlier than any other time value, which is
  672. // wanted. Thus this value is not initialized.
  673. base::Time earliest_access_time_;
  674. std::vector<std::string> cookieable_schemes_;
  675. base::Time last_statistic_record_time_;
  676. bool persist_session_cookies_ = false;
  677. bool first_party_sets_enabled_;
  678. base::ThreadChecker thread_checker_;
  679. base::WeakPtrFactory<CookieMonster> weak_ptr_factory_{this};
  680. };
  681. typedef base::RefCountedThreadSafe<CookieMonster::PersistentCookieStore>
  682. RefcountedPersistentCookieStore;
  683. class NET_EXPORT CookieMonster::PersistentCookieStore
  684. : public RefcountedPersistentCookieStore {
  685. public:
  686. typedef base::OnceCallback<void(
  687. std::vector<std::unique_ptr<CanonicalCookie>>)>
  688. LoadedCallback;
  689. PersistentCookieStore(const PersistentCookieStore&) = delete;
  690. PersistentCookieStore& operator=(const PersistentCookieStore&) = delete;
  691. // Initializes the store and retrieves the existing cookies. This will be
  692. // called only once at startup. The callback will return all the cookies
  693. // that are not yet returned to CookieMonster by previous priority loads.
  694. //
  695. // |loaded_callback| may not be NULL.
  696. // |net_log| is a NetLogWithSource that may be copied if the persistent
  697. // store wishes to log NetLog events.
  698. virtual void Load(LoadedCallback loaded_callback,
  699. const NetLogWithSource& net_log) = 0;
  700. // Does a priority load of all cookies for the domain key (eTLD+1). The
  701. // callback will return all the cookies that are not yet returned by previous
  702. // loads, which includes cookies for the requested domain key if they are not
  703. // already returned, plus all cookies that are chain-loaded and not yet
  704. // returned to CookieMonster.
  705. //
  706. // |loaded_callback| may not be NULL.
  707. virtual void LoadCookiesForKey(const std::string& key,
  708. LoadedCallback loaded_callback) = 0;
  709. virtual void AddCookie(const CanonicalCookie& cc) = 0;
  710. virtual void UpdateCookieAccessTime(const CanonicalCookie& cc) = 0;
  711. virtual void DeleteCookie(const CanonicalCookie& cc) = 0;
  712. // Instructs the store to not discard session only cookies on shutdown.
  713. virtual void SetForceKeepSessionState() = 0;
  714. // Sets a callback that will be run before the store flushes. If |callback|
  715. // performs any async operations, the store will not wait for those to finish
  716. // before flushing.
  717. virtual void SetBeforeCommitCallback(base::RepeatingClosure callback) = 0;
  718. // Flushes the store and posts |callback| when complete. |callback| may be
  719. // NULL.
  720. virtual void Flush(base::OnceClosure callback) = 0;
  721. protected:
  722. PersistentCookieStore() = default;
  723. virtual ~PersistentCookieStore() = default;
  724. private:
  725. friend class base::RefCountedThreadSafe<PersistentCookieStore>;
  726. };
  727. } // namespace net
  728. #endif // NET_COOKIES_COOKIE_MONSTER_H_