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> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/bind.h" | 13 #include "base/bind.h" |
| 14 #include "base/callback.h" | 14 #include "base/callback.h" |
| 15 #include "base/file_util.h" | 15 #include "base/file_util.h" |
| 16 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
| 17 #include "base/location.h" | 17 #include "base/location.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/memory/ref_counted.h" | 19 #include "base/memory/ref_counted.h" |
| 20 #include "base/memory/scoped_ptr.h" | 20 #include "base/memory/scoped_ptr.h" |
| 21 #include "base/metrics/field_trial.h" | 21 #include "base/metrics/field_trial.h" |
| 22 #include "base/metrics/histogram.h" | 22 #include "base/metrics/histogram.h" |
| 23 #include "base/sequenced_task_runner.h" | 23 #include "base/sequenced_task_runner.h" |
| 24 #include "base/strings/string_util.h" | 24 #include "base/strings/string_util.h" |
| 25 #include "base/strings/stringprintf.h" | 25 #include "base/strings/stringprintf.h" |
| 26 #include "base/synchronization/lock.h" | 26 #include "base/synchronization/lock.h" |
| 27 #include "base/threading/sequenced_worker_pool.h" | 27 #include "base/threading/sequenced_worker_pool.h" |
| 28 #include "base/time/time.h" | 28 #include "base/time/time.h" |
| 29 #include "content/public/browser/browser_thread.h" | 29 #include "content/public/browser/browser_thread.h" |
| 30 #include "content/public/browser/cookie_crypto_delegate.h" | |
| 30 #include "content/public/browser/cookie_store_factory.h" | 31 #include "content/public/browser/cookie_store_factory.h" |
| 31 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" | 32 #include "net/base/registry_controlled_domains/registry_controlled_domain.h" |
| 32 #include "net/cookies/canonical_cookie.h" | 33 #include "net/cookies/canonical_cookie.h" |
| 33 #include "net/cookies/cookie_constants.h" | 34 #include "net/cookies/cookie_constants.h" |
| 34 #include "net/cookies/cookie_util.h" | 35 #include "net/cookies/cookie_util.h" |
| 35 #include "sql/error_delegate_util.h" | 36 #include "sql/error_delegate_util.h" |
| 36 #include "sql/meta_table.h" | 37 #include "sql/meta_table.h" |
| 37 #include "sql/statement.h" | 38 #include "sql/statement.h" |
| 38 #include "sql/transaction.h" | 39 #include "sql/transaction.h" |
| 39 #include "third_party/sqlite/sqlite3.h" | 40 #include "third_party/sqlite/sqlite3.h" |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 67 // disk on the BG runner every 30 seconds, 512 operations, or call to Flush(), | 68 // disk on the BG runner every 30 seconds, 512 operations, or call to Flush(), |
| 68 // whichever occurs first. | 69 // whichever occurs first. |
| 69 class SQLitePersistentCookieStore::Backend | 70 class SQLitePersistentCookieStore::Backend |
| 70 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { | 71 : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { |
| 71 public: | 72 public: |
| 72 Backend( | 73 Backend( |
| 73 const base::FilePath& path, | 74 const base::FilePath& path, |
| 74 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, | 75 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, |
| 75 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, | 76 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, |
| 76 bool restore_old_session_cookies, | 77 bool restore_old_session_cookies, |
| 77 quota::SpecialStoragePolicy* special_storage_policy) | 78 quota::SpecialStoragePolicy* special_storage_policy, |
| 79 CookieCryptoDelegate* crypto_delegate) | |
| 78 : path_(path), | 80 : path_(path), |
| 79 num_pending_(0), | 81 num_pending_(0), |
| 80 force_keep_session_state_(false), | 82 force_keep_session_state_(false), |
| 81 initialized_(false), | 83 initialized_(false), |
| 82 corruption_detected_(false), | 84 corruption_detected_(false), |
| 83 restore_old_session_cookies_(restore_old_session_cookies), | 85 restore_old_session_cookies_(restore_old_session_cookies), |
| 84 special_storage_policy_(special_storage_policy), | 86 special_storage_policy_(special_storage_policy), |
| 85 num_cookies_read_(0), | 87 num_cookies_read_(0), |
| 86 client_task_runner_(client_task_runner), | 88 client_task_runner_(client_task_runner), |
| 87 background_task_runner_(background_task_runner), | 89 background_task_runner_(background_task_runner), |
| 88 num_priority_waiting_(0), | 90 num_priority_waiting_(0), |
| 89 total_priority_requests_(0) {} | 91 total_priority_requests_(0), |
| 92 crypto_(crypto_delegate) {} | |
| 90 | 93 |
| 91 // Creates or loads the SQLite database. | 94 // Creates or loads the SQLite database. |
| 92 void Load(const LoadedCallback& loaded_callback); | 95 void Load(const LoadedCallback& loaded_callback); |
| 93 | 96 |
| 94 // Loads cookies for the domain key (eTLD+1). | 97 // Loads cookies for the domain key (eTLD+1). |
| 95 void LoadCookiesForKey(const std::string& domain, | 98 void LoadCookiesForKey(const std::string& domain, |
| 96 const LoadedCallback& loaded_callback); | 99 const LoadedCallback& loaded_callback); |
| 97 | 100 |
| 98 // Batch a cookie addition. | 101 // Batch a cookie addition. |
| 99 void AddCookie(const net::CanonicalCookie& cc); | 102 void AddCookie(const net::CanonicalCookie& cc); |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 262 // starting/completing priority loads or completing the total load). | 265 // starting/completing priority loads or completing the total load). |
| 263 base::Lock metrics_lock_; | 266 base::Lock metrics_lock_; |
| 264 int num_priority_waiting_; | 267 int num_priority_waiting_; |
| 265 // The total number of priority requests. | 268 // The total number of priority requests. |
| 266 int total_priority_requests_; | 269 int total_priority_requests_; |
| 267 // The time when |num_priority_waiting_| incremented to 1. | 270 // The time when |num_priority_waiting_| incremented to 1. |
| 268 base::Time current_priority_wait_start_; | 271 base::Time current_priority_wait_start_; |
| 269 // The cumulative duration of time when |num_priority_waiting_| was greater | 272 // The cumulative duration of time when |num_priority_waiting_| was greater |
| 270 // than 1. | 273 // than 1. |
| 271 base::TimeDelta priority_wait_duration_; | 274 base::TimeDelta priority_wait_duration_; |
| 275 // Class with functions that do cryptographic operations (for protecting | |
| 276 // cookies stored persistently). | |
| 277 scoped_ptr<CookieCryptoDelegate> crypto_; | |
| 272 | 278 |
| 273 DISALLOW_COPY_AND_ASSIGN(Backend); | 279 DISALLOW_COPY_AND_ASSIGN(Backend); |
| 274 }; | 280 }; |
| 275 | 281 |
| 276 namespace { | 282 namespace { |
| 277 | 283 |
| 278 // Version number of the database. | 284 // Version number of the database. |
| 279 // | 285 // |
| 286 // Version 7 adds encrypted values. Old values will continue to be used but | |
| 287 // all new values written will be encrypted on selected operating systems. | |
| 288 // | |
| 280 // Version 6 adds cookie priorities. This allows developers to influence the | 289 // Version 6 adds cookie priorities. This allows developers to influence the |
| 281 // order in which cookies are evicted in order to meet domain cookie limits. | 290 // order in which cookies are evicted in order to meet domain cookie limits. |
| 282 // | 291 // |
| 283 // Version 5 adds the columns has_expires and is_persistent, so that the | 292 // Version 5 adds the columns has_expires and is_persistent, so that the |
| 284 // database can store session cookies as well as persistent cookies. Databases | 293 // database can store session cookies as well as persistent cookies. Databases |
| 285 // of version 5 are incompatible with older versions of code. If a database of | 294 // of version 5 are incompatible with older versions of code. If a database of |
| 286 // version 5 is read by older code, session cookies will be treated as normal | 295 // version 5 is read by older code, session cookies will be treated as normal |
| 287 // cookies. Currently, these fields are written, but not read anymore. | 296 // cookies. Currently, these fields are written, but not read anymore. |
| 288 // | 297 // |
| 289 // In version 4, we migrated the time epoch. If you open the DB with an older | 298 // In version 4, we migrated the time epoch. If you open the DB with an older |
| 290 // version on Mac or Linux, the times will look wonky, but the file will likely | 299 // version on Mac or Linux, the times will look wonky, but the file will likely |
| 291 // be usable. On Windows version 3 and 4 are the same. | 300 // be usable. On Windows version 3 and 4 are the same. |
| 292 // | 301 // |
| 293 // Version 3 updated the database to include the last access time, so we can | 302 // Version 3 updated the database to include the last access time, so we can |
| 294 // expire them in decreasing order of use when we've reached the maximum | 303 // expire them in decreasing order of use when we've reached the maximum |
| 295 // number of cookies. | 304 // number of cookies. |
| 296 const int kCurrentVersionNumber = 6; | 305 const int kCurrentVersionNumber = 7; |
| 297 const int kCompatibleVersionNumber = 5; | 306 const int kCompatibleVersionNumber = 5; |
| 298 | 307 |
| 299 // Possible values for the 'priority' column. | 308 // Possible values for the 'priority' column. |
| 300 enum DBCookiePriority { | 309 enum DBCookiePriority { |
| 301 kCookiePriorityLow = 0, | 310 kCookiePriorityLow = 0, |
| 302 kCookiePriorityMedium = 1, | 311 kCookiePriorityMedium = 1, |
| 303 kCookiePriorityHigh = 2, | 312 kCookiePriorityHigh = 2, |
| 304 }; | 313 }; |
| 305 | 314 |
| 306 DBCookiePriority CookiePriorityToDBCookiePriority(net::CookiePriority value) { | 315 DBCookiePriority CookiePriorityToDBCookiePriority(net::CookiePriority value) { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 std::string stmt(base::StringPrintf( | 369 std::string stmt(base::StringPrintf( |
| 361 "CREATE TABLE cookies (" | 370 "CREATE TABLE cookies (" |
| 362 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," | 371 "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," |
| 363 "host_key TEXT NOT NULL," | 372 "host_key TEXT NOT NULL," |
| 364 "name TEXT NOT NULL," | 373 "name TEXT NOT NULL," |
| 365 "value TEXT NOT NULL," | 374 "value TEXT NOT NULL," |
| 366 "path TEXT NOT NULL," | 375 "path TEXT NOT NULL," |
| 367 "expires_utc INTEGER NOT NULL," | 376 "expires_utc INTEGER NOT NULL," |
| 368 "secure INTEGER NOT NULL," | 377 "secure INTEGER NOT NULL," |
| 369 "httponly INTEGER NOT NULL," | 378 "httponly INTEGER NOT NULL," |
| 370 "last_access_utc INTEGER NOT NULL, " | 379 "last_access_utc INTEGER NOT NULL," |
| 371 "has_expires INTEGER NOT NULL DEFAULT 1, " | 380 "has_expires INTEGER NOT NULL DEFAULT 1," |
| 372 "persistent INTEGER NOT NULL DEFAULT 1," | 381 "persistent INTEGER NOT NULL DEFAULT 1," |
| 373 "priority INTEGER NOT NULL DEFAULT %d)", | 382 "priority INTEGER NOT NULL DEFAULT %d," |
| 383 "encrypted_value BLOB NOT NULL)", | |
| 374 CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT))); | 384 CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT))); |
| 375 if (!db->Execute(stmt.c_str())) | 385 if (!db->Execute(stmt.c_str())) |
| 376 return false; | 386 return false; |
| 377 } | 387 } |
| 378 | 388 |
| 379 // Older code created an index on creation_utc, which is already | 389 // Older code created an index on creation_utc, which is already |
| 380 // primary key for the table. | 390 // primary key for the table. |
| 381 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) | 391 if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) |
| 382 return false; | 392 return false; |
| 383 | 393 |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 672 } | 682 } |
| 673 | 683 |
| 674 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( | 684 bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( |
| 675 const std::set<std::string>& domains) { | 685 const std::set<std::string>& domains) { |
| 676 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); | 686 DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); |
| 677 | 687 |
| 678 sql::Statement smt; | 688 sql::Statement smt; |
| 679 if (restore_old_session_cookies_) { | 689 if (restore_old_session_cookies_) { |
| 680 smt.Assign(db_->GetCachedStatement( | 690 smt.Assign(db_->GetCachedStatement( |
| 681 SQL_FROM_HERE, | 691 SQL_FROM_HERE, |
| 682 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 692 "SELECT creation_utc, host_key, name, value, encrypted_value, path, " |
| 683 "secure, httponly, last_access_utc, has_expires, persistent, priority " | 693 "expires_utc, secure, httponly, last_access_utc, has_expires, " |
| 684 "FROM cookies WHERE host_key = ?")); | 694 "persistent, priority FROM cookies WHERE host_key = ?")); |
| 685 } else { | 695 } else { |
| 686 smt.Assign(db_->GetCachedStatement( | 696 smt.Assign(db_->GetCachedStatement( |
| 687 SQL_FROM_HERE, | 697 SQL_FROM_HERE, |
| 688 "SELECT creation_utc, host_key, name, value, path, expires_utc, " | 698 "SELECT creation_utc, host_key, name, value, encrypted_value, path, " |
| 689 "secure, httponly, last_access_utc, has_expires, persistent, priority " | 699 "expires_utc, secure, httponly, last_access_utc, has_expires, " |
| 690 "FROM cookies WHERE host_key = ? AND persistent = 1")); | 700 "persistent, priority FROM cookies WHERE host_key = ? " |
| 701 "AND persistent = 1")); | |
| 691 } | 702 } |
| 692 if (!smt.is_valid()) { | 703 if (!smt.is_valid()) { |
| 693 smt.Clear(); // Disconnect smt_ref from db_. | 704 smt.Clear(); // Disconnect smt_ref from db_. |
| 694 meta_table_.Reset(); | 705 meta_table_.Reset(); |
| 695 db_.reset(); | 706 db_.reset(); |
| 696 return false; | 707 return false; |
| 697 } | 708 } |
| 698 | 709 |
| 699 std::vector<net::CanonicalCookie*> cookies; | 710 std::vector<net::CanonicalCookie*> cookies; |
| 700 std::set<std::string>::const_iterator it = domains.begin(); | 711 std::set<std::string>::const_iterator it = domains.begin(); |
| 701 for (; it != domains.end(); ++it) { | 712 for (; it != domains.end(); ++it) { |
| 702 smt.BindString(0, *it); | 713 smt.BindString(0, *it); |
| 703 while (smt.Step()) { | 714 while (smt.Step()) { |
| 715 std::string value; | |
| 716 std::string encrypted_value = smt.ColumnString(4); | |
| 717 DCHECK(encrypted_value.empty() || crypto_.get() != NULL); | |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
I can see that this condition corresponds to failu
bcwhite
2013/10/08 18:23:36
I like it. Done.
| |
| 718 if (!encrypted_value.empty() && crypto_.get()) { | |
| 719 crypto_->DecryptString(encrypted_value, &value); | |
| 720 } else { | |
| 721 value = smt.ColumnString(3); | |
| 722 } | |
| 704 scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie( | 723 scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie( |
| 705 // The "source" URL is not used with persisted cookies. | 724 // The "source" URL is not used with persisted cookies. |
| 706 GURL(), // Source | 725 GURL(), // Source |
| 707 smt.ColumnString(2), // name | 726 smt.ColumnString(2), // name |
| 708 smt.ColumnString(3), // value | 727 value, // value |
| 709 smt.ColumnString(1), // domain | 728 smt.ColumnString(1), // domain |
| 710 smt.ColumnString(4), // path | 729 smt.ColumnString(5), // path |
| 711 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc | 730 Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc |
| 712 Time::FromInternalValue(smt.ColumnInt64(5)), // expires_utc | 731 Time::FromInternalValue(smt.ColumnInt64(6)), // expires_utc |
| 713 Time::FromInternalValue(smt.ColumnInt64(8)), // last_access_utc | 732 Time::FromInternalValue(smt.ColumnInt64(9)), // last_access_utc |
| 714 smt.ColumnInt(6) != 0, // secure | 733 smt.ColumnInt(7) != 0, // secure |
| 715 smt.ColumnInt(7) != 0, // httponly | 734 smt.ColumnInt(8) != 0, // httponly |
| 716 DBCookiePriorityToCookiePriority( | 735 DBCookiePriorityToCookiePriority( |
| 717 static_cast<DBCookiePriority>(smt.ColumnInt(11))))); // priority | 736 static_cast<DBCookiePriority>(smt.ColumnInt(12))))); // priority |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
Not a review comment, just a suggestion that you m
bcwhite
2013/10/08 18:23:36
I've put "encrypted_value" next to "value" just be
Scott Hess - ex-Googler
2013/10/08 19:13:51
It's all synthetic all the way down, SQLite and th
| |
| 718 DLOG_IF(WARNING, | 737 DLOG_IF(WARNING, |
| 719 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; | 738 cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; |
| 720 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; | 739 cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; |
| 721 cookies.push_back(cc.release()); | 740 cookies.push_back(cc.release()); |
| 722 ++num_cookies_read_; | 741 ++num_cookies_read_; |
| 723 } | 742 } |
| 724 smt.Reset(true); | 743 smt.Reset(true); |
| 725 } | 744 } |
| 726 { | 745 { |
| 727 base::AutoLock locked(lock_); | 746 base::AutoLock locked(lock_); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 830 } | 849 } |
| 831 ++cur_version; | 850 ++cur_version; |
| 832 meta_table_.SetVersionNumber(cur_version); | 851 meta_table_.SetVersionNumber(cur_version); |
| 833 meta_table_.SetCompatibleVersionNumber( | 852 meta_table_.SetCompatibleVersionNumber( |
| 834 std::min(cur_version, kCompatibleVersionNumber)); | 853 std::min(cur_version, kCompatibleVersionNumber)); |
| 835 transaction.Commit(); | 854 transaction.Commit(); |
| 836 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6", | 855 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6", |
| 837 base::TimeTicks::Now() - start_time); | 856 base::TimeTicks::Now() - start_time); |
| 838 } | 857 } |
| 839 | 858 |
| 859 if (cur_version == 6) { | |
| 860 const base::TimeTicks start_time = base::TimeTicks::Now(); | |
| 861 sql::Transaction transaction(db_.get()); | |
| 862 if (!transaction.Begin()) | |
| 863 return false; | |
| 864 // Alter the table to add empty "encrypted value" column. | |
| 865 std::string stmt(base::StringPrintf( | |
| 866 "ALTER TABLE cookies ADD COLUMN encrypted_value BLOB DEFAULT ''")); | |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
There's really no reason to StringPrintf() this, i
bcwhite
2013/10/08 18:23:36
True. I'd just copied it from above. Done.
| |
| 867 if (!db_->Execute(stmt.c_str())) { | |
| 868 LOG(WARNING) << "Unable to update cookie database to version 7."; | |
| 869 return false; | |
| 870 } | |
| 871 ++cur_version; | |
| 872 meta_table_.SetVersionNumber(cur_version); | |
| 873 meta_table_.SetCompatibleVersionNumber( | |
| 874 std::min(cur_version, kCompatibleVersionNumber)); | |
| 875 transaction.Commit(); | |
| 876 UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV7", | |
| 877 base::TimeTicks::Now() - start_time); | |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
I think it's interesting that we're histogramming
erikwright (departed)
2013/10/08 18:41:53
I'll take a look at how useful this actually is. I
Scott Hess - ex-Googler
2013/10/08 19:13:51
If it is kept, then obviously a histograms.xml cha
| |
| 878 } | |
| 879 | |
| 840 // Put future migration cases here. | 880 // Put future migration cases here. |
| 841 | 881 |
| 842 if (cur_version < kCurrentVersionNumber) { | 882 if (cur_version < kCurrentVersionNumber) { |
| 843 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); | 883 UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); |
| 844 | 884 |
| 845 meta_table_.Reset(); | 885 meta_table_.Reset(); |
| 846 db_.reset(new sql::Connection); | 886 db_.reset(new sql::Connection); |
| 847 if (!base::DeleteFile(path_, false) || | 887 if (!base::DeleteFile(path_, false) || |
| 848 !db_->Open(path_) || | 888 !db_->Open(path_) || |
| 849 !meta_table_.Init( | 889 !meta_table_.Init( |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 914 base::AutoLock locked(lock_); | 954 base::AutoLock locked(lock_); |
| 915 pending_.swap(ops); | 955 pending_.swap(ops); |
| 916 num_pending_ = 0; | 956 num_pending_ = 0; |
| 917 } | 957 } |
| 918 | 958 |
| 919 // Maybe an old timer fired or we are already Close()'ed. | 959 // Maybe an old timer fired or we are already Close()'ed. |
| 920 if (!db_.get() || ops.empty()) | 960 if (!db_.get() || ops.empty()) |
| 921 return; | 961 return; |
| 922 | 962 |
| 923 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 963 sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
| 924 "INSERT INTO cookies (creation_utc, host_key, name, value, path, " | 964 "INSERT INTO cookies (creation_utc, host_key, name, value, " |
| 925 "expires_utc, secure, httponly, last_access_utc, has_expires, " | 965 "encrypted_value, path, expires_utc, secure, httponly, last_access_utc, " |
| 926 "persistent, priority) " | 966 "has_expires, persistent, priority) " |
| 927 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?)")); | 967 "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)")); |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
My earlier comment about ordering also applies her
| |
| 928 if (!add_smt.is_valid()) | 968 if (!add_smt.is_valid()) |
| 929 return; | 969 return; |
| 930 | 970 |
| 931 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 971 sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
| 932 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); | 972 "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); |
| 933 if (!update_access_smt.is_valid()) | 973 if (!update_access_smt.is_valid()) |
| 934 return; | 974 return; |
| 935 | 975 |
| 936 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, | 976 sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, |
| 937 "DELETE FROM cookies WHERE creation_utc=?")); | 977 "DELETE FROM cookies WHERE creation_utc=?")); |
| 938 if (!del_smt.is_valid()) | 978 if (!del_smt.is_valid()) |
| 939 return; | 979 return; |
| 940 | 980 |
| 941 sql::Transaction transaction(db_.get()); | 981 sql::Transaction transaction(db_.get()); |
| 942 if (!transaction.Begin()) | 982 if (!transaction.Begin()) |
| 943 return; | 983 return; |
| 944 | 984 |
| 945 for (PendingOperationsList::iterator it = ops.begin(); | 985 for (PendingOperationsList::iterator it = ops.begin(); |
| 946 it != ops.end(); ++it) { | 986 it != ops.end(); ++it) { |
| 947 // Free the cookies as we commit them to the database. | 987 // Free the cookies as we commit them to the database. |
| 948 scoped_ptr<PendingOperation> po(*it); | 988 scoped_ptr<PendingOperation> po(*it); |
| 949 switch (po->op()) { | 989 switch (po->op()) { |
| 950 case PendingOperation::COOKIE_ADD: | 990 case PendingOperation::COOKIE_ADD: |
| 951 cookies_per_origin_[ | 991 cookies_per_origin_[ |
| 952 CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]++; | 992 CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]++; |
| 953 add_smt.Reset(true); | 993 add_smt.Reset(true); |
| 954 add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue()); | 994 add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue()); |
| 955 add_smt.BindString(1, po->cc().Domain()); | 995 add_smt.BindString(1, po->cc().Domain()); |
| 956 add_smt.BindString(2, po->cc().Name()); | 996 add_smt.BindString(2, po->cc().Name()); |
| 957 add_smt.BindString(3, po->cc().Value()); | 997 if (crypto_.get()) { |
| 958 add_smt.BindString(4, po->cc().Path()); | 998 std::string encrypted_value; |
| 959 add_smt.BindInt64(5, po->cc().ExpiryDate().ToInternalValue()); | 999 add_smt.BindString(3, std::string()); // value |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
BindCString(3, "");
bcwhite
2013/10/08 18:23:36
Done.
| |
| 960 add_smt.BindInt(6, po->cc().IsSecure()); | 1000 crypto_->EncryptString(po->cc().Value(), &encrypted_value); |
| 961 add_smt.BindInt(7, po->cc().IsHttpOnly()); | 1001 // BindBlob() calls sqlite3_bind_blob() with SQLITE_TRANSIENT and so |
| 962 add_smt.BindInt64(8, po->cc().LastAccessDate().ToInternalValue()); | 1002 // immediately makes an internal copy of the data. |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
I think you can trim this to "BindBlob() makes a c
bcwhite
2013/10/08 18:23:36
Done.
| |
| 963 add_smt.BindInt(9, po->cc().IsPersistent()); | 1003 add_smt.BindBlob(4, encrypted_value.data(), |
| 1004 static_cast<int>(encrypted_value.length())); | |
| 1005 } else { | |
| 1006 add_smt.BindString(3, po->cc().Value()); | |
| 1007 add_smt.BindBlob(4, "", 0); // encrypted_value | |
|
Scott Hess - ex-Googler
2013/10/08 17:35:55
With the CREATE change, I think this should be Bin
| |
| 1008 } | |
| 1009 add_smt.BindString(5, po->cc().Path()); | |
| 1010 add_smt.BindInt64(6, po->cc().ExpiryDate().ToInternalValue()); | |
| 1011 add_smt.BindInt(7, po->cc().IsSecure()); | |
| 1012 add_smt.BindInt(8, po->cc().IsHttpOnly()); | |
| 1013 add_smt.BindInt64(9, po->cc().LastAccessDate().ToInternalValue()); | |
| 964 add_smt.BindInt(10, po->cc().IsPersistent()); | 1014 add_smt.BindInt(10, po->cc().IsPersistent()); |
| 1015 add_smt.BindInt(11, po->cc().IsPersistent()); | |
| 965 add_smt.BindInt( | 1016 add_smt.BindInt( |
| 966 11, CookiePriorityToDBCookiePriority(po->cc().Priority())); | 1017 12, CookiePriorityToDBCookiePriority(po->cc().Priority())); |
| 967 if (!add_smt.Run()) | 1018 if (!add_smt.Run()) |
| 968 NOTREACHED() << "Could not add a cookie to the DB."; | 1019 NOTREACHED() << "Could not add a cookie to the DB."; |
| 969 break; | 1020 break; |
| 970 | 1021 |
| 971 case PendingOperation::COOKIE_UPDATEACCESS: | 1022 case PendingOperation::COOKIE_UPDATEACCESS: |
| 972 update_access_smt.Reset(true); | 1023 update_access_smt.Reset(true); |
| 973 update_access_smt.BindInt64(0, | 1024 update_access_smt.BindInt64(0, |
| 974 po->cc().LastAccessDate().ToInternalValue()); | 1025 po->cc().LastAccessDate().ToInternalValue()); |
| 975 update_access_smt.BindInt64(1, | 1026 update_access_smt.BindInt64(1, |
| 976 po->cc().CreationDate().ToInternalValue()); | 1027 po->cc().CreationDate().ToInternalValue()); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1142 LOG(WARNING) << "Failed to post task from " << origin.ToString() | 1193 LOG(WARNING) << "Failed to post task from " << origin.ToString() |
| 1143 << " to client_task_runner_."; | 1194 << " to client_task_runner_."; |
| 1144 } | 1195 } |
| 1145 } | 1196 } |
| 1146 | 1197 |
| 1147 SQLitePersistentCookieStore::SQLitePersistentCookieStore( | 1198 SQLitePersistentCookieStore::SQLitePersistentCookieStore( |
| 1148 const base::FilePath& path, | 1199 const base::FilePath& path, |
| 1149 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, | 1200 const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, |
| 1150 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, | 1201 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, |
| 1151 bool restore_old_session_cookies, | 1202 bool restore_old_session_cookies, |
| 1152 quota::SpecialStoragePolicy* special_storage_policy) | 1203 quota::SpecialStoragePolicy* special_storage_policy, |
| 1204 CookieCryptoDelegate* crypto_delegate) | |
| 1153 : backend_(new Backend(path, | 1205 : backend_(new Backend(path, |
| 1154 client_task_runner, | 1206 client_task_runner, |
| 1155 background_task_runner, | 1207 background_task_runner, |
| 1156 restore_old_session_cookies, | 1208 restore_old_session_cookies, |
| 1157 special_storage_policy)) { | 1209 special_storage_policy, |
| 1210 crypto_delegate)) { | |
| 1158 } | 1211 } |
| 1159 | 1212 |
| 1160 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { | 1213 void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { |
| 1161 backend_->Load(loaded_callback); | 1214 backend_->Load(loaded_callback); |
| 1162 } | 1215 } |
| 1163 | 1216 |
| 1164 void SQLitePersistentCookieStore::LoadCookiesForKey( | 1217 void SQLitePersistentCookieStore::LoadCookiesForKey( |
| 1165 const std::string& key, | 1218 const std::string& key, |
| 1166 const LoadedCallback& loaded_callback) { | 1219 const LoadedCallback& loaded_callback) { |
| 1167 backend_->LoadCookiesForKey(key, loaded_callback); | 1220 backend_->LoadCookiesForKey(key, loaded_callback); |
| (...skipping 24 matching lines...) Expand all Loading... | |
| 1192 backend_->Close(); | 1245 backend_->Close(); |
| 1193 // We release our reference to the Backend, though it will probably still have | 1246 // We release our reference to the Backend, though it will probably still have |
| 1194 // a reference if the background runner has not run Close() yet. | 1247 // a reference if the background runner has not run Close() yet. |
| 1195 } | 1248 } |
| 1196 | 1249 |
| 1197 net::CookieStore* CreatePersistentCookieStore( | 1250 net::CookieStore* CreatePersistentCookieStore( |
| 1198 const base::FilePath& path, | 1251 const base::FilePath& path, |
| 1199 bool restore_old_session_cookies, | 1252 bool restore_old_session_cookies, |
| 1200 quota::SpecialStoragePolicy* storage_policy, | 1253 quota::SpecialStoragePolicy* storage_policy, |
| 1201 net::CookieMonster::Delegate* cookie_monster_delegate, | 1254 net::CookieMonster::Delegate* cookie_monster_delegate, |
| 1202 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner) { | 1255 const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, |
| 1256 CookieCryptoDelegate* crypto_delegate) { | |
| 1203 SQLitePersistentCookieStore* persistent_store = | 1257 SQLitePersistentCookieStore* persistent_store = |
| 1204 new SQLitePersistentCookieStore( | 1258 new SQLitePersistentCookieStore( |
| 1205 path, | 1259 path, |
| 1206 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), | 1260 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO), |
| 1207 background_task_runner.get() ? background_task_runner : | 1261 background_task_runner.get() ? background_task_runner : |
| 1208 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( | 1262 BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( |
| 1209 BrowserThread::GetBlockingPool()->GetSequenceToken()), | 1263 BrowserThread::GetBlockingPool()->GetSequenceToken()), |
| 1210 restore_old_session_cookies, | 1264 restore_old_session_cookies, |
| 1211 storage_policy); | 1265 storage_policy, |
| 1266 crypto_delegate); | |
| 1212 net::CookieMonster* cookie_monster = | 1267 net::CookieMonster* cookie_monster = |
| 1213 new net::CookieMonster(persistent_store, cookie_monster_delegate); | 1268 new net::CookieMonster(persistent_store, cookie_monster_delegate); |
| 1214 | 1269 |
| 1215 const std::string cookie_priority_experiment_group = | 1270 const std::string cookie_priority_experiment_group = |
| 1216 base::FieldTrialList::FindFullName("CookieRetentionPriorityStudy"); | 1271 base::FieldTrialList::FindFullName("CookieRetentionPriorityStudy"); |
| 1217 cookie_monster->SetPriorityAwareGarbageCollection( | 1272 cookie_monster->SetPriorityAwareGarbageCollection( |
| 1218 cookie_priority_experiment_group == "ExperimentOn"); | 1273 cookie_priority_experiment_group == "ExperimentOn"); |
| 1219 | 1274 |
| 1220 return cookie_monster; | 1275 return cookie_monster; |
| 1221 } | 1276 } |
| 1222 | 1277 |
| 1223 } // namespace content | 1278 } // namespace content |
| OLD | NEW |