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 #include "chrome/browser/net/sqlite_persistent_cookie_store.h" | 5 #include "chrome/browser/net/sqlite_persistent_cookie_store.h" |
6 | 6 |
7 #include <list> | 7 #include <list> |
8 #include <map> | 8 #include <map> |
9 #include <set> | 9 #include <set> |
10 #include <utility> | 10 #include <utility> |
(...skipping 10 matching lines...) Expand all Loading... |
21 #include "base/string_util.h" | 21 #include "base/string_util.h" |
22 #include "base/synchronization/lock.h" | 22 #include "base/synchronization/lock.h" |
23 #include "base/threading/thread.h" | 23 #include "base/threading/thread.h" |
24 #include "base/threading/thread_restrictions.h" | 24 #include "base/threading/thread_restrictions.h" |
25 #include "base/time.h" | 25 #include "base/time.h" |
26 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" | 26 #include "chrome/browser/diagnostics/sqlite_diagnostics.h" |
27 #include "chrome/browser/net/clear_on_exit_policy.h" | 27 #include "chrome/browser/net/clear_on_exit_policy.h" |
28 #include "content/public/browser/browser_thread.h" | 28 #include "content/public/browser/browser_thread.h" |
29 #include "googleurl/src/gurl.h" | 29 #include "googleurl/src/gurl.h" |
30 #include "net/base/registry_controlled_domain.h" | 30 #include "net/base/registry_controlled_domain.h" |
| 31 #include "net/cookies/canonical_cookie.h" |
31 #include "sql/meta_table.h" | 32 #include "sql/meta_table.h" |
32 #include "sql/statement.h" | 33 #include "sql/statement.h" |
33 #include "sql/transaction.h" | 34 #include "sql/transaction.h" |
34 | 35 |
35 using base::Time; | 36 using base::Time; |
36 using content::BrowserThread; | 37 using content::BrowserThread; |
37 | 38 |
38 // This class is designed to be shared between any calling threads and the | 39 // This class is designed to be shared between any calling threads and the |
39 // database thread. It batches operations and commits them on a timer. | 40 // database thread. It batches operations and commits them on a timer. |
40 // | 41 // |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
76 } | 77 } |
77 | 78 |
78 // Creates or loads the SQLite database. | 79 // Creates or loads the SQLite database. |
79 void Load(const LoadedCallback& loaded_callback); | 80 void Load(const LoadedCallback& loaded_callback); |
80 | 81 |
81 // Loads cookies for the domain key (eTLD+1). | 82 // Loads cookies for the domain key (eTLD+1). |
82 void LoadCookiesForKey(const std::string& domain, | 83 void LoadCookiesForKey(const std::string& domain, |
83 const LoadedCallback& loaded_callback); | 84 const LoadedCallback& loaded_callback); |
84 | 85 |
85 // Batch a cookie addition. | 86 // Batch a cookie addition. |
86 void AddCookie(const net::CookieMonster::CanonicalCookie& cc); | 87 void AddCookie(const net::CanonicalCookie& cc); |
87 | 88 |
88 // Batch a cookie access time update. | 89 // Batch a cookie access time update. |
89 void UpdateCookieAccessTime(const net::CookieMonster::CanonicalCookie& cc); | 90 void UpdateCookieAccessTime(const net::CanonicalCookie& cc); |
90 | 91 |
91 // Batch a cookie deletion. | 92 // Batch a cookie deletion. |
92 void DeleteCookie(const net::CookieMonster::CanonicalCookie& cc); | 93 void DeleteCookie(const net::CanonicalCookie& cc); |
93 | 94 |
94 // Commit pending operations as soon as possible. | 95 // Commit pending operations as soon as possible. |
95 void Flush(const base::Closure& callback); | 96 void Flush(const base::Closure& callback); |
96 | 97 |
97 // Commit any pending operations and close the database. This must be called | 98 // Commit any pending operations and close the database. This must be called |
98 // before the object is destructed. | 99 // before the object is destructed. |
99 void Close(); | 100 void Close(); |
100 | 101 |
101 void SetForceKeepSessionState(); | 102 void SetForceKeepSessionState(); |
102 | 103 |
(...skipping 10 matching lines...) Expand all Loading... |
113 bool EnsureDatabaseVersion(); | 114 bool EnsureDatabaseVersion(); |
114 | 115 |
115 class PendingOperation { | 116 class PendingOperation { |
116 public: | 117 public: |
117 typedef enum { | 118 typedef enum { |
118 COOKIE_ADD, | 119 COOKIE_ADD, |
119 COOKIE_UPDATEACCESS, | 120 COOKIE_UPDATEACCESS, |
120 COOKIE_DELETE, | 121 COOKIE_DELETE, |
121 } OperationType; | 122 } OperationType; |
122 | 123 |
123 PendingOperation(OperationType op, | 124 PendingOperation(OperationType op, const net::CanonicalCookie& cc) |
124 const net::CookieMonster::CanonicalCookie& cc) | |
125 : op_(op), cc_(cc) { } | 125 : op_(op), cc_(cc) { } |
126 | 126 |
127 OperationType op() const { return op_; } | 127 OperationType op() const { return op_; } |
128 const net::CookieMonster::CanonicalCookie& cc() const { return cc_; } | 128 const net::CanonicalCookie& cc() const { return cc_; } |
129 | 129 |
130 private: | 130 private: |
131 OperationType op_; | 131 OperationType op_; |
132 net::CookieMonster::CanonicalCookie cc_; | 132 net::CanonicalCookie cc_; |
133 }; | 133 }; |
134 | 134 |
135 private: | 135 private: |
136 // Creates or loads the SQLite database on DB thread. | 136 // Creates or loads the SQLite database on DB thread. |
137 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback, | 137 void LoadAndNotifyOnDBThread(const LoadedCallback& loaded_callback, |
138 const base::Time& posted_at); | 138 const base::Time& posted_at); |
139 | 139 |
140 // Loads cookies for the domain key (eTLD+1) on DB thread. | 140 // Loads cookies for the domain key (eTLD+1) on DB thread. |
141 void LoadKeyAndNotifyOnDBThread(const std::string& domains, | 141 void LoadKeyAndNotifyOnDBThread(const std::string& domains, |
142 const LoadedCallback& loaded_callback, | 142 const LoadedCallback& loaded_callback, |
(...skipping 29 matching lines...) Expand all Loading... |
172 // Loads cookies for the next domain key from the DB, then either reschedules | 172 // Loads cookies for the next domain key from the DB, then either reschedules |
173 // itself or schedules the provided callback to run on the IO thread (if all | 173 // itself or schedules the provided callback to run on the IO thread (if all |
174 // domains are loaded). | 174 // domains are loaded). |
175 void ChainLoadCookies(const LoadedCallback& loaded_callback); | 175 void ChainLoadCookies(const LoadedCallback& loaded_callback); |
176 | 176 |
177 // Load all cookies for a set of domains/hosts | 177 // Load all cookies for a set of domains/hosts |
178 bool LoadCookiesForDomains(const std::set<std::string>& key); | 178 bool LoadCookiesForDomains(const std::set<std::string>& key); |
179 | 179 |
180 // Batch a cookie operation (add or delete) | 180 // Batch a cookie operation (add or delete) |
181 void BatchOperation(PendingOperation::OperationType op, | 181 void BatchOperation(PendingOperation::OperationType op, |
182 const net::CookieMonster::CanonicalCookie& cc); | 182 const net::CanonicalCookie& cc); |
183 // Commit our pending operations to the database. | 183 // Commit our pending operations to the database. |
184 void Commit(); | 184 void Commit(); |
185 // Close() executed on the background thread. | 185 // Close() executed on the background thread. |
186 void InternalBackgroundClose(); | 186 void InternalBackgroundClose(); |
187 | 187 |
188 void DeleteSessionCookiesOnStartup(); | 188 void DeleteSessionCookiesOnStartup(); |
189 | 189 |
190 void DeleteSessionCookiesOnShutdown(); | 190 void DeleteSessionCookiesOnShutdown(); |
191 | 191 |
192 FilePath path_; | 192 FilePath path_; |
193 scoped_ptr<sql::Connection> db_; | 193 scoped_ptr<sql::Connection> db_; |
194 sql::MetaTable meta_table_; | 194 sql::MetaTable meta_table_; |
195 | 195 |
196 typedef std::list<PendingOperation*> PendingOperationsList; | 196 typedef std::list<PendingOperation*> PendingOperationsList; |
197 PendingOperationsList pending_; | 197 PendingOperationsList pending_; |
198 PendingOperationsList::size_type num_pending_; | 198 PendingOperationsList::size_type num_pending_; |
199 // True if the persistent store should skip delete on exit rules. | 199 // True if the persistent store should skip delete on exit rules. |
200 bool force_keep_session_state_; | 200 bool force_keep_session_state_; |
201 // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_| | 201 // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_| |
202 base::Lock lock_; | 202 base::Lock lock_; |
203 | 203 |
204 // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce | 204 // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce |
205 // the number of messages sent to the IO thread. Sent back in response to | 205 // the number of messages sent to the IO thread. Sent back in response to |
206 // individual load requests for domain keys or when all loading completes. | 206 // individual load requests for domain keys or when all loading completes. |
207 std::vector<net::CookieMonster::CanonicalCookie*> cookies_; | 207 std::vector<net::CanonicalCookie*> cookies_; |
208 | 208 |
209 // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB. | 209 // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB. |
210 std::map<std::string, std::set<std::string> > keys_to_load_; | 210 std::map<std::string, std::set<std::string> > keys_to_load_; |
211 | 211 |
212 // Map of (domain keys(eTLD+1), is secure cookie) to number of cookies in the | 212 // Map of (domain keys(eTLD+1), is secure cookie) to number of cookies in the |
213 // database. | 213 // database. |
214 typedef std::pair<std::string, bool> CookieOrigin; | 214 typedef std::pair<std::string, bool> CookieOrigin; |
215 typedef std::map<CookieOrigin, int> CookiesPerOriginMap; | 215 typedef std::map<CookieOrigin, int> CookiesPerOriginMap; |
216 CookiesPerOriginMap cookies_per_origin_; | 216 CookiesPerOriginMap cookies_per_origin_; |
217 | 217 |
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 | 455 |
456 if (load_success) | 456 if (load_success) |
457 ReportMetrics(); | 457 ReportMetrics(); |
458 } | 458 } |
459 | 459 |
460 void SQLitePersistentCookieStore::Backend::Notify( | 460 void SQLitePersistentCookieStore::Backend::Notify( |
461 const LoadedCallback& loaded_callback, | 461 const LoadedCallback& loaded_callback, |
462 bool load_success) { | 462 bool load_success) { |
463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 463 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
464 | 464 |
465 std::vector<net::CookieMonster::CanonicalCookie*> cookies; | 465 std::vector<net::CanonicalCookie*> cookies; |
466 { | 466 { |
467 base::AutoLock locked(lock_); | 467 base::AutoLock locked(lock_); |
468 cookies.swap(cookies_); | 468 cookies.swap(cookies_); |
469 } | 469 } |
470 | 470 |
471 loaded_callback.Run(cookies); | 471 loaded_callback.Run(cookies); |
472 } | 472 } |
473 | 473 |
474 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { | 474 bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { |
475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 475 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
(...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
601 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 601 "SELECT creation_utc, host_key, name, value, path, expires_utc, " |
602 "secure, httponly, last_access_utc, has_expires, persistent " | 602 "secure, httponly, last_access_utc, has_expires, persistent " |
603 "FROM cookies WHERE host_key = ? AND persistent = 1")); | 603 "FROM cookies WHERE host_key = ? AND persistent = 1")); |
604 } | 604 } |
605 if (!smt.is_valid()) { | 605 if (!smt.is_valid()) { |
606 smt.Clear(); // Disconnect smt_ref from db_. | 606 smt.Clear(); // Disconnect smt_ref from db_. |
607 db_.reset(); | 607 db_.reset(); |
608 return false; | 608 return false; |
609 } | 609 } |
610 | 610 |
611 std::vector<net::CookieMonster::CanonicalCookie*> cookies; | 611 std::vector<net::CanonicalCookie*> cookies; |
612 std::set<std::string>::const_iterator it = domains.begin(); | 612 std::set<std::string>::const_iterator it = domains.begin(); |
613 for (; it != domains.end(); ++it) { | 613 for (; it != domains.end(); ++it) { |
614 smt.BindString(0, *it); | 614 smt.BindString(0, *it); |
615 while (smt.Step()) { | 615 while (smt.Step()) { |
616 scoped_ptr<net::CookieMonster::CanonicalCookie> cc( | 616 scoped_ptr<net::CanonicalCookie> cc( |
617 new net::CookieMonster::CanonicalCookie( | 617 new net::CanonicalCookie( |
618 // The "source" URL is not used with persisted cookies. | 618 // The "source" URL is not used with persisted cookies. |
619 GURL(), // Source | 619 GURL(), // Source |
620 smt.ColumnString(2), // name | 620 smt.ColumnString(2), // name |
621 smt.ColumnString(3), // value | 621 smt.ColumnString(3), // value |
622 smt.ColumnString(1), // domain | 622 smt.ColumnString(1), // domain |
623 smt.ColumnString(4), // path | 623 smt.ColumnString(4), // path |
624 std::string(), // TODO(abarth): Persist mac_key | 624 std::string(), // TODO(abarth): Persist mac_key |
625 std::string(), // TODO(abarth): Persist mac_algorithm | 625 std::string(), // TODO(abarth): Persist mac_algorithm |
626 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc | 626 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc |
627 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc | 627 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc |
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
744 meta_table_.Reset(); | 744 meta_table_.Reset(); |
745 db_.reset(); | 745 db_.reset(); |
746 return false; | 746 return false; |
747 } | 747 } |
748 } | 748 } |
749 | 749 |
750 return true; | 750 return true; |
751 } | 751 } |
752 | 752 |
753 void SQLitePersistentCookieStore::Backend::AddCookie( | 753 void SQLitePersistentCookieStore::Backend::AddCookie( |
754 const net::CookieMonster::CanonicalCookie& cc) { | 754 const net::CanonicalCookie& cc) { |
755 BatchOperation(PendingOperation::COOKIE_ADD, cc); | 755 BatchOperation(PendingOperation::COOKIE_ADD, cc); |
756 } | 756 } |
757 | 757 |
758 void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime( | 758 void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime( |
759 const net::CookieMonster::CanonicalCookie& cc) { | 759 const net::CanonicalCookie& cc) { |
760 BatchOperation(PendingOperation::COOKIE_UPDATEACCESS, cc); | 760 BatchOperation(PendingOperation::COOKIE_UPDATEACCESS, cc); |
761 } | 761 } |
762 | 762 |
763 void SQLitePersistentCookieStore::Backend::DeleteCookie( | 763 void SQLitePersistentCookieStore::Backend::DeleteCookie( |
764 const net::CookieMonster::CanonicalCookie& cc) { | 764 const net::CanonicalCookie& cc) { |
765 BatchOperation(PendingOperation::COOKIE_DELETE, cc); | 765 BatchOperation(PendingOperation::COOKIE_DELETE, cc); |
766 } | 766 } |
767 | 767 |
768 void SQLitePersistentCookieStore::Backend::BatchOperation( | 768 void SQLitePersistentCookieStore::Backend::BatchOperation( |
769 PendingOperation::OperationType op, | 769 PendingOperation::OperationType op, |
770 const net::CookieMonster::CanonicalCookie& cc) { | 770 const net::CanonicalCookie& cc) { |
771 // Commit every 30 seconds. | 771 // Commit every 30 seconds. |
772 static const int kCommitIntervalMs = 30 * 1000; | 772 static const int kCommitIntervalMs = 30 * 1000; |
773 // Commit right away if we have more than 512 outstanding operations. | 773 // Commit right away if we have more than 512 outstanding operations. |
774 static const size_t kCommitAfterBatchSize = 512; | 774 static const size_t kCommitAfterBatchSize = 512; |
775 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); | 775 DCHECK(!BrowserThread::CurrentlyOn(BrowserThread::DB)); |
776 | 776 |
777 // We do a full copy of the cookie here, and hopefully just here. | 777 // We do a full copy of the cookie here, and hopefully just here. |
778 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc)); | 778 scoped_ptr<PendingOperation> po(new PendingOperation(op, cc)); |
779 | 779 |
780 PendingOperationsList::size_type num_pending; | 780 PendingOperationsList::size_type num_pending; |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
990 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { | 990 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { |
991 backend_->Load(loaded_callback); | 991 backend_->Load(loaded_callback); |
992 } | 992 } |
993 | 993 |
994 void SQLitePersistentCookieStore::LoadCookiesForKey( | 994 void SQLitePersistentCookieStore::LoadCookiesForKey( |
995 const std::string& key, | 995 const std::string& key, |
996 const LoadedCallback& loaded_callback) { | 996 const LoadedCallback& loaded_callback) { |
997 backend_->LoadCookiesForKey(key, loaded_callback); | 997 backend_->LoadCookiesForKey(key, loaded_callback); |
998 } | 998 } |
999 | 999 |
1000 void SQLitePersistentCookieStore::AddCookie( | 1000 void SQLitePersistentCookieStore::AddCookie(const net::CanonicalCookie& cc) { |
1001 const net::CookieMonster::CanonicalCookie& cc) { | |
1002 if (backend_.get()) | 1001 if (backend_.get()) |
1003 backend_->AddCookie(cc); | 1002 backend_->AddCookie(cc); |
1004 } | 1003 } |
1005 | 1004 |
1006 void SQLitePersistentCookieStore::UpdateCookieAccessTime( | 1005 void SQLitePersistentCookieStore::UpdateCookieAccessTime( |
1007 const net::CookieMonster::CanonicalCookie& cc) { | 1006 const net::CanonicalCookie& cc) { |
1008 if (backend_.get()) | 1007 if (backend_.get()) |
1009 backend_->UpdateCookieAccessTime(cc); | 1008 backend_->UpdateCookieAccessTime(cc); |
1010 } | 1009 } |
1011 | 1010 |
1012 void SQLitePersistentCookieStore::DeleteCookie( | 1011 void SQLitePersistentCookieStore::DeleteCookie(const net::CanonicalCookie& cc) { |
1013 const net::CookieMonster::CanonicalCookie& cc) { | |
1014 if (backend_.get()) | 1012 if (backend_.get()) |
1015 backend_->DeleteCookie(cc); | 1013 backend_->DeleteCookie(cc); |
1016 } | 1014 } |
1017 | 1015 |
1018 void SQLitePersistentCookieStore::SetForceKeepSessionState() { | 1016 void SQLitePersistentCookieStore::SetForceKeepSessionState() { |
1019 if (backend_.get()) | 1017 if (backend_.get()) |
1020 backend_->SetForceKeepSessionState(); | 1018 backend_->SetForceKeepSessionState(); |
1021 } | 1019 } |
1022 | 1020 |
1023 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { | 1021 void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { |
1024 if (backend_.get()) | 1022 if (backend_.get()) |
1025 backend_->Flush(callback); | 1023 backend_->Flush(callback); |
1026 else if (!callback.is_null()) | 1024 else if (!callback.is_null()) |
1027 MessageLoop::current()->PostTask(FROM_HERE, callback); | 1025 MessageLoop::current()->PostTask(FROM_HERE, callback); |
1028 } | 1026 } |
1029 | 1027 |
1030 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { | 1028 SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { |
1031 if (backend_.get()) { | 1029 if (backend_.get()) { |
1032 backend_->Close(); | 1030 backend_->Close(); |
1033 // Release our reference, it will probably still have a reference if the | 1031 // Release our reference, it will probably still have a reference if the |
1034 // background thread has not run Close() yet. | 1032 // background thread has not run Close() yet. |
1035 backend_ = NULL; | 1033 backend_ = NULL; |
1036 } | 1034 } |
1037 } | 1035 } |
OLD | NEW |