| Index: chrome/browser/net/sqlite_persistent_cookie_store.cc
|
| diff --git a/chrome/browser/net/sqlite_persistent_cookie_store.cc b/chrome/browser/net/sqlite_persistent_cookie_store.cc
|
| index 444e1fa78fb0fdae0813e55b82440250a91e2ca4..58f44cae81ae7ced0bea3a8dc2cdacccc4805650 100644
|
| --- a/chrome/browser/net/sqlite_persistent_cookie_store.cc
|
| +++ b/chrome/browser/net/sqlite_persistent_cookie_store.cc
|
| @@ -58,12 +58,13 @@ using content::BrowserThread;
|
| class SQLitePersistentCookieStore::Backend
|
| : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> {
|
| public:
|
| - explicit Backend(const FilePath& path)
|
| + Backend(const FilePath& path, bool restore_old_session_cookies)
|
| : path_(path),
|
| db_(NULL),
|
| num_pending_(0),
|
| clear_local_state_on_exit_(false),
|
| initialized_(false),
|
| + restore_old_session_cookies_(restore_old_session_cookies),
|
| num_priority_waiting_(0),
|
| total_priority_requests_(0) {
|
| }
|
| @@ -176,6 +177,8 @@ class SQLitePersistentCookieStore::Backend
|
| // Close() executed on the background thread.
|
| void InternalBackgroundClose();
|
|
|
| + void DeleteSessionCookies();
|
| +
|
| FilePath path_;
|
| scoped_ptr<sql::Connection> db_;
|
| sql::MetaTable meta_table_;
|
| @@ -199,6 +202,9 @@ class SQLitePersistentCookieStore::Backend
|
| // Indicates if DB has been initialized.
|
| bool initialized_;
|
|
|
| + // If false, we should filter out session cookies when reading the DB.
|
| + bool restore_old_session_cookies_;
|
| +
|
| // The cumulative time spent loading the cookies on the DB thread. Incremented
|
| // and reported from the DB thread.
|
| base::TimeDelta cookie_load_duration_;
|
| @@ -218,16 +224,23 @@ class SQLitePersistentCookieStore::Backend
|
| DISALLOW_COPY_AND_ASSIGN(Backend);
|
| };
|
|
|
| -// Version number of the database. In version 4, we migrated the time epoch.
|
| -// If you open the DB with an older version on Mac or Linux, the times will
|
| -// look wonky, but the file will likely be usable. On Windows version 3 and 4
|
| -// are the same.
|
| +// Version number of the database.
|
| +//
|
| +// Version 5 adds the columns has_expires and is_persistent, so that the
|
| +// database can store session cookies as well as persistent cookies. Databases
|
| +// of version 5 are incompatible with older versions of code. If a database of
|
| +// version 5 is read by older code, session cookies will be treated as normal
|
| +// cookies.
|
| +//
|
| +// In version 4, we migrated the time epoch. If you open the DB with an older
|
| +// version on Mac or Linux, the times will look wonky, but the file will likely
|
| +// be usable. On Windows version 3 and 4 are the same.
|
| //
|
| // Version 3 updated the database to include the last access time, so we can
|
| // expire them in decreasing order of use when we've reached the maximum
|
| // number of cookies.
|
| -static const int kCurrentVersionNumber = 4;
|
| -static const int kCompatibleVersionNumber = 3;
|
| +static const int kCurrentVersionNumber = 5;
|
| +static const int kCompatibleVersionNumber = 5;
|
|
|
| namespace {
|
|
|
| @@ -263,11 +276,12 @@ bool InitTable(sql::Connection* db) {
|
| "name TEXT NOT NULL,"
|
| "value TEXT NOT NULL,"
|
| "path TEXT NOT NULL,"
|
| - // We only store persistent, so we know it expires
|
| "expires_utc INTEGER NOT NULL,"
|
| "secure INTEGER NOT NULL,"
|
| "httponly INTEGER NOT NULL,"
|
| - "last_access_utc INTEGER NOT NULL)"))
|
| + "last_access_utc INTEGER NOT NULL, "
|
| + "has_expires INTEGER NOT NULL DEFAULT 1, "
|
| + "persistent INTEGER NOT NULL DEFAULT 1)"))
|
| return false;
|
| }
|
|
|
| @@ -498,6 +512,8 @@ void SQLitePersistentCookieStore::Backend::ChainLoadCookies(
|
| BrowserThread::IO, FROM_HERE,
|
| base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread,
|
| this, loaded_callback, load_success));
|
| + if (!restore_old_session_cookies_)
|
| + DeleteSessionCookies();
|
| }
|
| }
|
|
|
| @@ -505,9 +521,19 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
|
| const std::set<std::string>& domains) {
|
| DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
|
|
| - sql::Statement smt(db_->GetCachedStatement(SQL_FROM_HERE,
|
| - "SELECT creation_utc, host_key, name, value, path, expires_utc, secure, "
|
| - "httponly, last_access_utc FROM cookies WHERE host_key = ?"));
|
| + const char* sql;
|
| + if (restore_old_session_cookies_) {
|
| + sql =
|
| + "SELECT creation_utc, host_key, name, value, path, expires_utc, "
|
| + "secure, httponly, last_access_utc, has_expires, persistent "
|
| + "FROM cookies WHERE host_key = ?";
|
| + } else {
|
| + sql =
|
| + "SELECT creation_utc, host_key, name, value, path, expires_utc, "
|
| + "secure, httponly, last_access_utc, has_expires, persistent "
|
| + "FROM cookies WHERE host_key = ? AND persistent == 1";
|
| + }
|
| + sql::Statement smt(db_->GetCachedStatement(SQL_FROM_HERE, sql));
|
| if (!smt) {
|
| NOTREACHED() << "select statement prep failed";
|
| db_.reset();
|
| @@ -534,8 +560,8 @@ bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains(
|
| Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc
|
| smt.ColumnInt(6) != 0, // secure
|
| smt.ColumnInt(7) != 0, // httponly
|
| - true, // has_expires
|
| - true)); // is_persistent
|
| + smt.ColumnInt(9) != 0, // has_expires
|
| + smt.ColumnInt(10) != 0)); // is_persistent
|
| DLOG_IF(WARNING,
|
| cc->CreationDate() > Time::Now()) << L"CreationDate too recent";
|
| cookies.push_back(cc.release());
|
| @@ -613,6 +639,27 @@ bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() {
|
| transaction.Commit();
|
| }
|
|
|
| + if (cur_version == 4) {
|
| + const base::TimeTicks start_time = base::TimeTicks::Now();
|
| + sql::Transaction transaction(db_.get());
|
| + if (!transaction.Begin())
|
| + return false;
|
| + if (!db_->Execute("ALTER TABLE cookies "
|
| + "ADD COLUMN has_expires INTEGER DEFAULT 1") ||
|
| + !db_->Execute("ALTER TABLE cookies "
|
| + "ADD COLUMN persistent INTEGER DEFAULT 1")) {
|
| + LOG(WARNING) << "Unable to update cookie database to version 5.";
|
| + return false;
|
| + }
|
| + ++cur_version;
|
| + meta_table_.SetVersionNumber(cur_version);
|
| + meta_table_.SetCompatibleVersionNumber(
|
| + std::min(cur_version, kCompatibleVersionNumber));
|
| + transaction.Commit();
|
| + UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5",
|
| + base::TimeTicks::Now() - start_time);
|
| + }
|
| +
|
| // Put future migration cases here.
|
|
|
| // When the version is too old, we just try to continue anyway, there should
|
| @@ -686,8 +733,9 @@ void SQLitePersistentCookieStore::Backend::Commit() {
|
|
|
| sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE,
|
| "INSERT INTO cookies (creation_utc, host_key, name, value, path, "
|
| - "expires_utc, secure, httponly, last_access_utc) "
|
| - "VALUES (?,?,?,?,?,?,?,?,?)"));
|
| + "expires_utc, secure, httponly, last_access_utc, has_expires, "
|
| + "persistent) "
|
| + "VALUES (?,?,?,?,?,?,?,?,?,?,?)"));
|
| if (!add_smt) {
|
| NOTREACHED();
|
| return;
|
| @@ -728,6 +776,8 @@ void SQLitePersistentCookieStore::Backend::Commit() {
|
| add_smt.BindInt(6, po->cc().IsSecure());
|
| add_smt.BindInt(7, po->cc().IsHttpOnly());
|
| add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue());
|
| + add_smt.BindInt(9, po->cc().DoesExpire());
|
| + add_smt.BindInt(10, po->cc().IsPersistent());
|
| if (!add_smt.Run())
|
| NOTREACHED() << "Could not add a cookie to the DB.";
|
| break;
|
| @@ -801,8 +851,17 @@ void SQLitePersistentCookieStore::Backend::SetClearLocalStateOnExit(
|
| base::AutoLock locked(lock_);
|
| clear_local_state_on_exit_ = clear_local_state;
|
| }
|
| -SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path)
|
| - : backend_(new Backend(path)) {
|
| +
|
| +void SQLitePersistentCookieStore::Backend::DeleteSessionCookies() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB));
|
| + if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0"))
|
| + LOG(WARNING) << "Unable to delete session cookies.";
|
| +}
|
| +
|
| +SQLitePersistentCookieStore::SQLitePersistentCookieStore(
|
| + const FilePath& path,
|
| + bool restore_old_session_cookies)
|
| + : backend_(new Backend(path, restore_old_session_cookies)) {
|
| }
|
|
|
| SQLitePersistentCookieStore::~SQLitePersistentCookieStore() {
|
|
|