Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(299)

Side by Side Diff: net/cookies/cookie_monster.cc

Issue 2924933002: Fix CookieMonster garbage collection when no insecure cookies. (Closed)
Patch Set: Oops Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/cookies/cookie_monster.h ('k') | net/cookies/cookie_monster_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // Portions of this code based on Mozilla: 5 // Portions of this code based on Mozilla:
6 // (netwerk/cookie/src/nsCookieService.cpp) 6 // (netwerk/cookie/src/nsCookieService.cpp)
7 /* ***** BEGIN LICENSE BLOCK ***** 7 /* ***** BEGIN LICENSE BLOCK *****
8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1 8 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
9 * 9 *
10 * The contents of this file are subject to the Mozilla Public License Version 10 * The contents of this file are subject to the Mozilla Public License Version
(...skipping 204 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 215
216 return path.compare(cs.path) < 0; 216 return path.compare(cs.path) < 0;
217 } 217 }
218 218
219 std::string name; 219 std::string name;
220 std::string domain; 220 std::string domain;
221 std::string path; 221 std::string path;
222 }; 222 };
223 223
224 // For a CookieItVector iterator range [|it_begin|, |it_end|), 224 // For a CookieItVector iterator range [|it_begin|, |it_end|),
225 // sorts the first |num_sort| + 1 elements by LastAccessDate(). 225 // sorts the first |num_sort| elements by LastAccessDate().
226 // The + 1 element exists so for any interval of length <= |num_sort| starting
227 // from |cookies_its_begin|, a LastAccessDate() bound can be found.
228 void SortLeastRecentlyAccessed(CookieMonster::CookieItVector::iterator it_begin, 226 void SortLeastRecentlyAccessed(CookieMonster::CookieItVector::iterator it_begin,
229 CookieMonster::CookieItVector::iterator it_end, 227 CookieMonster::CookieItVector::iterator it_end,
230 size_t num_sort) { 228 size_t num_sort) {
231 DCHECK_LT(static_cast<int>(num_sort), it_end - it_begin); 229 DCHECK_LE(static_cast<int>(num_sort), it_end - it_begin);
232 std::partial_sort(it_begin, it_begin + num_sort + 1, it_end, LRACookieSorter); 230 std::partial_sort(it_begin, it_begin + num_sort, it_end, LRACookieSorter);
233 } 231 }
234 232
235 // Given a single cookie vector |cookie_its|, pushs all of the secure cookies in 233 // Given a single cookie vector |cookie_its|, pushs all of the secure cookies in
236 // |cookie_its| into |secure_cookie_its| and all of the non-secure cookies into 234 // |cookie_its| into |secure_cookie_its| and all of the non-secure cookies into
237 // |non_secure_cookie_its|. Both |secure_cookie_its| and |non_secure_cookie_its| 235 // |non_secure_cookie_its|. Both |secure_cookie_its| and |non_secure_cookie_its|
238 // must be non-NULL. 236 // must be non-NULL.
239 void SplitCookieVectorIntoSecureAndNonSecure( 237 void SplitCookieVectorIntoSecureAndNonSecure(
240 const CookieMonster::CookieItVector& cookie_its, 238 const CookieMonster::CookieItVector& cookie_its,
241 CookieMonster::CookieItVector* secure_cookie_its, 239 CookieMonster::CookieItVector* secure_cookie_its,
242 CookieMonster::CookieItVector* non_secure_cookie_its) { 240 CookieMonster::CookieItVector* non_secure_cookie_its) {
(...skipping 1772 matching lines...) Expand 10 before | Expand all | Expand 10 after
2015 if (cookie_its.size() > kMaxCookies) { 2013 if (cookie_its.size() > kMaxCookies) {
2016 VLOG(kVlogGarbageCollection) << "Deep Garbage Collect everything."; 2014 VLOG(kVlogGarbageCollection) << "Deep Garbage Collect everything.";
2017 size_t purge_goal = cookie_its.size() - (kMaxCookies - kPurgeCookies); 2015 size_t purge_goal = cookie_its.size() - (kMaxCookies - kPurgeCookies);
2018 DCHECK(purge_goal > kPurgeCookies); 2016 DCHECK(purge_goal > kPurgeCookies);
2019 2017
2020 CookieItVector secure_cookie_its; 2018 CookieItVector secure_cookie_its;
2021 CookieItVector non_secure_cookie_its; 2019 CookieItVector non_secure_cookie_its;
2022 SplitCookieVectorIntoSecureAndNonSecure(cookie_its, &secure_cookie_its, 2020 SplitCookieVectorIntoSecureAndNonSecure(cookie_its, &secure_cookie_its,
2023 &non_secure_cookie_its); 2021 &non_secure_cookie_its);
2024 size_t non_secure_purge_goal = 2022 size_t non_secure_purge_goal =
2025 std::min<size_t>(purge_goal, non_secure_cookie_its.size() - 1); 2023 std::min<size_t>(purge_goal, non_secure_cookie_its.size());
2026 2024
2025 base::Time earliest_non_secure_access_time;
2027 size_t just_deleted = GarbageCollectLeastRecentlyAccessed( 2026 size_t just_deleted = GarbageCollectLeastRecentlyAccessed(
2028 current, safe_date, non_secure_purge_goal, non_secure_cookie_its); 2027 current, safe_date, non_secure_purge_goal, non_secure_cookie_its,
2028 &earliest_non_secure_access_time);
2029 num_deleted += just_deleted; 2029 num_deleted += just_deleted;
2030 2030
2031 if (just_deleted < purge_goal && secure_cookie_its.size() > 0) { 2031 if (secure_cookie_its.size() == 0) {
2032 size_t secure_purge_goal = std::min<size_t>( 2032 // This case is unlikely, but should still update
2033 purge_goal - just_deleted, secure_cookie_its.size() - 1); 2033 // |earliest_access_time_| if only have non-secure cookies.
2034 earliest_access_time_ = earliest_non_secure_access_time;
2035 // Garbage collection can't delete all cookies.
2036 DCHECK(!earliest_access_time_.is_null());
2037 } else if (just_deleted < purge_goal) {
2038 size_t secure_purge_goal = std::min<size_t>(purge_goal - just_deleted,
2039 secure_cookie_its.size());
2040 base::Time earliest_secure_access_time;
2034 num_deleted += GarbageCollectLeastRecentlyAccessed( 2041 num_deleted += GarbageCollectLeastRecentlyAccessed(
2035 current, safe_date, secure_purge_goal, secure_cookie_its); 2042 current, safe_date, secure_purge_goal, secure_cookie_its,
2043 &earliest_secure_access_time);
2044
2045 if (!earliest_non_secure_access_time.is_null() &&
2046 earliest_non_secure_access_time < earliest_secure_access_time) {
2047 earliest_access_time_ = earliest_non_secure_access_time;
2048 } else {
2049 earliest_access_time_ = earliest_secure_access_time;
2050 }
2051
2052 // Garbage collection can't delete all cookies.
2053 DCHECK(!earliest_access_time_.is_null());
2036 } 2054 }
2055
2056 // If there are secure cookies, but deleting non-secure cookies was enough
2057 // to meet the purge goal, secure cookies are never examined, so
2058 // |earliest_access_time_| can't be determined. Leaving it alone will mean
2059 // it's no later than the real earliest last access time, so this won't
2060 // lead to any problems.
2037 } 2061 }
2038 } 2062 }
2039 2063
2040 return num_deleted; 2064 return num_deleted;
2041 } 2065 }
2042 2066
2043 size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies, 2067 size_t CookieMonster::PurgeLeastRecentMatches(CookieItVector* cookies,
2044 CookiePriority priority, 2068 CookiePriority priority,
2045 size_t to_protect, 2069 size_t to_protect,
2046 size_t purge_goal, 2070 size_t purge_goal,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 (current - (*it)->second->LastAccessDate()).InMinutes()); 2149 (current - (*it)->second->LastAccessDate()).InMinutes());
2126 InternalDeleteCookie((*it), true, cause); 2150 InternalDeleteCookie((*it), true, cause);
2127 } 2151 }
2128 return it_end - it_begin; 2152 return it_end - it_begin;
2129 } 2153 }
2130 2154
2131 size_t CookieMonster::GarbageCollectLeastRecentlyAccessed( 2155 size_t CookieMonster::GarbageCollectLeastRecentlyAccessed(
2132 const base::Time& current, 2156 const base::Time& current,
2133 const base::Time& safe_date, 2157 const base::Time& safe_date,
2134 size_t purge_goal, 2158 size_t purge_goal,
2135 CookieItVector cookie_its) { 2159 CookieItVector cookie_its,
2160 base::Time* earliest_time) {
2161 DCHECK_LE(purge_goal, cookie_its.size());
2136 DCHECK(thread_checker_.CalledOnValidThread()); 2162 DCHECK(thread_checker_.CalledOnValidThread());
2137 2163
2138 // Sorts up to *and including* |cookie_its[purge_goal]|, so 2164 // Sorts up to *and including* |cookie_its[purge_goal]| (if it exists), so
2139 // |earliest_access_time| will be properly assigned even if 2165 // |earliest_time| will be properly assigned even if
2140 // |global_purge_it| == |cookie_its.begin() + purge_goal|. 2166 // |global_purge_it| == |cookie_its.begin() + purge_goal|.
2141 SortLeastRecentlyAccessed(cookie_its.begin(), cookie_its.end(), purge_goal); 2167 SortLeastRecentlyAccessed(
2168 cookie_its.begin(), cookie_its.end(),
2169 cookie_its.size() < purge_goal ? purge_goal + 1 : purge_goal);
2142 // Find boundary to cookies older than safe_date. 2170 // Find boundary to cookies older than safe_date.
2143 CookieItVector::iterator global_purge_it = LowerBoundAccessDate( 2171 CookieItVector::iterator global_purge_it = LowerBoundAccessDate(
2144 cookie_its.begin(), cookie_its.begin() + purge_goal, safe_date); 2172 cookie_its.begin(), cookie_its.begin() + purge_goal, safe_date);
2145 // Only delete the old cookies and delete non-secure ones first. 2173 // Only delete the old cookies and delete non-secure ones first.
2146 size_t num_deleted = 2174 size_t num_deleted =
2147 GarbageCollectDeleteRange(current, DELETE_COOKIE_EVICTED_GLOBAL, 2175 GarbageCollectDeleteRange(current, DELETE_COOKIE_EVICTED_GLOBAL,
2148 cookie_its.begin(), global_purge_it); 2176 cookie_its.begin(), global_purge_it);
2149 // Set access day to the oldest cookie that wasn't deleted. 2177 if (global_purge_it != cookie_its.end())
2150 earliest_access_time_ = (*global_purge_it)->second->LastAccessDate(); 2178 *earliest_time = (*global_purge_it)->second->LastAccessDate();
2151 return num_deleted; 2179 return num_deleted;
2152 } 2180 }
2153 2181
2154 // A wrapper around registry_controlled_domains::GetDomainAndRegistry 2182 // A wrapper around registry_controlled_domains::GetDomainAndRegistry
2155 // to make clear we're creating a key for our local map. Here and 2183 // to make clear we're creating a key for our local map. Here and
2156 // in FindCookiesForHostAndDomain() are the only two places where 2184 // in FindCookiesForHostAndDomain() are the only two places where
2157 // we need to conditionalize based on key type. 2185 // we need to conditionalize based on key type.
2158 // 2186 //
2159 // Note that this key algorithm explicitly ignores the scheme. This is 2187 // Note that this key algorithm explicitly ignores the scheme. This is
2160 // because when we're entering cookies into the map from the backing store, 2188 // because when we're entering cookies into the map from the backing store,
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
2414 it != hook_map_.end(); ++it) { 2442 it != hook_map_.end(); ++it) {
2415 std::pair<GURL, std::string> key = it->first; 2443 std::pair<GURL, std::string> key = it->first;
2416 if (cookie.IncludeForRequestURL(key.first, opts) && 2444 if (cookie.IncludeForRequestURL(key.first, opts) &&
2417 cookie.Name() == key.second) { 2445 cookie.Name() == key.second) {
2418 it->second->Notify(cookie, cause); 2446 it->second->Notify(cookie, cause);
2419 } 2447 }
2420 } 2448 }
2421 } 2449 }
2422 2450
2423 } // namespace net 2451 } // namespace net
OLDNEW
« no previous file with comments | « net/cookies/cookie_monster.h ('k') | net/cookies/cookie_monster_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698