From ba4ad0eeaa410d421066ba5b5df03011548f9f51 Mon Sep 17 00:00:00 2001 From: "jochen@chromium.org" Date: Tue, 15 Mar 2011 08:12:47 +0000 Subject: Keep expired and file: cookies when using the cookie monster as dumb data store BUG=none TEST=net_unittests Review URL: http://codereview.chromium.org/6626071 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78174 0039d316-1c4b-4281-b951-d872f2087c98 --- .../tab_contents/tab_specific_content_settings.cc | 4 ++++ net/base/cookie_monster.cc | 24 +++++++++++++++---- net/base/cookie_monster.h | 11 +++++++++ net/base/cookie_monster_unittest.cc | 28 ++++++++++++++++++++++ 4 files changed, 62 insertions(+), 5 deletions(-) diff --git a/chrome/browser/tab_contents/tab_specific_content_settings.cc b/chrome/browser/tab_contents/tab_specific_content_settings.cc index 545c6af..8fe5240 100644 --- a/chrome/browser/tab_contents/tab_specific_content_settings.cc +++ b/chrome/browser/tab_contents/tab_specific_content_settings.cc @@ -293,6 +293,10 @@ TabSpecificContentSettings::LocalSharedObjectsContainer:: indexed_dbs_(new CannedBrowsingDataIndexedDBHelper(profile)), local_storages_(new CannedBrowsingDataLocalStorageHelper(profile)), session_storages_(new CannedBrowsingDataLocalStorageHelper(profile)) { + cookies_->SetCookieableSchemes( + net::CookieMonster::kDefaultCookieableSchemes, + net::CookieMonster::kDefaultCookieableSchemesCount); + cookies_->SetKeepExpiredCookies(); } TabSpecificContentSettings::LocalSharedObjectsContainer:: diff --git a/net/base/cookie_monster.cc b/net/base/cookie_monster.cc index c0d6130..1117add 100644 --- a/net/base/cookie_monster.cc +++ b/net/base/cookie_monster.cc @@ -361,6 +361,7 @@ CookieMonster::CookieMonster(PersistentCookieStore* store, Delegate* delegate) TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)), delegate_(delegate), last_statistic_record_time_(Time::Now()), + keep_expired_cookies_(false), monster_alive_(kMonsterAlive) { InitializeHistograms(); SetDefaultCookieableSchemes(); @@ -376,6 +377,7 @@ CookieMonster::CookieMonster(PersistentCookieStore* store, last_access_threshold_milliseconds)), delegate_(delegate), last_statistic_record_time_(base::Time::Now()), + keep_expired_cookies_(false), monster_alive_(kMonsterAlive) { InitializeHistograms(); SetDefaultCookieableSchemes(); @@ -706,6 +708,10 @@ void CookieMonster::SetExpiryAndKeyScheme(ExpiryAndKeyScheme key_scheme) { expiry_and_key_scheme_ = key_scheme; } +void CookieMonster::SetKeepExpiredCookies() { + keep_expired_cookies_ = true; +} + void CookieMonster::SetClearPersistentStoreOnExit(bool clear_local_store) { if (store_) store_->SetClearLocalStateOnExit(clear_local_store); @@ -1011,10 +1017,15 @@ int CookieMonster::TrimDuplicateCookiesForKey( return num_duplicates; } +// Note: file must be the last scheme. +const char* CookieMonster::kDefaultCookieableSchemes[] = + { "http", "https", "file" }; +const int CookieMonster::kDefaultCookieableSchemesCount = + arraysize(CookieMonster::kDefaultCookieableSchemes); + void CookieMonster::SetDefaultCookieableSchemes() { - // Note: file must be the last scheme. - static const char* kDefaultCookieableSchemes[] = { "http", "https", "file" }; - int num_schemes = enable_file_scheme_ ? 3 : 2; + int num_schemes = enable_file_scheme_ ? + kDefaultCookieableSchemesCount : kDefaultCookieableSchemesCount - 1; SetCookieableSchemes(kDefaultCookieableSchemes, num_schemes); } @@ -1090,7 +1101,7 @@ void CookieMonster::FindCookiesForKey( ++its.first; // If the cookie is expired, delete it. - if (cc->IsExpired(current)) { + if (cc->IsExpired(current) && !keep_expired_cookies_) { InternalDeleteCookie(curit, true, DELETE_COOKIE_EXPIRED); continue; } @@ -1229,7 +1240,7 @@ bool CookieMonster::SetCanonicalCookie(scoped_ptr* cc, // Realize that we might be setting an expired cookie, and the only point // was to delete the cookie which we've already done. - if (!(*cc)->IsExpired(creation_time)) { + if (!(*cc)->IsExpired(creation_time) || keep_expired_cookies_) { // See InitializeHistograms() for details. histogram_expiration_duration_minutes_->Add( ((*cc)->ExpiryDate() - creation_time).InMinutes()); @@ -1380,6 +1391,9 @@ int CookieMonster::GarbageCollectExpired( const Time& current, const CookieMapItPair& itpair, std::vector* cookie_its) { + if (keep_expired_cookies_) + return 0; + lock_.AssertAcquired(); int num_deleted = 0; diff --git a/net/base/cookie_monster.h b/net/base/cookie_monster.h index c7a9675..0155735 100644 --- a/net/base/cookie_monster.h +++ b/net/base/cookie_monster.h @@ -194,6 +194,11 @@ class CookieMonster : public CookieStore { // function must be called before initialization. void SetExpiryAndKeyScheme(ExpiryAndKeyScheme key_scheme); + // Instructs the cookie monster to not delete expired cookies. This is used + // in cases where the cookie monster is used as a data structure to keep + // arbitrary cookies. + void SetKeepExpiredCookies(); + // Delegates the call to set the |clear_local_store_on_exit_| flag of the // PersistentStore if it exists. void SetClearPersistentStoreOnExit(bool clear_local_store); @@ -237,6 +242,10 @@ class CookieMonster : public CookieStore { // in the function trip. TODO(rdsmith):Remove hack. void ValidateMap(int arg); + // The default list of schemes the cookie monster can handle. + static const char* kDefaultCookieableSchemes[]; + static const int kDefaultCookieableSchemesCount; + private: // Testing support. // For SetCookieWithCreationTime. @@ -500,6 +509,8 @@ class CookieMonster : public CookieStore { base::Time last_statistic_record_time_; + bool keep_expired_cookies_; + static bool enable_file_scheme_; // For temporary debugging; allows for an assert in ValidateMap() diff --git a/net/base/cookie_monster_unittest.cc b/net/base/cookie_monster_unittest.cc index 4262f67..c6488b1 100644 --- a/net/base/cookie_monster_unittest.cc +++ b/net/base/cookie_monster_unittest.cc @@ -2080,6 +2080,34 @@ TEST(CookieMonsterTest, ForceSessionOnly) { ASSERT_EQ(0U, cookie_list.size()); } +// This test checks that keep expired cookies flag is working. +TEST(CookieMonsterTest, KeepExpiredCookies) { + GURL url_google(kUrlGoogle); + scoped_refptr cm(new net::CookieMonster(NULL, NULL)); + cm->SetKeepExpiredCookies(); + net::CookieOptions options; + + // Set a persistent cookie. + ASSERT_TRUE(cm->SetCookieWithOptions(url_google, + std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-22 22:50:13 GMT", + options)); + + // Get the canonical cookie. + CookieList cookie_list = cm->GetAllCookies(); + ASSERT_EQ(1U, cookie_list.size()); + + // Use a past expiry date to delete the cookie. + ASSERT_TRUE(cm->SetCookieWithOptions(url_google, + std::string(kValidCookieLine) + "; expires=Mon, 18-Apr-1977 22:50:13 GMT", + options)); + + // Check that the cookie with the past expiry date is still there. + // GetAllCookies() also triggers garbage collection. + cookie_list = cm->GetAllCookies(); + ASSERT_EQ(1U, cookie_list.size()); + ASSERT_TRUE(cookie_list[0].IsExpired(Time::Now())); +} + namespace { // Mock PersistentCookieStore that keeps track of the number of Flush() calls. -- cgit v1.1