OLD | NEW |
---|---|
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 #include <set> | 48 #include <set> |
49 | 49 |
50 #include "base/basictypes.h" | 50 #include "base/basictypes.h" |
51 #include "base/bind.h" | 51 #include "base/bind.h" |
52 #include "base/callback.h" | |
52 #include "base/format_macros.h" | 53 #include "base/format_macros.h" |
53 #include "base/logging.h" | 54 #include "base/logging.h" |
54 #include "base/memory/scoped_ptr.h" | 55 #include "base/memory/scoped_ptr.h" |
55 #include "base/message_loop.h" | 56 #include "base/message_loop.h" |
56 #include "base/message_loop_proxy.h" | 57 #include "base/message_loop_proxy.h" |
57 #include "base/metrics/histogram.h" | 58 #include "base/metrics/histogram.h" |
58 #include "base/string_tokenizer.h" | 59 #include "base/string_tokenizer.h" |
59 #include "base/string_util.h" | 60 #include "base/string_util.h" |
60 #include "base/stringprintf.h" | 61 #include "base/stringprintf.h" |
61 #include "googleurl/src/gurl.h" | 62 #include "googleurl/src/gurl.h" |
(...skipping 924 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
986 void CookieMonster::SetCookieWithDetailsAsync( | 987 void CookieMonster::SetCookieWithDetailsAsync( |
987 const GURL& url, const std::string& name, const std::string& value, | 988 const GURL& url, const std::string& name, const std::string& value, |
988 const std::string& domain, const std::string& path, | 989 const std::string& domain, const std::string& path, |
989 const base::Time& expiration_time, bool secure, bool http_only, | 990 const base::Time& expiration_time, bool secure, bool http_only, |
990 const SetCookiesCallback& callback) { | 991 const SetCookiesCallback& callback) { |
991 scoped_refptr<SetCookieWithDetailsTask> task = | 992 scoped_refptr<SetCookieWithDetailsTask> task = |
992 new SetCookieWithDetailsTask(this, url, name, value, domain, path, | 993 new SetCookieWithDetailsTask(this, url, name, value, domain, path, |
993 expiration_time, secure, http_only, | 994 expiration_time, secure, http_only, |
994 callback); | 995 callback); |
995 | 996 |
996 DoCookieTask(task); | 997 DoCookieTaskForURL(task, url); |
997 } | 998 } |
998 | 999 |
999 void CookieMonster::GetAllCookiesAsync(const GetCookieListCallback& callback) { | 1000 void CookieMonster::GetAllCookiesAsync(const GetCookieListCallback& callback) { |
1000 scoped_refptr<GetAllCookiesTask> task = | 1001 scoped_refptr<GetAllCookiesTask> task = |
1001 new GetAllCookiesTask(this, callback); | 1002 new GetAllCookiesTask(this, callback); |
1002 | 1003 |
1003 DoCookieTask(task); | 1004 DoCookieTask(task); |
1004 } | 1005 } |
1005 | 1006 |
1006 | 1007 |
1007 void CookieMonster::GetAllCookiesForURLWithOptionsAsync( | 1008 void CookieMonster::GetAllCookiesForURLWithOptionsAsync( |
1008 const GURL& url, | 1009 const GURL& url, |
1009 const CookieOptions& options, | 1010 const CookieOptions& options, |
1010 const GetCookieListCallback& callback) { | 1011 const GetCookieListCallback& callback) { |
1011 scoped_refptr<GetAllCookiesForURLWithOptionsTask> task = | 1012 scoped_refptr<GetAllCookiesForURLWithOptionsTask> task = |
1012 new GetAllCookiesForURLWithOptionsTask(this, url, options, callback); | 1013 new GetAllCookiesForURLWithOptionsTask(this, url, options, callback); |
1013 | 1014 |
1014 DoCookieTask(task); | 1015 DoCookieTaskForURL(task, url); |
1015 } | 1016 } |
1016 | 1017 |
1017 void CookieMonster::GetAllCookiesForURLAsync( | 1018 void CookieMonster::GetAllCookiesForURLAsync( |
1018 const GURL& url, const GetCookieListCallback& callback) { | 1019 const GURL& url, const GetCookieListCallback& callback) { |
1019 CookieOptions options; | 1020 CookieOptions options; |
1020 options.set_include_httponly(); | 1021 options.set_include_httponly(); |
1021 scoped_refptr<GetAllCookiesForURLWithOptionsTask> task = | 1022 scoped_refptr<GetAllCookiesForURLWithOptionsTask> task = |
1022 new GetAllCookiesForURLWithOptionsTask(this, url, options, callback); | 1023 new GetAllCookiesForURLWithOptionsTask(this, url, options, callback); |
1023 | 1024 |
1024 DoCookieTask(task); | 1025 DoCookieTaskForURL(task, url); |
1025 } | 1026 } |
1026 | 1027 |
1027 void CookieMonster::DeleteAllAsync(const DeleteCallback& callback) { | 1028 void CookieMonster::DeleteAllAsync(const DeleteCallback& callback) { |
1028 scoped_refptr<DeleteAllTask> task = | 1029 scoped_refptr<DeleteAllTask> task = |
1029 new DeleteAllTask(this, callback); | 1030 new DeleteAllTask(this, callback); |
1030 | 1031 |
1031 DoCookieTask(task); | 1032 DoCookieTask(task); |
1032 } | 1033 } |
1033 | 1034 |
1034 void CookieMonster::DeleteAllCreatedBetweenAsync( | 1035 void CookieMonster::DeleteAllCreatedBetweenAsync( |
1035 const Time& delete_begin, const Time& delete_end, | 1036 const Time& delete_begin, const Time& delete_end, |
1036 const DeleteCallback& callback) { | 1037 const DeleteCallback& callback) { |
1037 scoped_refptr<DeleteAllCreatedBetweenTask> task = | 1038 scoped_refptr<DeleteAllCreatedBetweenTask> task = |
1038 new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end, | 1039 new DeleteAllCreatedBetweenTask(this, delete_begin, delete_end, |
1039 callback); | 1040 callback); |
1040 | 1041 |
1041 DoCookieTask(task); | 1042 DoCookieTask(task); |
1042 } | 1043 } |
1043 | 1044 |
1044 void CookieMonster::DeleteAllForHostAsync( | 1045 void CookieMonster::DeleteAllForHostAsync( |
1045 const GURL& url, const DeleteCallback& callback) { | 1046 const GURL& url, const DeleteCallback& callback) { |
1046 scoped_refptr<DeleteAllForHostTask> task = | 1047 scoped_refptr<DeleteAllForHostTask> task = |
1047 new DeleteAllForHostTask(this, url, callback); | 1048 new DeleteAllForHostTask(this, url, callback); |
1048 | 1049 |
1049 DoCookieTask(task); | 1050 DoCookieTaskForURL(task, url); |
1050 } | 1051 } |
1051 | 1052 |
1052 void CookieMonster::DeleteCanonicalCookieAsync( | 1053 void CookieMonster::DeleteCanonicalCookieAsync( |
1053 const CanonicalCookie& cookie, | 1054 const CanonicalCookie& cookie, |
1054 const DeleteCookieCallback& callback) { | 1055 const DeleteCookieCallback& callback) { |
1055 scoped_refptr<DeleteCanonicalCookieTask> task = | 1056 scoped_refptr<DeleteCanonicalCookieTask> task = |
1056 new DeleteCanonicalCookieTask(this, cookie, callback); | 1057 new DeleteCanonicalCookieTask(this, cookie, callback); |
1057 | 1058 |
1058 DoCookieTask(task); | 1059 DoCookieTask(task); |
1059 } | 1060 } |
1060 | 1061 |
1061 void CookieMonster::SetCookieWithOptionsAsync( | 1062 void CookieMonster::SetCookieWithOptionsAsync( |
1062 const GURL& url, | 1063 const GURL& url, |
1063 const std::string& cookie_line, | 1064 const std::string& cookie_line, |
1064 const CookieOptions& options, | 1065 const CookieOptions& options, |
1065 const SetCookiesCallback& callback) { | 1066 const SetCookiesCallback& callback) { |
1066 scoped_refptr<SetCookieWithOptionsTask> task = | 1067 scoped_refptr<SetCookieWithOptionsTask> task = |
1067 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); | 1068 new SetCookieWithOptionsTask(this, url, cookie_line, options, callback); |
1068 | 1069 |
1069 DoCookieTask(task); | 1070 DoCookieTaskForURL(task, url); |
1070 } | 1071 } |
1071 | 1072 |
1072 void CookieMonster::GetCookiesWithOptionsAsync( | 1073 void CookieMonster::GetCookiesWithOptionsAsync( |
1073 const GURL& url, | 1074 const GURL& url, |
1074 const CookieOptions& options, | 1075 const CookieOptions& options, |
1075 const GetCookiesCallback& callback) { | 1076 const GetCookiesCallback& callback) { |
1076 scoped_refptr<GetCookiesWithOptionsTask> task = | 1077 scoped_refptr<GetCookiesWithOptionsTask> task = |
1077 new GetCookiesWithOptionsTask(this, url, options, callback); | 1078 new GetCookiesWithOptionsTask(this, url, options, callback); |
1078 | 1079 |
1079 DoCookieTask(task); | 1080 DoCookieTaskForURL(task, url); |
1080 } | 1081 } |
1081 | 1082 |
1082 void CookieMonster::GetCookiesWithInfoAsync( | 1083 void CookieMonster::GetCookiesWithInfoAsync( |
1083 const GURL& url, | 1084 const GURL& url, |
1084 const CookieOptions& options, | 1085 const CookieOptions& options, |
1085 const GetCookieInfoCallback& callback) { | 1086 const GetCookieInfoCallback& callback) { |
1086 scoped_refptr<GetCookiesWithInfoTask> task = | 1087 scoped_refptr<GetCookiesWithInfoTask> task = |
1087 new GetCookiesWithInfoTask(this, url, options, callback); | 1088 new GetCookiesWithInfoTask(this, url, options, callback); |
1088 | 1089 |
1089 DoCookieTask(task); | 1090 DoCookieTaskForURL(task, url); |
1090 } | 1091 } |
1091 | 1092 |
1092 void CookieMonster::DeleteCookieAsync(const GURL& url, | 1093 void CookieMonster::DeleteCookieAsync(const GURL& url, |
1093 const std::string& cookie_name, | 1094 const std::string& cookie_name, |
1094 const base::Closure& callback) { | 1095 const base::Closure& callback) { |
1095 scoped_refptr<DeleteCookieTask> task = | 1096 scoped_refptr<DeleteCookieTask> task = |
1096 new DeleteCookieTask(this, url, cookie_name, callback); | 1097 new DeleteCookieTask(this, url, cookie_name, callback); |
1097 | 1098 |
1098 DoCookieTask(task); | 1099 DoCookieTaskForURL(task, url); |
1099 } | 1100 } |
1100 | 1101 |
1101 void CookieMonster::DoCookieTask( | 1102 void CookieMonster::DoCookieTask( |
1102 const scoped_refptr<CookieMonsterTask>& task_item) { | 1103 const scoped_refptr<CookieMonsterTask>& task_item) { |
1103 InitIfNecessary(); | 1104 InitIfNecessary(); |
erikwright (departed)
2011/09/20 19:00:44
Randy is correct. Please move the InitIfNecessary
guohui
2011/10/06 15:40:00
Done.
| |
1104 | 1105 |
1105 { | 1106 { |
1106 base::AutoLock autolock(lock_); | 1107 base::AutoLock autolock(lock_); |
1107 if (!loaded_) { | 1108 if (!loaded_) { |
1108 queue_.push(task_item); | 1109 queue_.push(task_item); |
1109 return; | 1110 return; |
1110 } | 1111 } |
1111 } | 1112 } |
1112 | 1113 |
1113 task_item->Run(); | 1114 task_item->Run(); |
1114 } | 1115 } |
1115 | 1116 |
1117 void CookieMonster::DoCookieTaskForURL( | |
1118 const scoped_refptr<CookieMonsterTask>& task_item, | |
1119 const GURL& url) { | |
1120 InitIfNecessary(); | |
erikwright (departed)
2011/09/20 19:00:44
Randy is correct. Please move the InitIfNecessary
guohui
2011/10/06 15:40:00
Done.
| |
1121 | |
1122 { | |
1123 base::AutoLock autolock(lock_); | |
1124 // If cookies for the requested domain key (eTLD+1) have been loaded from DB | |
1125 // then run the task, otherwise load from DB. | |
1126 if (!loaded_) { | |
1127 // Checks if the domain key has been loaded. | |
1128 std::string key(GetEffectiveDomain(url.scheme(), url.host())); | |
1129 if (keys_loaded_.find(key) == keys_loaded_.end()) { | |
1130 store_->LoadCookiesForKey(key, | |
1131 base::Bind(&CookieMonster::OnKeyLoaded, this, | |
1132 base::Bind(&CookieMonsterTask::Run, task_item.get()), | |
1133 key)); | |
1134 return; | |
1135 } | |
1136 } | |
1137 } | |
1138 task_item->Run(); | |
1139 } | |
1140 | |
1116 bool CookieMonster::SetCookieWithDetails( | 1141 bool CookieMonster::SetCookieWithDetails( |
1117 const GURL& url, const std::string& name, const std::string& value, | 1142 const GURL& url, const std::string& name, const std::string& value, |
1118 const std::string& domain, const std::string& path, | 1143 const std::string& domain, const std::string& path, |
1119 const base::Time& expiration_time, bool secure, bool http_only) { | 1144 const base::Time& expiration_time, bool secure, bool http_only) { |
1120 base::AutoLock autolock(lock_); | 1145 base::AutoLock autolock(lock_); |
1121 | 1146 |
1122 if (!HasCookieableScheme(url)) | 1147 if (!HasCookieableScheme(url)) |
1123 return false; | 1148 return false; |
1124 | 1149 |
1125 Time creation_time = CurrentTime(); | 1150 Time creation_time = CurrentTime(); |
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1463 | 1488 |
1464 void CookieMonster::OnLoaded(TimeTicks beginning_time, | 1489 void CookieMonster::OnLoaded(TimeTicks beginning_time, |
1465 const std::vector<CanonicalCookie*>& cookies) { | 1490 const std::vector<CanonicalCookie*>& cookies) { |
1466 StoreLoadedCookies(cookies); | 1491 StoreLoadedCookies(cookies); |
1467 histogram_time_load_->AddTime(TimeTicks::Now() - beginning_time); | 1492 histogram_time_load_->AddTime(TimeTicks::Now() - beginning_time); |
1468 | 1493 |
1469 // Invoke the task queue of cookie request. | 1494 // Invoke the task queue of cookie request. |
1470 InvokeQueue(); | 1495 InvokeQueue(); |
1471 } | 1496 } |
1472 | 1497 |
1498 void CookieMonster::OnKeyLoaded( | |
1499 const base::Closure& request_task, const std::string& key, | |
1500 const std::vector<CanonicalCookie*>& cookies) { | |
1501 // This function does its own separate locking. | |
1502 StoreLoadedCookies(cookies); | |
1503 { | |
1504 base::AutoLock autolock(lock_); | |
1505 keys_loaded_.insert(key); | |
1506 } | |
1507 request_task.Run(); | |
1508 } | |
1509 | |
1473 void CookieMonster::StoreLoadedCookies( | 1510 void CookieMonster::StoreLoadedCookies( |
1474 const std::vector<CanonicalCookie*>& cookies) { | 1511 const std::vector<CanonicalCookie*>& cookies) { |
1475 // Initialize the store and sync in any saved persistent cookies. We don't | 1512 // Initialize the store and sync in any saved persistent cookies. We don't |
1476 // care if it's expired, insert it so it can be garbage collected, removed, | 1513 // care if it's expired, insert it so it can be garbage collected, removed, |
1477 // and sync'd. | 1514 // and sync'd. |
1478 base::AutoLock autolock(lock_); | 1515 base::AutoLock autolock(lock_); |
1479 | 1516 |
1480 // Avoid ever letting cookies with duplicate creation times into the store; | |
1481 // that way we don't have to worry about what sections of code are safe | |
1482 // to call while it's in that state. | |
1483 std::set<int64> creation_times; | |
1484 | |
1485 // Presumably later than any access time in the store. | |
1486 Time earliest_access_time; | |
1487 | |
1488 for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin(); | 1517 for (std::vector<CanonicalCookie*>::const_iterator it = cookies.begin(); |
1489 it != cookies.end(); ++it) { | 1518 it != cookies.end(); ++it) { |
1490 int64 cookie_creation_time = (*it)->CreationDate().ToInternalValue(); | 1519 int64 cookie_creation_time = (*it)->CreationDate().ToInternalValue(); |
1491 | 1520 |
1492 if (creation_times.insert(cookie_creation_time).second) { | 1521 if (creation_times_.insert(cookie_creation_time).second) { |
1493 InternalInsertCookie(GetKey((*it)->Domain()), *it, false); | 1522 InternalInsertCookie(GetKey((*it)->Domain()), *it, false); |
1494 const Time cookie_access_time((*it)->LastAccessDate()); | 1523 const Time cookie_access_time((*it)->LastAccessDate()); |
1495 if (earliest_access_time.is_null() || | 1524 if (earliest_access_time_.is_null() || |
1496 cookie_access_time < earliest_access_time) | 1525 cookie_access_time < earliest_access_time_) |
1497 earliest_access_time = cookie_access_time; | 1526 earliest_access_time_ = cookie_access_time; |
1498 } else { | 1527 } else { |
1499 LOG(ERROR) << base::StringPrintf("Found cookies with duplicate creation " | 1528 LOG(ERROR) << base::StringPrintf("Found cookies with duplicate creation " |
1500 "times in backing store: " | 1529 "times in backing store: " |
1501 "{name='%s', domain='%s', path='%s'}", | 1530 "{name='%s', domain='%s', path='%s'}", |
1502 (*it)->Name().c_str(), | 1531 (*it)->Name().c_str(), |
1503 (*it)->Domain().c_str(), | 1532 (*it)->Domain().c_str(), |
1504 (*it)->Path().c_str()); | 1533 (*it)->Path().c_str()); |
1505 // We've been given ownership of the cookie and are throwing it | 1534 // We've been given ownership of the cookie and are throwing it |
1506 // away; reclaim the space. | 1535 // away; reclaim the space. |
1507 delete (*it); | 1536 delete (*it); |
1508 } | 1537 } |
1509 } | 1538 } |
1510 earliest_access_time_= earliest_access_time; | |
1511 | 1539 |
1512 // After importing cookies from the PersistentCookieStore, verify that | 1540 // After importing cookies from the PersistentCookieStore, verify that |
1513 // none of our other constraints are violated. | 1541 // none of our other constraints are violated. |
1514 // | |
1515 // In particular, the backing store might have given us duplicate cookies. | 1542 // In particular, the backing store might have given us duplicate cookies. |
1543 // "Priority loaded" cookies will be validated more than once, but this is OK | |
1544 // since they are expected to be much fewer than total DB. | |
1516 EnsureCookiesMapIsValid(); | 1545 EnsureCookiesMapIsValid(); |
1517 } | 1546 } |
1518 | 1547 |
1519 void CookieMonster::InvokeQueue() { | 1548 void CookieMonster::InvokeQueue() { |
1520 while (true) { | 1549 while (true) { |
1521 scoped_refptr<CookieMonsterTask> request_task; | 1550 scoped_refptr<CookieMonsterTask> request_task; |
1522 { | 1551 { |
1523 base::AutoLock autolock(lock_); | 1552 base::AutoLock autolock(lock_); |
1524 if (queue_.empty()) { | 1553 if (queue_.empty()) { |
1525 loaded_ = true; | 1554 loaded_ = true; |
1555 creation_times_.clear(); | |
1556 keys_loaded_.clear(); | |
1526 break; | 1557 break; |
1527 } | 1558 } |
1528 request_task = queue_.front(); | 1559 request_task = queue_.front(); |
1529 queue_.pop(); | 1560 queue_.pop(); |
1530 } | 1561 } |
1531 request_task->Run(); | 1562 request_task->Run(); |
1532 } | 1563 } |
1533 } | 1564 } |
1534 | 1565 |
1535 void CookieMonster::EnsureCookiesMapIsValid() { | 1566 void CookieMonster::EnsureCookiesMapIsValid() { |
(...skipping 1228 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2764 std::string CookieMonster::CanonicalCookie::DebugString() const { | 2795 std::string CookieMonster::CanonicalCookie::DebugString() const { |
2765 return base::StringPrintf( | 2796 return base::StringPrintf( |
2766 "name: %s value: %s domain: %s path: %s creation: %" | 2797 "name: %s value: %s domain: %s path: %s creation: %" |
2767 PRId64, | 2798 PRId64, |
2768 name_.c_str(), value_.c_str(), | 2799 name_.c_str(), value_.c_str(), |
2769 domain_.c_str(), path_.c_str(), | 2800 domain_.c_str(), path_.c_str(), |
2770 static_cast<int64>(creation_date_.ToTimeT())); | 2801 static_cast<int64>(creation_date_.ToTimeT())); |
2771 } | 2802 } |
2772 | 2803 |
2773 } // namespace | 2804 } // namespace |
OLD | NEW |