| 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 |