Chromium Code Reviews| 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. | |
| 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")) | |
| 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, prioirity " |
|
huangs
2013/04/16 17:56:28
Typo "prioirity"?
Roger McFarlane (Chromium)
2013/04/16 18:04:28
Yes, thank you!
| |
| 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")) { | |
| 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 |