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 "content/browser/net/sqlite_persistent_cookie_store.h" | 5 #include "content/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 297 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
308 attempted_to_kill_database_ = true; | 308 attempted_to_kill_database_ = true; |
309 | 309 |
310 backend_->ScheduleKillDatabase(); | 310 backend_->ScheduleKillDatabase(); |
311 } | 311 } |
312 | 312 |
313 return error; | 313 return error; |
314 } | 314 } |
315 | 315 |
316 // Version number of the database. | 316 // Version number of the database. |
317 // | 317 // |
318 // Version 6 adds cookie priorities. This allows developers to influence the | |
319 // order in which cookies are deleted in order to meet domain cookie limits. | |
huangs
2013/04/16 18:25:55
s/deleted/evicted/g to conform with terminology.
Roger McFarlane (Chromium)
2013/04/16 19:17:25
Done.
| |
320 // | |
318 // Version 5 adds the columns has_expires and is_persistent, so that the | 321 // Version 5 adds the columns has_expires and is_persistent, so that the |
319 // database can store session cookies as well as persistent cookies. Databases | 322 // database can store session cookies as well as persistent cookies. Databases |
320 // of version 5 are incompatible with older versions of code. If a database of | 323 // of version 5 are incompatible with older versions of code. If a database of |
321 // version 5 is read by older code, session cookies will be treated as normal | 324 // version 5 is read by older code, session cookies will be treated as normal |
322 // cookies. Currently, these fields are written, but not read anymore. | 325 // cookies. Currently, these fields are written, but not read anymore. |
323 // | 326 // |
324 // In version 4, we migrated the time epoch. If you open the DB with an older | 327 // In version 4, we migrated the time epoch. If you open the DB with an older |
325 // version on Mac or Linux, the times will look wonky, but the file will likely | 328 // version on Mac or Linux, the times will look wonky, but the file will likely |
326 // be usable. On Windows version 3 and 4 are the same. | 329 // be usable. On Windows version 3 and 4 are the same. |
327 // | 330 // |
328 // Version 3 updated the database to include the last access time, so we can | 331 // Version 3 updated the database to include the last access time, so we can |
329 // expire them in decreasing order of use when we've reached the maximum | 332 // expire them in decreasing order of use when we've reached the maximum |
330 // number of cookies. | 333 // number of cookies. |
331 static const int kCurrentVersionNumber = 5; | 334 static const int kCurrentVersionNumber = 6; |
332 static const int kCompatibleVersionNumber = 5; | 335 static const int kCompatibleVersionNumber = 5; |
333 | 336 |
334 namespace { | 337 namespace { |
335 | 338 |
336 // Increments a specified TimeDelta by the duration between this object's | 339 // Increments a specified TimeDelta by the duration between this object's |
337 // constructor and destructor. Not thread safe. Multiple instances may be | 340 // constructor and destructor. Not thread safe. Multiple instances may be |
338 // created with the same delta instance as long as their lifetimes are nested. | 341 // created with the same delta instance as long as their lifetimes are nested. |
339 // The shortest lived instances have no impact. | 342 // The shortest lived instances have no impact. |
340 class IncrementTimeDelta { | 343 class IncrementTimeDelta { |
341 public: | 344 public: |
(...skipping 21 matching lines...) Expand all Loading... | |
363 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," | 366 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," |
364 "host_key TEXT NOT NULL," | 367 "host_key TEXT NOT NULL," |
365 "name TEXT NOT NULL," | 368 "name TEXT NOT NULL," |
366 "value TEXT NOT NULL," | 369 "value TEXT NOT NULL," |
367 "path TEXT NOT NULL," | 370 "path TEXT NOT NULL," |
368 "expires_utc INTEGER NOT NULL," | 371 "expires_utc INTEGER NOT NULL," |
369 "secure INTEGER NOT NULL," | 372 "secure INTEGER NOT NULL," |
370 "httponly INTEGER NOT NULL," | 373 "httponly INTEGER NOT NULL," |
371 "last_access_utc INTEGER NOT NULL, " | 374 "last_access_utc INTEGER NOT NULL, " |
372 "has_expires INTEGER NOT NULL DEFAULT 1, " | 375 "has_expires INTEGER NOT NULL DEFAULT 1, " |
373 "persistent INTEGER NOT NULL DEFAULT 1)")) | 376 "persistent INTEGER NOT NULL DEFAULT 1," |
377 "priority INTEGER NOT NULL DEFAULT 1")) | |
huangs
2013/04/16 18:25:55
1 == net::PRIORITY_DEFAULT. While it's messy to i
Roger McFarlane (Chromium)
2013/04/16 19:17:25
Done.
| |
374 return false; | 378 return false; |
375 } | 379 } |
376 | 380 |
377 // Older code created an index on creation_utc, which is already | 381 // Older code created an index on creation_utc, which is already |
378 // primary key for the table. | 382 // primary key for the table. |
379 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) | 383 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) |
380 return false; | 384 return false; |
381 | 385 |
382 if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)")) | 386 if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)")) |
383 return false; | 387 return false; |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 | 656 |
653 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( | 657 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( |
654 const std::set<std::string>& domains) { | 658 const std::set<std::string>& domains) { |
655 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); | 659 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); |
656 | 660 |
657 sql::Statement smt; | 661 sql::Statement smt; |
658 if (restore_old_session_cookies_) { | 662 if (restore_old_session_cookies_) { |
659 smt.Assign(db_->GetCachedStatement( | 663 smt.Assign(db_->GetCachedStatement( |
660 SQL_FROM_HERE, | 664 SQL_FROM_HERE, |
661 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 665 "SELECT creation_utc, host_key, name, value, path, expires_utc, " |
662 "secure, httponly, last_access_utc, has_expires, persistent " | 666 "secure, httponly, last_access_utc, has_expires, persistent, priority " |
663 "FROM cookies WHERE host_key = ?")); | 667 "FROM cookies WHERE host_key = ?")); |
664 } else { | 668 } else { |
665 smt.Assign(db_->GetCachedStatement( | 669 smt.Assign(db_->GetCachedStatement( |
666 SQL_FROM_HERE, | 670 SQL_FROM_HERE, |
667 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 671 "SELECT creation_utc, host_key, name, value, path, expires_utc, " |
668 "secure, httponly, last_access_utc, has_expires, persistent " | 672 "secure, httponly, last_access_utc, has_expires, persistent, priority " |
669 "FROM cookies WHERE host_key = ? AND persistent = 1")); | 673 "FROM cookies WHERE host_key = ? AND persistent = 1")); |
670 } | 674 } |
671 if (!smt.is_valid()) { | 675 if (!smt.is_valid()) { |
672 smt.Clear(); // Disconnect smt_ref from db_. | 676 smt.Clear(); // Disconnect smt_ref from db_. |
673 meta_table_.Reset(); | 677 meta_table_.Reset(); |
674 db_.reset(); | 678 db_.reset(); |
675 return false; | 679 return false; |
676 } | 680 } |
677 | 681 |
678 std::vector<net::CanonicalCookie*> cookies; | 682 std::vector<net::CanonicalCookie*> cookies; |
679 std::set<std::string>::const_iterator it = domains.begin(); | 683 std::set<std::string>::const_iterator it = domains.begin(); |
680 for (; it != domains.end(); ++it) { | 684 for (; it != domains.end(); ++it) { |
681 smt.BindString(0, *it); | 685 smt.BindString(0, *it); |
682 while (smt.Step()) { | 686 while (smt.Step()) { |
683 scoped_ptr<net::CanonicalCookie> cc( | 687 scoped_ptr<net::CanonicalCookie> cc( |
684 new net::CanonicalCookie( | 688 new net::CanonicalCookie( |
685 // The "source" URL is not used with persisted cookies. | 689 // The "source" URL is not used with persisted cookies. |
686 GURL(), // Source | 690 GURL(), // Source |
687 smt.ColumnString(2), // name | 691 smt.ColumnString(2), // name |
688 smt.ColumnString(3), // value | 692 smt.ColumnString(3), // value |
689 smt.ColumnString(1), // domain | 693 smt.ColumnString(1), // domain |
690 smt.ColumnString(4), // path | 694 smt.ColumnString(4), // path |
691 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc | 695 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc |
692 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc | 696 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc |
693 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc | 697 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc |
694 smt.ColumnInt(6) != 0, // secure | 698 smt.ColumnInt(6) != 0, // secure |
695 smt.ColumnInt(7) != 0)); // httponly | 699 smt.ColumnInt(7) != 0), // httponly |
700 smt.ColumnInt(9)); // priority | |
696 DLOG_IF(WARNING, | 701 DLOG_IF(WARNING, |
697 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; | 702 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; |
698 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; | 703 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; |
699 cookies.push_back(cc.release()); | 704 cookies.push_back(cc.release()); |
700 ++num_cookies_read_; | 705 ++num_cookies_read_; |
701 } | 706 } |
702 smt.Reset(true); | 707 smt.Reset(true); |
703 } | 708 } |
704 { | 709 { |
705 base::AutoLock locked(lock_); | 710 base::AutoLock locked(lock_); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
786 } | 791 } |
787 ++cur_version; | 792 ++cur_version; |
788 meta_table_.SetVersionNumber(cur_version); | 793 meta_table_.SetVersionNumber(cur_version); |
789 meta_table_.SetCompatibleVersionNumber( | 794 meta_table_.SetCompatibleVersionNumber( |
790 std::min(cur_version, kCompatibleVersionNumber)); | 795 std::min(cur_version, kCompatibleVersionNumber)); |
791 transaction.Commit(); | 796 transaction.Commit(); |
792 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", | 797 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", |
793 base::TimeTicks::Now() - start_time); | 798 base::TimeTicks::Now() - start_time); |
794 } | 799 } |
795 | 800 |
801 if (cur_version == 5) { | |
802 const base::TimeTicks start_time = base::TimeTicks::Now(); | |
803 sql::Transaction transaction(db_.get()); | |
804 if (!transaction.Begin()) | |
805 return false; | |
806 if (!db_->Execute("ALTER TABLE cookies " | |
807 "ADD COLUMN priority INTEGER DEFAULT 1")) { | |
huangs
2013/04/16 18:25:55
Add comment that we set 1 == net::PRIORITY_DEFAULT
Roger McFarlane (Chromium)
2013/04/16 19:17:25
Done.
| |
808 LOG(WARNING) << "Unable to update cookie database to version 6."; | |
809 return false; | |
810 } | |
811 ++cur_version; | |
812 meta_table_.SetVersionNumber(cur_version); | |
813 meta_table_.SetCompatibleVersionNumber( | |
814 std::min(cur_version, kCompatibleVersionNumber)); | |
815 transaction.Commit(); | |
816 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6", | |
817 base::TimeTicks::Now() - start_time); | |
818 } | |
819 | |
796 // Put future migration cases here. | 820 // Put future migration cases here. |
797 | 821 |
798 if (cur_version < kCurrentVersionNumber) { | 822 if (cur_version < kCurrentVersionNumber) { |
799 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); | 823 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); |
800 | 824 |
801 meta_table_.Reset(); | 825 meta_table_.Reset(); |
802 db_.reset(new sql::Connection); | 826 db_.reset(new sql::Connection); |
803 if (!file_util::Delete(path_, false) || | 827 if (!file_util::Delete(path_, false) || |
804 !db_->Open(path_) || | 828 !db_->Open(path_) || |
805 !meta_table_.Init( | 829 !meta_table_.Init( |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 num_pending_ = 0; | 896 num_pending_ = 0; |
873 } | 897 } |
874 | 898 |
875 // Maybe an old timer fired or we are already Close()'ed. | 899 // Maybe an old timer fired or we are already Close()'ed. |
876 if (!db_.get() || ops.empty()) | 900 if (!db_.get() || ops.empty()) |
877 return; | 901 return; |
878 | 902 |
879 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 903 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
880 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " | 904 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " |
881 "expires_utc, secure, httponly, last_access_utc, has_expires, " | 905 "expires_utc, secure, httponly, last_access_utc, has_expires, " |
882 "persistent) " | 906 "persistent, priority) " |
883 "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); | 907 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")); |
884 if (!add_smt.is_valid()) | 908 if (!add_smt.is_valid()) |
885 return; | 909 return; |
886 | 910 |
887 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 911 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
888 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); | 912 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); |
889 if (!update_access_smt.is_valid()) | 913 if (!update_access_smt.is_valid()) |
890 return; | 914 return; |
891 | 915 |
892 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 916 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
893 "DELETE FROM cookies WHERE creation_utc=?")); | 917 "DELETE FROM cookies WHERE creation_utc=?")); |
(...skipping 17 matching lines...) Expand all Loading... | |
911 add_smt.BindString(1, po->cc().Domain()); | 935 add_smt.BindString(1, po->cc().Domain()); |
912 add_smt.BindString(2, po->cc().Name()); | 936 add_smt.BindString(2, po->cc().Name()); |
913 add_smt.BindString(3, po->cc().Value()); | 937 add_smt.BindString(3, po->cc().Value()); |
914 add_smt.BindString(4, po->cc().Path()); | 938 add_smt.BindString(4, po->cc().Path()); |
915 add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue()); | 939 add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue()); |
916 add_smt.BindInt(6, po->cc().IsSecure()); | 940 add_smt.BindInt(6, po->cc().IsSecure()); |
917 add_smt.BindInt(7, po->cc().IsHttpOnly()); | 941 add_smt.BindInt(7, po->cc().IsHttpOnly()); |
918 add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue()); | 942 add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue()); |
919 add_smt.BindInt(9, po->cc().IsPersistent()); | 943 add_smt.BindInt(9, po->cc().IsPersistent()); |
920 add_smt.BindInt(10, po->cc().IsPersistent()); | 944 add_smt.BindInt(10, po->cc().IsPersistent()); |
945 add_smg.BindInt(11, po->cc().Priority()); | |
921 if (!add_smt.Run()) | 946 if (!add_smt.Run()) |
922 NOTREACHED() << "Could not add a cookie to the DB."; | 947 NOTREACHED() << "Could not add a cookie to the DB."; |
923 break; | 948 break; |
924 | 949 |
925 case PendingOperation::COOKIE_UPDATEACCESS: | 950 case PendingOperation::COOKIE_UPDATEACCESS: |
926 update_access_smt.Reset(true); | 951 update_access_smt.Reset(true); |
927 update_access_smt.BindInt64(0, | 952 update_access_smt.BindInt64(0, |
928 po->cc().LastAccessDate().ToInternalValue()); | 953 po->cc().LastAccessDate().ToInternalValue()); |
929 update_access_smt.BindInt64(1, | 954 update_access_smt.BindInt64(1, |
930 po->cc().CreationDate().ToInternalValue()); | 955 po->cc().CreationDate().ToInternalValue()); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1145 path, | 1170 path, |
1146 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 1171 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
1147 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( | 1172 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( |
1148 BrowserThread::GetBlockingPool()->GetSequenceToken()), | 1173 BrowserThread::GetBlockingPool()->GetSequenceToken()), |
1149 restore_old_session_cookies, | 1174 restore_old_session_cookies, |
1150 storage_policy); | 1175 storage_policy); |
1151 return new net::CookieMonster(persistent_store, cookie_monster_delegate); | 1176 return new net::CookieMonster(persistent_store, cookie_monster_delegate); |
1152 } | 1177 } |
1153 | 1178 |
1154 } // namespace content | 1179 } // namespace content |
OLD | NEW |