| OLD | NEW |
| 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 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 139 // creation date. | 139 // creation date. |
| 140 struct OrderByCreationTimeDesc { | 140 struct OrderByCreationTimeDesc { |
| 141 bool operator()(const CookieMonster::CookieMap::iterator& a, | 141 bool operator()(const CookieMonster::CookieMap::iterator& a, |
| 142 const CookieMonster::CookieMap::iterator& b) const { | 142 const CookieMonster::CookieMap::iterator& b) const { |
| 143 return a->second->CreationDate() > b->second->CreationDate(); | 143 return a->second->CreationDate() > b->second->CreationDate(); |
| 144 } | 144 } |
| 145 }; | 145 }; |
| 146 | 146 |
| 147 // Constants for use in VLOG | 147 // Constants for use in VLOG |
| 148 const int kVlogPerCookieMonster = 1; | 148 const int kVlogPerCookieMonster = 1; |
| 149 const int kVlogPeriodic = 3; | |
| 150 const int kVlogGarbageCollection = 5; | 149 const int kVlogGarbageCollection = 5; |
| 151 const int kVlogSetCookies = 7; | 150 const int kVlogSetCookies = 7; |
| 152 const int kVlogGetCookies = 9; | 151 const int kVlogGetCookies = 9; |
| 153 | 152 |
| 154 // Mozilla sorts on the path length (longest first), and then it | 153 // Mozilla sorts on the path length (longest first), and then it |
| 155 // sorts by creation time (oldest first). | 154 // sorts by creation time (oldest first). |
| 156 // The RFC says the sort order for the domain attribute is undefined. | 155 // The RFC says the sort order for the domain attribute is undefined. |
| 157 bool CookieSorter(CanonicalCookie* cc1, CanonicalCookie* cc2) { | 156 bool CookieSorter(CanonicalCookie* cc1, CanonicalCookie* cc2) { |
| 158 if (cc1->Path().length() == cc2->Path().length()) | 157 if (cc1->Path().length() == cc2->Path().length()) |
| 159 return cc1->CreationDate() < cc2->CreationDate(); | 158 return cc1->CreationDate() < cc2->CreationDate(); |
| (...skipping 1498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1658 request_task = tasks_pending_.front(); | 1657 request_task = tasks_pending_.front(); |
| 1659 tasks_pending_.pop(); | 1658 tasks_pending_.pop(); |
| 1660 } | 1659 } |
| 1661 request_task->Run(); | 1660 request_task->Run(); |
| 1662 } | 1661 } |
| 1663 } | 1662 } |
| 1664 | 1663 |
| 1665 void CookieMonster::EnsureCookiesMapIsValid() { | 1664 void CookieMonster::EnsureCookiesMapIsValid() { |
| 1666 lock_.AssertAcquired(); | 1665 lock_.AssertAcquired(); |
| 1667 | 1666 |
| 1668 int num_duplicates_trimmed = 0; | |
| 1669 | |
| 1670 // Iterate through all the of the cookies, grouped by host. | 1667 // Iterate through all the of the cookies, grouped by host. |
| 1671 CookieMap::iterator prev_range_end = cookies_.begin(); | 1668 CookieMap::iterator prev_range_end = cookies_.begin(); |
| 1672 while (prev_range_end != cookies_.end()) { | 1669 while (prev_range_end != cookies_.end()) { |
| 1673 CookieMap::iterator cur_range_begin = prev_range_end; | 1670 CookieMap::iterator cur_range_begin = prev_range_end; |
| 1674 const std::string key = cur_range_begin->first; // Keep a copy. | 1671 const std::string key = cur_range_begin->first; // Keep a copy. |
| 1675 CookieMap::iterator cur_range_end = cookies_.upper_bound(key); | 1672 CookieMap::iterator cur_range_end = cookies_.upper_bound(key); |
| 1676 prev_range_end = cur_range_end; | 1673 prev_range_end = cur_range_end; |
| 1677 | 1674 |
| 1678 // Ensure no equivalent cookies for this host. | 1675 // Ensure no equivalent cookies for this host. |
| 1679 num_duplicates_trimmed += | 1676 TrimDuplicateCookiesForKey(key, cur_range_begin, cur_range_end); |
| 1680 TrimDuplicateCookiesForKey(key, cur_range_begin, cur_range_end); | |
| 1681 } | 1677 } |
| 1682 | |
| 1683 // Record how many duplicates were found in the database. | |
| 1684 // See InitializeHistograms() for details. | |
| 1685 histogram_number_duplicate_db_cookies_->Add(num_duplicates_trimmed); | |
| 1686 } | 1678 } |
| 1687 | 1679 |
| 1688 int CookieMonster::TrimDuplicateCookiesForKey(const std::string& key, | 1680 void CookieMonster::TrimDuplicateCookiesForKey(const std::string& key, |
| 1689 CookieMap::iterator begin, | 1681 CookieMap::iterator begin, |
| 1690 CookieMap::iterator end) { | 1682 CookieMap::iterator end) { |
| 1691 lock_.AssertAcquired(); | 1683 lock_.AssertAcquired(); |
| 1692 | 1684 |
| 1693 // Set of cookies ordered by creation time. | 1685 // Set of cookies ordered by creation time. |
| 1694 typedef std::set<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet; | 1686 typedef std::set<CookieMap::iterator, OrderByCreationTimeDesc> CookieSet; |
| 1695 | 1687 |
| 1696 // Helper map we populate to find the duplicates. | 1688 // Helper map we populate to find the duplicates. |
| 1697 typedef std::map<CookieSignature, CookieSet> EquivalenceMap; | 1689 typedef std::map<CookieSignature, CookieSet> EquivalenceMap; |
| 1698 EquivalenceMap equivalent_cookies; | 1690 EquivalenceMap equivalent_cookies; |
| 1699 | 1691 |
| 1700 // The number of duplicate cookies that have been found. | 1692 // The number of duplicate cookies that have been found. |
| (...skipping 14 matching lines...) Expand all Loading... |
| 1715 | 1707 |
| 1716 // We save the iterator into |cookies_| rather than the actual cookie | 1708 // We save the iterator into |cookies_| rather than the actual cookie |
| 1717 // pointer, since we may need to delete it later. | 1709 // pointer, since we may need to delete it later. |
| 1718 bool insert_success = set.insert(it).second; | 1710 bool insert_success = set.insert(it).second; |
| 1719 DCHECK(insert_success) | 1711 DCHECK(insert_success) |
| 1720 << "Duplicate creation times found in duplicate cookie name scan."; | 1712 << "Duplicate creation times found in duplicate cookie name scan."; |
| 1721 } | 1713 } |
| 1722 | 1714 |
| 1723 // If there were no duplicates, we are done! | 1715 // If there were no duplicates, we are done! |
| 1724 if (num_duplicates == 0) | 1716 if (num_duplicates == 0) |
| 1725 return 0; | 1717 return; |
| 1726 | 1718 |
| 1727 // Make sure we find everything below that we did above. | 1719 // Make sure we find everything below that we did above. |
| 1728 int num_duplicates_found = 0; | 1720 int num_duplicates_found = 0; |
| 1729 | 1721 |
| 1730 // Otherwise, delete all the duplicate cookies, both from our in-memory store | 1722 // Otherwise, delete all the duplicate cookies, both from our in-memory store |
| 1731 // and from the backing store. | 1723 // and from the backing store. |
| 1732 for (EquivalenceMap::iterator it = equivalent_cookies.begin(); | 1724 for (EquivalenceMap::iterator it = equivalent_cookies.begin(); |
| 1733 it != equivalent_cookies.end(); ++it) { | 1725 it != equivalent_cookies.end(); ++it) { |
| 1734 const CookieSignature& signature = it->first; | 1726 const CookieSignature& signature = it->first; |
| 1735 CookieSet& dupes = it->second; | 1727 CookieSet& dupes = it->second; |
| (...skipping 15 matching lines...) Expand all Loading... |
| 1751 // Remove all the cookies identified by |dupes|. It is valid to delete our | 1743 // Remove all the cookies identified by |dupes|. It is valid to delete our |
| 1752 // list of iterators one at a time, since |cookies_| is a multimap (they | 1744 // list of iterators one at a time, since |cookies_| is a multimap (they |
| 1753 // don't invalidate existing iterators following deletion). | 1745 // don't invalidate existing iterators following deletion). |
| 1754 for (CookieSet::iterator dupes_it = dupes.begin(); dupes_it != dupes.end(); | 1746 for (CookieSet::iterator dupes_it = dupes.begin(); dupes_it != dupes.end(); |
| 1755 ++dupes_it) { | 1747 ++dupes_it) { |
| 1756 InternalDeleteCookie(*dupes_it, true, | 1748 InternalDeleteCookie(*dupes_it, true, |
| 1757 DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE); | 1749 DELETE_COOKIE_DUPLICATE_IN_BACKING_STORE); |
| 1758 } | 1750 } |
| 1759 } | 1751 } |
| 1760 DCHECK_EQ(num_duplicates, num_duplicates_found); | 1752 DCHECK_EQ(num_duplicates, num_duplicates_found); |
| 1761 | |
| 1762 return num_duplicates; | |
| 1763 } | 1753 } |
| 1764 | 1754 |
| 1765 // Note: file must be the last scheme. | 1755 // Note: file must be the last scheme. |
| 1766 const char* const CookieMonster::kDefaultCookieableSchemes[] = {"http", | 1756 const char* const CookieMonster::kDefaultCookieableSchemes[] = {"http", |
| 1767 "https", | 1757 "https", |
| 1768 "ws", | 1758 "ws", |
| 1769 "wss", | 1759 "wss", |
| 1770 "file"}; | 1760 "file"}; |
| 1771 const int CookieMonster::kDefaultCookieableSchemesCount = | 1761 const int CookieMonster::kDefaultCookieableSchemesCount = |
| 1772 arraysize(kDefaultCookieableSchemes); | 1762 arraysize(kDefaultCookieableSchemes); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1981 const Time& current) { | 1971 const Time& current) { |
| 1982 lock_.AssertAcquired(); | 1972 lock_.AssertAcquired(); |
| 1983 | 1973 |
| 1984 // Based off the Mozilla code. When a cookie has been accessed recently, | 1974 // Based off the Mozilla code. When a cookie has been accessed recently, |
| 1985 // don't bother updating its access time again. This reduces the number of | 1975 // don't bother updating its access time again. This reduces the number of |
| 1986 // updates we do during pageload, which in turn reduces the chance our storage | 1976 // updates we do during pageload, which in turn reduces the chance our storage |
| 1987 // backend will hit its batch thresholds and be forced to update. | 1977 // backend will hit its batch thresholds and be forced to update. |
| 1988 if ((current - cc->LastAccessDate()) < last_access_threshold_) | 1978 if ((current - cc->LastAccessDate()) < last_access_threshold_) |
| 1989 return; | 1979 return; |
| 1990 | 1980 |
| 1991 // See InitializeHistograms() for details. | |
| 1992 histogram_between_access_interval_minutes_->Add( | |
| 1993 (current - cc->LastAccessDate()).InMinutes()); | |
| 1994 | |
| 1995 cc->SetLastAccessDate(current); | 1981 cc->SetLastAccessDate(current); |
| 1996 if ((cc->IsPersistent() || persist_session_cookies_) && store_.get()) | 1982 if ((cc->IsPersistent() || persist_session_cookies_) && store_.get()) |
| 1997 store_->UpdateCookieAccessTime(*cc); | 1983 store_->UpdateCookieAccessTime(*cc); |
| 1998 } | 1984 } |
| 1999 | 1985 |
| 2000 // InternalDeleteCookies must not invalidate iterators other than the one being | 1986 // InternalDeleteCookies must not invalidate iterators other than the one being |
| 2001 // deleted. | 1987 // deleted. |
| 2002 void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, | 1988 void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, |
| 2003 bool sync_to_store, | 1989 bool sync_to_store, |
| 2004 DeletionCause deletion_cause) { | 1990 DeletionCause deletion_cause) { |
| (...skipping 246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2251 // If we've taken statistics recently, return. | 2237 // If we've taken statistics recently, return. |
| 2252 if (current_time - last_statistic_record_time_ <= | 2238 if (current_time - last_statistic_record_time_ <= |
| 2253 kRecordStatisticsIntervalTime) { | 2239 kRecordStatisticsIntervalTime) { |
| 2254 return; | 2240 return; |
| 2255 } | 2241 } |
| 2256 | 2242 |
| 2257 // See InitializeHistograms() for details. | 2243 // See InitializeHistograms() for details. |
| 2258 histogram_count_->Add(cookies_.size()); | 2244 histogram_count_->Add(cookies_.size()); |
| 2259 | 2245 |
| 2260 // More detailed statistics on cookie counts at different granularities. | 2246 // More detailed statistics on cookie counts at different granularities. |
| 2261 TimeTicks beginning_of_time(TimeTicks::Now()); | |
| 2262 | |
| 2263 for (CookieMap::const_iterator it_key = cookies_.begin(); | |
| 2264 it_key != cookies_.end();) { | |
| 2265 const std::string& key(it_key->first); | |
| 2266 | |
| 2267 int key_count = 0; | |
| 2268 typedef std::map<std::string, unsigned int> DomainMap; | |
| 2269 DomainMap domain_map; | |
| 2270 CookieMapItPair its_cookies = cookies_.equal_range(key); | |
| 2271 while (its_cookies.first != its_cookies.second) { | |
| 2272 key_count++; | |
| 2273 const std::string& cookie_domain(its_cookies.first->second->Domain()); | |
| 2274 domain_map[cookie_domain]++; | |
| 2275 | |
| 2276 its_cookies.first++; | |
| 2277 } | |
| 2278 histogram_etldp1_count_->Add(key_count); | |
| 2279 histogram_domain_per_etldp1_count_->Add(domain_map.size()); | |
| 2280 for (DomainMap::const_iterator domain_map_it = domain_map.begin(); | |
| 2281 domain_map_it != domain_map.end(); domain_map_it++) | |
| 2282 histogram_domain_count_->Add(domain_map_it->second); | |
| 2283 | |
| 2284 it_key = its_cookies.second; | |
| 2285 } | |
| 2286 | |
| 2287 VLOG(kVlogPeriodic) << "Time for recording cookie stats (us): " | |
| 2288 << (TimeTicks::Now() - beginning_of_time) | |
| 2289 .InMicroseconds(); | |
| 2290 | |
| 2291 last_statistic_record_time_ = current_time; | 2247 last_statistic_record_time_ = current_time; |
| 2292 } | 2248 } |
| 2293 | 2249 |
| 2294 // Initialize all histogram counter variables used in this class. | 2250 // Initialize all histogram counter variables used in this class. |
| 2295 // | 2251 // |
| 2296 // Normal histogram usage involves using the macros defined in | 2252 // Normal histogram usage involves using the macros defined in |
| 2297 // histogram.h, which automatically takes care of declaring these | 2253 // histogram.h, which automatically takes care of declaring these |
| 2298 // variables (as statics), initializing them, and accumulating into | 2254 // variables (as statics), initializing them, and accumulating into |
| 2299 // them, all from a single entry point. Unfortunately, that solution | 2255 // them, all from a single entry point. Unfortunately, that solution |
| 2300 // doesn't work for the CookieMonster, as it's vulnerable to races between | 2256 // doesn't work for the CookieMonster, as it's vulnerable to races between |
| (...skipping 11 matching lines...) Expand all Loading... |
| 2312 // To do this we've expanded out the individual histogram macros calls, | 2268 // To do this we've expanded out the individual histogram macros calls, |
| 2313 // with declarations of the variables in the class decl, initialization here | 2269 // with declarations of the variables in the class decl, initialization here |
| 2314 // (done from the class constructor) and direct calls to the accumulation | 2270 // (done from the class constructor) and direct calls to the accumulation |
| 2315 // methods where needed. The specific histogram macro calls on which the | 2271 // methods where needed. The specific histogram macro calls on which the |
| 2316 // initialization is based are included in comments below. | 2272 // initialization is based are included in comments below. |
| 2317 void CookieMonster::InitializeHistograms() { | 2273 void CookieMonster::InitializeHistograms() { |
| 2318 // From UMA_HISTOGRAM_CUSTOM_COUNTS | 2274 // From UMA_HISTOGRAM_CUSTOM_COUNTS |
| 2319 histogram_expiration_duration_minutes_ = base::Histogram::FactoryGet( | 2275 histogram_expiration_duration_minutes_ = base::Histogram::FactoryGet( |
| 2320 "Cookie.ExpirationDurationMinutes", 1, kMinutesInTenYears, 50, | 2276 "Cookie.ExpirationDurationMinutes", 1, kMinutesInTenYears, 50, |
| 2321 base::Histogram::kUmaTargetedHistogramFlag); | 2277 base::Histogram::kUmaTargetedHistogramFlag); |
| 2322 histogram_between_access_interval_minutes_ = base::Histogram::FactoryGet( | |
| 2323 "Cookie.BetweenAccessIntervalMinutes", 1, kMinutesInTenYears, 50, | |
| 2324 base::Histogram::kUmaTargetedHistogramFlag); | |
| 2325 histogram_evicted_last_access_minutes_ = base::Histogram::FactoryGet( | 2278 histogram_evicted_last_access_minutes_ = base::Histogram::FactoryGet( |
| 2326 "Cookie.EvictedLastAccessMinutes", 1, kMinutesInTenYears, 50, | 2279 "Cookie.EvictedLastAccessMinutes", 1, kMinutesInTenYears, 50, |
| 2327 base::Histogram::kUmaTargetedHistogramFlag); | 2280 base::Histogram::kUmaTargetedHistogramFlag); |
| 2328 histogram_count_ = base::Histogram::FactoryGet( | 2281 histogram_count_ = base::Histogram::FactoryGet( |
| 2329 "Cookie.Count", 1, 4000, 50, base::Histogram::kUmaTargetedHistogramFlag); | 2282 "Cookie.Count", 1, 4000, 50, base::Histogram::kUmaTargetedHistogramFlag); |
| 2330 histogram_domain_count_ = | |
| 2331 base::Histogram::FactoryGet("Cookie.DomainCount", 1, 4000, 50, | |
| 2332 base::Histogram::kUmaTargetedHistogramFlag); | |
| 2333 histogram_etldp1_count_ = | |
| 2334 base::Histogram::FactoryGet("Cookie.Etldp1Count", 1, 4000, 50, | |
| 2335 base::Histogram::kUmaTargetedHistogramFlag); | |
| 2336 histogram_domain_per_etldp1_count_ = | |
| 2337 base::Histogram::FactoryGet("Cookie.DomainPerEtldp1Count", 1, 4000, 50, | |
| 2338 base::Histogram::kUmaTargetedHistogramFlag); | |
| 2339 | |
| 2340 // From UMA_HISTOGRAM_COUNTS_10000 & UMA_HISTOGRAM_CUSTOM_COUNTS | |
| 2341 histogram_number_duplicate_db_cookies_ = | |
| 2342 base::Histogram::FactoryGet("Net.NumDuplicateCookiesInDb", 1, 10000, 50, | |
| 2343 base::Histogram::kUmaTargetedHistogramFlag); | |
| 2344 | 2283 |
| 2345 // From UMA_HISTOGRAM_ENUMERATION | 2284 // From UMA_HISTOGRAM_ENUMERATION |
| 2346 histogram_cookie_deletion_cause_ = base::LinearHistogram::FactoryGet( | 2285 histogram_cookie_deletion_cause_ = base::LinearHistogram::FactoryGet( |
| 2347 "Cookie.DeletionCause", 1, DELETE_COOKIE_LAST_ENTRY - 1, | 2286 "Cookie.DeletionCause", 1, DELETE_COOKIE_LAST_ENTRY - 1, |
| 2348 DELETE_COOKIE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); | 2287 DELETE_COOKIE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); |
| 2349 histogram_cookie_type_ = base::LinearHistogram::FactoryGet( | 2288 histogram_cookie_type_ = base::LinearHistogram::FactoryGet( |
| 2350 "Cookie.Type", 1, (1 << COOKIE_TYPE_LAST_ENTRY) - 1, | 2289 "Cookie.Type", 1, (1 << COOKIE_TYPE_LAST_ENTRY) - 1, |
| 2351 1 << COOKIE_TYPE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); | 2290 1 << COOKIE_TYPE_LAST_ENTRY, base::Histogram::kUmaTargetedHistogramFlag); |
| 2352 | 2291 |
| 2353 // From UMA_HISTOGRAM_{CUSTOM_,}TIMES | 2292 // From UMA_HISTOGRAM_{CUSTOM_,}TIMES |
| (...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2441 it != hook_map_.end(); ++it) { | 2380 it != hook_map_.end(); ++it) { |
| 2442 std::pair<GURL, std::string> key = it->first; | 2381 std::pair<GURL, std::string> key = it->first; |
| 2443 if (cookie.IncludeForRequestURL(key.first, opts) && | 2382 if (cookie.IncludeForRequestURL(key.first, opts) && |
| 2444 cookie.Name() == key.second) { | 2383 cookie.Name() == key.second) { |
| 2445 it->second->Notify(cookie, removed); | 2384 it->second->Notify(cookie, removed); |
| 2446 } | 2385 } |
| 2447 } | 2386 } |
| 2448 } | 2387 } |
| 2449 | 2388 |
| 2450 } // namespace net | 2389 } // namespace net |
| OLD | NEW |