Chromium Code Reviews| 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..3cd223e6ce12aeaccac0b26e30b729ff0f60cb4b 100644 |
| --- a/chrome/browser/net/sqlite_persistent_cookie_store.cc |
| +++ b/chrome/browser/net/sqlite_persistent_cookie_store.cc |
| @@ -64,6 +64,7 @@ class SQLitePersistentCookieStore::Backend |
| num_pending_(0), |
| clear_local_state_on_exit_(false), |
| initialized_(false), |
| + return_session_cookies_(true), |
| num_priority_waiting_(0), |
| total_priority_requests_(0) { |
| } |
| @@ -93,6 +94,8 @@ class SQLitePersistentCookieStore::Backend |
| void SetClearLocalStateOnExit(bool clear_local_state); |
| + void DeleteSessionCookies(); |
| + |
| private: |
| friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>; |
| @@ -176,6 +179,8 @@ class SQLitePersistentCookieStore::Backend |
| // Close() executed on the background thread. |
| void InternalBackgroundClose(); |
| + void DeleteSessionCookiesOnDBThread(); |
| + |
| FilePath path_; |
| scoped_ptr<sql::Connection> db_; |
| sql::MetaTable meta_table_; |
| @@ -199,6 +204,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 return_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_; |
| @@ -226,8 +234,8 @@ class SQLitePersistentCookieStore::Backend |
| // 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 +271,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," |
| + "persistent INTEGER NOT NULL)")) |
| return false; |
| } |
| @@ -498,6 +507,10 @@ void SQLitePersistentCookieStore::Backend::ChainLoadCookies( |
| BrowserThread::IO, FROM_HERE, |
| base::Bind(&SQLitePersistentCookieStore::Backend::CompleteLoadOnIOThread, |
| this, loaded_callback, load_success)); |
| + // We haven't yet had the chance to delete session cookies from the DB; do |
| + // it now. |
| + if (!return_session_cookies_) |
| + DeleteSessionCookiesOnDBThread(); |
| } |
| } |
| @@ -505,9 +518,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 (return_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 +557,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 +636,24 @@ bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() { |
| transaction.Commit(); |
| } |
| + if (cur_version == 4) { |
| + sql::Transaction transaction(db_.get()); |
|
erikwright (departed)
2011/11/28 16:18:16
Please add a metric, recorded and reported here, f
marja
2011/11/29 12:56:01
Done.
|
| + if (!transaction.Begin()) |
| + return false; |
| + if (!db_->Execute("ALTER TABLE cookies " |
| + "ADD COLUMN has_expires INTEGER DEFAULT 1") || |
|
erikwright (departed)
2011/11/28 16:18:16
I don't see any documentation that states that the
marja
2011/11/29 12:56:01
Done. (1 & 3)
|
| + !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(); |
| + } |
| + |
| // Put future migration cases here. |
| // When the version is too old, we just try to continue anyway, there should |
| @@ -686,8 +727,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 +770,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,6 +845,27 @@ void SQLitePersistentCookieStore::Backend::SetClearLocalStateOnExit( |
| base::AutoLock locked(lock_); |
| clear_local_state_on_exit_ = clear_local_state; |
| } |
| + |
| +void SQLitePersistentCookieStore::Backend::DeleteSessionCookies() { |
| + { |
| + base::AutoLock locked(lock_); |
| + return_session_cookies_ = false; |
| + } |
| + BrowserThread::PostTask( |
| + BrowserThread::DB, FROM_HERE, |
| + base::Bind(&Backend::DeleteSessionCookiesOnDBThread, this)); |
| +} |
| + |
| +void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnDBThread() { |
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| + // If the store hasn't been initialized, the session cookie deletion is done |
| + // after all cookies have been loaded. |
| + if (!initialized_) |
| + return; |
| + if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0")) |
| + LOG(WARNING) << "Unable to delete session cookies."; |
| +} |
| + |
| SQLitePersistentCookieStore::SQLitePersistentCookieStore(const FilePath& path) |
| : backend_(new Backend(path)) { |
| } |
| @@ -854,3 +919,8 @@ void SQLitePersistentCookieStore::Flush(Task* completion_task) { |
| else if (completion_task) |
| MessageLoop::current()->PostTask(FROM_HERE, completion_task); |
| } |
| + |
| +void SQLitePersistentCookieStore::DeleteSessionCookies() { |
| + if (backend_.get()) |
| + backend_->DeleteSessionCookies(); |
| +} |