| 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 676 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 687 private: | 687 private: |
| 688 CanonicalCookie cookie_; | 688 CanonicalCookie cookie_; |
| 689 | 689 |
| 690 DISALLOW_COPY_AND_ASSIGN(DeleteCanonicalCookieTask); | 690 DISALLOW_COPY_AND_ASSIGN(DeleteCanonicalCookieTask); |
| 691 }; | 691 }; |
| 692 | 692 |
| 693 int CookieMonster::DeleteCanonicalCookieTask::RunDeleteTask() { | 693 int CookieMonster::DeleteCanonicalCookieTask::RunDeleteTask() { |
| 694 return this->cookie_monster()->DeleteCanonicalCookie(cookie_); | 694 return this->cookie_monster()->DeleteCanonicalCookie(cookie_); |
| 695 } | 695 } |
| 696 | 696 |
| 697 // Task class for SetCanonicalCookie call. |
| 698 class CookieMonster::SetCanonicalCookieTask : public CookieMonsterTask { |
| 699 public: |
| 700 SetCanonicalCookieTask(CookieMonster* cookie_monster, |
| 701 std::unique_ptr<CanonicalCookie> cookie, |
| 702 bool secure_source, |
| 703 bool modify_http_only, |
| 704 const SetCookiesCallback& callback) |
| 705 : CookieMonsterTask(cookie_monster), |
| 706 cookie_(std::move(cookie)), |
| 707 secure_source_(secure_source), |
| 708 modify_http_only_(modify_http_only), |
| 709 callback_(callback) {} |
| 710 |
| 711 // CookieMonsterTask: |
| 712 void Run() override; |
| 713 |
| 714 protected: |
| 715 ~SetCanonicalCookieTask() override {} |
| 716 |
| 717 private: |
| 718 std::unique_ptr<CanonicalCookie> cookie_; |
| 719 bool secure_source_; |
| 720 bool modify_http_only_; |
| 721 SetCookiesCallback callback_; |
| 722 |
| 723 DISALLOW_COPY_AND_ASSIGN(SetCanonicalCookieTask); |
| 724 }; |
| 725 |
| 726 void CookieMonster::SetCanonicalCookieTask::Run() { |
| 727 bool result = this->cookie_monster()->SetCanonicalCookie( |
| 728 std::move(cookie_), secure_source_, modify_http_only_); |
| 729 if (!callback_.is_null()) |
| 730 callback_.Run(result); |
| 731 } |
| 732 |
| 697 // Task class for SetCookieWithOptions call. | 733 // Task class for SetCookieWithOptions call. |
| 698 class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask { | 734 class CookieMonster::SetCookieWithOptionsTask : public CookieMonsterTask { |
| 699 public: | 735 public: |
| 700 SetCookieWithOptionsTask(CookieMonster* cookie_monster, | 736 SetCookieWithOptionsTask(CookieMonster* cookie_monster, |
| 701 const GURL& url, | 737 const GURL& url, |
| 702 const std::string& cookie_line, | 738 const std::string& cookie_line, |
| 703 const CookieOptions& options, | 739 const CookieOptions& options, |
| 704 const SetCookiesCallback& callback) | 740 const SetCookiesCallback& callback) |
| 705 : CookieMonsterTask(cookie_monster), | 741 : CookieMonsterTask(cookie_monster), |
| 706 url_(url), | 742 url_(url), |
| (...skipping 188 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 895 store_->SetForceKeepSessionState(); | 931 store_->SetForceKeepSessionState(); |
| 896 } | 932 } |
| 897 | 933 |
| 898 void CookieMonster::SetAllCookiesAsync(const CookieList& list, | 934 void CookieMonster::SetAllCookiesAsync(const CookieList& list, |
| 899 const SetCookiesCallback& callback) { | 935 const SetCookiesCallback& callback) { |
| 900 scoped_refptr<SetAllCookiesTask> task = | 936 scoped_refptr<SetAllCookiesTask> task = |
| 901 new SetAllCookiesTask(this, list, callback); | 937 new SetAllCookiesTask(this, list, callback); |
| 902 DoCookieTask(task); | 938 DoCookieTask(task); |
| 903 } | 939 } |
| 904 | 940 |
| 941 void CookieMonster::SetCanonicalCookieAsync( |
| 942 std::unique_ptr<CanonicalCookie> cookie, |
| 943 bool secure_source, |
| 944 bool modify_http_only, |
| 945 const SetCookiesCallback& callback) { |
| 946 DCHECK(cookie->IsCanonical()); |
| 947 scoped_refptr<SetCanonicalCookieTask> task = new SetCanonicalCookieTask( |
| 948 this, std::move(cookie), secure_source, modify_http_only, callback); |
| 949 |
| 950 // TODO(rdsmith): Switch to DoCookieTaskForURL (or the equivalent). |
| 951 // This is tricky because we don't have the scheme in this routine |
| 952 // and DoCookieTaskForURL uses cookie_util::GetEffectiveDomain(scheme, host) |
| 953 // to generate the database key to block behind. |
| 954 DoCookieTask(task); |
| 955 } |
| 956 |
| 905 void CookieMonster::SetCookieWithOptionsAsync( | 957 void CookieMonster::SetCookieWithOptionsAsync( |
| 906 const GURL& url, | 958 const GURL& url, |
| 907 const std::string& cookie_line, | 959 const std::string& cookie_line, |
| 908 const CookieOptions& options, | 960 const CookieOptions& options, |
| 909 const SetCookiesCallback& callback) { | 961 const SetCookiesCallback& callback) { |
| 910 scoped_refptr<SetCookieWithOptionsTask> task = | 962 scoped_refptr<SetCookieWithOptionsTask> task = |
| 911 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); | 963 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); |
| 912 | 964 |
| 913 DoCookieTaskForURL(task, url); | 965 DoCookieTaskForURL(task, url); |
| 914 } | 966 } |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1061 base::Time last_access_time, | 1113 base::Time last_access_time, |
| 1062 bool secure, | 1114 bool secure, |
| 1063 bool http_only, | 1115 bool http_only, |
| 1064 CookieSameSite same_site, | 1116 CookieSameSite same_site, |
| 1065 CookiePriority priority) { | 1117 CookiePriority priority) { |
| 1066 DCHECK(thread_checker_.CalledOnValidThread()); | 1118 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1067 | 1119 |
| 1068 if (!HasCookieableScheme(url)) | 1120 if (!HasCookieableScheme(url)) |
| 1069 return false; | 1121 return false; |
| 1070 | 1122 |
| 1071 // TODO(mmenke): This class assumes each cookie to have a unique creation | |
| 1072 // time. Allowing the caller to set the creation time violates that | |
| 1073 // assumption. Worth fixing? Worth noting that time changes between browser | |
| 1074 // restarts can cause the same issue. | |
| 1075 base::Time actual_creation_time = creation_time; | |
| 1076 if (creation_time.is_null()) { | |
| 1077 actual_creation_time = CurrentTime(); | |
| 1078 last_time_seen_ = actual_creation_time; | |
| 1079 } | |
| 1080 | |
| 1081 // Validate consistency of passed arguments. | 1123 // Validate consistency of passed arguments. |
| 1082 if (ParsedCookie::ParseTokenString(name) != name || | 1124 if (ParsedCookie::ParseTokenString(name) != name || |
| 1083 ParsedCookie::ParseValueString(value) != value || | 1125 ParsedCookie::ParseValueString(value) != value || |
| 1084 ParsedCookie::ParseValueString(domain) != domain || | 1126 ParsedCookie::ParseValueString(domain) != domain || |
| 1085 ParsedCookie::ParseValueString(path) != path) { | 1127 ParsedCookie::ParseValueString(path) != path) { |
| 1086 return false; | 1128 return false; |
| 1087 } | 1129 } |
| 1088 | 1130 |
| 1089 std::string cookie_domain; | 1131 std::string cookie_domain; |
| 1090 if (!cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain)) | 1132 if (!cookie_util::GetCookieDomainWithString(url, domain, &cookie_domain)) |
| 1091 return false; | 1133 return false; |
| 1092 | 1134 |
| 1093 std::string cookie_path = CanonicalCookie::CanonPathWithString(url, path); | 1135 std::string cookie_path = CanonicalCookie::CanonPathWithString(url, path); |
| 1094 if (!path.empty() && cookie_path != path) | 1136 if (!path.empty() && cookie_path != path) |
| 1095 return false; | 1137 return false; |
| 1096 | 1138 |
| 1097 // Canonicalize path again to make sure it escapes characters as needed. | 1139 // Canonicalize path again to make sure it escapes characters as needed. |
| 1098 url::Component path_component(0, cookie_path.length()); | 1140 url::Component path_component(0, cookie_path.length()); |
| 1099 url::RawCanonOutputT<char> canon_path; | 1141 url::RawCanonOutputT<char> canon_path; |
| 1100 url::Component canon_path_component; | 1142 url::Component canon_path_component; |
| 1101 url::CanonicalizePath(cookie_path.data(), path_component, &canon_path, | 1143 url::CanonicalizePath(cookie_path.data(), path_component, &canon_path, |
| 1102 &canon_path_component); | 1144 &canon_path_component); |
| 1103 cookie_path = std::string(canon_path.data() + canon_path_component.begin, | 1145 cookie_path = std::string(canon_path.data() + canon_path_component.begin, |
| 1104 canon_path_component.len); | 1146 canon_path_component.len); |
| 1105 | 1147 |
| 1106 std::unique_ptr<CanonicalCookie> cc(base::MakeUnique<CanonicalCookie>( | 1148 std::unique_ptr<CanonicalCookie> cc(base::MakeUnique<CanonicalCookie>( |
| 1107 name, value, cookie_domain, cookie_path, actual_creation_time, | 1149 name, value, cookie_domain, cookie_path, creation_time, expiration_time, |
| 1108 expiration_time, last_access_time, secure, http_only, same_site, | 1150 last_access_time, secure, http_only, same_site, priority)); |
| 1109 priority)); | |
| 1110 | 1151 |
| 1111 return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), true); | 1152 return SetCanonicalCookie(std::move(cc), url.SchemeIsCryptographic(), true); |
| 1112 } | 1153 } |
| 1113 | 1154 |
| 1114 CookieList CookieMonster::GetAllCookies() { | 1155 CookieList CookieMonster::GetAllCookies() { |
| 1115 DCHECK(thread_checker_.CalledOnValidThread()); | 1156 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1116 | 1157 |
| 1117 // This function is being called to scrape the cookie list for management UI | 1158 // This function is being called to scrape the cookie list for management UI |
| 1118 // or similar. We shouldn't show expired cookies in this list since it will | 1159 // or similar. We shouldn't show expired cookies in this list since it will |
| 1119 // just be confusing to users, and this function is called rarely enough (and | 1160 // just be confusing to users, and this function is called rarely enough (and |
| (...skipping 639 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1759 } | 1800 } |
| 1760 | 1801 |
| 1761 bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc, | 1802 bool CookieMonster::SetCanonicalCookie(std::unique_ptr<CanonicalCookie> cc, |
| 1762 bool secure_source, | 1803 bool secure_source, |
| 1763 bool modify_http_only) { | 1804 bool modify_http_only) { |
| 1764 DCHECK(thread_checker_.CalledOnValidThread()); | 1805 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1765 | 1806 |
| 1766 if (cc->IsSecure() && !secure_source) | 1807 if (cc->IsSecure() && !secure_source) |
| 1767 return false; | 1808 return false; |
| 1768 | 1809 |
| 1769 Time creation_time = cc->CreationDate(); | |
| 1770 const std::string key(GetKey(cc->Domain())); | 1810 const std::string key(GetKey(cc->Domain())); |
| 1771 bool already_expired = cc->IsExpired(creation_time); | 1811 |
| 1812 // TODO(mmenke): This class assumes each cookie to have a unique creation |
| 1813 // time. Allowing the caller to set the creation time violates that |
| 1814 // assumption. Worth fixing? Worth noting that time changes between browser |
| 1815 // restarts can cause the same issue. |
| 1816 base::Time creation_date = cc->CreationDate(); |
| 1817 if (creation_date.is_null()) { |
| 1818 creation_date = CurrentTime(); |
| 1819 cc->SetCreationDate(creation_date); |
| 1820 last_time_seen_ = creation_date; |
| 1821 } |
| 1822 bool already_expired = cc->IsExpired(creation_date); |
| 1772 | 1823 |
| 1773 if (DeleteAnyEquivalentCookie(key, *cc, secure_source, !modify_http_only, | 1824 if (DeleteAnyEquivalentCookie(key, *cc, secure_source, !modify_http_only, |
| 1774 already_expired)) { | 1825 already_expired)) { |
| 1775 std::string error; | 1826 std::string error; |
| 1776 error = | 1827 error = |
| 1777 "SetCookie() not clobbering httponly cookie or secure cookie for " | 1828 "SetCookie() not clobbering httponly cookie or secure cookie for " |
| 1778 "insecure scheme"; | 1829 "insecure scheme"; |
| 1779 | 1830 |
| 1780 VLOG(kVlogSetCookies) << error; | 1831 VLOG(kVlogSetCookies) << error; |
| 1781 return false; | 1832 return false; |
| 1782 } | 1833 } |
| 1783 | 1834 |
| 1784 VLOG(kVlogSetCookies) << "SetCookie() key: " << key | 1835 VLOG(kVlogSetCookies) << "SetCookie() key: " << key |
| 1785 << " cc: " << cc->DebugString(); | 1836 << " cc: " << cc->DebugString(); |
| 1786 | 1837 |
| 1787 // Realize that we might be setting an expired cookie, and the only point | 1838 // Realize that we might be setting an expired cookie, and the only point |
| 1788 // was to delete the cookie which we've already done. | 1839 // was to delete the cookie which we've already done. |
| 1789 if (!already_expired) { | 1840 if (!already_expired) { |
| 1790 // See InitializeHistograms() for details. | 1841 // See InitializeHistograms() for details. |
| 1791 if (cc->IsPersistent()) { | 1842 if (cc->IsPersistent()) { |
| 1792 histogram_expiration_duration_minutes_->Add( | 1843 histogram_expiration_duration_minutes_->Add( |
| 1793 (cc->ExpiryDate() - creation_time).InMinutes()); | 1844 (cc->ExpiryDate() - creation_date).InMinutes()); |
| 1794 } | 1845 } |
| 1795 | 1846 |
| 1796 // Histogram the type of scheme used on URLs that set cookies. This | 1847 // Histogram the type of scheme used on URLs that set cookies. This |
| 1797 // intentionally includes cookies that are set or overwritten by | 1848 // intentionally includes cookies that are set or overwritten by |
| 1798 // http:// URLs, but not cookies that are cleared by http:// URLs, to | 1849 // http:// URLs, but not cookies that are cleared by http:// URLs, to |
| 1799 // understand if the former behavior can be deprecated for Secure | 1850 // understand if the former behavior can be deprecated for Secure |
| 1800 // cookies. | 1851 // cookies. |
| 1801 CookieSource cookie_source_sample = | 1852 CookieSource cookie_source_sample = |
| 1802 (secure_source | 1853 (secure_source |
| 1803 ? (cc->IsSecure() | 1854 ? (cc->IsSecure() |
| 1804 ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME | 1855 ? COOKIE_SOURCE_SECURE_COOKIE_CRYPTOGRAPHIC_SCHEME |
| 1805 : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME) | 1856 : COOKIE_SOURCE_NONSECURE_COOKIE_CRYPTOGRAPHIC_SCHEME) |
| 1806 : (cc->IsSecure() | 1857 : (cc->IsSecure() |
| 1807 ? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME | 1858 ? COOKIE_SOURCE_SECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME |
| 1808 : COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME)); | 1859 : COOKIE_SOURCE_NONSECURE_COOKIE_NONCRYPTOGRAPHIC_SCHEME)); |
| 1809 histogram_cookie_source_scheme_->Add(cookie_source_sample); | 1860 histogram_cookie_source_scheme_->Add(cookie_source_sample); |
| 1810 | 1861 |
| 1811 InternalInsertCookie(key, std::move(cc), true); | 1862 InternalInsertCookie(key, std::move(cc), true); |
| 1812 } else { | 1863 } else { |
| 1813 VLOG(kVlogSetCookies) << "SetCookie() not storing already expired cookie."; | 1864 VLOG(kVlogSetCookies) << "SetCookie() not storing already expired cookie."; |
| 1814 } | 1865 } |
| 1815 | 1866 |
| 1816 // We assume that hopefully setting a cookie will be less common than | 1867 // We assume that hopefully setting a cookie will be less common than |
| 1817 // querying a cookie. Since setting a cookie can put us over our limits, | 1868 // querying a cookie. Since setting a cookie can put us over our limits, |
| 1818 // make sure that we garbage collect... We can also make the assumption that | 1869 // make sure that we garbage collect... We can also make the assumption that |
| 1819 // if a cookie was set, in the common case it will be used soon after, | 1870 // if a cookie was set, in the common case it will be used soon after, |
| 1820 // and we will purge the expired cookies in GetCookies(). | 1871 // and we will purge the expired cookies in GetCookies(). |
| 1821 GarbageCollect(creation_time, key); | 1872 GarbageCollect(creation_date, key); |
| 1822 | 1873 |
| 1823 return true; | 1874 return true; |
| 1824 } | 1875 } |
| 1825 | 1876 |
| 1826 bool CookieMonster::SetAllCookies(const CookieList& list) { | 1877 bool CookieMonster::SetAllCookies(const CookieList& list) { |
| 1827 DCHECK(thread_checker_.CalledOnValidThread()); | 1878 DCHECK(thread_checker_.CalledOnValidThread()); |
| 1828 for (const auto& cookie : list) { | 1879 for (const auto& cookie : list) { |
| 1829 const std::string key(GetKey(cookie.Domain())); | 1880 const std::string key(GetKey(cookie.Domain())); |
| 1830 Time creation_time = cookie.CreationDate(); | 1881 Time creation_time = cookie.CreationDate(); |
| 1831 bool already_expired = cookie.IsExpired(creation_time); | 1882 bool already_expired = cookie.IsExpired(creation_time); |
| (...skipping 611 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2443 it != hook_map_.end(); ++it) { | 2494 it != hook_map_.end(); ++it) { |
| 2444 std::pair<GURL, std::string> key = it->first; | 2495 std::pair<GURL, std::string> key = it->first; |
| 2445 if (cookie.IncludeForRequestURL(key.first, opts) && | 2496 if (cookie.IncludeForRequestURL(key.first, opts) && |
| 2446 cookie.Name() == key.second) { | 2497 cookie.Name() == key.second) { |
| 2447 it->second->Notify(cookie, cause); | 2498 it->second->Notify(cookie, cause); |
| 2448 } | 2499 } |
| 2449 } | 2500 } |
| 2450 } | 2501 } |
| 2451 | 2502 |
| 2452 } // namespace net | 2503 } // namespace net |
| OLD | NEW |