OLD | NEW |
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 531 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
542 } | 542 } |
543 } | 543 } |
544 | 544 |
545 // The scheme didn't match any in our whitelist. | 545 // The scheme didn't match any in our whitelist. |
546 COOKIE_DLOG(WARNING) << "Unsupported cookie scheme: " << url.scheme(); | 546 COOKIE_DLOG(WARNING) << "Unsupported cookie scheme: " << url.scheme(); |
547 return false; | 547 return false; |
548 } | 548 } |
549 | 549 |
550 void CookieMonster::SetCookieableSchemes( | 550 void CookieMonster::SetCookieableSchemes( |
551 const char* schemes[], size_t num_schemes) { | 551 const char* schemes[], size_t num_schemes) { |
| 552 DCHECK(CalledOnValidThread()); |
552 AutoLock autolock(lock_); | 553 AutoLock autolock(lock_); |
553 | 554 |
554 cookieable_schemes_.clear(); | 555 cookieable_schemes_.clear(); |
555 cookieable_schemes_.insert(cookieable_schemes_.end(), | 556 cookieable_schemes_.insert(cookieable_schemes_.end(), |
556 schemes, schemes + num_schemes); | 557 schemes, schemes + num_schemes); |
557 } | 558 } |
558 | 559 |
559 bool CookieMonster::SetCookieWithCreationTimeAndOptions( | 560 bool CookieMonster::SetCookieWithCreationTimeAndOptions( |
560 const GURL& url, | 561 const GURL& url, |
561 const std::string& cookie_line, | 562 const std::string& cookie_line, |
562 const Time& creation_time_or_null, | 563 const Time& creation_time_or_null, |
563 const CookieOptions& options) { | 564 const CookieOptions& options) { |
| 565 DCHECK(CalledOnValidThread()); |
564 AutoLock autolock(lock_); | 566 AutoLock autolock(lock_); |
565 | 567 |
566 if (!HasCookieableScheme(url)) { | 568 if (!HasCookieableScheme(url)) { |
567 return false; | 569 return false; |
568 } | 570 } |
569 | 571 |
570 InitIfNecessary(); | 572 InitIfNecessary(); |
571 | 573 |
572 COOKIE_DLOG(INFO) << "SetCookie() line: " << cookie_line; | 574 COOKIE_DLOG(INFO) << "SetCookie() line: " << cookie_line; |
573 | 575 |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
609 COOKIE_DLOG(WARNING) << "Failed to allocate CanonicalCookie"; | 611 COOKIE_DLOG(WARNING) << "Failed to allocate CanonicalCookie"; |
610 return false; | 612 return false; |
611 } | 613 } |
612 return SetCanonicalCookie(&cc, cookie_domain, creation_time, options); | 614 return SetCanonicalCookie(&cc, cookie_domain, creation_time, options); |
613 } | 615 } |
614 | 616 |
615 bool CookieMonster::SetCookieWithDetails( | 617 bool CookieMonster::SetCookieWithDetails( |
616 const GURL& url, const std::string& name, const std::string& value, | 618 const GURL& url, const std::string& name, const std::string& value, |
617 const std::string& domain, const std::string& path, | 619 const std::string& domain, const std::string& path, |
618 const base::Time& expiration_time, bool secure, bool http_only) { | 620 const base::Time& expiration_time, bool secure, bool http_only) { |
| 621 DCHECK(CalledOnValidThread()); |
619 | 622 |
620 // Expect a valid domain attribute with no illegal characters. | 623 // Expect a valid domain attribute with no illegal characters. |
621 std::string parsed_domain = ParsedCookie::ParseValueString(domain); | 624 std::string parsed_domain = ParsedCookie::ParseValueString(domain); |
622 if (parsed_domain != domain) | 625 if (parsed_domain != domain) |
623 return false; | 626 return false; |
624 std::string cookie_domain; | 627 std::string cookie_domain; |
625 if (!GetCookieDomainKeyWithString(url, parsed_domain, &cookie_domain)) | 628 if (!GetCookieDomainKeyWithString(url, parsed_domain, &cookie_domain)) |
626 return false; | 629 return false; |
627 | 630 |
628 AutoLock autolock(lock_); | 631 AutoLock autolock(lock_); |
(...skipping 197 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
826 ++num_deleted; | 829 ++num_deleted; |
827 } else if (cookie_its) { | 830 } else if (cookie_its) { |
828 cookie_its->push_back(curit); | 831 cookie_its->push_back(curit); |
829 } | 832 } |
830 } | 833 } |
831 | 834 |
832 return num_deleted; | 835 return num_deleted; |
833 } | 836 } |
834 | 837 |
835 int CookieMonster::DeleteAll(bool sync_to_store) { | 838 int CookieMonster::DeleteAll(bool sync_to_store) { |
| 839 DCHECK(CalledOnValidThread()); |
836 AutoLock autolock(lock_); | 840 AutoLock autolock(lock_); |
837 InitIfNecessary(); | 841 InitIfNecessary(); |
838 | 842 |
839 int num_deleted = 0; | 843 int num_deleted = 0; |
840 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { | 844 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
841 CookieMap::iterator curit = it; | 845 CookieMap::iterator curit = it; |
842 ++it; | 846 ++it; |
843 InternalDeleteCookie(curit, sync_to_store); | 847 InternalDeleteCookie(curit, sync_to_store); |
844 ++num_deleted; | 848 ++num_deleted; |
845 } | 849 } |
846 | 850 |
847 return num_deleted; | 851 return num_deleted; |
848 } | 852 } |
849 | 853 |
850 int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin, | 854 int CookieMonster::DeleteAllCreatedBetween(const Time& delete_begin, |
851 const Time& delete_end, | 855 const Time& delete_end, |
852 bool sync_to_store) { | 856 bool sync_to_store) { |
| 857 DCHECK(CalledOnValidThread()); |
853 AutoLock autolock(lock_); | 858 AutoLock autolock(lock_); |
854 InitIfNecessary(); | 859 InitIfNecessary(); |
855 | 860 |
856 int num_deleted = 0; | 861 int num_deleted = 0; |
857 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { | 862 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
858 CookieMap::iterator curit = it; | 863 CookieMap::iterator curit = it; |
859 CanonicalCookie* cc = curit->second; | 864 CanonicalCookie* cc = curit->second; |
860 ++it; | 865 ++it; |
861 | 866 |
862 if (cc->CreationDate() >= delete_begin && | 867 if (cc->CreationDate() >= delete_begin && |
863 (delete_end.is_null() || cc->CreationDate() < delete_end)) { | 868 (delete_end.is_null() || cc->CreationDate() < delete_end)) { |
864 InternalDeleteCookie(curit, sync_to_store); | 869 InternalDeleteCookie(curit, sync_to_store); |
865 ++num_deleted; | 870 ++num_deleted; |
866 } | 871 } |
867 } | 872 } |
868 | 873 |
869 return num_deleted; | 874 return num_deleted; |
870 } | 875 } |
871 | 876 |
872 int CookieMonster::DeleteAllCreatedAfter(const Time& delete_begin, | 877 int CookieMonster::DeleteAllCreatedAfter(const Time& delete_begin, |
873 bool sync_to_store) { | 878 bool sync_to_store) { |
| 879 DCHECK(CalledOnValidThread()); |
874 return DeleteAllCreatedBetween(delete_begin, Time(), sync_to_store); | 880 return DeleteAllCreatedBetween(delete_begin, Time(), sync_to_store); |
875 } | 881 } |
876 | 882 |
877 int CookieMonster::DeleteAllForURL(const GURL& url, | 883 int CookieMonster::DeleteAllForURL(const GURL& url, |
878 bool sync_to_store) { | 884 bool sync_to_store) { |
| 885 DCHECK(CalledOnValidThread()); |
879 AutoLock autolock(lock_); | 886 AutoLock autolock(lock_); |
880 InitIfNecessary(); | 887 InitIfNecessary(); |
881 | 888 |
882 CookieList cookies = InternalGetAllCookiesForURL(url); | 889 CookieList cookies = InternalGetAllCookiesForURL(url); |
883 int num_deleted = 0; | 890 int num_deleted = 0; |
884 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { | 891 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
885 CookieMap::iterator curit = it; | 892 CookieMap::iterator curit = it; |
886 ++it; | 893 ++it; |
887 InternalDeleteCookie(curit, sync_to_store); | 894 InternalDeleteCookie(curit, sync_to_store); |
888 } | 895 } |
889 return num_deleted; | 896 return num_deleted; |
890 } | 897 } |
891 | 898 |
892 bool CookieMonster::DeleteCookie(const std::string& domain, | 899 bool CookieMonster::DeleteCookie(const std::string& domain, |
893 const CanonicalCookie& cookie, | 900 const CanonicalCookie& cookie, |
894 bool sync_to_store) { | 901 bool sync_to_store) { |
| 902 DCHECK(CalledOnValidThread()); |
895 AutoLock autolock(lock_); | 903 AutoLock autolock(lock_); |
896 InitIfNecessary(); | 904 InitIfNecessary(); |
897 | 905 |
898 for (CookieMapItPair its = cookies_.equal_range(domain); | 906 for (CookieMapItPair its = cookies_.equal_range(domain); |
899 its.first != its.second; ++its.first) { | 907 its.first != its.second; ++its.first) { |
900 // The creation date acts as our unique index... | 908 // The creation date acts as our unique index... |
901 if (its.first->second->CreationDate() == cookie.CreationDate()) { | 909 if (its.first->second->CreationDate() == cookie.CreationDate()) { |
902 InternalDeleteCookie(its.first, sync_to_store); | 910 InternalDeleteCookie(its.first, sync_to_store); |
903 return true; | 911 return true; |
904 } | 912 } |
905 } | 913 } |
906 return false; | 914 return false; |
907 } | 915 } |
908 | 916 |
909 // Mozilla sorts on the path length (longest first), and then it | 917 // Mozilla sorts on the path length (longest first), and then it |
910 // sorts by creation time (oldest first). | 918 // sorts by creation time (oldest first). |
911 // The RFC says the sort order for the domain attribute is undefined. | 919 // The RFC says the sort order for the domain attribute is undefined. |
912 static bool CookieSorter(CookieMonster::CanonicalCookie* cc1, | 920 static bool CookieSorter(CookieMonster::CanonicalCookie* cc1, |
913 CookieMonster::CanonicalCookie* cc2) { | 921 CookieMonster::CanonicalCookie* cc2) { |
914 if (cc1->Path().length() == cc2->Path().length()) | 922 if (cc1->Path().length() == cc2->Path().length()) |
915 return cc1->CreationDate() < cc2->CreationDate(); | 923 return cc1->CreationDate() < cc2->CreationDate(); |
916 return cc1->Path().length() > cc2->Path().length(); | 924 return cc1->Path().length() > cc2->Path().length(); |
917 } | 925 } |
918 | 926 |
919 bool CookieMonster::SetCookieWithOptions(const GURL& url, | 927 bool CookieMonster::SetCookieWithOptions(const GURL& url, |
920 const std::string& cookie_line, | 928 const std::string& cookie_line, |
921 const CookieOptions& options) { | 929 const CookieOptions& options) { |
| 930 DCHECK(CalledOnValidThread()); |
922 return SetCookieWithCreationTimeAndOptions(url, cookie_line, Time(), options); | 931 return SetCookieWithCreationTimeAndOptions(url, cookie_line, Time(), options); |
923 } | 932 } |
924 | 933 |
925 // Currently our cookie datastructure is based on Mozilla's approach. We have a | 934 // Currently our cookie datastructure is based on Mozilla's approach. We have a |
926 // hash keyed on the cookie's domain, and for any query we walk down the domain | 935 // hash keyed on the cookie's domain, and for any query we walk down the domain |
927 // components and probe for cookies until we reach the TLD, where we stop. | 936 // components and probe for cookies until we reach the TLD, where we stop. |
928 // For example, a.b.blah.com, we would probe | 937 // For example, a.b.blah.com, we would probe |
929 // - a.b.blah.com | 938 // - a.b.blah.com |
930 // - .a.b.blah.com (TODO should we check this first or second?) | 939 // - .a.b.blah.com (TODO should we check this first or second?) |
931 // - .b.blah.com | 940 // - .b.blah.com |
932 // - .blah.com | 941 // - .blah.com |
933 // There are some alternative datastructures we could try, like a | 942 // There are some alternative datastructures we could try, like a |
934 // search/prefix trie, where we reverse the hostname and query for all | 943 // search/prefix trie, where we reverse the hostname and query for all |
935 // keys that are a prefix of our hostname. I think the hash probing | 944 // keys that are a prefix of our hostname. I think the hash probing |
936 // should be fast and simple enough for now. | 945 // should be fast and simple enough for now. |
937 std::string CookieMonster::GetCookiesWithOptions(const GURL& url, | 946 std::string CookieMonster::GetCookiesWithOptions(const GURL& url, |
938 const CookieOptions& options) { | 947 const CookieOptions& options) { |
| 948 DCHECK(CalledOnValidThread()); |
939 AutoLock autolock(lock_); | 949 AutoLock autolock(lock_); |
940 InitIfNecessary(); | 950 InitIfNecessary(); |
941 | 951 |
942 if (!HasCookieableScheme(url)) { | 952 if (!HasCookieableScheme(url)) { |
943 return std::string(); | 953 return std::string(); |
944 } | 954 } |
945 | 955 |
946 // Get the cookies for this host and its domain(s). | 956 // Get the cookies for this host and its domain(s). |
947 std::vector<CanonicalCookie*> cookies; | 957 std::vector<CanonicalCookie*> cookies; |
948 FindCookiesForHostAndDomain(url, options, &cookies); | 958 FindCookiesForHostAndDomain(url, options, &cookies); |
(...skipping 12 matching lines...) Expand all Loading... |
961 cookie_line += (*it)->Value(); | 971 cookie_line += (*it)->Value(); |
962 } | 972 } |
963 | 973 |
964 COOKIE_DLOG(INFO) << "GetCookies() result: " << cookie_line; | 974 COOKIE_DLOG(INFO) << "GetCookies() result: " << cookie_line; |
965 | 975 |
966 return cookie_line; | 976 return cookie_line; |
967 } | 977 } |
968 | 978 |
969 void CookieMonster::DeleteCookie(const GURL& url, | 979 void CookieMonster::DeleteCookie(const GURL& url, |
970 const std::string& cookie_name) { | 980 const std::string& cookie_name) { |
| 981 DCHECK(CalledOnValidThread()); |
971 AutoLock autolock(lock_); | 982 AutoLock autolock(lock_); |
972 InitIfNecessary(); | 983 InitIfNecessary(); |
973 | 984 |
974 if (!HasCookieableScheme(url)) | 985 if (!HasCookieableScheme(url)) |
975 return; | 986 return; |
976 | 987 |
977 CookieOptions options; | 988 CookieOptions options; |
978 options.set_include_httponly(); | 989 options.set_include_httponly(); |
979 // Get the cookies for this host and its domain(s). | 990 // Get the cookies for this host and its domain(s). |
980 std::vector<CanonicalCookie*> cookies; | 991 std::vector<CanonicalCookie*> cookies; |
(...skipping 11 matching lines...) Expand all Loading... |
992 | 1003 |
993 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { | 1004 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end();) { |
994 CookieMap::iterator curit = it; | 1005 CookieMap::iterator curit = it; |
995 ++it; | 1006 ++it; |
996 if (matching_cookies.find(curit->second) != matching_cookies.end()) | 1007 if (matching_cookies.find(curit->second) != matching_cookies.end()) |
997 InternalDeleteCookie(curit, true); | 1008 InternalDeleteCookie(curit, true); |
998 } | 1009 } |
999 } | 1010 } |
1000 | 1011 |
1001 CookieMonster::CookieList CookieMonster::GetAllCookies() { | 1012 CookieMonster::CookieList CookieMonster::GetAllCookies() { |
| 1013 DCHECK(CalledOnValidThread()); |
1002 AutoLock autolock(lock_); | 1014 AutoLock autolock(lock_); |
1003 InitIfNecessary(); | 1015 InitIfNecessary(); |
1004 | 1016 |
1005 // This function is being called to scrape the cookie list for management UI | 1017 // This function is being called to scrape the cookie list for management UI |
1006 // or similar. We shouldn't show expired cookies in this list since it will | 1018 // or similar. We shouldn't show expired cookies in this list since it will |
1007 // just be confusing to users, and this function is called rarely enough (and | 1019 // just be confusing to users, and this function is called rarely enough (and |
1008 // is already slow enough) that it's OK to take the time to garbage collect | 1020 // is already slow enough) that it's OK to take the time to garbage collect |
1009 // the expired cookies now. | 1021 // the expired cookies now. |
1010 // | 1022 // |
1011 // Note that this does not prune cookies to be below our limits (if we've | 1023 // Note that this does not prune cookies to be below our limits (if we've |
1012 // exceeded them) the way that calling GarbageCollect() would. | 1024 // exceeded them) the way that calling GarbageCollect() would. |
1013 GarbageCollectExpired(Time::Now(), | 1025 GarbageCollectExpired(Time::Now(), |
1014 CookieMapItPair(cookies_.begin(), cookies_.end()), | 1026 CookieMapItPair(cookies_.begin(), cookies_.end()), |
1015 NULL); | 1027 NULL); |
1016 | 1028 |
1017 CookieList cookie_list; | 1029 CookieList cookie_list; |
1018 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end(); ++it) | 1030 for (CookieMap::iterator it = cookies_.begin(); it != cookies_.end(); ++it) |
1019 cookie_list.push_back(CookieListPair(it->first, *it->second)); | 1031 cookie_list.push_back(CookieListPair(it->first, *it->second)); |
1020 | 1032 |
1021 return cookie_list; | 1033 return cookie_list; |
1022 } | 1034 } |
1023 | 1035 |
1024 CookieMonster::CookieList CookieMonster::GetAllCookiesForURL(const GURL& url) { | 1036 CookieMonster::CookieList CookieMonster::GetAllCookiesForURL(const GURL& url) { |
| 1037 DCHECK(CalledOnValidThread()); |
1025 AutoLock autolock(lock_); | 1038 AutoLock autolock(lock_); |
1026 InitIfNecessary(); | 1039 InitIfNecessary(); |
1027 | 1040 |
1028 return InternalGetAllCookiesForURL(url); | 1041 return InternalGetAllCookiesForURL(url); |
1029 } | 1042 } |
1030 | 1043 |
1031 void CookieMonster::FindCookiesForHostAndDomain( | 1044 void CookieMonster::FindCookiesForHostAndDomain( |
1032 const GURL& url, | 1045 const GURL& url, |
1033 const CookieOptions& options, | 1046 const CookieOptions& options, |
1034 std::vector<CanonicalCookie*>* cookies) { | 1047 std::vector<CanonicalCookie*>* cookies) { |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1512 return true; | 1525 return true; |
1513 } | 1526 } |
1514 | 1527 |
1515 std::string CookieMonster::CanonicalCookie::DebugString() const { | 1528 std::string CookieMonster::CanonicalCookie::DebugString() const { |
1516 return StringPrintf("name: %s value: %s path: %s creation: %" PRId64, | 1529 return StringPrintf("name: %s value: %s path: %s creation: %" PRId64, |
1517 name_.c_str(), value_.c_str(), path_.c_str(), | 1530 name_.c_str(), value_.c_str(), path_.c_str(), |
1518 static_cast<int64>(creation_date_.ToTimeT())); | 1531 static_cast<int64>(creation_date_.ToTimeT())); |
1519 } | 1532 } |
1520 | 1533 |
1521 } // namespace | 1534 } // namespace |
OLD | NEW |