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 evicted in order to meet domain cookie limits. | |
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 10 matching lines...) Expand all Loading... | |
352 base::TimeDelta* delta_; | 355 base::TimeDelta* delta_; |
353 base::TimeDelta original_value_; | 356 base::TimeDelta original_value_; |
354 base::Time start_; | 357 base::Time start_; |
355 | 358 |
356 DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta); | 359 DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta); |
357 }; | 360 }; |
358 | 361 |
359 // Initializes the cookies table, returning true on success. | 362 // Initializes the cookies table, returning true on success. |
360 bool InitTable(sql::Connection* db) { | 363 bool InitTable(sql::Connection* db) { |
361 if (!db->DoesTableExist("cookies")) { | 364 if (!db->DoesTableExist("cookies")) { |
362 if (!db->Execute("CREATE TABLE cookies (" | 365 if (!db->Execute( |
363 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," | 366 "CREATE TABLE cookies (" |
364 "host_key TEXT NOT NULL," | 367 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," |
365 "name TEXT NOT NULL," | 368 "host_key TEXT NOT NULL," |
366 "value TEXT NOT NULL," | 369 "name TEXT NOT NULL," |
367 "path TEXT NOT NULL," | 370 "value TEXT NOT NULL," |
368 "expires_utc INTEGER NOT NULL," | 371 "path TEXT NOT NULL," |
369 "secure INTEGER NOT NULL," | 372 "expires_utc INTEGER NOT NULL," |
370 "httponly INTEGER NOT NULL," | 373 "secure INTEGER NOT NULL," |
371 "last_access_utc INTEGER NOT NULL, " | 374 "httponly INTEGER NOT NULL," |
372 "has_expires INTEGER NOT NULL DEFAULT 1, " | 375 "last_access_utc INTEGER NOT NULL, " |
373 "persistent INTEGER NOT NULL DEFAULT 1)")) | 376 "has_expires INTEGER NOT NULL DEFAULT 1, " |
377 "persistent INTEGER NOT NULL DEFAULT 1," | |
378 "priority INTEGER NOT NULL DEFAULT 1")) { // Medium priority. | |
374 return false; | 379 return false; |
375 } | 380 } |
376 | 381 |
377 // Older code created an index on creation_utc, which is already | 382 // Older code created an index on creation_utc, which is already |
378 // primary key for the table. | 383 // primary key for the table. |
379 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) | 384 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) |
380 return false; | 385 return false; |
381 | 386 |
382 if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)")) | 387 if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)")) |
383 return false; | 388 return false; |
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
652 | 657 |
653 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( | 658 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( |
654 const std::set<std::string>& domains) { | 659 const std::set<std::string>& domains) { |
655 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); | 660 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); |
656 | 661 |
657 sql::Statement smt; | 662 sql::Statement smt; |
658 if (restore_old_session_cookies_) { | 663 if (restore_old_session_cookies_) { |
659 smt.Assign(db_->GetCachedStatement( | 664 smt.Assign(db_->GetCachedStatement( |
660 SQL_FROM_HERE, | 665 SQL_FROM_HERE, |
661 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 666 "SELECT creation_utc, host_key, name, value, path, expires_utc, " |
662 "secure, httponly, last_access_utc, has_expires, persistent " | 667 "secure, httponly, last_access_utc, has_expires, persistent, priority " |
663 "FROM cookies WHERE host_key = ?")); | 668 "FROM cookies WHERE host_key = ?")); |
664 } else { | 669 } else { |
665 smt.Assign(db_->GetCachedStatement( | 670 smt.Assign(db_->GetCachedStatement( |
666 SQL_FROM_HERE, | 671 SQL_FROM_HERE, |
667 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 672 "SELECT creation_utc, host_key, name, value, path, expires_utc, " |
668 "secure, httponly, last_access_utc, has_expires, persistent " | 673 "secure, httponly, last_access_utc, has_expires, persistent, priority " |
669 "FROM cookies WHERE host_key = ? AND persistent = 1")); | 674 "FROM cookies WHERE host_key = ? AND persistent = 1")); |
670 } | 675 } |
671 if (!smt.is_valid()) { | 676 if (!smt.is_valid()) { |
672 smt.Clear(); // Disconnect smt_ref from db_. | 677 smt.Clear(); // Disconnect smt_ref from db_. |
673 meta_table_.Reset(); | 678 meta_table_.Reset(); |
674 db_.reset(); | 679 db_.reset(); |
675 return false; | 680 return false; |
676 } | 681 } |
677 | 682 |
678 std::vector<net::CanonicalCookie*> cookies; | 683 std::vector<net::CanonicalCookie*> cookies; |
679 std::set<std::string>::const_iterator it = domains.begin(); | 684 std::set<std::string>::const_iterator it = domains.begin(); |
680 for (; it != domains.end(); ++it) { | 685 for (; it != domains.end(); ++it) { |
681 smt.BindString(0, *it); | 686 smt.BindString(0, *it); |
682 while (smt.Step()) { | 687 while (smt.Step()) { |
683 scoped_ptr<net::CanonicalCookie> cc( | 688 scoped_ptr<net::CanonicalCookie> cc( |
684 new net::CanonicalCookie( | 689 new net::CanonicalCookie( |
685 // The "source" URL is not used with persisted cookies. | 690 // The "source" URL is not used with persisted cookies. |
686 GURL(), // Source | 691 GURL(), // Source |
687 smt.ColumnString(2), // name | 692 smt.ColumnString(2), // name |
688 smt.ColumnString(3), // value | 693 smt.ColumnString(3), // value |
689 smt.ColumnString(1), // domain | 694 smt.ColumnString(1), // domain |
690 smt.ColumnString(4), // path | 695 smt.ColumnString(4), // path |
691 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc | 696 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc |
692 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc | 697 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc |
693 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc | 698 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc |
694 smt.ColumnInt(6) != 0, // secure | 699 smt.ColumnInt(6) != 0, // secure |
695 smt.ColumnInt(7) != 0)); // httponly | 700 smt.ColumnInt(7) != 0), // httponly |
701 smt.ColumnInt(9)); // priority | |
696 DLOG_IF(WARNING, | 702 DLOG_IF(WARNING, |
697 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; | 703 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; |
698 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; | 704 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; |
699 cookies.push_back(cc.release()); | 705 cookies.push_back(cc.release()); |
700 ++num_cookies_read_; | 706 ++num_cookies_read_; |
701 } | 707 } |
702 smt.Reset(true); | 708 smt.Reset(true); |
703 } | 709 } |
704 { | 710 { |
705 base::AutoLock locked(lock_); | 711 base::AutoLock locked(lock_); |
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
786 } | 792 } |
787 ++cur_version; | 793 ++cur_version; |
788 meta_table_.SetVersionNumber(cur_version); | 794 meta_table_.SetVersionNumber(cur_version); |
789 meta_table_.SetCompatibleVersionNumber( | 795 meta_table_.SetCompatibleVersionNumber( |
790 std::min(cur_version, kCompatibleVersionNumber)); | 796 std::min(cur_version, kCompatibleVersionNumber)); |
791 transaction.Commit(); | 797 transaction.Commit(); |
792 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", | 798 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", |
793 base::TimeTicks::Now() - start_time); | 799 base::TimeTicks::Now() - start_time); |
794 } | 800 } |
795 | 801 |
802 if (cur_version == 5) { | |
803 const base::TimeTicks start_time = base::TimeTicks::Now(); | |
804 sql::Transaction transaction(db_.get()); | |
805 if (!transaction.Begin()) | |
806 return false; | |
807 // Alter the table to add the priority collum with a default value of | |
erikwright (departed)
2013/04/16 20:41:03
collum -> column
Roger McFarlane (Chromium)
2013/04/18 18:54:29
Done.
| |
808 // 1 (Medium) for the value. | |
809 if (!db_->Execute("ALTER TABLE cookies " | |
810 "ADD COLUMN priority INTEGER DEFAULT 1")) { | |
811 LOG(WARNING) << "Unable to update cookie database to version 6."; | |
812 return false; | |
813 } | |
814 ++cur_version; | |
815 meta_table_.SetVersionNumber(cur_version); | |
816 meta_table_.SetCompatibleVersionNumber( | |
817 std::min(cur_version, kCompatibleVersionNumber)); | |
818 transaction.Commit(); | |
819 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6", | |
820 base::TimeTicks::Now() - start_time); | |
821 } | |
822 | |
796 // Put future migration cases here. | 823 // Put future migration cases here. |
797 | 824 |
798 if (cur_version < kCurrentVersionNumber) { | 825 if (cur_version < kCurrentVersionNumber) { |
799 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); | 826 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); |
800 | 827 |
801 meta_table_.Reset(); | 828 meta_table_.Reset(); |
802 db_.reset(new sql::Connection); | 829 db_.reset(new sql::Connection); |
803 if (!file_util::Delete(path_, false) || | 830 if (!file_util::Delete(path_, false) || |
804 !db_->Open(path_) || | 831 !db_->Open(path_) || |
805 !meta_table_.Init( | 832 !meta_table_.Init( |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
872 num_pending_ = 0; | 899 num_pending_ = 0; |
873 } | 900 } |
874 | 901 |
875 // Maybe an old timer fired or we are already Close()'ed. | 902 // Maybe an old timer fired or we are already Close()'ed. |
876 if (!db_.get() || ops.empty()) | 903 if (!db_.get() || ops.empty()) |
877 return; | 904 return; |
878 | 905 |
879 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 906 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
880 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " | 907 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " |
881 "expires_utc, secure, httponly, last_access_utc, has_expires, " | 908 "expires_utc, secure, httponly, last_access_utc, has_expires, " |
882 "persistent) " | 909 "persistent, priority) " |
883 "VALUES (?,?,?,?,?,?,?,?,?,?,?)")); | 910 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")); |
884 if (!add_smt.is_valid()) | 911 if (!add_smt.is_valid()) |
885 return; | 912 return; |
886 | 913 |
887 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 914 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
888 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); | 915 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); |
889 if (!update_access_smt.is_valid()) | 916 if (!update_access_smt.is_valid()) |
890 return; | 917 return; |
891 | 918 |
892 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 919 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
893 "DELETE FROM cookies WHERE creation_utc=?")); | 920 "DELETE FROM cookies WHERE creation_utc=?")); |
(...skipping 17 matching lines...) Expand all Loading... | |
911 add_smt.BindString(1, po->cc().Domain()); | 938 add_smt.BindString(1, po->cc().Domain()); |
912 add_smt.BindString(2, po->cc().Name()); | 939 add_smt.BindString(2, po->cc().Name()); |
913 add_smt.BindString(3, po->cc().Value()); | 940 add_smt.BindString(3, po->cc().Value()); |
914 add_smt.BindString(4, po->cc().Path()); | 941 add_smt.BindString(4, po->cc().Path()); |
915 add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue()); | 942 add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue()); |
916 add_smt.BindInt(6, po->cc().IsSecure()); | 943 add_smt.BindInt(6, po->cc().IsSecure()); |
917 add_smt.BindInt(7, po->cc().IsHttpOnly()); | 944 add_smt.BindInt(7, po->cc().IsHttpOnly()); |
918 add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue()); | 945 add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue()); |
919 add_smt.BindInt(9, po->cc().IsPersistent()); | 946 add_smt.BindInt(9, po->cc().IsPersistent()); |
920 add_smt.BindInt(10, po->cc().IsPersistent()); | 947 add_smt.BindInt(10, po->cc().IsPersistent()); |
948 add_smg.BindInt(11, po->cc().Priority()); | |
921 if (!add_smt.Run()) | 949 if (!add_smt.Run()) |
922 NOTREACHED() << "Could not add a cookie to the DB."; | 950 NOTREACHED() << "Could not add a cookie to the DB."; |
923 break; | 951 break; |
924 | 952 |
925 case PendingOperation::COOKIE_UPDATEACCESS: | 953 case PendingOperation::COOKIE_UPDATEACCESS: |
926 update_access_smt.Reset(true); | 954 update_access_smt.Reset(true); |
927 update_access_smt.BindInt64(0, | 955 update_access_smt.BindInt64(0, |
928 po->cc().LastAccessDate().ToInternalValue()); | 956 po->cc().LastAccessDate().ToInternalValue()); |
929 update_access_smt.BindInt64(1, | 957 update_access_smt.BindInt64(1, |
930 po->cc().CreationDate().ToInternalValue()); | 958 po->cc().CreationDate().ToInternalValue()); |
(...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1145 path, | 1173 path, |
1146 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 1174 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
1147 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( | 1175 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( |
1148 BrowserThread::GetBlockingPool()->GetSequenceToken()), | 1176 BrowserThread::GetBlockingPool()->GetSequenceToken()), |
1149 restore_old_session_cookies, | 1177 restore_old_session_cookies, |
1150 storage_policy); | 1178 storage_policy); |
1151 return new net::CookieMonster(persistent_store, cookie_monster_delegate); | 1179 return new net::CookieMonster(persistent_store, cookie_monster_delegate); |
1152 } | 1180 } |
1153 | 1181 |
1154 } // namespace content | 1182 } // namespace content |
OLD | NEW |