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

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

Issue 1000103002: Add a method to override all the cookies in CookieMonster (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 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
OLDNEW
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 145 matching lines...) Expand 10 before | Expand all | Expand 10 after
156 // Cookies accessed less recently should be deleted first. 156 // Cookies accessed less recently should be deleted first.
157 if (it1->second->LastAccessDate() != it2->second->LastAccessDate()) 157 if (it1->second->LastAccessDate() != it2->second->LastAccessDate())
158 return it1->second->LastAccessDate() < it2->second->LastAccessDate(); 158 return it1->second->LastAccessDate() < it2->second->LastAccessDate();
159 159
160 // In rare cases we might have two cookies with identical last access times. 160 // In rare cases we might have two cookies with identical last access times.
161 // To preserve the stability of the sort, in these cases prefer to delete 161 // To preserve the stability of the sort, in these cases prefer to delete
162 // older cookies over newer ones. CreationDate() is guaranteed to be unique. 162 // older cookies over newer ones. CreationDate() is guaranteed to be unique.
163 return it1->second->CreationDate() < it2->second->CreationDate(); 163 return it1->second->CreationDate() < it2->second->CreationDate();
164 } 164 }
165 165
166 // Compare cookies using name, domain and path, so that "equivalent" cookies
167 // (per RFC 2965) are equal to each other.
168 int PartialDiffCookieOrdering(const net::CanonicalCookie& a,
169 const net::CanonicalCookie& b) {
170 int diff = a.Name().compare(b.Name());
171 if (diff != 0)
172 return diff;
173
174 diff = a.Domain().compare(b.Domain());
175 if (diff != 0)
176 return diff;
177
178 return a.Path().compare(b.Path());
179 }
180
181 bool PartialDiffCookieSorter(const net::CanonicalCookie& a,
182 const net::CanonicalCookie& b) {
183 return PartialDiffCookieOrdering(a, b) < 0;
184 }
185
186 // This is a stricter ordering than PartialDiffCookieOrdering, where all fields
187 // are used except the last access time and the creation date.
188 bool FullDiffCookieSorter(const net::CanonicalCookie& a,
189 const net::CanonicalCookie& b) {
190 int diff = PartialDiffCookieOrdering(a, b);
191 if (diff != 0)
192 return diff < 0;
193
194 DCHECK(a.IsEquivalent(b));
195
196 // Compare other fields.
197 diff = a.Value().compare(b.Value());
198 if (diff != 0)
199 return diff < 0;
200
201 if (a.ExpiryDate() != b.ExpiryDate())
202 return a.ExpiryDate() < b.ExpiryDate();
203
204 if (a.IsSecure() != b.IsSecure())
205 return a.IsSecure();
206
207 if (a.IsHttpOnly() != b.IsHttpOnly())
208 return a.IsHttpOnly();
209
210 return a.Priority() < b.Priority();
211 }
212
166 // Our strategy to find duplicates is: 213 // Our strategy to find duplicates is:
167 // (1) Build a map from (cookiename, cookiepath) to 214 // (1) Build a map from (cookiename, cookiepath) to
168 // {list of cookies with this signature, sorted by creation time}. 215 // {list of cookies with this signature, sorted by creation time}.
169 // (2) For each list with more than 1 entry, keep the cookie having the 216 // (2) For each list with more than 1 entry, keep the cookie having the
170 // most recent creation time, and delete the others. 217 // most recent creation time, and delete the others.
171 // 218 //
172 // Two cookies are considered equivalent if they have the same domain, 219 // Two cookies are considered equivalent if they have the same domain,
173 // name, and path. 220 // name, and path.
174 struct CookieSignature { 221 struct CookieSignature {
175 public: 222 public:
(...skipping 581 matching lines...) Expand 10 before | Expand all | Expand 10 after
757 FROM_HERE_WITH_EXPLICIT_FUNCTION( 804 FROM_HERE_WITH_EXPLICIT_FUNCTION(
758 "456373 CookieMonster::SetCookieWithOptionsTask::Run")); 805 "456373 CookieMonster::SetCookieWithOptionsTask::Run"));
759 bool result = this->cookie_monster()->SetCookieWithOptions(url_, cookie_line_, 806 bool result = this->cookie_monster()->SetCookieWithOptions(url_, cookie_line_,
760 options_); 807 options_);
761 if (!callback_.is_null()) { 808 if (!callback_.is_null()) {
762 this->InvokeCallback(base::Bind(&SetCookiesCallback::Run, 809 this->InvokeCallback(base::Bind(&SetCookiesCallback::Run,
763 base::Unretained(&callback_), result)); 810 base::Unretained(&callback_), result));
764 } 811 }
765 } 812 }
766 813
814 // Task class for SetAllCookies call.
815 class CookieMonster::SetAllCookiesTask : public CookieMonsterTask {
816 public:
817 SetAllCookiesTask(CookieMonster* cookie_monster,
818 const CookieList& list,
819 const SetCookiesCallback& callback)
820 : CookieMonsterTask(cookie_monster), list_(list), callback_(callback) {}
821
822 // CookieMonsterTask:
823 void Run() override;
824
825 protected:
826 ~SetAllCookiesTask() override {}
827
828 private:
829 CookieList list_;
830 SetCookiesCallback callback_;
831
832 DISALLOW_COPY_AND_ASSIGN(SetAllCookiesTask);
833 };
834
835 void CookieMonster::SetAllCookiesTask::Run() {
836 CookieList positive_diff;
837 CookieList negative_diff;
838 CookieList old_cookies = this->cookie_monster()->GetAllCookies();
839 this->cookie_monster()->ComputeCookieDiff(&old_cookies, &list_,
840 &positive_diff, &negative_diff);
841
842 for (CookieList::const_iterator it = negative_diff.begin();
843 it != negative_diff.end(); ++it) {
844 this->cookie_monster()->DeleteCanonicalCookie(*it);
845 }
846
847 bool result = true;
848 if (positive_diff.size() > 0)
849 result = this->cookie_monster()->SetCanonicalCookies(list_);
850
851 if (!callback_.is_null()) {
852 this->InvokeCallback(base::Bind(&SetCookiesCallback::Run,
853 base::Unretained(&callback_), result));
854 }
855 }
856
767 // Task class for GetCookiesWithOptions call. 857 // Task class for GetCookiesWithOptions call.
768 class CookieMonster::GetCookiesWithOptionsTask : public CookieMonsterTask { 858 class CookieMonster::GetCookiesWithOptionsTask : public CookieMonsterTask {
769 public: 859 public:
770 GetCookiesWithOptionsTask(CookieMonster* cookie_monster, 860 GetCookiesWithOptionsTask(CookieMonster* cookie_monster,
771 const GURL& url, 861 const GURL& url,
772 const CookieOptions& options, 862 const CookieOptions& options,
773 const GetCookiesCallback& callback) 863 const GetCookiesCallback& callback)
774 : CookieMonsterTask(cookie_monster), 864 : CookieMonsterTask(cookie_monster),
775 url_(url), 865 url_(url),
776 options_(options), 866 options_(options),
(...skipping 201 matching lines...) Expand 10 before | Expand all | Expand 10 after
978 1068
979 void CookieMonster::DeleteCanonicalCookieAsync( 1069 void CookieMonster::DeleteCanonicalCookieAsync(
980 const CanonicalCookie& cookie, 1070 const CanonicalCookie& cookie,
981 const DeleteCookieCallback& callback) { 1071 const DeleteCookieCallback& callback) {
982 scoped_refptr<DeleteCanonicalCookieTask> task = 1072 scoped_refptr<DeleteCanonicalCookieTask> task =
983 new DeleteCanonicalCookieTask(this, cookie, callback); 1073 new DeleteCanonicalCookieTask(this, cookie, callback);
984 1074
985 DoCookieTask(task); 1075 DoCookieTask(task);
986 } 1076 }
987 1077
1078 void CookieMonster::SetAllCookiesAsync(const CookieList& list,
1079 const SetCookiesCallback& callback) {
1080 scoped_refptr<SetAllCookiesTask> task =
1081 new SetAllCookiesTask(this, list, callback);
1082 DoCookieTask(task);
1083 }
1084
988 void CookieMonster::SetCookieWithOptionsAsync( 1085 void CookieMonster::SetCookieWithOptionsAsync(
989 const GURL& url, 1086 const GURL& url,
990 const std::string& cookie_line, 1087 const std::string& cookie_line,
991 const CookieOptions& options, 1088 const CookieOptions& options,
992 const SetCookiesCallback& callback) { 1089 const SetCookiesCallback& callback) {
993 scoped_refptr<SetCookieWithOptionsTask> task = 1090 scoped_refptr<SetCookieWithOptionsTask> task =
994 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); 1091 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback);
995 1092
996 DoCookieTaskForURL(task, url); 1093 DoCookieTaskForURL(task, url);
997 } 1094 }
(...skipping 838 matching lines...) Expand 10 before | Expand all | Expand 10 after
1836 // We assume that hopefully setting a cookie will be less common than 1933 // We assume that hopefully setting a cookie will be less common than
1837 // querying a cookie. Since setting a cookie can put us over our limits, 1934 // querying a cookie. Since setting a cookie can put us over our limits,
1838 // make sure that we garbage collect... We can also make the assumption that 1935 // make sure that we garbage collect... We can also make the assumption that
1839 // if a cookie was set, in the common case it will be used soon after, 1936 // if a cookie was set, in the common case it will be used soon after,
1840 // and we will purge the expired cookies in GetCookies(). 1937 // and we will purge the expired cookies in GetCookies().
1841 GarbageCollect(creation_time, key); 1938 GarbageCollect(creation_time, key);
1842 1939
1843 return true; 1940 return true;
1844 } 1941 }
1845 1942
1943 bool CookieMonster::SetCanonicalCookies(const CookieList& list) {
1944 base::AutoLock autolock(lock_);
1945
1946 net::CookieOptions options;
1947 options.set_include_httponly();
1948
1949 for (CookieList::const_iterator it = list.begin(); it != list.end(); ++it) {
1950 scoped_ptr<CanonicalCookie> canonical_cookie(new CanonicalCookie(*it));
1951 if (!SetCanonicalCookie(&canonical_cookie, it->CreationDate(), options))
1952 return false;
1953 }
1954
1955 return true;
1956 }
1957
1846 void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc, 1958 void CookieMonster::InternalUpdateCookieAccessTime(CanonicalCookie* cc,
1847 const Time& current) { 1959 const Time& current) {
1848 lock_.AssertAcquired(); 1960 lock_.AssertAcquired();
1849 1961
1850 // Based off the Mozilla code. When a cookie has been accessed recently, 1962 // Based off the Mozilla code. When a cookie has been accessed recently,
1851 // don't bother updating its access time again. This reduces the number of 1963 // don't bother updating its access time again. This reduces the number of
1852 // updates we do during pageload, which in turn reduces the chance our storage 1964 // updates we do during pageload, which in turn reduces the chance our storage
1853 // backend will hit its batch thresholds and be forced to update. 1965 // backend will hit its batch thresholds and be forced to update.
1854 if ((current - cc->LastAccessDate()) < last_access_threshold_) 1966 if ((current - cc->LastAccessDate()) < last_access_threshold_)
1855 return; 1967 return;
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
2219 } 2331 }
2220 2332
2221 // The system resolution is not high enough, so we can have multiple 2333 // The system resolution is not high enough, so we can have multiple
2222 // set cookies that result in the same system time. When this happens, we 2334 // set cookies that result in the same system time. When this happens, we
2223 // increment by one Time unit. Let's hope computers don't get too fast. 2335 // increment by one Time unit. Let's hope computers don't get too fast.
2224 Time CookieMonster::CurrentTime() { 2336 Time CookieMonster::CurrentTime() {
2225 return std::max(Time::Now(), Time::FromInternalValue( 2337 return std::max(Time::Now(), Time::FromInternalValue(
2226 last_time_seen_.ToInternalValue() + 1)); 2338 last_time_seen_.ToInternalValue() + 1));
2227 } 2339 }
2228 2340
2341 void CookieMonster::ComputeCookieDiff(CookieList* old_cookies,
2342 CookieList* new_cookies,
2343 CookieList* cookies_to_add,
2344 CookieList* cookies_to_delete) {
2345 DCHECK(old_cookies);
2346 DCHECK(new_cookies);
2347 DCHECK(cookies_to_add);
2348 DCHECK(cookies_to_delete);
2349 DCHECK(cookies_to_add->empty());
2350 DCHECK(cookies_to_delete->empty());
2351
2352 // Sort both lists.
2353 std::sort(old_cookies->begin(), old_cookies->end(), FullDiffCookieSorter);
2354 std::sort(new_cookies->begin(), new_cookies->end(), FullDiffCookieSorter);
2355
2356 // Compute the cookies to be deleted.
2357 // It is OK to call set_difference using PartialDiffCookieSorter even though
erikwright (departed) 2015/03/13 13:59:01 // A set ordered by FullDiffCookieSorter is also o
droger 2015/03/16 13:03:50 Comment updated. Unfortunately it seems that std::
2358 // the list was sorted using FullDiffCookieSorter.
2359 std::set_difference(
erikwright (departed) 2015/03/13 13:59:01 How about the following comment. // Select any ol
droger 2015/03/16 13:03:50 Done.
2360 old_cookies->begin(), old_cookies->end(), new_cookies->begin(),
2361 new_cookies->end(),
2362 std::inserter(*cookies_to_delete, cookies_to_delete->begin()),
2363 PartialDiffCookieSorter);
2364
2365 // Compute the cookies to be added.
2366 std::set_difference(new_cookies->begin(), new_cookies->end(),
erikwright (departed) 2015/03/13 13:59:01 // Select any new cookie for addition (or update)
droger 2015/03/16 13:03:50 Done.
2367 old_cookies->begin(), old_cookies->end(),
2368 std::inserter(*cookies_to_add, cookies_to_add->begin()),
2369 FullDiffCookieSorter);
2370 }
2371
2229 scoped_ptr<CookieStore::CookieChangedSubscription> 2372 scoped_ptr<CookieStore::CookieChangedSubscription>
2230 CookieMonster::AddCallbackForCookie(const GURL& gurl, 2373 CookieMonster::AddCallbackForCookie(const GURL& gurl,
2231 const std::string& name, 2374 const std::string& name,
2232 const CookieChangedCallback& callback) { 2375 const CookieChangedCallback& callback) {
2233 base::AutoLock autolock(lock_); 2376 base::AutoLock autolock(lock_);
2234 std::pair<GURL, std::string> key(gurl, name); 2377 std::pair<GURL, std::string> key(gurl, name);
2235 if (hook_map_.count(key) == 0) 2378 if (hook_map_.count(key) == 0)
2236 hook_map_[key] = make_linked_ptr(new CookieChangedCallbackList()); 2379 hook_map_[key] = make_linked_ptr(new CookieChangedCallbackList());
2237 return hook_map_[key]->Add( 2380 return hook_map_[key]->Add(
2238 base::Bind(&RunAsync, base::MessageLoopProxy::current(), callback)); 2381 base::Bind(&RunAsync, base::MessageLoopProxy::current(), callback));
(...skipping 13 matching lines...) Expand all
2252 it != hook_map_.end(); ++it) { 2395 it != hook_map_.end(); ++it) {
2253 std::pair<GURL, std::string> key = it->first; 2396 std::pair<GURL, std::string> key = it->first;
2254 if (cookie.IncludeForRequestURL(key.first, opts) && 2397 if (cookie.IncludeForRequestURL(key.first, opts) &&
2255 cookie.Name() == key.second) { 2398 cookie.Name() == key.second) {
2256 it->second->Notify(cookie, removed); 2399 it->second->Notify(cookie, removed);
2257 } 2400 }
2258 } 2401 }
2259 } 2402 }
2260 2403
2261 } // namespace net 2404 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698