summaryrefslogtreecommitdiffstats
path: root/net/cookies
diff options
context:
space:
mode:
authormkwst <mkwst@chromium.org>2016-03-03 09:36:23 -0800
committerCommit bot <commit-bot@chromium.org>2016-03-03 17:37:31 +0000
commit8773435ab4441ce8f78611b694e92659e9b50a63 (patch)
tree81d8f1a8eecc1ecebafa5a51d57fa59bd5fd7aec /net/cookies
parent95fce647f4a7255235418dcad030927cc4724b78 (diff)
downloadchromium_src-8773435ab4441ce8f78611b694e92659e9b50a63.zip
chromium_src-8773435ab4441ce8f78611b694e92659e9b50a63.tar.gz
chromium_src-8773435ab4441ce8f78611b694e92659e9b50a63.tar.bz2
Revert of Evict non-secure cookies less agressively. (patchset #4 id:60001 of https://codereview.chromium.org/1705753002/ )
Reason for revert: Let's see if the automagical reversion thingie will work on a ~2 week old patch. ``` I updated the eviction algorithm with our initial pass at a merger between leave-secure-cookies-along and cookie-priorities, and neglected to ensure that that new algorithm was safely locked up behind the "strict secure cookies" experiment. That patch is in M50. I think the right thing to do is to revert https://codereview.chromium.org/1705753002 on the M50 branch so that we retain the status quo behavior for beta. That means that we're going to have to wait a bit longer to start ratcheting down on cookies, which is unfortunate, but the safe choice this late in the game. ``` BUG=591720 Original issue's description: > Evict non-secure cookies less agressively. > > The current implementation of strict-secure cookies wipes all non-secure > cookies when an origin exceeds ~180. This is a bit agressive, and has > real impact on users. > > This patch softens that to remove only the number of non-secure cookies > necessary to get under the ~150 cap. If a user has 150 secure cookies, > we'll still wipe all non-secure cookies, but that seems less likely to > impact users than the current behavior. > > The patch is a bit more complicated than I expected due to interactions > with the Chrome-only "priority" feature we shipped back in 2013. In > short, we execute priority-driven removal of non-secure cookies first, > and only touch secure cookies if necessary. > > BUG=581588 > R=mmenke@chromium.org, jww@chromium.org > > Committed: https://crrev.com/162d27135f2ee44ae01341de055d1b827a930767 > Cr-Commit-Position: refs/heads/master@{#376204} TBR=jww@chromium.org,mmenke@chromium.org # Not skipping CQ checks because original CL landed more than 1 days ago. BUG=581588 Review URL: https://codereview.chromium.org/1762693002 Cr-Commit-Position: refs/heads/master@{#379030}
Diffstat (limited to 'net/cookies')
-rw-r--r--net/cookies/cookie_monster.cc252
-rw-r--r--net/cookies/cookie_monster.h31
-rw-r--r--net/cookies/cookie_monster_unittest.cc293
3 files changed, 157 insertions, 419 deletions
diff --git a/net/cookies/cookie_monster.cc b/net/cookies/cookie_monster.cc
index e9eccd2..1d38146 100644
--- a/net/cookies/cookie_monster.cc
+++ b/net/cookies/cookie_monster.cc
@@ -111,10 +111,11 @@ const size_t CookieMonster::kDomainPurgeCookies = 30;
const size_t CookieMonster::kMaxCookies = 3300;
const size_t CookieMonster::kPurgeCookies = 300;
-const double CookieMonster::kDomainCookiesQuotaLow = 0.2;
-const double CookieMonster::kDomainCookiesQuotaMedium = 0.333333333333333333333;
-const double CookieMonster::kDomainCookiesQuotaHigh =
- 1 - kDomainCookiesQuotaLow - kDomainCookiesQuotaMedium;
+const size_t CookieMonster::kDomainCookiesQuotaLow = 30;
+const size_t CookieMonster::kDomainCookiesQuotaMedium = 50;
+const size_t CookieMonster::kDomainCookiesQuotaHigh =
+ kDomainMaxCookies - kDomainPurgeCookies - kDomainCookiesQuotaLow -
+ kDomainCookiesQuotaMedium;
const int CookieMonster::kSafeFromGlobalPurgeDays = 30;
@@ -249,6 +250,19 @@ void SplitCookieVectorIntoSecureAndNonSecure(
}
}
+// Predicate to support PartitionCookieByPriority().
+struct CookiePriorityEqualsTo
+ : std::unary_function<const CookieMonster::CookieMap::iterator, bool> {
+ explicit CookiePriorityEqualsTo(CookiePriority priority)
+ : priority_(priority) {}
+
+ bool operator()(const CookieMonster::CookieMap::iterator it) const {
+ return it->second->Priority() == priority_;
+ }
+
+ const CookiePriority priority_;
+};
+
// For a CookieItVector iterator range [|it_begin|, |it_end|),
// moves all cookies with a given |priority| to the beginning of the list.
// Returns: An iterator in [it_begin, it_end) to the first element with
@@ -257,11 +271,7 @@ CookieMonster::CookieItVector::iterator PartitionCookieByPriority(
CookieMonster::CookieItVector::iterator it_begin,
CookieMonster::CookieItVector::iterator it_end,
CookiePriority priority) {
- return std::partition(
- it_begin, it_end,
- [priority](const CookieMonster::CookieMap::iterator& it) {
- return it->second->Priority() == priority;
- });
+ return std::partition(it_begin, it_end, CookiePriorityEqualsTo(priority));
}
bool LowerBoundAccessDateComparator(const CookieMonster::CookieMap::iterator it,
@@ -1858,113 +1868,77 @@ size_t CookieMonster::GarbageCollect(const Time& current,
if (cookies_.count(key) > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "GarbageCollect() key: " << key;
- CookieItVector cookie_its;
+ CookieItVector* cookie_its;
- // First, we purge all expired cookies for this key (regardless of our
- // target number of cookies, as we have no need to keep expired cookies
- // around).
+ CookieItVector non_expired_cookie_its;
+ cookie_its = &non_expired_cookie_its;
num_deleted +=
- GarbageCollectExpired(current, cookies_.equal_range(key), &cookie_its);
-
- if (cookie_its.size() > kDomainMaxCookies) {
- // Then, if we're over the maximum allowed for this key, we'll remove
- // cookies in the following order:
- //
- // 1. Low-priority non-secure cookies.
- // 2. Medium-priority non-secure cookies.
- // 3. High-priority non-secure cookies.
- // 4. Low-priority secure cookies.
- // 5. Medium-priority secure cookies.
- // 6. High-priority secure cookies.
- //
- // Note that this implies that _all_ non-secure cookies will be removed
- // before _any_ secure cookie is removed, in accordance with
- // https://tools.ietf.org/html/draft-west-leave-secure-cookies-alone
+ GarbageCollectExpired(current, cookies_.equal_range(key), cookie_its);
+
+ CookieItVector secure_cookie_its;
+ if (enforce_strict_secure && cookie_its->size() > kDomainMaxCookies) {
+ VLOG(kVlogGarbageCollection) << "Garbage collecting non-Secure cookies.";
+ num_deleted +=
+ GarbageCollectNonSecure(non_expired_cookie_its, &secure_cookie_its);
+ cookie_its = &secure_cookie_its;
+ }
+ if (cookie_its->size() > kDomainMaxCookies) {
VLOG(kVlogGarbageCollection) << "Deep Garbage Collect domain.";
size_t purge_goal =
- cookie_its.size() - (kDomainMaxCookies - kDomainPurgeCookies);
+ cookie_its->size() - (kDomainMaxCookies - kDomainPurgeCookies);
DCHECK(purge_goal > kDomainPurgeCookies);
- // To execute the above removals, we'll divide |cookies_its| into 6
- // partitions, using 7 boundaries (note that the last boundary is off the
- // end of the list):
- //
- // If both non-secure and secure cookies are present, the list will look
- // like this:
- //
- // LLLLMMMMHHHHHLLLLMMMMHHHH
- // ^ ^ ^ ^ ^ ^ ^
- // 0 1 2 3 4 5 6
- //
- // If only secure cookies are present, the list will look like this:
- //
- // LLLLMMMMHHHHH
- // ^ ^ ^ ^
- // 0 4 5 6
- // 1
- // 2
- // 3
- //
- // If only non-secure cookies are present, the list will look like this:
- //
- // LLLLMMMMHHHHH
- // ^ ^ ^ ^
- // 0 1 2 3
- // 4
- // 5
- // 6
- CookieItVector::iterator it_bdd[7];
- it_bdd[0] = cookie_its.begin();
- it_bdd[1] = it_bdd[0];
- it_bdd[2] = it_bdd[0];
- it_bdd[3] = cookie_its.end();
- it_bdd[4] = it_bdd[3];
- it_bdd[5] = it_bdd[3];
- it_bdd[6] = it_bdd[3];
-
- size_t num_nonsecure = 0;
-
- // Move all non-secure cookies to the front of the list, and set boundary
- // #3 to the first secure cookie (or off the end of the list, in the case
- // where no secure cookies are present).
- it_bdd[3] = std::partition(it_bdd[0], it_bdd[6],
- [](const CookieMap::iterator& it) {
- return !it->second->IsSecure();
- });
-
- // If we have non-secure cookies, partition them into priorities:
- if (it_bdd[3] > it_bdd[0]) {
- it_bdd[1] = PartitionCookieByPriority(it_bdd[0], it_bdd[3],
- COOKIE_PRIORITY_LOW);
- it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
- COOKIE_PRIORITY_MEDIUM);
- num_nonsecure = it_bdd[3] - it_bdd[0];
- }
-
- // Likewise, if we have secure cookies, partition them into priorities:
- if (it_bdd[3] < it_bdd[6]) {
- it_bdd[4] = PartitionCookieByPriority(it_bdd[3], it_bdd[6],
- COOKIE_PRIORITY_LOW);
- it_bdd[5] = PartitionCookieByPriority(it_bdd[4], it_bdd[6],
- COOKIE_PRIORITY_MEDIUM);
- }
-
- // Start with the non-secure cookies.
- if (purge_goal >= num_nonsecure) {
- // If we need to purge more cookies than we have non-secure, remove
- // them all, update |purge_goal| then purge the new |purge_goal| from
- // the secure cookies.
+ // Boundary iterators into |cookie_its| for different priorities.
+ CookieItVector::iterator it_bdd[4];
+ // Intialize |it_bdd| while sorting |cookie_its| by priorities.
+ // Schematic: [MLLHMHHLMM] => [LLL|MMMM|HHH], with 4 boundaries.
+ it_bdd[0] = cookie_its->begin();
+ it_bdd[3] = cookie_its->end();
+ it_bdd[1] =
+ PartitionCookieByPriority(it_bdd[0], it_bdd[3], COOKIE_PRIORITY_LOW);
+ it_bdd[2] = PartitionCookieByPriority(it_bdd[1], it_bdd[3],
+ COOKIE_PRIORITY_MEDIUM);
+ size_t quota[3] = {kDomainCookiesQuotaLow,
+ kDomainCookiesQuotaMedium,
+ kDomainCookiesQuotaHigh};
+
+ // Purge domain cookies in 3 rounds.
+ // Round 1: consider low-priority cookies only: evict least-recently
+ // accessed, while protecting quota[0] of these from deletion.
+ // Round 2: consider {low, medium}-priority cookies, evict least-recently
+ // accessed, while protecting quota[0] + quota[1].
+ // Round 3: consider all cookies, evict least-recently accessed.
+ size_t accumulated_quota = 0;
+ CookieItVector::iterator it_purge_begin = it_bdd[0];
+ for (int i = 0; i < 3 && purge_goal > 0; ++i) {
+ accumulated_quota += quota[i];
+
+ size_t num_considered = it_bdd[i + 1] - it_purge_begin;
+ if (num_considered <= accumulated_quota)
+ continue;
+
+ // Number of cookies that will be purged in this round.
+ size_t round_goal =
+ std::min(purge_goal, num_considered - accumulated_quota);
+ purge_goal -= round_goal;
+
+ SortLeastRecentlyAccessed(it_purge_begin, it_bdd[i + 1], round_goal);
+ // Cookies accessed on or after |safe_date| would have been safe from
+ // global purge, and we want to keep track of this.
+ CookieItVector::iterator it_purge_end = it_purge_begin + round_goal;
+ CookieItVector::iterator it_purge_middle =
+ LowerBoundAccessDate(it_purge_begin, it_purge_end, safe_date);
+ // Delete cookies accessed before |safe_date|.
num_deleted += GarbageCollectDeleteRange(
- current, DELETE_COOKIE_NON_SECURE, it_bdd[0], it_bdd[3]);
- num_deleted += GarbageCollectNumFromRangeWithQuota(
- current, safe_date, purge_goal - num_deleted, it_bdd, GC_SECURE);
- } else {
- num_deleted += GarbageCollectNumFromRangeWithQuota(
- current, safe_date, purge_goal, it_bdd, GC_NONSECURE);
+ current, DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE, it_purge_begin,
+ it_purge_middle);
+ // Delete cookies accessed on or after |safe_date|.
+ num_deleted += GarbageCollectDeleteRange(
+ current, DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE, it_purge_middle,
+ it_purge_end);
+ it_purge_begin = it_purge_end;
}
- purge_goal -= num_deleted;
-
DCHECK_EQ(0U, purge_goal);
}
}
@@ -2012,70 +1986,6 @@ size_t CookieMonster::GarbageCollect(const Time& current,
return num_deleted;
}
-size_t CookieMonster::GarbageCollectNumFromRangeWithQuota(
- const Time& current,
- const Time& safe_date,
- size_t purge_goal,
- CookieItVector::iterator* it_bdd,
- GCType type) {
- size_t num_deleted = 0;
- size_t begin_partition = type == GC_SECURE ? 3 : 0;
- size_t num_cookies = it_bdd[begin_partition + 3] - it_bdd[begin_partition];
- size_t num_to_keep = num_cookies - purge_goal;
- size_t quota[3] = {std::floor(num_to_keep * kDomainCookiesQuotaLow),
- std::floor(num_to_keep * kDomainCookiesQuotaMedium),
- std::floor(num_to_keep * kDomainCookiesQuotaHigh)};
-
- // The quota calculation will be up to 3 fewer than the number of
- // cookies we can keep. Bump up the numbers to get the right answer:
- if (quota[0] + quota[1] + quota[2] < num_to_keep)
- quota[2] += 1;
- if (quota[0] + quota[1] + quota[2] < num_to_keep)
- quota[1] += 1;
- if (quota[0] + quota[1] + quota[2] < num_to_keep)
- quota[0] += 1;
- DCHECK_EQ(num_to_keep, quota[0] + quota[1] + quota[2]);
-
- // Purge domain cookies in 3 rounds.
- // Round 1: consider low-priority cookies only: evict least-recently
- // accessed, while protecting quota[0] of these from deletion.
- // Round 2: consider {low, medium}-priority cookies, evict least-recently
- // accessed, while protecting quota[0] + quota[1].
- // Round 3: consider all cookies, evict least-recently accessed.
- size_t accumulated_quota = 0;
- CookieItVector::iterator it_purge_begin = it_bdd[begin_partition];
- for (size_t i = 0; i < arraysize(quota) && purge_goal > 0; ++i) {
- accumulated_quota += quota[i];
-
- size_t num_considered = it_bdd[i + begin_partition + 1] - it_purge_begin;
- if (num_considered <= accumulated_quota)
- continue;
-
- // Number of cookies that will be purged in this round.
- size_t round_goal =
- std::min(purge_goal, num_considered - accumulated_quota);
- purge_goal -= round_goal;
-
- SortLeastRecentlyAccessed(it_purge_begin, it_bdd[i + begin_partition + 1],
- round_goal);
- // Cookies accessed on or after |safe_date| would have been safe from
- // global purge, and we want to keep track of this.
- CookieItVector::iterator it_purge_end = it_purge_begin + round_goal;
- CookieItVector::iterator it_purge_middle =
- LowerBoundAccessDate(it_purge_begin, it_purge_end, safe_date);
- // Delete cookies accessed before |safe_date|.
- num_deleted += GarbageCollectDeleteRange(
- current, DELETE_COOKIE_EVICTED_DOMAIN_PRE_SAFE, it_purge_begin,
- it_purge_middle);
- // Delete cookies accessed on or after |safe_date|.
- num_deleted += GarbageCollectDeleteRange(
- current, DELETE_COOKIE_EVICTED_DOMAIN_POST_SAFE, it_purge_middle,
- it_purge_end);
- it_purge_begin = it_purge_end;
- }
- return num_deleted;
-}
-
size_t CookieMonster::GarbageCollectExpired(const Time& current,
const CookieMapItPair& itpair,
CookieItVector* cookie_its) {
diff --git a/net/cookies/cookie_monster.h b/net/cookies/cookie_monster.h
index 8c39440..8103b74 100644
--- a/net/cookies/cookie_monster.h
+++ b/net/cookies/cookie_monster.h
@@ -125,11 +125,9 @@ class NET_EXPORT CookieMonster : public CookieStore {
static const size_t kPurgeCookies;
// Quota for cookies with {low, medium, high} priorities within a domain.
- // The quota is specified as a percentage of the total number of cookies we
- // intend to retain for a domain.
- static const double kDomainCookiesQuotaLow;
- static const double kDomainCookiesQuotaMedium;
- static const double kDomainCookiesQuotaHigh;
+ static const size_t kDomainCookiesQuotaLow;
+ static const size_t kDomainCookiesQuotaMedium;
+ static const size_t kDomainCookiesQuotaHigh;
// The store passed in should not have had Init() called on it yet. This
// class will take care of initializing it. The backing store is NOT owned by
@@ -361,8 +359,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
COOKIE_DELETE_EQUIVALENT_LAST_ENTRY
};
- enum GCType { GC_NONSECURE, GC_SECURE };
-
// The strategy for fetching cookies. Controlled by Finch experiment.
enum FetchStrategy {
// Fetches all cookies only when they're needed.
@@ -575,27 +571,6 @@ class NET_EXPORT CookieMonster : public CookieStore {
size_t purge_goal,
CookieItVector cookie_its);
- // Helper for GarbageCollect(). Deletes |purge_goal| cookies of type |type|
- // from the ranges specified in |it_bdd|. Returns the number of cookies
- // deleted.
- //
- // |it_bdd| is a bit of a complicated beast: it must be a 7-element array
- // of 'CookieItVector::Iterator' objects that demarcate the boundaries of
- // a list of cookies sorted first by secure/non-secure, and then by priority,
- // low to high. That is, it ought to look something like:
- //
- // LLLLMMMMHHHHHLLLLMMMMHHHH
- // ^ ^ ^ ^ ^ ^ ^
- // 0 1 2 3 4 5 6
- //
- // TODO(mkwst): This is super-complicated. We should determine whether we
- // can simplify our implementation of "priority".
- size_t GarbageCollectNumFromRangeWithQuota(const base::Time& current,
- const base::Time& safe_date,
- size_t purge_goal,
- CookieItVector::iterator* it_bdd,
- GCType type);
-
// Find the key (for lookup in cookies_) based on the given domain.
// See comment on keys before the CookieMap typedef.
std::string GetKey(const std::string& domain) const;
diff --git a/net/cookies/cookie_monster_unittest.cc b/net/cookies/cookie_monster_unittest.cc
index 4f64b2f..a92f2be 100644
--- a/net/cookies/cookie_monster_unittest.cc
+++ b/net/cookies/cookie_monster_unittest.cc
@@ -347,12 +347,11 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
// Instantiates a CookieMonster, adds multiple cookies (to http_www_google_)
// with priorities specified by |coded_priority_str|, and tests priority-aware
// domain cookie eviction.
- //
- // Example: |coded_priority_string| of "2MN 3LS MN 4HN" specifies sequential
- // (i.e., from least- to most-recently accessed) insertion of 2
- // medium-priority non-secure cookies, 3 low-priority secure cookies, 1
- // medium-priority non-secure cookie, and 4 high-priority non-secure cookies.
- //
+ // |coded_priority_str| specifies a run-length-encoded string of priorities.
+ // Example: "2M 3L M 4H" means "MMLLLMHHHH", and speicifies sequential (i.e.,
+ // from least- to most-recently accessed) insertion of 2 medium-priority
+ // cookies, 3 low-priority cookies, 1 medium-priority cookie, and 4
+ // high-priority cookies.
// Within each priority, only the least-accessed cookies should be evicted.
// Thus, to describe expected suriving cookies, it suffices to specify the
// expected population of surviving cookies per priority, i.e.,
@@ -361,55 +360,41 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
const std::string& coded_priority_str,
size_t expected_low_count,
size_t expected_medium_count,
- size_t expected_high_count,
- size_t expected_nonsecure,
- size_t expected_secure) {
- SCOPED_TRACE(coded_priority_str.c_str());
+ size_t expected_high_count) {
this->DeleteAll(cm);
int next_cookie_id = 0;
- // A list of cookie IDs, indexed by secure status, then by priority.
- std::vector<int> id_list[2][3];
- // A list of all the cookies stored, along with their properties.
- std::vector<std::pair<bool, CookiePriority>> cookie_data;
+ std::vector<CookiePriority> priority_list;
+ std::vector<int> id_list[3]; // Indexed by CookiePriority.
// Parse |coded_priority_str| and add cookies.
for (const std::string& token :
base::SplitString(coded_priority_str, " ", base::TRIM_WHITESPACE,
base::SPLIT_WANT_ALL)) {
DCHECK(!token.empty());
-
- // Take last character as security status, then discard it.
- bool is_secure = token[token.size() - 1] == 'S';
-
- // The second-to-last character is the priority. Grab and discard it.
- CookiePriority priority = CharToPriority(token[token.size() - 2]);
-
+ // Take last character as priority.
+ CookiePriority priority = CharToPriority(token.back());
+ std::string priority_str = CookiePriorityToString(priority);
// The rest of the string (possibly empty) specifies repetition.
int rep = 1;
if (!token.empty()) {
bool result = base::StringToInt(
- base::StringPiece(token.begin(), token.end() - 2), &rep);
+ base::StringPiece(token.begin(), token.end() - 1), &rep);
DCHECK(result);
}
for (; rep > 0; --rep, ++next_cookie_id) {
- std::string cookie =
- base::StringPrintf("a%d=b;priority=%s;%s", next_cookie_id,
- CookiePriorityToString(priority).c_str(),
- is_secure ? "secure" : "");
- EXPECT_TRUE(SetCookie(cm, https_www_google_.url(), cookie));
- cookie_data.push_back(std::make_pair(is_secure, priority));
- id_list[is_secure][priority].push_back(next_cookie_id);
+ std::string cookie = base::StringPrintf(
+ "a%d=b;priority=%s", next_cookie_id, priority_str.c_str());
+ EXPECT_TRUE(SetCookie(cm, http_www_google_.url(), cookie));
+ priority_list.push_back(priority);
+ id_list[priority].push_back(next_cookie_id);
}
}
- int num_cookies = static_cast<int>(cookie_data.size());
- // A list of cookie IDs, indexed by secure status, then by priority.
- std::vector<int> surviving_id_list[2][3];
+ int num_cookies = static_cast<int>(priority_list.size());
+ std::vector<int> surviving_id_list[3]; // Indexed by CookiePriority.
// Parse the list of cookies
- std::string cookie_str = this->GetCookies(cm, https_www_google_.url());
- size_t num_nonsecure = 0;
- size_t num_secure = 0;
+ std::string cookie_str = this->GetCookies(cm, http_www_google_.url());
for (const std::string& token : base::SplitString(
cookie_str, ";", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
// Assuming *it is "a#=b", so extract and parse "#" portion.
@@ -419,40 +404,22 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
DCHECK(result);
DCHECK_GE(id, 0);
DCHECK_LT(id, num_cookies);
- surviving_id_list[cookie_data[id].first][cookie_data[id].second]
- .push_back(id);
- if (cookie_data[id].first)
- num_secure += 1;
- else
- num_nonsecure += 1;
+ surviving_id_list[priority_list[id]].push_back(id);
}
- EXPECT_EQ(expected_nonsecure, num_nonsecure);
- EXPECT_EQ(expected_secure, num_secure);
-
// Validate each priority.
size_t expected_count[3] = {
expected_low_count, expected_medium_count, expected_high_count};
for (int i = 0; i < 3; ++i) {
- size_t num_for_priority =
- surviving_id_list[0][i].size() + surviving_id_list[1][i].size();
- EXPECT_EQ(expected_count[i], num_for_priority);
+ DCHECK_LE(surviving_id_list[i].size(), id_list[i].size());
+ EXPECT_EQ(expected_count[i], surviving_id_list[i].size());
// Verify that the remaining cookies are the most recent among those
// with the same priorities.
- if (expected_count[i] == num_for_priority) {
- // Non-secure:
- std::sort(surviving_id_list[0][i].begin(),
- surviving_id_list[0][i].end());
- EXPECT_TRUE(std::equal(
- surviving_id_list[0][i].begin(), surviving_id_list[0][i].end(),
- id_list[0][i].end() - surviving_id_list[0][i].size()));
-
- // Secure:
- std::sort(surviving_id_list[1][i].begin(),
- surviving_id_list[1][i].end());
- EXPECT_TRUE(std::equal(
- surviving_id_list[1][i].begin(), surviving_id_list[1][i].end(),
- id_list[1][i].end() - surviving_id_list[1][i].size()));
+ if (expected_count[i] == surviving_id_list[i].size()) {
+ std::sort(surviving_id_list[i].begin(), surviving_id_list[i].end());
+ EXPECT_TRUE(std::equal(surviving_id_list[i].begin(),
+ surviving_id_list[i].end(),
+ id_list[i].end() - expected_count[i]));
}
}
}
@@ -519,158 +486,54 @@ class CookieMonsterTestBase : public CookieStoreTest<T> {
EXPECT_EQ(expected_non_secure_cookies, total_non_secure_cookies);
}
- void TestPriorityAwareGarbageCollectHelperNonSecure() {
- // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
- DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
- DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
- CookieMonster::kDomainPurgeCookies);
-
- scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
-
- // Each test case adds 181 cookies, so 31 cookies are evicted.
- // Cookie same priority, repeated for each priority.
- TestPriorityCookieCase(cm.get(), "181LN", 150U, 0U, 0U, 150U, 0U);
- TestPriorityCookieCase(cm.get(), "181MN", 0U, 150U, 0U, 150U, 0U);
- TestPriorityCookieCase(cm.get(), "181HN", 0U, 0U, 150U, 150U, 0U);
-
- // Pairwise scenarios.
- // Round 1 => none; round2 => 31M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "10HN 171MN", 0U, 140U, 10U, 150U, 0U);
- // Round 1 => 10L; round2 => 21M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "141MN 40LN", 30U, 120U, 0U, 150U, 0U);
- // Round 1 => none; round2 => none; round 3 => 31H.
- TestPriorityCookieCase(cm.get(), "101HN 80MN", 0U, 80U, 70U, 150U, 0U);
-
- // For {low, medium} priorities right on quota, different orders.
- // Round 1 => 1L; round 2 => none, round3 => 30L.
- TestPriorityCookieCase(cm.get(), "31LN 50MN 100HN", 0U, 50U, 100U, 150U,
- 0U);
- // Round 1 => none; round 2 => 1M, round3 => 30M.
- TestPriorityCookieCase(cm.get(), "51MN 100HN 30LN", 30U, 20U, 100U, 150U,
- 0U);
- // Round 1 => none; round 2 => none; round3 => 31H.
- TestPriorityCookieCase(cm.get(), "101HN 50MN 30LN", 30U, 50U, 70U, 150U,
- 0U);
-
- // Round 1 => 10L; round 2 => 10M; round3 => 11H.
- TestPriorityCookieCase(cm.get(), "81HN 60MN 40LN", 30U, 50U, 70U, 150U, 0U);
-
- // More complex scenarios.
- // Round 1 => 10L; round 2 => 10M; round 3 => 11H.
- TestPriorityCookieCase(cm.get(), "21HN 60MN 40LN 60HN", 30U, 50U, 70U, 150U,
- 0U);
- // Round 1 => 10L; round 2 => 11M, 10L; round 3 => none.
- TestPriorityCookieCase(cm.get(), "11HN 10MN 20LN 110MN 20LN 10HN", 20U,
- 109U, 21U, 150U, 0U);
- // Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H.
- TestPriorityCookieCase(cm.get(), "11LN 10MN 140HN 10MN 10LN", 10U, 10U,
- 130U, 150U, 0U);
- // Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H.
- TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 60MN 90HN", 0U, 60U, 90U,
- 150U, 0U);
- // Round 1 => none; round 2 => 10L, 21M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "11MN 10HN 10LN 90MN 60HN", 0U, 80U, 70U,
- 150U, 0U);
- }
-
- void TestPriorityAwareGarbageCollectHelperSecure() {
+ void TestPriorityAwareGarbageCollectHelper() {
// Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
CookieMonster::kDomainPurgeCookies);
+ DCHECK_EQ(30U, CookieMonster::kDomainCookiesQuotaLow);
+ DCHECK_EQ(50U, CookieMonster::kDomainCookiesQuotaMedium);
+ DCHECK_EQ(70U, CookieMonster::kDomainCookiesQuotaHigh);
scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
// Each test case adds 181 cookies, so 31 cookies are evicted.
// Cookie same priority, repeated for each priority.
- TestPriorityCookieCase(cm.get(), "181LS", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "181MS", 0U, 150U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "181HS", 0U, 0U, 150U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "181L", 150U, 0U, 0U);
+ TestPriorityCookieCase(cm.get(), "181M", 0U, 150U, 0U);
+ TestPriorityCookieCase(cm.get(), "181H", 0U, 0U, 150U);
// Pairwise scenarios.
// Round 1 => none; round2 => 31M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "10HS 171MS", 0U, 140U, 10U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "10H 171M", 0U, 140U, 10U);
// Round 1 => 10L; round2 => 21M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "141MS 40LS", 30U, 120U, 0U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "141M 40L", 30U, 120U, 0U);
// Round 1 => none; round2 => none; round 3 => 31H.
- TestPriorityCookieCase(cm.get(), "101HS 80MS", 0U, 80U, 70U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "101H 80M", 0U, 80U, 70U);
// For {low, medium} priorities right on quota, different orders.
// Round 1 => 1L; round 2 => none, round3 => 30L.
- TestPriorityCookieCase(cm.get(), "31LS 50MS 100HS", 0U, 50U, 100U, 0U,
- 150U);
+ TestPriorityCookieCase(cm.get(), "31L 50M 100H", 0U, 50U, 100U);
// Round 1 => none; round 2 => 1M, round3 => 30M.
- TestPriorityCookieCase(cm.get(), "51MS 100HS 30LS", 30U, 20U, 100U, 0U,
- 150U);
+ TestPriorityCookieCase(cm.get(), "51M 100H 30L", 30U, 20U, 100U);
// Round 1 => none; round 2 => none; round3 => 31H.
- TestPriorityCookieCase(cm.get(), "101HS 50MS 30LS", 30U, 50U, 70U, 0U,
- 150U);
+ TestPriorityCookieCase(cm.get(), "101H 50M 30L", 30U, 50U, 70U);
// Round 1 => 10L; round 2 => 10M; round3 => 11H.
- TestPriorityCookieCase(cm.get(), "81HS 60MS 40LS", 30U, 50U, 70U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "81H 60M 40L", 30U, 50U, 70U);
// More complex scenarios.
// Round 1 => 10L; round 2 => 10M; round 3 => 11H.
- TestPriorityCookieCase(cm.get(), "21HS 60MS 40LS 60HS", 30U, 50U, 70U, 0U,
- 150U);
+ TestPriorityCookieCase(cm.get(), "21H 60M 40L 60H", 30U, 50U, 70U);
// Round 1 => 10L; round 2 => 11M, 10L; round 3 => none.
- TestPriorityCookieCase(cm.get(), "11HS 10MS 20LS 110MS 20LS 10HS", 20U,
- 109U, 21U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "11H 10M 20L 110M 20L 10H", 20U, 109U,
+ 21U);
// Round 1 => none; round 2 => none; round 3 => 11L, 10M, 10H.
- TestPriorityCookieCase(cm.get(), "11LS 10MS 140HS 10MS 10LS", 10U, 10U,
- 130U, 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "11L 10M 140H 10M 10L", 10U, 10U, 130U);
// Round 1 => none; round 2 => 1M; round 3 => 10L, 10M, 10H.
- TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 60MS 90HS", 0U, 60U, 90U,
- 0U, 150U);
+ TestPriorityCookieCase(cm.get(), "11M 10H 10L 60M 90H", 0U, 60U, 90U);
// Round 1 => none; round 2 => 10L, 21M; round 3 => none.
- TestPriorityCookieCase(cm.get(), "11MS 10HS 10LS 90MS 60HS", 0U, 80U, 70U,
- 0U, 150U);
- }
-
- void TestPriorityAwareGarbageCollectHelperMixed() {
- // Hard-coding limits in the test, but use DCHECK_EQ to enforce constraint.
- DCHECK_EQ(180U, CookieMonster::kDomainMaxCookies);
- DCHECK_EQ(150U, CookieMonster::kDomainMaxCookies -
- CookieMonster::kDomainPurgeCookies);
-
- scoped_refptr<CookieMonster> cm(new CookieMonster(NULL, NULL));
-
- // Each test case adds 180 secure cookies, and some non-secure cookie. The
- // secure cookies take priority, so the non-secure cookie is removed, along
- // with 30 secure cookies. Repeated for each priority, and with the
- // non-secure cookie as older and newer.
- TestPriorityCookieCase(cm.get(), "1LN 180LS", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1MN 180MS", 0U, 150U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1HN 180HS", 0U, 0U, 150U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "180LS 1LN", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "180MS 1MN", 0U, 150U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "180HS 1HN", 0U, 0U, 150U, 0U, 150U);
-
- // Higher-priority non-secure cookies are removed before any secure cookie.
- TestPriorityCookieCase(cm.get(), "180LS 1MN", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "180LS 1HN", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "180MS 1HN", 0U, 150U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1MN 180LS", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1HN 180LS", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1HN 180MS", 0U, 150U, 0U, 0U, 150U);
-
- // Pairwise:
- TestPriorityCookieCase(cm.get(), "1LS 180LN", 150U, 0U, 0U, 149U, 1U);
- TestPriorityCookieCase(cm.get(), "100LS 81LN", 150U, 0U, 0U, 50U, 100U);
- TestPriorityCookieCase(cm.get(), "150LS 31LN", 150U, 0U, 0U, 0U, 150U);
- TestPriorityCookieCase(cm.get(), "1LS 180HN", 1U, 0U, 149U, 149U, 1U);
- TestPriorityCookieCase(cm.get(), "100LS 81HN", 100U, 0U, 50U, 50U, 100U);
- TestPriorityCookieCase(cm.get(), "150LS 31HN", 150U, 0U, 0U, 0U, 150U);
-
- // Quota calculations inside non-secure/secure blocks remain in place:
- TestPriorityCookieCase(cm.get(), "50HN 50LS 81HS", 50U, 0U, 100U, 19U,
- 131U);
- TestPriorityCookieCase(cm.get(), "11MS 10HN 10LS 90MN 60HN", 10U, 79U, 61U,
- 129U, 21U);
-
- // Multiple GC rounds end up with consistent behavior:
- TestPriorityCookieCase(cm.get(), "100HS 100LN 100MN", 0, 76U, 100U, 76U,
- 100U);
+ TestPriorityCookieCase(cm.get(), "11M 10H 10L 90M 60H", 0U, 80U, 70U);
}
// Function for creating a CM with a number of cookies in it,
@@ -1400,16 +1263,8 @@ TEST_F(CookieMonsterTest, TestHostGarbageCollection) {
TestHostGarbageCollectHelper();
}
-TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollectionNonSecure) {
- TestPriorityAwareGarbageCollectHelperNonSecure();
-}
-
-TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollectionSecure) {
- TestPriorityAwareGarbageCollectHelperSecure();
-}
-
-TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollectionMixed) {
- TestPriorityAwareGarbageCollectHelperMixed();
+TEST_F(CookieMonsterTest, TestPriorityAwareGarbageCollection) {
+ TestPriorityAwareGarbageCollectHelper();
}
TEST_F(CookieMonsterTest, SetCookieableSchemes) {
@@ -2798,13 +2653,13 @@ TEST_F(CookieMonsterStrictSecureTest, EvictSecureCookies) {
// non-secure cookie will not evict them (and, in fact, the non-secure cookie
// will be removed right after creation).
const CookiesEntry test1[] = {{180U, true}, {1U, false}};
- TestSecureCookieEviction(test1, arraysize(test1), 150U, 0U, nullptr);
+ TestSecureCookieEviction(test1, arraysize(test1), 180U, 0U, nullptr);
// If non-secure cookies for one domain hit the per domain limit (180), the
- // creation of secure cookies will evict the non-secure cookies first, making
- // room for the secure cookies.
+ // creation of secure cookies will evict all of the non-secure cookies, and
+ // the secure cookies will still be created.
const CookiesEntry test2[] = {{180U, false}, {20U, true}};
- TestSecureCookieEviction(test2, arraysize(test2), 20U, 149U, nullptr);
+ TestSecureCookieEviction(test2, arraysize(test2), 20U, 0U, nullptr);
// If secure cookies for one domain go past the per domain limit (180), they
// will be evicted as normal by the per domain purge amount (30) down to a
@@ -2816,9 +2671,9 @@ TEST_F(CookieMonsterStrictSecureTest, EvictSecureCookies) {
// If a non-secure cookie is created, and a number of secure cookies exceeds
// the per domain limit (18), the total cookies will be evicted down to a
// lower amount (150), enforcing the eviction of the non-secure cookie, and
- // the remaining secure cookies will be created (another 19 to 169).
+ // the remaining secure cookies will be created (another 18 to 168).
const CookiesEntry test4[] = {{1U, false}, {199U, true}};
- TestSecureCookieEviction(test4, arraysize(test4), 169U, 0U, nullptr);
+ TestSecureCookieEviction(test4, arraysize(test4), 168U, 0U, nullptr);
// If an even number of non-secure and secure cookies are created below the
// per-domain limit (180), all will be created and none evicted.
@@ -2827,40 +2682,38 @@ TEST_F(CookieMonsterStrictSecureTest, EvictSecureCookies) {
// If the same number of secure and non-secure cookies are created (50 each)
// below the per domain limit (180), and then another set of secure cookies
- // are created to bring the total above the per-domain limit, all secure
- // cookies will be retained, and the non-secure cookies will be culled down
- // to the limit.
+ // are created to bring the total above the per-domain limit, all of the
+ // non-secure cookies will be evicted but none of the secure ones will be
+ // evicted.
const CookiesEntry test6[] = {{50U, true}, {50U, false}, {81U, true}};
- TestSecureCookieEviction(test6, arraysize(test6), 131U, 19U, nullptr);
+ TestSecureCookieEviction(test6, arraysize(test6), 131U, 0U, nullptr);
// If the same number of non-secure and secure cookies are created (50 each)
// below the per domain limit (180), and then another set of non-secure
- // cookies are created to bring the total above the per-domain limit, all
- // secure cookies will be retained, and the non-secure cookies will be culled
- // down to the limit.
+ // cookies are created to bring the total above the per-domain limit, all of
+ // the non-secure cookies will be evicted but none of the secure ones will be
+ // evicted.
const CookiesEntry test7[] = {{50U, false}, {50U, true}, {81U, false}};
- TestSecureCookieEviction(test7, arraysize(test7), 50U, 100U, nullptr);
+ TestSecureCookieEviction(test7, arraysize(test7), 50U, 0U, nullptr);
// If the same number of non-secure and secure cookies are created (50 each)
// below the per domain limit (180), and then another set of non-secure
- // cookies are created to bring the total above the per-domain limit, all
- // secure cookies will be retained, and the non-secure cookies will be culled
- // down to the limit, then the remaining non-secure cookies will be created
- // (9).
+ // cookies are created to bring the total above the per-domain limit, all of
+ // the non-secure cookies will be evicted but none of the secure ones will be
+ // evicted, and then the remaining non-secure cookies will be created (9).
const CookiesEntry test8[] = {{50U, false}, {50U, true}, {90U, false}};
- TestSecureCookieEviction(test8, arraysize(test8), 50U, 109U, nullptr);
+ TestSecureCookieEviction(test8, arraysize(test8), 50U, 9U, nullptr);
// If a number of non-secure cookies are created on other hosts (20) and are
// past the global 'safe' date, and then the number of non-secure cookies for
// a single domain are brought to the per-domain limit (180), followed by
- // another set of secure cookies on that same domain (20), all the secure
- // cookies for that domain should be retained, while the non-secure should be
- // culled down to the per-domain limit. The non-secure cookies for other
- // domains should remain untouched.
+ // another set of secure cookies on that same domain (20), all of the
+ // non-secure cookies for that domain should be evicted, but the non-secure
+ // cookies for other domains should remain, as should the secure cookies for
+ // that domain.
const CookiesEntry test9[] = {{180U, false}, {20U, true}};
const AltHosts test9_alt_hosts(0, 20);
- TestSecureCookieEviction(test9, arraysize(test9), 20U, 169U,
- &test9_alt_hosts);
+ TestSecureCookieEviction(test9, arraysize(test9), 20U, 20U, &test9_alt_hosts);
// If a number of secure cookies are created on other hosts and hit the global
// cookie limit (3300) and are past the global 'safe' date, and then a single