blob: ef5f9ab3de84f6808033b205373d9cb9f538fd17 [file] [log] [blame]
[email protected]63ee33bd2012-03-15 09:29:581// 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
5// Brought to you by the letter D and the number 2.
6
7#ifndef NET_COOKIES_COOKIE_MONSTER_H_
8#define NET_COOKIES_COOKIE_MONSTER_H_
[email protected]63ee33bd2012-03-15 09:29:589
10#include <deque>
11#include <map>
12#include <queue>
13#include <set>
14#include <string>
15#include <utility>
16#include <vector>
17
18#include "base/basictypes.h"
19#include "base/callback_forward.h"
20#include "base/gtest_prod_util.h"
21#include "base/memory/ref_counted.h"
22#include "base/memory/scoped_ptr.h"
23#include "base/synchronization/lock.h"
24#include "base/time.h"
25#include "net/cookies/cookie_store.h"
26#include "net/base/net_export.h"
27
28class GURL;
29
30namespace base {
31class Histogram;
32class TimeTicks;
33} // namespace base
34
35namespace net {
36
[email protected]5b9bc352012-07-18 13:13:3437class CanonicalCookie;
[email protected]63ee33bd2012-03-15 09:29:5838class CookieList;
[email protected]ebfe3172012-07-12 12:21:4139class ParsedCookie;
[email protected]63ee33bd2012-03-15 09:29:5840
41// The cookie monster is the system for storing and retrieving cookies. It has
42// an in-memory list of all cookies, and synchronizes non-session cookies to an
43// optional permanent storage that implements the PersistentCookieStore
44// interface.
45//
46// This class IS thread-safe. Normally, it is only used on the I/O thread, but
47// is also accessed directly through Automation for UI testing.
48//
49// All cookie tasks are handled asynchronously. Tasks may be deferred if
50// all affected cookies are not yet loaded from the backing store. Otherwise,
51// the callback may be invoked immediately (prior to return of the asynchronous
52// function).
53//
54// A cookie task is either pending loading of the entire cookie store, or
55// loading of cookies for a specfic domain key(eTLD+1). In the former case, the
56// cookie task will be queued in queue_ while PersistentCookieStore chain loads
57// the cookie store on DB thread. In the latter case, the cookie task will be
58// queued in tasks_queued_ while PermanentCookieStore loads cookies for the
59// specified domain key(eTLD+1) on DB thread.
60//
61// Callbacks are guaranteed to be invoked on the calling thread.
62//
63// TODO(deanm) Implement CookieMonster, the cookie database.
64// - Verify that our domain enforcement and non-dotted handling is correct
65class NET_EXPORT CookieMonster : public CookieStore {
66 public:
[email protected]63ee33bd2012-03-15 09:29:5867 class Delegate;
[email protected]63ee33bd2012-03-15 09:29:5868 class PersistentCookieStore;
69
70 // Terminology:
71 // * The 'top level domain' (TLD) of an internet domain name is
72 // the terminal "." free substring (e.g. "com" for google.com
73 // or world.std.com).
74 // * The 'effective top level domain' (eTLD) is the longest
75 // "." initiated terminal substring of an internet domain name
76 // that is controlled by a general domain registrar.
77 // (e.g. "co.uk" for news.bbc.co.uk).
78 // * The 'effective top level domain plus one' (eTLD+1) is the
79 // shortest "." delimited terminal substring of an internet
80 // domain name that is not controlled by a general domain
81 // registrar (e.g. "bbc.co.uk" for news.bbc.co.uk, or
82 // "google.com" for news.google.com). The general assumption
83 // is that all hosts and domains under an eTLD+1 share some
84 // administrative control.
85
86 // CookieMap is the central data structure of the CookieMonster. It
87 // is a map whose values are pointers to CanonicalCookie data
88 // structures (the data structures are owned by the CookieMonster
89 // and must be destroyed when removed from the map). The key is based on the
90 // effective domain of the cookies. If the domain of the cookie has an
91 // eTLD+1, that is the key for the map. If the domain of the cookie does not
92 // have an eTLD+1, the key of the map is the host the cookie applies to (it is
93 // not legal to have domain cookies without an eTLD+1). This rule
94 // excludes cookies for, e.g, ".com", ".co.uk", or ".internalnetwork".
95 // This behavior is the same as the behavior in Firefox v 3.6.10.
96
97 // NOTE(deanm):
98 // I benchmarked hash_multimap vs multimap. We're going to be query-heavy
99 // so it would seem like hashing would help. However they were very
100 // close, with multimap being a tiny bit faster. I think this is because
101 // our map is at max around 1000 entries, and the additional complexity
102 // for the hashing might not overcome the O(log(1000)) for querying
103 // a multimap. Also, multimap is standard, another reason to use it.
104 // TODO(rdsmith): This benchmark should be re-done now that we're allowing
105 // subtantially more entries in the map.
106 typedef std::multimap<std::string, CanonicalCookie*> CookieMap;
107 typedef std::pair<CookieMap::iterator, CookieMap::iterator> CookieMapItPair;
108
109 // The store passed in should not have had Init() called on it yet. This
110 // class will take care of initializing it. The backing store is NOT owned by
111 // this class, but it must remain valid for the duration of the cookie
112 // monster's existence. If |store| is NULL, then no backing store will be
113 // updated. If |delegate| is non-NULL, it will be notified on
114 // creation/deletion of cookies.
115 CookieMonster(PersistentCookieStore* store, Delegate* delegate);
116
117 // Only used during unit testing.
118 CookieMonster(PersistentCookieStore* store,
119 Delegate* delegate,
120 int last_access_threshold_milliseconds);
121
[email protected]63ee33bd2012-03-15 09:29:58122 // Helper function that adds all cookies from |list| into this instance.
123 bool InitializeFrom(const CookieList& list);
124
125 typedef base::Callback<void(const CookieList& cookies)> GetCookieListCallback;
126 typedef base::Callback<void(bool success)> DeleteCookieCallback;
127
128 // Sets a cookie given explicit user-provided cookie attributes. The cookie
129 // name, value, domain, etc. are each provided as separate strings. This
130 // function expects each attribute to be well-formed. It will check for
131 // disallowed characters (e.g. the ';' character is disallowed within the
132 // cookie value attribute) and will return false without setting the cookie
133 // if such characters are found.
134 void SetCookieWithDetailsAsync(const GURL& url,
135 const std::string& name,
136 const std::string& value,
137 const std::string& domain,
138 const std::string& path,
139 const base::Time& expiration_time,
140 bool secure, bool http_only,
141 const SetCookiesCallback& callback);
142
143
144 // Returns all the cookies, for use in management UI, etc. This does not mark
145 // the cookies as having been accessed.
146 // The returned cookies are ordered by longest path, then by earliest
147 // creation date.
148 void GetAllCookiesAsync(const GetCookieListCallback& callback);
149
150 // Returns all the cookies, for use in management UI, etc. Filters results
151 // using given url scheme, host / domain and path and options. This does not
152 // mark the cookies as having been accessed.
153 // The returned cookies are ordered by longest path, then earliest
154 // creation date.
155 void GetAllCookiesForURLWithOptionsAsync(
156 const GURL& url,
157 const CookieOptions& options,
158 const GetCookieListCallback& callback);
159
160 // Invokes GetAllCookiesForURLWithOptions with options set to include HTTP
161 // only cookies.
162 void GetAllCookiesForURLAsync(const GURL& url,
163 const GetCookieListCallback& callback);
164
165 // Deletes all of the cookies.
166 void DeleteAllAsync(const DeleteCallback& callback);
167
168 // Deletes all cookies that match the host of the given URL
169 // regardless of path. This includes all http_only and secure cookies,
170 // but does not include any domain cookies that may apply to this host.
171 // Returns the number of cookies deleted.
172 void DeleteAllForHostAsync(const GURL& url,
173 const DeleteCallback& callback);
174
175 // Deletes one specific cookie.
176 void DeleteCanonicalCookieAsync(const CanonicalCookie& cookie,
177 const DeleteCookieCallback& callback);
178
[email protected]97a3b6e2012-06-12 01:53:56179 // Resets the list of cookieable schemes to the supplied schemes.
[email protected]63ee33bd2012-03-15 09:29:58180 // If this this method is called, it must be called before first use of
181 // the instance (i.e. as part of the instance initialization process).
182 void SetCookieableSchemes(const char* schemes[], size_t num_schemes);
183
[email protected]97a3b6e2012-06-12 01:53:56184 // Resets the list of cookieable schemes to kDefaultCookieableSchemes with or
185 // without 'file' being included.
186 void SetEnableFileScheme(bool accept);
187
[email protected]63ee33bd2012-03-15 09:29:58188 // Instructs the cookie monster to not delete expired cookies. This is used
189 // in cases where the cookie monster is used as a data structure to keep
190 // arbitrary cookies.
191 void SetKeepExpiredCookies();
192
[email protected]bf510ed2012-06-05 08:31:43193 // Protects session cookies from deletion on shutdown.
194 void SetForceKeepSessionState();
[email protected]63ee33bd2012-03-15 09:29:58195
196 // There are some unknowns about how to correctly handle file:// cookies,
197 // and our implementation for this is not robust enough. This allows you
198 // to enable support, but it should only be used for testing. Bug 1157243.
199 // Must be called before creating a CookieMonster instance.
200 static void EnableFileScheme();
201
202 // Flush the backing store (if any) to disk and post the given callback when
203 // done.
204 // WARNING: THE CALLBACK WILL RUN ON A RANDOM THREAD. IT MUST BE THREAD SAFE.
205 // It may be posted to the current thread, or it may run on the thread that
206 // actually does the flushing. Your Task should generally post a notification
207 // to the thread you actually want to be notified on.
208 void FlushStore(const base::Closure& callback);
209
210 // CookieStore implementation.
211
212 // Sets the cookies specified by |cookie_list| returned from |url|
213 // with options |options| in effect.
214 virtual void SetCookieWithOptionsAsync(
215 const GURL& url,
216 const std::string& cookie_line,
217 const CookieOptions& options,
218 const SetCookiesCallback& callback) OVERRIDE;
219
220 // Gets all cookies that apply to |url| given |options|.
221 // The returned cookies are ordered by longest path, then earliest
222 // creation date.
223 virtual void GetCookiesWithOptionsAsync(
224 const GURL& url,
225 const CookieOptions& options,
226 const GetCookiesCallback& callback) OVERRIDE;
227
228 virtual void GetCookiesWithInfoAsync(
229 const GURL& url,
230 const CookieOptions& options,
231 const GetCookieInfoCallback& callback) OVERRIDE;
232
233 // Deletes all cookies with that might apply to |url| that has |cookie_name|.
234 virtual void DeleteCookieAsync(
235 const GURL& url, const std::string& cookie_name,
236 const base::Closure& callback) OVERRIDE;
237
238 // Deletes all of the cookies that have a creation_date greater than or equal
239 // to |delete_begin| and less than |delete_end|
240 // Returns the number of cookies that have been deleted.
241 virtual void DeleteAllCreatedBetweenAsync(
242 const base::Time& delete_begin,
243 const base::Time& delete_end,
244 const DeleteCallback& callback) OVERRIDE;
245
[email protected]264807b2012-04-25 14:49:37246 virtual void DeleteSessionCookiesAsync(const DeleteCallback&) OVERRIDE;
247
[email protected]63ee33bd2012-03-15 09:29:58248 virtual CookieMonster* GetCookieMonster() OVERRIDE;
249
250 // Enables writing session cookies into the cookie database. If this this
251 // method is called, it must be called before first use of the instance
252 // (i.e. as part of the instance initialization process).
253 void SetPersistSessionCookies(bool persist_session_cookies);
254
[email protected]63ee33bd2012-03-15 09:29:58255 // Debugging method to perform various validation checks on the map.
256 // Currently just checking that there are no null CanonicalCookie pointers
257 // in the map.
258 // Argument |arg| is to allow retaining of arbitrary data if the CHECKs
259 // in the function trip. TODO(rdsmith):Remove hack.
260 void ValidateMap(int arg);
261
[email protected]97a3b6e2012-06-12 01:53:56262 // Determines if the scheme of the URL is a scheme that cookies will be
263 // stored for.
264 bool IsCookieableScheme(const std::string& scheme);
265
[email protected]63ee33bd2012-03-15 09:29:58266 // The default list of schemes the cookie monster can handle.
267 static const char* kDefaultCookieableSchemes[];
268 static const int kDefaultCookieableSchemesCount;
269
270 private:
271 // For queueing the cookie monster calls.
272 class CookieMonsterTask;
273 class DeleteAllCreatedBetweenTask;
274 class DeleteAllForHostTask;
275 class DeleteAllTask;
276 class DeleteCookieTask;
277 class DeleteCanonicalCookieTask;
278 class GetAllCookiesForURLWithOptionsTask;
279 class GetAllCookiesTask;
280 class GetCookiesWithOptionsTask;
281 class GetCookiesWithInfoTask;
282 class SetCookieWithDetailsTask;
283 class SetCookieWithOptionsTask;
[email protected]264807b2012-04-25 14:49:37284 class DeleteSessionCookiesTask;
[email protected]63ee33bd2012-03-15 09:29:58285
286 // Testing support.
287 // For SetCookieWithCreationTime.
288 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest,
289 TestCookieDeleteAllCreatedBetweenTimestamps);
290
291 // For gargage collection constants.
292 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestHostGarbageCollection);
293 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestTotalGarbageCollection);
294 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, GarbageCollectionTriggers);
295 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestGCTimes);
296
297 // For validation of key values.
298 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestDomainTree);
299 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestImport);
300 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, GetKey);
301 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, TestGetKey);
302
303 // For FindCookiesForKey.
304 FRIEND_TEST_ALL_PREFIXES(CookieMonsterTest, ShortLivedSessionCookies);
305
306 // Internal reasons for deletion, used to populate informative histograms
307 // and to provide a public cause for onCookieChange notifications.
308 //
309 // If you add or remove causes from this list, please be sure to also update
310 // the Delegate::ChangeCause mapping inside ChangeCauseMapping. Moreover,
311 // these are used as array indexes, so avoid reordering to keep the
312 // histogram buckets consistent. New items (if necessary) should be added
313 // at the end of the list, just before DELETE_COOKIE_LAST_ENTRY.
314 enum DeletionCause {
315 DELETE_COOKIE_EXPLICIT = 0,
316 DELETE_COOKIE_OVERWRITE,
317 DELETE_COOKIE_EXPIRED,
318 DELETE_COOKIE_EVICTED,
319 DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE,
320 DELETE_COOKIE_DONT_RECORD, // e.g. For final cleanup after flush to store.
321 DELETE_COOKIE_EVICTED_DOMAIN,
322 DELETE_COOKIE_EVICTED_GLOBAL,
323
324 // Cookies evicted during domain level garbage collection that
325 // were accessed longer ago than kSafeFromGlobalPurgeDays
326 DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE,
327
328 // Cookies evicted during domain level garbage collection that
329 // were accessed more recently than kSafeFromGlobalPurgeDays
330 // (and thus would have been preserved by global garbage collection).
331 DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE,
332
333 // A common idiom is to remove a cookie by overwriting it with an
334 // already-expired expiration date. This captures that case.
335 DELETE_COOKIE_EXPIRED_OVERWRITE,
336
337 DELETE_COOKIE_LAST_ENTRY
338 };
339
340 // Cookie garbage collection thresholds. Based off of the Mozilla defaults.
341 // When the number of cookies gets to k{Domain,}MaxCookies
342 // purge down to k{Domain,}MaxCookies - k{Domain,}PurgeCookies.
343 // It might seem scary to have a high purge value, but really it's not.
344 // You just make sure that you increase the max to cover the increase
345 // in purge, and we would have been purging the same amount of cookies.
346 // We're just going through the garbage collection process less often.
347 // Note that the DOMAIN values are per eTLD+1; see comment for the
348 // CookieMap typedef. So, e.g., the maximum number of cookies allowed for
349 // google.com and all of its subdomains will be 150-180.
350 //
351 // Any cookies accessed more recently than kSafeFromGlobalPurgeDays will not
352 // be evicted by global garbage collection, even if we have more than
353 // kMaxCookies. This does not affect domain garbage collection.
354 //
355 // Present in .h file to make accessible to tests through FRIEND_TEST.
356 // Actual definitions are in cookie_monster.cc.
357 static const size_t kDomainMaxCookies;
358 static const size_t kDomainPurgeCookies;
359 static const size_t kMaxCookies;
360 static const size_t kPurgeCookies;
361
362 // The number of days since last access that cookies will not be subject
363 // to global garbage collection.
364 static const int kSafeFromGlobalPurgeDays;
365
366 // Record statistics every kRecordStatisticsIntervalSeconds of uptime.
367 static const int kRecordStatisticsIntervalSeconds = 10 * 60;
368
369 virtual ~CookieMonster();
370
371 // The following are synchronous calls to which the asynchronous methods
372 // delegate either immediately (if the store is loaded) or through a deferred
373 // task (if the store is not yet loaded).
374 bool SetCookieWithDetails(const GURL& url,
375 const std::string& name,
376 const std::string& value,
377 const std::string& domain,
378 const std::string& path,
379 const base::Time& expiration_time,
380 bool secure, bool http_only);
381
382 CookieList GetAllCookies();
383
384 CookieList GetAllCookiesForURLWithOptions(const GURL& url,
385 const CookieOptions& options);
386
387 CookieList GetAllCookiesForURL(const GURL& url);
388
389 int DeleteAll(bool sync_to_store);
390
391 int DeleteAllCreatedBetween(const base::Time& delete_begin,
392 const base::Time& delete_end);
393
394 int DeleteAllForHost(const GURL& url);
395
396 bool DeleteCanonicalCookie(const CanonicalCookie& cookie);
397
398 bool SetCookieWithOptions(const GURL& url,
399 const std::string& cookie_line,
400 const CookieOptions& options);
401
402 std::string GetCookiesWithOptions(const GURL& url,
403 const CookieOptions& options);
404
405 void GetCookiesWithInfo(const GURL& url,
406 const CookieOptions& options,
407 std::string* cookie_line,
408 std::vector<CookieInfo>* cookie_infos);
409
410 void DeleteCookie(const GURL& url, const std::string& cookie_name);
411
412 bool SetCookieWithCreationTime(const GURL& url,
413 const std::string& cookie_line,
414 const base::Time& creation_time);
415
[email protected]264807b2012-04-25 14:49:37416 int DeleteSessionCookies();
417
[email protected]63ee33bd2012-03-15 09:29:58418 // Called by all non-static functions to ensure that the cookies store has
419 // been initialized. This is not done during creating so it doesn't block
420 // the window showing.
421 // Note: this method should always be called with lock_ held.
422 void InitIfNecessary() {
423 if (!initialized_) {
424 if (store_) {
425 InitStore();
426 } else {
427 loaded_ = true;
428 }
429 initialized_ = true;
430 }
431 }
432
433 // Initializes the backing store and reads existing cookies from it.
434 // Should only be called by InitIfNecessary().
435 void InitStore();
436
437 // Stores cookies loaded from the backing store and invokes any deferred
438 // calls. |beginning_time| should be the moment PersistentCookieStore::Load
439 // was invoked and is used for reporting histogram_time_blocked_on_load_.
440 // See PersistentCookieStore::Load for details on the contents of cookies.
441 void OnLoaded(base::TimeTicks beginning_time,
442 const std::vector<CanonicalCookie*>& cookies);
443
444 // Stores cookies loaded from the backing store and invokes the deferred
445 // task(s) pending loading of cookies associated with the domain key
446 // (eTLD+1). Called when all cookies for the domain key(eTLD+1) have been
447 // loaded from DB. See PersistentCookieStore::Load for details on the contents
448 // of cookies.
449 void OnKeyLoaded(
450 const std::string& key,
451 const std::vector<CanonicalCookie*>& cookies);
452
453 // Stores the loaded cookies.
454 void StoreLoadedCookies(const std::vector<CanonicalCookie*>& cookies);
455
456 // Invokes deferred calls.
457 void InvokeQueue();
458
459 // Checks that |cookies_| matches our invariants, and tries to repair any
460 // inconsistencies. (In other words, it does not have duplicate cookies).
461 void EnsureCookiesMapIsValid();
462
463 // Checks for any duplicate cookies for CookieMap key |key| which lie between
464 // |begin| and |end|. If any are found, all but the most recent are deleted.
465 // Returns the number of duplicate cookies that were deleted.
466 int TrimDuplicateCookiesForKey(const std::string& key,
467 CookieMap::iterator begin,
468 CookieMap::iterator end);
469
470 void SetDefaultCookieableSchemes();
471
472 void FindCookiesForHostAndDomain(const GURL& url,
473 const CookieOptions& options,
474 bool update_access_time,
475 std::vector<CanonicalCookie*>* cookies);
476
477 void FindCookiesForKey(const std::string& key,
478 const GURL& url,
479 const CookieOptions& options,
480 const base::Time& current,
481 bool update_access_time,
482 std::vector<CanonicalCookie*>* cookies);
483
484 // Delete any cookies that are equivalent to |ecc| (same path, domain, etc).
485 // If |skip_httponly| is true, httponly cookies will not be deleted. The
486 // return value with be true if |skip_httponly| skipped an httponly cookie.
487 // |key| is the key to find the cookie in cookies_; see the comment before
488 // the CookieMap typedef for details.
489 // NOTE: There should never be more than a single matching equivalent cookie.
490 bool DeleteAnyEquivalentCookie(const std::string& key,
491 const CanonicalCookie& ecc,
492 bool skip_httponly,
493 bool already_expired);
494
495 // Takes ownership of *cc.
496 void InternalInsertCookie(const std::string& key,
497 CanonicalCookie* cc,
498 bool sync_to_store);
499
500 // Helper function that sets cookies with more control.
501 // Not exposed as we don't want callers to have the ability
502 // to specify (potentially duplicate) creation times.
503 bool SetCookieWithCreationTimeAndOptions(const GURL& url,
504 const std::string& cookie_line,
505 const base::Time& creation_time,
506 const CookieOptions& options);
507
508 // Helper function that sets a canonical cookie, deleting equivalents and
509 // performing garbage collection.
510 bool SetCanonicalCookie(scoped_ptr<CanonicalCookie>* cc,
511 const base::Time& creation_time,
512 const CookieOptions& options);
513
514 void InternalUpdateCookieAccessTime(CanonicalCookie* cc,
515 const base::Time& current_time);
516
517 // |deletion_cause| argument is used for collecting statistics and choosing
518 // the correct Delegate::ChangeCause for OnCookieChanged notifications.
519 void InternalDeleteCookie(CookieMap::iterator it, bool sync_to_store,
520 DeletionCause deletion_cause);
521
522 // If the number of cookies for CookieMap key |key|, or globally, are
523 // over the preset maximums above, garbage collect, first for the host and
524 // then globally. See comments above garbage collection threshold
525 // constants for details.
526 //
527 // Returns the number of cookies deleted (useful for debugging).
528 int GarbageCollect(const base::Time& current, const std::string& key);
529
530 // Helper for GarbageCollect(); can be called directly as well. Deletes
531 // all expired cookies in |itpair|. If |cookie_its| is non-NULL, it is
532 // populated with all the non-expired cookies from |itpair|.
533 //
534 // Returns the number of cookies deleted.
535 int GarbageCollectExpired(const base::Time& current,
536 const CookieMapItPair& itpair,
537 std::vector<CookieMap::iterator>* cookie_its);
538
539 // Helper for GarbageCollect(). Deletes all cookies in the list
540 // that were accessed before |keep_accessed_after|, using DeletionCause
541 // |cause|. If |keep_accessed_after| is null, deletes all cookies in the
542 // list. Returns the number of cookies deleted.
543 int GarbageCollectDeleteList(const base::Time& current,
544 const base::Time& keep_accessed_after,
545 DeletionCause cause,
546 std::vector<CookieMap::iterator>& cookie_its);
547
548 // Find the key (for lookup in cookies_) based on the given domain.
549 // See comment on keys before the CookieMap typedef.
550 std::string GetKey(const std::string& domain) const;
551
552 bool HasCookieableScheme(const GURL& url);
553
554 // Statistics support
555
556 // This function should be called repeatedly, and will record
557 // statistics if a sufficient time period has passed.
558 void RecordPeriodicStats(const base::Time& current_time);
559
560 // Initialize the above variables; should only be called from
561 // the constructor.
562 void InitializeHistograms();
563
564 // The resolution of our time isn't enough, so we do something
565 // ugly and increment when we've seen the same time twice.
566 base::Time CurrentTime();
567
568 // Runs the task if, or defers the task until, the full cookie database is
569 // loaded.
570 void DoCookieTask(const scoped_refptr<CookieMonsterTask>& task_item);
571
572 // Runs the task if, or defers the task until, the cookies for the given URL
573 // are loaded.
574 void DoCookieTaskForURL(const scoped_refptr<CookieMonsterTask>& task_item,
575 const GURL& url);
576
577 // Histogram variables; see CookieMonster::InitializeHistograms() in
578 // cookie_monster.cc for details.
579 base::Histogram* histogram_expiration_duration_minutes_;
580 base::Histogram* histogram_between_access_interval_minutes_;
581 base::Histogram* histogram_evicted_last_access_minutes_;
582 base::Histogram* histogram_count_;
583 base::Histogram* histogram_domain_count_;
584 base::Histogram* histogram_etldp1_count_;
585 base::Histogram* histogram_domain_per_etldp1_count_;
586 base::Histogram* histogram_number_duplicate_db_cookies_;
587 base::Histogram* histogram_cookie_deletion_cause_;
588 base::Histogram* histogram_time_get_;
589 base::Histogram* histogram_time_mac_;
590 base::Histogram* histogram_time_blocked_on_load_;
591
592 CookieMap cookies_;
593
594 // Indicates whether the cookie store has been initialized. This happens
595 // lazily in InitStoreIfNecessary().
596 bool initialized_;
597
598 // Indicates whether loading from the backend store is completed and
599 // calls may be immediately processed.
600 bool loaded_;
601
602 // List of domain keys that have been loaded from the DB.
603 std::set<std::string> keys_loaded_;
604
605 // Map of domain keys to their associated task queues. These tasks are blocked
606 // until all cookies for the associated domain key eTLD+1 are loaded from the
607 // backend store.
608 std::map<std::string, std::deque<scoped_refptr<CookieMonsterTask> > >
609 tasks_queued_;
610
611 // Queues tasks that are blocked until all cookies are loaded from the backend
612 // store.
613 std::queue<scoped_refptr<CookieMonsterTask> > queue_;
614
615 scoped_refptr<PersistentCookieStore> store_;
616
617 base::Time last_time_seen_;
618
619 // Minimum delay after updating a cookie's LastAccessDate before we will
620 // update it again.
621 const base::TimeDelta last_access_threshold_;
622
623 // Approximate date of access time of least recently accessed cookie
624 // in |cookies_|. Note that this is not guaranteed to be accurate, only a)
625 // to be before or equal to the actual time, and b) to be accurate
626 // immediately after a garbage collection that scans through all the cookies.
627 // This value is used to determine whether global garbage collection might
628 // find cookies to purge.
629 // Note: The default Time() constructor will create a value that compares
630 // earlier than any other time value, which is wanted. Thus this
631 // value is not initialized.
632 base::Time earliest_access_time_;
633
634 // During loading, holds the set of all loaded cookie creation times. Used to
635 // avoid ever letting cookies with duplicate creation times into the store;
636 // that way we don't have to worry about what sections of code are safe
637 // to call while it's in that state.
638 std::set<int64> creation_times_;
639
640 std::vector<std::string> cookieable_schemes_;
641
642 scoped_refptr<Delegate> delegate_;
643
644 // Lock for thread-safety
645 base::Lock lock_;
646
647 base::Time last_statistic_record_time_;
648
649 bool keep_expired_cookies_;
650 bool persist_session_cookies_;
651
[email protected]97a3b6e2012-06-12 01:53:56652 // Static setting for whether or not file scheme cookies are allows when
653 // a new CookieMonster is created, or the accepted schemes on a CookieMonster
654 // instance are reset back to defaults.
655 static bool default_enable_file_scheme_;
[email protected]63ee33bd2012-03-15 09:29:58656
657 DISALLOW_COPY_AND_ASSIGN(CookieMonster);
658};
659
[email protected]63ee33bd2012-03-15 09:29:58660class CookieMonster::Delegate
661 : public base::RefCountedThreadSafe<CookieMonster::Delegate> {
662 public:
663 // The publicly relevant reasons a cookie might be changed.
664 enum ChangeCause {
665 // The cookie was changed directly by a consumer's action.
666 CHANGE_COOKIE_EXPLICIT,
667 // The cookie was automatically removed due to an insert operation that
668 // overwrote it.
669 CHANGE_COOKIE_OVERWRITE,
670 // The cookie was automatically removed as it expired.
671 CHANGE_COOKIE_EXPIRED,
672 // The cookie was automatically evicted during garbage collection.
673 CHANGE_COOKIE_EVICTED,
674 // The cookie was overwritten with an already-expired expiration date.
675 CHANGE_COOKIE_EXPIRED_OVERWRITE
676 };
677
678 // Will be called when a cookie is added or removed. The function is passed
679 // the respective |cookie| which was added to or removed from the cookies.
680 // If |removed| is true, the cookie was deleted, and |cause| will be set
[email protected]a2c92a1c2012-04-03 12:32:14681 // to the reason for its removal. If |removed| is false, the cookie was
[email protected]63ee33bd2012-03-15 09:29:58682 // added, and |cause| will be set to CHANGE_COOKIE_EXPLICIT.
683 //
684 // As a special case, note that updating a cookie's properties is implemented
685 // as a two step process: the cookie to be updated is first removed entirely,
686 // generating a notification with cause CHANGE_COOKIE_OVERWRITE. Afterwards,
687 // a new cookie is written with the updated values, generating a notification
688 // with cause CHANGE_COOKIE_EXPLICIT.
[email protected]5b9bc352012-07-18 13:13:34689 virtual void OnCookieChanged(const CanonicalCookie& cookie,
[email protected]63ee33bd2012-03-15 09:29:58690 bool removed,
691 ChangeCause cause) = 0;
692 protected:
693 friend class base::RefCountedThreadSafe<CookieMonster::Delegate>;
694 virtual ~Delegate() {}
695};
696
[email protected]63ee33bd2012-03-15 09:29:58697typedef base::RefCountedThreadSafe<CookieMonster::PersistentCookieStore>
698 RefcountedPersistentCookieStore;
699
700class CookieMonster::PersistentCookieStore
701 : public RefcountedPersistentCookieStore {
702 public:
[email protected]5b9bc352012-07-18 13:13:34703 typedef base::Callback<void(const std::vector<CanonicalCookie*>&)>
704 LoadedCallback;
[email protected]63ee33bd2012-03-15 09:29:58705
706 // Initializes the store and retrieves the existing cookies. This will be
707 // called only once at startup. The callback will return all the cookies
708 // that are not yet returned to CookieMonster by previous priority loads.
709 virtual void Load(const LoadedCallback& loaded_callback) = 0;
710
711 // Does a priority load of all cookies for the domain key (eTLD+1). The
712 // callback will return all the cookies that are not yet returned by previous
713 // loads, which includes cookies for the requested domain key if they are not
714 // already returned, plus all cookies that are chain-loaded and not yet
715 // returned to CookieMonster.
716 virtual void LoadCookiesForKey(const std::string& key,
717 const LoadedCallback& loaded_callback) = 0;
718
719 virtual void AddCookie(const CanonicalCookie& cc) = 0;
720 virtual void UpdateCookieAccessTime(const CanonicalCookie& cc) = 0;
721 virtual void DeleteCookie(const CanonicalCookie& cc) = 0;
722
[email protected]bf510ed2012-06-05 08:31:43723 // Instructs the store to not discard session only cookies on shutdown.
724 virtual void SetForceKeepSessionState() = 0;
[email protected]63ee33bd2012-03-15 09:29:58725
726 // Flushes the store and posts |callback| when complete.
727 virtual void Flush(const base::Closure& callback) = 0;
728
729 protected:
730 PersistentCookieStore() {}
[email protected]a9813302012-04-28 09:29:28731 virtual ~PersistentCookieStore() {}
[email protected]63ee33bd2012-03-15 09:29:58732
733 private:
[email protected]a9813302012-04-28 09:29:28734 friend class base::RefCountedThreadSafe<PersistentCookieStore>;
[email protected]63ee33bd2012-03-15 09:29:58735 DISALLOW_COPY_AND_ASSIGN(PersistentCookieStore);
736};
737
[email protected]63ee33bd2012-03-15 09:29:58738} // namespace net
739
740#endif // NET_COOKIES_COOKIE_MONSTER_H_