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

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

Issue 2718011: Initial commit of CookieMonster statistics. (Closed)
Patch Set: Fix perf degradation, add requested comment. Created 10 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
« net/base/cookie_monster.h ('K') | « net/base/cookie_monster.h ('k') | no next file » | 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) 2010 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2010 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 30 matching lines...) Expand all
41 * the terms of any one of the MPL, the GPL or the LGPL. 41 * the terms of any one of the MPL, the GPL or the LGPL.
42 * 42 *
43 * ***** END LICENSE BLOCK ***** */ 43 * ***** END LICENSE BLOCK ***** */
44 44
45 #include "net/base/cookie_monster.h" 45 #include "net/base/cookie_monster.h"
46 46
47 #include <algorithm> 47 #include <algorithm>
48 48
49 #include "base/basictypes.h" 49 #include "base/basictypes.h"
50 #include "base/format_macros.h" 50 #include "base/format_macros.h"
51 #include "base/histogram.h"
52 #include "base/logging.h" 51 #include "base/logging.h"
53 #include "base/scoped_ptr.h" 52 #include "base/scoped_ptr.h"
54 #include "base/string_tokenizer.h" 53 #include "base/string_tokenizer.h"
55 #include "base/string_util.h" 54 #include "base/string_util.h"
56 #include "googleurl/src/gurl.h" 55 #include "googleurl/src/gurl.h"
57 #include "googleurl/src/url_canon.h" 56 #include "googleurl/src/url_canon.h"
58 #include "net/base/net_util.h" 57 #include "net/base/net_util.h"
59 #include "net/base/registry_controlled_domain.h" 58 #include "net/base/registry_controlled_domain.h"
60 59
61 // #define COOKIE_LOGGING_ENABLED 60 // #define COOKIE_LOGGING_ENABLED
62 #ifdef COOKIE_LOGGING_ENABLED 61 #ifdef COOKIE_LOGGING_ENABLED
63 #define COOKIE_DLOG(severity) DLOG_IF(INFO, 1) 62 #define COOKIE_DLOG(severity) DLOG_IF(INFO, 1)
64 #else 63 #else
65 #define COOKIE_DLOG(severity) DLOG_IF(INFO, 0) 64 #define COOKIE_DLOG(severity) DLOG_IF(INFO, 0)
66 #endif 65 #endif
67 66
68 using base::Time; 67 using base::Time;
69 using base::TimeDelta; 68 using base::TimeDelta;
70 69
70 static const int kMinutesInTenYears = 10 * 365 * 24 * 60;
71
71 namespace net { 72 namespace net {
72 73
73 namespace { 74 namespace {
74 75
75 // Cookie garbage collection thresholds. Based off of the Mozilla defaults. 76 // Cookie garbage collection thresholds. Based off of the Mozilla defaults.
76 // It might seem scary to have a high purge value, but really it's not. You 77 // It might seem scary to have a high purge value, but really it's not. You
77 // just make sure that you increase the max to cover the increase in purge, 78 // just make sure that you increase the max to cover the increase in purge,
78 // and we would have been purging the same amount of cookies. We're just 79 // and we would have been purging the same amount of cookies. We're just
79 // going through the garbage collection process less often. 80 // going through the garbage collection process less often.
80 const size_t kNumCookiesPerHost = 70; // ~50 cookies 81 const size_t kNumCookiesPerHost = 70; // ~50 cookies
(...skipping 22 matching lines...) Expand all
103 // static 104 // static
104 void CookieMonster::EnableFileScheme() { 105 void CookieMonster::EnableFileScheme() {
105 enable_file_scheme_ = true; 106 enable_file_scheme_ = true;
106 } 107 }
107 108
108 CookieMonster::CookieMonster(PersistentCookieStore* store, Delegate* delegate) 109 CookieMonster::CookieMonster(PersistentCookieStore* store, Delegate* delegate)
109 : initialized_(false), 110 : initialized_(false),
110 store_(store), 111 store_(store),
111 last_access_threshold_( 112 last_access_threshold_(
112 TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)), 113 TimeDelta::FromSeconds(kDefaultAccessUpdateThresholdSeconds)),
113 delegate_(delegate) { 114 delegate_(delegate),
115 last_statistic_record_time_(Time::Now()) {
114 SetDefaultCookieableSchemes(); 116 SetDefaultCookieableSchemes();
115 } 117 }
116 118
117 CookieMonster::~CookieMonster() { 119 CookieMonster::~CookieMonster() {
118 DeleteAll(false); 120 DeleteAll(false);
119 } 121 }
120 122
121 void CookieMonster::InitStore() { 123 void CookieMonster::InitStore() {
122 DCHECK(store_) << "Store must exist to initialize"; 124 DCHECK(store_) << "Store must exist to initialize";
123 125
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
234 key.c_str(), 236 key.c_str(),
235 signature.first.c_str(), 237 signature.first.c_str(),
236 signature.second.c_str()); 238 signature.second.c_str());
237 239
238 // Remove all the cookies identified by |dupes|. It is valid to delete our 240 // Remove all the cookies identified by |dupes|. It is valid to delete our
239 // list of iterators one at a time, since |cookies_| is a multimap (they 241 // list of iterators one at a time, since |cookies_| is a multimap (they
240 // don't invalidate existing iterators following deletion). 242 // don't invalidate existing iterators following deletion).
241 for (CookieList::iterator dupes_it = dupes.begin(); 243 for (CookieList::iterator dupes_it = dupes.begin();
242 dupes_it != dupes.end(); 244 dupes_it != dupes.end();
243 ++dupes_it) { 245 ++dupes_it) {
244 InternalDeleteCookie(*dupes_it, true /*sync_to_store*/); 246 InternalDeleteCookie(*dupes_it, true /*sync_to_store*/,
247 kDeleteCookieDuplicateInBackingStore);
245 } 248 }
246 } 249 }
247 250
248 return num_duplicates; 251 return num_duplicates;
249 } 252 }
250 253
251 void CookieMonster::SetDefaultCookieableSchemes() { 254 void CookieMonster::SetDefaultCookieableSchemes() {
252 // Note: file must be the last scheme. 255 // Note: file must be the last scheme.
253 static const char* kDefaultCookieableSchemes[] = { "http", "https", "file" }; 256 static const char* kDefaultCookieableSchemes[] = { "http", "https", "file" };
254 int num_schemes = enable_file_scheme_ ? 3 : 2; 257 int num_schemes = enable_file_scheme_ ? 3 : 2;
(...skipping 403 matching lines...) Expand 10 before | Expand all | Expand 10 after
658 if (DeleteAnyEquivalentCookie(cookie_domain, **cc, 661 if (DeleteAnyEquivalentCookie(cookie_domain, **cc,
659 options.exclude_httponly())) { 662 options.exclude_httponly())) {
660 COOKIE_DLOG(INFO) << "SetCookie() not clobbering httponly cookie"; 663 COOKIE_DLOG(INFO) << "SetCookie() not clobbering httponly cookie";
661 return false; 664 return false;
662 } 665 }
663 666
664 COOKIE_DLOG(INFO) << "SetCookie() cc: " << (*cc)->DebugString(); 667 COOKIE_DLOG(INFO) << "SetCookie() cc: " << (*cc)->DebugString();
665 668
666 // Realize that we might be setting an expired cookie, and the only point 669 // Realize that we might be setting an expired cookie, and the only point
667 // was to delete the cookie which we've already done. 670 // was to delete the cookie which we've already done.
668 if (!(*cc)->IsExpired(creation_time)) 671 if (!(*cc)->IsExpired(creation_time)) {
672 UMA_HISTOGRAM_CUSTOM_COUNTS(
673 "net.CookieExpirationDurationMinutes",
674 ((*cc)->ExpiryDate() - creation_time).InMinutes(),
675 1, kMinutesInTenYears, 50);
669 InternalInsertCookie(cookie_domain, cc->release(), true); 676 InternalInsertCookie(cookie_domain, cc->release(), true);
677 }
670 678
671 // We assume that hopefully setting a cookie will be less common than 679 // We assume that hopefully setting a cookie will be less common than
672 // querying a cookie. Since setting a cookie can put us over our limits, 680 // querying a cookie. Since setting a cookie can put us over our limits,
673 // make sure that we garbage collect... We can also make the assumption that 681 // make sure that we garbage collect... We can also make the assumption that
674 // if a cookie was set, in the common case it will be used soon after, 682 // if a cookie was set, in the common case it will be used soon after,
675 // and we will purge the expired cookies in GetCookies(). 683 // and we will purge the expired cookies in GetCookies().
676 GarbageCollect(creation_time, cookie_domain); 684 GarbageCollect(creation_time, cookie_domain);
677 685
678 return true; 686 return true;
679 } 687 }
(...skipping 14 matching lines...) Expand all
694 lock_.AssertAcquired(); 702 lock_.AssertAcquired();
695 703
696 // Based off the Mozilla code. When a cookie has been accessed recently, 704 // Based off the Mozilla code. When a cookie has been accessed recently,
697 // don't bother updating its access time again. This reduces the number of 705 // don't bother updating its access time again. This reduces the number of
698 // updates we do during pageload, which in turn reduces the chance our storage 706 // updates we do during pageload, which in turn reduces the chance our storage
699 // backend will hit its batch thresholds and be forced to update. 707 // backend will hit its batch thresholds and be forced to update.
700 const Time current = Time::Now(); 708 const Time current = Time::Now();
701 if ((current - cc->LastAccessDate()) < last_access_threshold_) 709 if ((current - cc->LastAccessDate()) < last_access_threshold_)
702 return; 710 return;
703 711
712 UMA_HISTOGRAM_CUSTOM_COUNTS(
713 "net.CookieBetweenAccessIntervalMinutes",
714 (current - cc->LastAccessDate()).InMinutes(),
715 1, kMinutesInTenYears, 50);
716
704 cc->SetLastAccessDate(current); 717 cc->SetLastAccessDate(current);
705 if (cc->IsPersistent() && store_) 718 if (cc->IsPersistent() && store_)
706 store_->UpdateCookieAccessTime(*cc); 719 store_->UpdateCookieAccessTime(*cc);
707 } 720 }
708 721
709 void CookieMonster::InternalDeleteCookie(CookieMap::iterator it, 722 void CookieMonster::InternalDeleteCookie(CookieMap::iterator it,
710 bool sync_to_store) { 723 bool sync_to_store,
724 DeletionCause deletion_cause) {
711 lock_.AssertAcquired(); 725 lock_.AssertAcquired();
712 726
727 UMA_HISTOGRAM_ENUMERATION("net.CookieDeletionCause", deletion_cause,
728 kDeleteCookieLastEntry);
729
713 CanonicalCookie* cc = it->second; 730 CanonicalCookie* cc = it->second;
714 COOKIE_DLOG(INFO) << "InternalDeleteCookie() cc: " << cc->DebugString(); 731 COOKIE_DLOG(INFO) << "InternalDeleteCookie() cc: " << cc->DebugString();
715 if (cc->IsPersistent() && store_ && sync_to_store) 732 if (cc->IsPersistent() && store_ && sync_to_store)
716 store_->DeleteCookie(*cc); 733 store_->DeleteCookie(*cc);
717 if (delegate_.get()) 734 if (delegate_.get())
718 delegate_->OnCookieChanged(it->first, *cc, true); 735 delegate_->OnCookieChanged(it->first, *cc, true);
719 cookies_.erase(it); 736 cookies_.erase(it);
720 delete cc; 737 delete cc;
721 } 738 }
722 739
(...skipping 11 matching lines...) Expand all
734 ++its.first; 751 ++its.first;
735 752
736 if (ecc.IsEquivalent(*cc)) { 753 if (ecc.IsEquivalent(*cc)) {
737 // We should never have more than one equivalent cookie, since they should 754 // We should never have more than one equivalent cookie, since they should
738 // overwrite each other. 755 // overwrite each other.
739 CHECK(!found_equivalent_cookie) << 756 CHECK(!found_equivalent_cookie) <<
740 "Duplicate equivalent cookies found, cookie store is corrupted."; 757 "Duplicate equivalent cookies found, cookie store is corrupted.";
741 if (skip_httponly && cc->IsHttpOnly()) { 758 if (skip_httponly && cc->IsHttpOnly()) {
742 skipped_httponly = true; 759 skipped_httponly = true;
743 } else { 760 } else {
744 InternalDeleteCookie(curit, true); 761 InternalDeleteCookie(curit, true, kDeleteCookieOverwrite);
745 } 762 }
746 found_equivalent_cookie = true; 763 found_equivalent_cookie = true;
747 } 764 }
748 } 765 }
749 return skipped_httponly; 766 return skipped_httponly;
750 } 767 }
751 768
752 int CookieMonster::GarbageCollect(const Time& current, 769 int CookieMonster::GarbageCollect(const Time& current,
753 const std::string& key) { 770 const std::string& key) {
754 lock_.AssertAcquired(); 771 lock_.AssertAcquired();
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
797 814
798 // If the range still has too many cookies, delete the least recently used. 815 // If the range still has too many cookies, delete the least recently used.
799 if (cookie_its.size() > num_max) { 816 if (cookie_its.size() > num_max) {
800 COOKIE_DLOG(INFO) << "GarbageCollectRange() Deep Garbage Collect."; 817 COOKIE_DLOG(INFO) << "GarbageCollectRange() Deep Garbage Collect.";
801 // Purge down to (|num_max| - |num_purge|) total cookies. 818 // Purge down to (|num_max| - |num_purge|) total cookies.
802 DCHECK(num_purge <= num_max); 819 DCHECK(num_purge <= num_max);
803 num_purge += cookie_its.size() - num_max; 820 num_purge += cookie_its.size() - num_max;
804 821
805 std::partial_sort(cookie_its.begin(), cookie_its.begin() + num_purge, 822 std::partial_sort(cookie_its.begin(), cookie_its.begin() + num_purge,
806 cookie_its.end(), LRUCookieSorter); 823 cookie_its.end(), LRUCookieSorter);
807 for (size_t i = 0; i < num_purge; ++i) 824 for (size_t i = 0; i < num_purge; ++i) {
808 InternalDeleteCookie(cookie_its[i], true); 825 UMA_HISTOGRAM_CUSTOM_COUNTS(
826 "net.CookieEvictedLastAccessMinutes",
827 (current - cookie_its[i]->second->LastAccessDate()).InMinutes(),
828 1, kMinutesInTenYears, 50);
829 InternalDeleteCookie(cookie_its[i], true, kDeleteCookieEvicted);
830 }
809 831
810 num_deleted += num_purge; 832 num_deleted += num_purge;
811 } 833 }
812 834
813 return num_deleted; 835 return num_deleted;
814 } 836 }
815 837
816 int CookieMonster::GarbageCollectExpired( 838 int CookieMonster::GarbageCollectExpired(
817 const Time& current, 839 const Time& current,
818 const CookieMapItPair& itpair, 840 const CookieMapItPair& itpair,
819 std::vector<CookieMap::iterator>* cookie_its) { 841 std::vector<CookieMap::iterator>* cookie_its) {
820 lock_.AssertAcquired(); 842 lock_.AssertAcquired();
821 843
822 int num_deleted = 0; 844 int num_deleted = 0;
823 for (CookieMap::iterator it = itpair.first, end = itpair.second; it != end;) { 845 for (CookieMap::iterator it = itpair.first, end = itpair.second; it != end;) {
824 CookieMap::iterator curit = it; 846 CookieMap::iterator curit = it;
825 ++it; 847 ++it;
826 848
827 if (curit->second->IsExpired(current)) { 849 if (curit->second->IsExpired(current)) {
828 InternalDeleteCookie(curit, true); 850 InternalDeleteCookie(curit, true, kDeleteCookieExpired);
829 ++num_deleted; 851 ++num_deleted;
830 } else if (cookie_its) { 852 } else if (cookie_its) {
831 cookie_its->push_back(curit); 853 cookie_its->push_back(curit);
832 } 854 }
833 } 855 }
834 856
835 return num_deleted; 857 return num_deleted;
836 } 858 }
837 859
838 int CookieMonster::DeleteAll(bool sync_to_store) { 860 int CookieMonster::DeleteAll(bool sync_to_store) {
839 AutoLock autolock(lock_); 861 AutoLock autolock(lock_);
840 InitIfNecessary(); 862 InitIfNecessary();
841 863
842 int num_deleted = 0; 864 int num_deleted = 0;
843 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { 865 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
844 CookieMap::iterator curit = it; 866 CookieMap::iterator curit = it;
845 ++it; 867 ++it;
846 InternalDeleteCookie(curit, sync_to_store); 868 InternalDeleteCookie(curit, sync_to_store,
869 sync_to_store ? kDeleteCookieExplicit :
870 kDeleteCookieDontRecord /* Destruction. */);
847 ++num_deleted; 871 ++num_deleted;
848 } 872 }
849 873
850 return num_deleted; 874 return num_deleted;
851 } 875 }
852 876
853 int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin, 877 int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin,
854 const Time& delete_end, 878 const Time& delete_end,
855 bool sync_to_store) { 879 bool sync_to_store) {
856 AutoLock autolock(lock_); 880 AutoLock autolock(lock_);
857 InitIfNecessary(); 881 InitIfNecessary();
858 882
859 int num_deleted = 0; 883 int num_deleted = 0;
860 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { 884 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
861 CookieMap::iterator curit = it; 885 CookieMap::iterator curit = it;
862 CanonicalCookie* cc = curit->second; 886 CanonicalCookie* cc = curit->second;
863 ++it; 887 ++it;
864 888
865 if (cc->CreationDate() >= delete_begin && 889 if (cc->CreationDate() >= delete_begin &&
866 (delete_end.is_null() || cc->CreationDate() < delete_end)) { 890 (delete_end.is_null() || cc->CreationDate() < delete_end)) {
867 InternalDeleteCookie(curit, sync_to_store); 891 InternalDeleteCookie(curit, sync_to_store, kDeleteCookieExplicit);
868 ++num_deleted; 892 ++num_deleted;
869 } 893 }
870 } 894 }
871 895
872 return num_deleted; 896 return num_deleted;
873 } 897 }
874 898
875 int CookieMonster::DeleteAllCreatedAfter(const Time& delete_begin, 899 int CookieMonster::DeleteAllCreatedAfter(const Time& delete_begin,
876 bool sync_to_store) { 900 bool sync_to_store) {
877 return DeleteAllCreatedBetween(delete_begin, Time(), sync_to_store); 901 return DeleteAllCreatedBetween(delete_begin, Time(), sync_to_store);
878 } 902 }
879 903
880 int CookieMonster::DeleteAllForURL(const GURL& url, 904 int CookieMonster::DeleteAllForURL(const GURL& url,
881 bool sync_to_store) { 905 bool sync_to_store) {
882 AutoLock autolock(lock_); 906 AutoLock autolock(lock_);
883 InitIfNecessary(); 907 InitIfNecessary();
884 908
885 CookieList cookies = InternalGetAllCookiesForURL(url); 909 CookieList cookies = InternalGetAllCookiesForURL(url);
886 int num_deleted = 0; 910 int num_deleted = 0;
887 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { 911 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
888 CookieMap::iterator curit = it; 912 CookieMap::iterator curit = it;
889 ++it; 913 ++it;
890 InternalDeleteCookie(curit, sync_to_store); 914 InternalDeleteCookie(curit, sync_to_store, kDeleteCookieExplicit);
891 } 915 }
892 return num_deleted; 916 return num_deleted;
893 } 917 }
894 918
895 bool CookieMonster::DeleteCookie(const std::string& domain, 919 bool CookieMonster::DeleteCookie(const std::string& domain,
896 const CanonicalCookie& cookie, 920 const CanonicalCookie& cookie,
897 bool sync_to_store) { 921 bool sync_to_store) {
898 AutoLock autolock(lock_); 922 AutoLock autolock(lock_);
899 InitIfNecessary(); 923 InitIfNecessary();
900 924
901 for (CookieMapItPair its = cookies_.equal_range(domain); 925 for (CookieMapItPair its = cookies_.equal_range(domain);
902 its.first != its.second; ++its.first) { 926 its.first != its.second; ++its.first) {
903 // The creation date acts as our unique index... 927 // The creation date acts as our unique index...
904 if (its.first->second->CreationDate() == cookie.CreationDate()) { 928 if (its.first->second->CreationDate() == cookie.CreationDate()) {
905 InternalDeleteCookie(its.first, sync_to_store); 929 InternalDeleteCookie(its.first, sync_to_store, kDeleteCookieExplicit);
906 return true; 930 return true;
907 } 931 }
908 } 932 }
909 return false; 933 return false;
910 } 934 }
911 935
912 // Mozilla sorts on the path length (longest first), and then it 936 // Mozilla sorts on the path length (longest first), and then it
913 // sorts by creation time (oldest first). 937 // sorts by creation time (oldest first).
914 // The RFC says the sort order for the domain attribute is undefined. 938 // The RFC says the sort order for the domain attribute is undefined.
915 static bool CookieSorter(CookieMonster::CanonicalCookie* cc1, 939 static bool CookieSorter(CookieMonster::CanonicalCookie* cc1,
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
989 if ((*it)->Name() != cookie_name) 1013 if ((*it)->Name() != cookie_name)
990 continue; 1014 continue;
991 if (url.path().find((*it)->Path())) 1015 if (url.path().find((*it)->Path()))
992 continue; 1016 continue;
993 matching_cookies.insert(*it); 1017 matching_cookies.insert(*it);
994 } 1018 }
995 1019
996 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { 1020 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) {
997 CookieMap::iterator curit = it; 1021 CookieMap::iterator curit = it;
998 ++it; 1022 ++it;
999 if (matching_cookies.find(curit->second) != matching_cookies.end()) 1023 if (matching_cookies.find(curit->second) != matching_cookies.end()) {
1000 InternalDeleteCookie(curit, true); 1024 InternalDeleteCookie(curit, true, kDeleteCookieExplicit);
1025 }
1001 } 1026 }
1002 } 1027 }
1003 1028
1004 CookieMonster::CookieList CookieMonster::GetAllCookies() { 1029 CookieMonster::CookieList CookieMonster::GetAllCookies() {
1005 AutoLock autolock(lock_); 1030 AutoLock autolock(lock_);
1006 InitIfNecessary(); 1031 InitIfNecessary();
1007 1032
1008 // This function is being called to scrape the cookie list for management UI 1033 // This function is being called to scrape the cookie list for management UI
1009 // or similar. We shouldn't show expired cookies in this list since it will 1034 // or similar. We shouldn't show expired cookies in this list since it will
1010 // just be confusing to users, and this function is called rarely enough (and 1035 // just be confusing to users, and this function is called rarely enough (and
(...skipping 21 matching lines...) Expand all
1032 } 1057 }
1033 1058
1034 void CookieMonster::FindCookiesForHostAndDomain( 1059 void CookieMonster::FindCookiesForHostAndDomain(
1035 const GURL& url, 1060 const GURL& url,
1036 const CookieOptions& options, 1061 const CookieOptions& options,
1037 std::vector<CanonicalCookie*>* cookies) { 1062 std::vector<CanonicalCookie*>* cookies) {
1038 lock_.AssertAcquired(); 1063 lock_.AssertAcquired();
1039 1064
1040 const Time current_time(CurrentTime()); 1065 const Time current_time(CurrentTime());
1041 1066
1067 // Probe to save statistics relatively frequently. We do it here rather
1068 // than in the set path as many websites won't set cookies, and we
1069 // want to collect statistics whenever the browser's being used.
1070 RecordPeriodicStats(current_time);
1071
1042 // Query for the full host, For example: 'a.c.blah.com'. 1072 // Query for the full host, For example: 'a.c.blah.com'.
1043 std::string key(url.host()); 1073 std::string key(url.host());
1044 FindCookiesForKey(key, url, options, current_time, cookies); 1074 FindCookiesForKey(key, url, options, current_time, cookies);
1045 1075
1046 // See if we can search for domain cookies, i.e. if the host has a TLD + 1. 1076 // See if we can search for domain cookies, i.e. if the host has a TLD + 1.
1047 const std::string domain(GetEffectiveDomain(url.scheme(), key)); 1077 const std::string domain(GetEffectiveDomain(url.scheme(), key));
1048 if (domain.empty()) 1078 if (domain.empty())
1049 return; 1079 return;
1050 DCHECK_LE(domain.length(), key.length()); 1080 DCHECK_LE(domain.length(), key.length());
1051 DCHECK_EQ(0, key.compare(key.length() - domain.length(), domain.length(), 1081 DCHECK_EQ(0, key.compare(key.length() - domain.length(), domain.length(),
(...skipping 22 matching lines...) Expand all
1074 bool secure = url.SchemeIsSecure(); 1104 bool secure = url.SchemeIsSecure();
1075 1105
1076 for (CookieMapItPair its = cookies_.equal_range(key); 1106 for (CookieMapItPair its = cookies_.equal_range(key);
1077 its.first != its.second; ) { 1107 its.first != its.second; ) {
1078 CookieMap::iterator curit = its.first; 1108 CookieMap::iterator curit = its.first;
1079 CanonicalCookie* cc = curit->second; 1109 CanonicalCookie* cc = curit->second;
1080 ++its.first; 1110 ++its.first;
1081 1111
1082 // If the cookie is expired, delete it. 1112 // If the cookie is expired, delete it.
1083 if (cc->IsExpired(current)) { 1113 if (cc->IsExpired(current)) {
1084 InternalDeleteCookie(curit, true); 1114 InternalDeleteCookie(curit, true, kDeleteCookieExpired);
1085 continue; 1115 continue;
1086 } 1116 }
1087 1117
1088 // Filter out HttpOnly cookies, per options. 1118 // Filter out HttpOnly cookies, per options.
1089 if (options.exclude_httponly() && cc->IsHttpOnly()) 1119 if (options.exclude_httponly() && cc->IsHttpOnly())
1090 continue; 1120 continue;
1091 1121
1092 // Filter out secure cookies unless we're https. 1122 // Filter out secure cookies unless we're https.
1093 if (!secure && cc->IsSecure()) 1123 if (!secure && cc->IsSecure())
1094 continue; 1124 continue;
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1149 DCHECK_EQ(0, key.compare(key.length() - domain.length(), domain.length(), 1179 DCHECK_EQ(0, key.compare(key.length() - domain.length(), domain.length(),
1150 domain)); 1180 domain));
1151 for (key = "." + key; key.length() > domain.length(); ) { 1181 for (key = "." + key; key.length() > domain.length(); ) {
1152 FindRawCookies(key, secure, url.path(), &cookie_list); 1182 FindRawCookies(key, secure, url.path(), &cookie_list);
1153 const size_t next_dot = key.find('.', 1); // Skip over leading dot. 1183 const size_t next_dot = key.find('.', 1); // Skip over leading dot.
1154 key.erase(0, next_dot); 1184 key.erase(0, next_dot);
1155 } 1185 }
1156 return cookie_list; 1186 return cookie_list;
1157 } 1187 }
1158 1188
1189 // Test to see if stats should be recorded, and record them if so.
1190 // The goal here is to get sampling for the average browser-hour of
1191 // activity. We won't take samples when the web isn't being surfed,
1192 // and when the web is being surfed, we'll take samples about every
1193 // kRecordStatisticsIntervalSeconds.
1194 // last_statistic_record_time_ is initialized to Now() rather than null
1195 // in the constructor so that we won't take statistics right after
1196 // startup, to avoid bias from browsers that are started but not used.
1197 void CookieMonster::RecordPeriodicStats(const base::Time &current_time) {
1198 const base::TimeDelta kRecordStatisticsIntervalTime(
1199 base::TimeDelta::FromSeconds(kRecordStatisticsIntervalSeconds));
1200
1201 if (current_time - last_statistic_record_time_ >
1202 kRecordStatisticsIntervalTime) {
1203 UMA_HISTOGRAM_CUSTOM_COUNTS("net.CookieCount", cookies_.size(),
1204 1, 4000, 50);
1205 last_statistic_record_time_ = current_time;
1206 }
1207 }
1208
1159 CookieMonster::ParsedCookie::ParsedCookie(const std::string& cookie_line) 1209 CookieMonster::ParsedCookie::ParsedCookie(const std::string& cookie_line)
1160 : is_valid_(false), 1210 : is_valid_(false),
1161 path_index_(0), 1211 path_index_(0),
1162 domain_index_(0), 1212 domain_index_(0),
1163 expires_index_(0), 1213 expires_index_(0),
1164 maxage_index_(0), 1214 maxage_index_(0),
1165 secure_index_(0), 1215 secure_index_(0),
1166 httponly_index_(0) { 1216 httponly_index_(0) {
1167 1217
1168 if (cookie_line.size() > kMaxCookieSize) { 1218 if (cookie_line.size() > kMaxCookieSize) {
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1515 return true; 1565 return true;
1516 } 1566 }
1517 1567
1518 std::string CookieMonster::CanonicalCookie::DebugString() const { 1568 std::string CookieMonster::CanonicalCookie::DebugString() const {
1519 return StringPrintf("name: %s value: %s path: %s creation: %" PRId64, 1569 return StringPrintf("name: %s value: %s path: %s creation: %" PRId64,
1520 name_.c_str(), value_.c_str(), path_.c_str(), 1570 name_.c_str(), value_.c_str(), path_.c_str(),
1521 static_cast<int64>(creation_date_.ToTimeT())); 1571 static_cast<int64>(creation_date_.ToTimeT()));
1522 } 1572 }
1523 1573
1524 } // namespace 1574 } // namespace
OLDNEW
« net/base/cookie_monster.h ('K') | « net/base/cookie_monster.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698