sqlite_persistent_cookie_store.cc revision 6e8cce623b6e4fe0c9e4af605d675dd9d0338c38
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/browser/net/sqlite_persistent_cookie_store.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <list> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <map> 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <set> 105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <utility> 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/basictypes.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/callback.h" 155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "base/command_line.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/files/file_path.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/location.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/sequenced_task_runner.h" 24868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 25868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/lock.h" 27c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "base/threading/sequenced_worker_pool.h" 28eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 29c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/browser_thread.h" 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/browser/cookie_crypto_delegate.h" 31c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "content/public/browser/cookie_store_factory.h" 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "content/public/common/content_switches.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/registry_controlled_domains/registry_controlled_domain.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/cookies/canonical_cookie.h" 35c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cookies/cookie_constants.h" 36c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/cookies/cookie_util.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/error_delegate_util.h" 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/meta_table.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/statement.h" 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "sql/transaction.h" 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "third_party/sqlite/sqlite3.h" 427dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "webkit/browser/quota/special_storage_policy.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time; 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 47c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace content { 48c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class is designed to be shared between any client thread and the 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// background task runner. It batches operations and commits them on a timer. 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SQLitePersistentCookieStore::Load is called to load all cookies. It 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// delegates to Backend::Load, which posts a Backend::LoadAndNotifyOnDBThread 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// task to the background runner. This task calls Backend::ChainLoadCookies(), 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// which repeatedly posts itself to the BG runner to load each eTLD+1's cookies 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// in separate tasks. When this is complete, Backend::CompleteLoadOnIOThread is 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// posted to the client runner, which notifies the caller of 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SQLitePersistentCookieStore::Load that the load is complete. 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// If a priority load request is invoked via SQLitePersistentCookieStore:: 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// LoadCookiesForKey, it is delegated to Backend::LoadCookiesForKey, which posts 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Backend::LoadKeyAndNotifyOnDBThread to the BG runner. That routine loads just 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// that single domain key (eTLD+1)'s cookies, and posts a Backend:: 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// CompleteLoadForKeyOnIOThread to the client runner to notify the caller of 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// SQLitePersistentCookieStore::LoadCookiesForKey that that load is complete. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Subsequent to loading, mutations may be queued by any thread using 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AddCookie, UpdateCookieAccessTime, and DeleteCookie. These are flushed to 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// disk on the BG runner every 30 seconds, 512 operations, or call to Flush(), 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// whichever occurs first. 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class SQLitePersistentCookieStore::Backend 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : public base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend> { 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Backend( 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool restore_old_session_cookies, 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quota::SpecialStoragePolicy* special_storage_policy, 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieCryptoDelegate* crypto_delegate) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : path_(path), 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pending_(0), 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_keep_session_state_(false), 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_(false), 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) corruption_detected_(false), 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) restore_old_session_cookies_(restore_old_session_cookies), 87c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) special_storage_policy_(special_storage_policy), 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_cookies_read_(0), 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_task_runner_(client_task_runner), 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) background_task_runner_(background_task_runner), 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_priority_waiting_(0), 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) total_priority_requests_(0), 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_(crypto_delegate) {} 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Creates or loads the SQLite database. 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Load(const LoadedCallback& loaded_callback); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads cookies for the domain key (eTLD+1). 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void LoadCookiesForKey(const std::string& domain, 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback); 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Batch a cookie addition. 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void AddCookie(const net::CanonicalCookie& cc); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Batch a cookie access time update. 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void UpdateCookieAccessTime(const net::CanonicalCookie& cc); 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Batch a cookie deletion. 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteCookie(const net::CanonicalCookie& cc); 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit pending operations as soon as possible. 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Flush(const base::Closure& callback); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit any pending operations and close the database. This must be called 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // before the object is destructed. 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Close(); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void SetForceKeepSessionState(); 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) friend class base::RefCountedThreadSafe<SQLitePersistentCookieStore::Backend>; 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // You should call Close() before destructing this object. 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~Backend() { 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!db_.get()) << "Close should have already been called."; 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(num_pending_ == 0 && pending_.empty()); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Database upgrade statements. 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool EnsureDatabaseVersion(); 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) class PendingOperation { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef enum { 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COOKIE_ADD, 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COOKIE_UPDATEACCESS, 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) COOKIE_DELETE, 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } OperationType; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperation(OperationType op, const net::CanonicalCookie& cc) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : op_(op), cc_(cc) { } 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OperationType op() const { return op_; } 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc() const { return cc_; } 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) OperationType op_; 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net::CanonicalCookie cc_; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Creates or loads the SQLite database on background runner. 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void LoadAndNotifyInBackground(const LoadedCallback& loaded_callback, 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& posted_at); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Loads cookies for the domain key (eTLD+1) on background runner. 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void LoadKeyAndNotifyInBackground(const std::string& domains, 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const LoadedCallback& loaded_callback, 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Time& posted_at); 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Notifies the CookieMonster when loading completes for a specific domain key 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // or for all domain keys. Triggers the callback and passes it all cookies 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that have been loaded from DB since last IO notification. 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Notify(const LoadedCallback& loaded_callback, bool load_success); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends notification when the entire store is loaded, and reports metrics 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // for the total time to load and aggregated results from any priority loads 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that occurred. 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CompleteLoadInForeground(const LoadedCallback& loaded_callback, 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool load_success); 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Sends notification when a single priority load completes. Updates priority 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // load metric data. The data is sent only after the final load completes. 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void CompleteLoadForKeyInForeground(const LoadedCallback& loaded_callback, 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool load_success); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sends all metrics, including posting a ReportMetricsInBackground task. 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Called after all priority and regular loading is complete. 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ReportMetrics(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Sends background-runner owned metrics (i.e., the combined duration of all 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // BG-runner tasks). 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ReportMetricsInBackground(); 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Initialize the data base. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool InitializeDatabase(); 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Loads cookies for the next domain key from the DB, then either reschedules 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // itself or schedules the provided callback to run on the client runner (if 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // all domains are loaded). 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ChainLoadCookies(const LoadedCallback& loaded_callback); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load all cookies for a set of domains/hosts 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool LoadCookiesForDomains(const std::set<std::string>& key); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Batch a cookie operation (add or delete) 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void BatchOperation(PendingOperation::OperationType op, 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc); 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit our pending operations to the database. 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void Commit(); 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Close() executed on the background runner. 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void InternalBackgroundClose(); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteSessionCookiesOnStartup(); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DeleteSessionCookiesOnShutdown(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 208868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) void DatabaseErrorCallback(int error, sql::Statement* stmt); 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void KillDatabase(); 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void PostBackgroundTask(const tracked_objects::Location& origin, 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& task); 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void PostClientTask(const tracked_objects::Location& origin, 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::Closure& task); 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath path_; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<sql::Connection> db_; 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::MetaTable meta_table_; 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::list<PendingOperation*> PendingOperationsList; 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperationsList pending_; 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperationsList::size_type num_pending_; 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if the persistent store should skip delete on exit rules. 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool force_keep_session_state_; 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Guard |cookies_|, |pending_|, |num_pending_|, |force_keep_session_state_| 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock lock_; 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Temporary buffer for cookies loaded from DB. Accumulates cookies to reduce 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // the number of messages sent to the client runner. Sent back in response to 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // individual load requests for domain keys or when all loading completes. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::CanonicalCookie*> cookies_; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of domain keys(eTLD+1) to domains/hosts that are to be loaded from DB. 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::set<std::string> > keys_to_load_; 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Map of (domain keys(eTLD+1), is secure cookie) to number of cookies in the 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // database. 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::pair<std::string, bool> CookieOrigin; 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) typedef std::map<CookieOrigin, int> CookiesPerOriginMap; 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookiesPerOriginMap cookies_per_origin_; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates if DB has been initialized. 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool initialized_; 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Indicates if the kill-database callback has been scheduled. 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool corruption_detected_; 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If false, we should filter out session cookies when reading the DB. 2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool restore_old_session_cookies_; 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Policy defining what data is deleted on shutdown. 252c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_; 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The cumulative time spent loading the cookies on the background runner. 2552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Incremented and reported from the background runner. 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta cookie_load_duration_; 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The total number of cookies read. Incremented and reported on the 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // background runner. 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_cookies_read_; 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> client_task_runner_; 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> background_task_runner_; 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Guards the following metrics-related properties (only accessed when 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // starting/completing priority loads or completing the total load). 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Lock metrics_lock_; 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_priority_waiting_; 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The total number of priority requests. 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int total_priority_requests_; 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time when |num_priority_waiting_| incremented to 1. 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time current_priority_wait_start_; 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The cumulative duration of time when |num_priority_waiting_| was greater 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // than 1. 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta priority_wait_duration_; 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Class with functions that do cryptographic operations (for protecting 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // cookies stored persistently). 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 2795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Not owned. 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieCryptoDelegate* crypto_; 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(Backend); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 285c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)namespace { 286c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version number of the database. 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Version 7 adds encrypted values. Old values will continue to be used but 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// all new values written will be encrypted on selected operating systems. New 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// records read by old clients will simply get an empty cookie value while old 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// records read by new clients will continue to operate with the unencrypted 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// version. New and old clients alike will always write/update records with 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// what they support. 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// 296c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Version 6 adds cookie priorities. This allows developers to influence the 297c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// order in which cookies are evicted in order to meet domain cookie limits. 298c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version 5 adds the columns has_expires and is_persistent, so that the 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// database can store session cookies as well as persistent cookies. Databases 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// of version 5 are incompatible with older versions of code. If a database of 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// version 5 is read by older code, session cookies will be treated as normal 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// cookies. Currently, these fields are written, but not read anymore. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// In version 4, we migrated the time epoch. If you open the DB with an older 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// version on Mac or Linux, the times will look wonky, but the file will likely 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// be usable. On Windows version 3 and 4 are the same. 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version 3 updated the database to include the last access time, so we can 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// expire them in decreasing order of use when we've reached the maximum 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// number of cookies. 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)const int kCurrentVersionNumber = 7; 313c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)const int kCompatibleVersionNumber = 5; 314c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 315c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)// Possible values for the 'priority' column. 316c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)enum DBCookiePriority { 317c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCookiePriorityLow = 0, 318c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCookiePriorityMedium = 1, 319c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) kCookiePriorityHigh = 2, 320c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)}; 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 322c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)DBCookiePriority CookiePriorityToDBCookiePriority(net::CookiePriority value) { 323c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (value) { 324c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case net::COOKIE_PRIORITY_LOW: 325c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kCookiePriorityLow; 326c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case net::COOKIE_PRIORITY_MEDIUM: 327c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kCookiePriorityMedium; 328c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case net::COOKIE_PRIORITY_HIGH: 329c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kCookiePriorityHigh; 330c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return kCookiePriorityMedium; 334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)net::CookiePriority DBCookiePriorityToCookiePriority(DBCookiePriority value) { 337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) switch (value) { 338c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case kCookiePriorityLow: 339c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::COOKIE_PRIORITY_LOW; 340c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case kCookiePriorityMedium: 341c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::COOKIE_PRIORITY_MEDIUM; 342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) case kCookiePriorityHigh: 343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::COOKIE_PRIORITY_HIGH; 344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) NOTREACHED(); 347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return net::COOKIE_PRIORITY_DEFAULT; 348c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Increments a specified TimeDelta by the duration between this object's 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// constructor and destructor. Not thread safe. Multiple instances may be 3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// created with the same delta instance as long as their lifetimes are nested. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The shortest lived instances have no impact. 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class IncrementTimeDelta { 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) explicit IncrementTimeDelta(base::TimeDelta* delta) : 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) delta_(delta), 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) original_value_(*delta), 3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start_(base::Time::Now()) {} 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ~IncrementTimeDelta() { 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) *delta_ = original_value_ + base::Time::Now() - start_; 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta* delta_; 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta original_value_; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start_; 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(IncrementTimeDelta); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Initializes the cookies table, returning true on success. 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool InitTable(sql::Connection* db) { 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db->DoesTableExist("cookies")) { 376c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string stmt(base::StringPrintf( 377c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "CREATE TABLE cookies (" 378c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "creation_utc INTEGER NOT NULL UNIQUE PRIMARY KEY," 379c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "host_key TEXT NOT NULL," 380c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "name TEXT NOT NULL," 381c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "value TEXT NOT NULL," 382c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "path TEXT NOT NULL," 383c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "expires_utc INTEGER NOT NULL," 384c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "secure INTEGER NOT NULL," 385c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "httponly INTEGER NOT NULL," 386c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "last_access_utc INTEGER NOT NULL, " 387c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "has_expires INTEGER NOT NULL DEFAULT 1, " 388c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "persistent INTEGER NOT NULL DEFAULT 1," 3895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "priority INTEGER NOT NULL DEFAULT %d," 3905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "encrypted_value BLOB DEFAULT '')", 391c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT))); 392c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!db->Execute(stmt.c_str())) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Older code created an index on creation_utc, which is already 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // primary key for the table. 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db->Execute("DROP INDEX IF EXISTS cookie_times")) 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db->Execute("CREATE INDEX IF NOT EXISTS domain ON cookies(host_key)")) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 4035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::Load( 4105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback) { 4115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This function should be called only once per instance. 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!db_.get()); 4132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind( 4142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Backend::LoadAndNotifyInBackground, this, 4152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loaded_callback, base::Time::Now())); 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::LoadCookiesForKey( 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback) { 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(metrics_lock_); 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_priority_waiting_ == 0) 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) current_priority_wait_start_ = base::Time::Now(); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_priority_waiting_++; 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_priority_requests_++; 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind( 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Backend::LoadKeyAndNotifyInBackground, 4312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, key, loaded_callback, base::Time::Now())); 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::LoadAndNotifyInBackground( 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback, const base::Time& posted_at) { 4362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementTimeDelta increment(&cookie_load_duration_); 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.TimeLoadDBQueueWait", 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - posted_at, 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!InitializeDatabase()) { 4462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostClientTask(FROM_HERE, base::Bind( 4472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Backend::CompleteLoadInForeground, this, loaded_callback, false)); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ChainLoadCookies(loaded_callback); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::LoadKeyAndNotifyInBackground( 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time& posted_at) { 4572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementTimeDelta increment(&cookie_load_duration_); 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.TimeKeyLoadDBQueueWait", 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - posted_at, 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool success = false; 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (InitializeDatabase()) { 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::set<std::string> >::iterator 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = keys_to_load_.find(key); 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it != keys_to_load_.end()) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = LoadCookiesForDomains(it->second); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys_to_load_.erase(it); 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) success = true; 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostClientTask(FROM_HERE, base::Bind( 4792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground, 4802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) this, loaded_callback, success)); 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::CompleteLoadForKeyInForeground( 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback, 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool load_success) { 4862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_task_runner_->RunsTasksOnCurrentThread()); 4872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(loaded_callback, load_success); 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(metrics_lock_); 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_priority_waiting_--; 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_priority_waiting_ == 0) { 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_wait_duration_ += 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() - current_priority_wait_start_; 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::ReportMetricsInBackground() { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.TimeLoad", 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookie_load_duration_, 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::ReportMetrics() { 5102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind( 5112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &SQLitePersistentCookieStore::Backend::ReportMetricsInBackground, this)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(metrics_lock_); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.PriorityBlockingTime", 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) priority_wait_duration_, 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 50); 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100( 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.PriorityLoadCount", 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) total_priority_requests_); 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_10000( 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "Cookie.NumberOfLoadedCookies", 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_cookies_read_); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::CompleteLoadInForeground( 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback, bool load_success) { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Notify(loaded_callback, load_success); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (load_success) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ReportMetrics(); 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::Notify( 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback, 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool load_success) { 5422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(client_task_runner_->RunsTasksOnCurrentThread()); 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::CanonicalCookie*> cookies; 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies.swap(cookies_); 5485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) loaded_callback.Run(cookies); 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SQLitePersistentCookieStore::Backend::InitializeDatabase() { 5542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (initialized_ || corruption_detected_) { 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return false if we were previously initialized but the DB has since been 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // closed, or if corruption caused a database reset during initialization. 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return db_ != NULL; 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time start = base::Time::Now(); 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath dir = path_.DirName(); 565a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (!base::PathExists(dir) && !base::CreateDirectory(dir)) { 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int64 db_size = 0; 570a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7Torne (Richard Coles) if (base::GetFileSize(path_, &db_size)) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS("Cookie.DBSizeInKB", db_size / 1024 ); 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(new sql::Connection); 57490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) db_->set_histogram_tag("Cookie"); 575868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 576868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // Unretained to avoid a ref loop with |db_|. 577868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) db_->set_error_callback( 578868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Bind(&SQLitePersistentCookieStore::Backend::DatabaseErrorCallback, 579868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) base::Unretained(this))); 5805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Open(path_)) { 5825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to open cookie DB."; 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (corruption_detected_) 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->Raze(); 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!EnsureDatabaseVersion() || !InitTable(db_.get())) { 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to open cookie DB."; 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (corruption_detected_) 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->Raze(); 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 5975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 600ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "Cookie.TimeInitializeDB", 601ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Time::Now() - start, 602ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 603ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 50); 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) start = base::Time::Now(); 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Retrieve all the domains 6085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement smt(db_->GetUniqueStatement( 6095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SELECT DISTINCT host_key FROM cookies")); 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!smt.is_valid()) { 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (corruption_detected_) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_->Raze(); 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 619ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch std::vector<std::string> host_keys; 620ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch while (smt.Step()) 621ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch host_keys.push_back(smt.ColumnString(0)); 622ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 623ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch UMA_HISTOGRAM_CUSTOM_TIMES( 624ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "Cookie.TimeLoadDomains", 625ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Time::Now() - start, 626ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 627ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 50); 628ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 629ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Time start_parse = base::Time::Now(); 630ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Build a map of domain keys (always eTLD+1) to domains. 632ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch for (size_t idx = 0; idx < host_keys.size(); ++idx) { 633ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch const std::string& domain = host_keys[idx]; 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string key = 635a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) net::registry_controlled_domains::GetDomainAndRegistry( 636a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) domain, 6375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES); 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 639ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch keys_to_load_[key].insert(domain); 6405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_CUSTOM_TIMES( 643ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "Cookie.TimeParseDomains", 644ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Time::Now() - start_parse, 645ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 646ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 50); 647ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 648ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch UMA_HISTOGRAM_CUSTOM_TIMES( 649ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch "Cookie.TimeInitializeDomainMap", 650ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::Time::Now() - start, 651ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::TimeDelta::FromMilliseconds(1), base::TimeDelta::FromMinutes(1), 652ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch 50); 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initialized_ = true; 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::ChainLoadCookies( 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback) { 6602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) IncrementTimeDelta increment(&cookie_load_duration_); 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool load_success = true; 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!db_) { 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Close() has been called on this store. 6675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_success = false; 6685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (keys_to_load_.size() > 0) { 6695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Load cookies for the first domain key. 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::map<std::string, std::set<std::string> >::iterator 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it = keys_to_load_.begin(); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) load_success = LoadCookiesForDomains(it->second); 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) keys_to_load_.erase(it); 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If load is successful and there are more domain keys to be loaded, 6772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // then post a background task to continue chain-load; 6782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Otherwise notify on client runner. 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (load_success && keys_to_load_.size() > 0) { 6802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind( 6812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Backend::ChainLoadCookies, this, loaded_callback)); 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostClientTask(FROM_HERE, base::Bind( 6842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &Backend::CompleteLoadInForeground, this, 6852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) loaded_callback, load_success)); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (load_success && !restore_old_session_cookies_) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSessionCookiesOnStartup(); 6885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SQLitePersistentCookieStore::Backend::LoadCookiesForDomains( 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::set<std::string>& domains) { 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 6945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement smt; 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (restore_old_session_cookies_) { 6975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) smt.Assign(db_->GetCachedStatement( 698c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SQL_FROM_HERE, 6995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "SELECT creation_utc, host_key, name, value, encrypted_value, path, " 7005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "expires_utc, secure, httponly, last_access_utc, has_expires, " 7015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "persistent, priority FROM cookies WHERE host_key = ?")); 7025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 7035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) smt.Assign(db_->GetCachedStatement( 704c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) SQL_FROM_HERE, 7055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "SELECT creation_utc, host_key, name, value, encrypted_value, path, " 7065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "expires_utc, secure, httponly, last_access_utc, has_expires, " 7075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "persistent, priority FROM cookies WHERE host_key = ? " 7085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "AND persistent = 1")); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!smt.is_valid()) { 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) smt.Clear(); // Disconnect smt_ref from db_. 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::vector<net::CanonicalCookie*> cookies; 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::set<std::string>::const_iterator it = domains.begin(); 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (; it != domains.end(); ++it) { 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) smt.BindString(0, *it); 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) while (smt.Step()) { 7225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string value; 7235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string encrypted_value = smt.ColumnString(4); 7245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!encrypted_value.empty() && crypto_) { 7255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_->DecryptString(encrypted_value, &value); 7265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 7275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DCHECK(encrypted_value.empty()); 7285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value = smt.ColumnString(3); 7295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 730c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) scoped_ptr<net::CanonicalCookie> cc(new net::CanonicalCookie( 731c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // The "source" URL is not used with persisted cookies. 732c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL(), // Source 733c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) smt.ColumnString(2), // name 7345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) value, // value 735c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) smt.ColumnString(1), // domain 7365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) smt.ColumnString(5), // path 737c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) Time::FromInternalValue(smt.ColumnInt64(0)), // creation_utc 7385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Time::FromInternalValue(smt.ColumnInt64(6)), // expires_utc 7395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Time::FromInternalValue(smt.ColumnInt64(9)), // last_access_utc 7405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) smt.ColumnInt(7) != 0, // secure 7415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) smt.ColumnInt(8) != 0, // httponly 742c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) DBCookiePriorityToCookiePriority( 7435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<DBCookiePriority>(smt.ColumnInt(12))))); // priority 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DLOG_IF(WARNING, 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cc->CreationDate() > Time::Now()) << L"CreationDate too recent"; 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies_per_origin_[CookieOrigin(cc->Domain(), cc->IsSecure())]++; 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies.push_back(cc.release()); 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++num_cookies_read_; 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) smt.Reset(true); 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies_.insert(cookies_.end(), cookies.begin(), cookies.end()); 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool SQLitePersistentCookieStore::Backend::EnsureDatabaseVersion() { 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Version check. 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!meta_table_.Init( 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (meta_table_.GetCompatibleVersionNumber() > kCurrentVersionNumber) { 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Cookie database is too new."; 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int cur_version = meta_table_.GetVersionNumber(); 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur_version == 2) { 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_.get()); 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Begin()) 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("ALTER TABLE cookies ADD COLUMN last_access_utc " 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "INTEGER DEFAULT 0") || 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !db_->Execute("UPDATE cookies SET last_access_utc = creation_utc")) { 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to update cookie database to version 3."; 7805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_version; 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.SetVersionNumber(cur_version); 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.SetCompatibleVersionNumber( 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(cur_version, kCompatibleVersionNumber)); 7865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction.Commit(); 7875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur_version == 3) { 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The time epoch changed for Mac & Linux in this version to match Windows. 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This patch came after the main epoch change happened, so some 7925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // developers have "good" times for cookies added by the more recent 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // versions. So we have to be careful to only update times that are under 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the old system (which will appear to be from before 1970 in the new 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // system). The magic number used below is 1970 in our time units. 7965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_.get()); 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction.Begin(); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if !defined(OS_WIN) 7995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_result(db_->Execute( 8005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE cookies " 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET creation_utc = creation_utc + 11644473600000000 " 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE rowid IN " 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(SELECT rowid FROM cookies WHERE " 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "creation_utc > 0 AND creation_utc < 11644473600000000)")); 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_result(db_->Execute( 8065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE cookies " 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET expires_utc = expires_utc + 11644473600000000 " 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE rowid IN " 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(SELECT rowid FROM cookies WHERE " 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "expires_utc > 0 AND expires_utc < 11644473600000000)")); 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_result(db_->Execute( 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE cookies " 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "SET last_access_utc = last_access_utc + 11644473600000000 " 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "WHERE rowid IN " 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "(SELECT rowid FROM cookies WHERE " 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "last_access_utc > 0 AND last_access_utc < 11644473600000000)")); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_version; 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.SetVersionNumber(cur_version); 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction.Commit(); 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur_version == 4) { 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_.get()); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Begin()) 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("ALTER TABLE cookies " 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ADD COLUMN has_expires INTEGER DEFAULT 1") || 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !db_->Execute("ALTER TABLE cookies " 8315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ADD COLUMN persistent INTEGER DEFAULT 1")) { 8325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to update cookie database to version 5."; 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 8345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ++cur_version; 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.SetVersionNumber(cur_version); 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.SetCompatibleVersionNumber( 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::min(cur_version, kCompatibleVersionNumber)); 8395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transaction.Commit(); 8405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV5", 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeTicks::Now() - start_time); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 844c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (cur_version == 5) { 845c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 846c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) sql::Transaction transaction(db_.get()); 847c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!transaction.Begin()) 848c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 849c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Alter the table to add the priority column with a default value. 850c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::string stmt(base::StringPrintf( 851c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) "ALTER TABLE cookies ADD COLUMN priority INTEGER DEFAULT %d", 852c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) CookiePriorityToDBCookiePriority(net::COOKIE_PRIORITY_DEFAULT))); 853c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!db_->Execute(stmt.c_str())) { 854c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) LOG(WARNING) << "Unable to update cookie database to version 6."; 855c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return false; 856c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 857c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ++cur_version; 858c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) meta_table_.SetVersionNumber(cur_version); 859c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) meta_table_.SetCompatibleVersionNumber( 860c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) std::min(cur_version, kCompatibleVersionNumber)); 861c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) transaction.Commit(); 862c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV6", 863c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::TimeTicks::Now() - start_time); 864c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 865c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 8665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (cur_version == 6) { 8675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::TimeTicks start_time = base::TimeTicks::Now(); 8685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) sql::Transaction transaction(db_.get()); 8695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!transaction.Begin()) 8705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 8715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Alter the table to add empty "encrypted value" column. 8725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!db_->Execute("ALTER TABLE cookies " 8735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "ADD COLUMN encrypted_value BLOB DEFAULT ''")) { 8745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) LOG(WARNING) << "Unable to update cookie database to version 7."; 8755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return false; 8765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) ++cur_version; 8785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) meta_table_.SetVersionNumber(cur_version); 8795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) meta_table_.SetCompatibleVersionNumber( 8805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::min(cur_version, kCompatibleVersionNumber)); 8815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) transaction.Commit(); 8825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) UMA_HISTOGRAM_TIMES("Cookie.TimeDatabaseMigrationToV7", 8835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) base::TimeTicks::Now() - start_time); 8845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 8855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 8865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Put future migration cases here. 8875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (cur_version < kCurrentVersionNumber) { 8895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTable", 1); 8905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 8925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(new sql::Connection); 8937dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (!base::DeleteFile(path_, false) || 8945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !db_->Open(path_) || 8955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) !meta_table_.Init( 8965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.get(), kCurrentVersionNumber, kCompatibleVersionNumber)) { 8975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_COUNTS_100("Cookie.CorruptMetaTableRecoveryFailed", 1); 8985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Unable to reset the cookie DB."; 8995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 9005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 9015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return false; 9025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 9065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::AddCookie( 9095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc) { 9105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BatchOperation(PendingOperation::COOKIE_ADD, cc); 9115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::UpdateCookieAccessTime( 9145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc) { 9155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BatchOperation(PendingOperation::COOKIE_UPDATEACCESS, cc); 9165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::DeleteCookie( 9195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc) { 9205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BatchOperation(PendingOperation::COOKIE_DELETE, cc); 9215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::BatchOperation( 9245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperation::OperationType op, 9255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc) { 9265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit every 30 seconds. 9275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const int kCommitIntervalMs = 30 * 1000; 9285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit right away if we have more than 512 outstanding operations. 9295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static const size_t kCommitAfterBatchSize = 512; 9302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!background_task_runner_->RunsTasksOnCurrentThread()); 9315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We do a full copy of the cookie here, and hopefully just here. 9335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PendingOperation> po(new PendingOperation(op, cc)); 9345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperationsList::size_type num_pending; 9365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 9385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_.push_back(po.release()); 9395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pending = ++num_pending_; 9405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (num_pending == 1) { 9435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've gotten our first entry for this batch, fire off the timer. 9442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!background_task_runner_->PostDelayedTask( 9452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) FROM_HERE, base::Bind(&Backend::Commit, this), 9462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta::FromMilliseconds(kCommitIntervalMs))) { 9472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NOTREACHED() << "background_task_runner_ is not running."; 9482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (num_pending == kCommitAfterBatchSize) { 9505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We've reached a big enough batch, fire off a commit now. 9512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this)); 9525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 9545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::Commit() { 9562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 9575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PendingOperationsList ops; 9595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 9605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 9615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pending_.swap(ops); 9625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) num_pending_ = 0; 9635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 9645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Maybe an old timer fired or we are already Close()'ed. 9665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_.get() || ops.empty()) 9675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement add_smt(db_->GetCachedStatement(SQL_FROM_HERE, 9705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "INSERT INTO cookies (creation_utc, host_key, name, value, " 9715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "encrypted_value, path, expires_utc, secure, httponly, last_access_utc, " 9725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "has_expires, persistent, priority) " 9735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) "VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)")); 9745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!add_smt.is_valid()) 9755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement update_access_smt(db_->GetCachedStatement(SQL_FROM_HERE, 9785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "UPDATE cookies SET last_access_utc=? WHERE creation_utc=?")); 9795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!update_access_smt.is_valid()) 9805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement del_smt(db_->GetCachedStatement(SQL_FROM_HERE, 9835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "DELETE FROM cookies WHERE creation_utc=?")); 9845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!del_smt.is_valid()) 9855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_.get()); 9885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Begin()) 9895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 9905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 9915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (PendingOperationsList::iterator it = ops.begin(); 9925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != ops.end(); ++it) { 9935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Free the cookies as we commit them to the database. 9945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<PendingOperation> po(*it); 9955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (po->op()) { 9965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PendingOperation::COOKIE_ADD: 9975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies_per_origin_[ 9985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]++; 9995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_smt.Reset(true); 10005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue()); 10015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_smt.BindString(1, po->cc().Domain()); 10025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_smt.BindString(2, po->cc().Name()); 10035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (crypto_) { 10045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::string encrypted_value; 10055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindCString(3, ""); // value 10065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_->EncryptString(po->cc().Value(), &encrypted_value); 10075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // BindBlob() immediately makes an internal copy of the data. 10085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindBlob(4, encrypted_value.data(), 10095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static_cast<int>(encrypted_value.length())); 10105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 10115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindString(3, po->cc().Value()); 10125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindBlob(4, "", 0); // encrypted_value 10135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 10145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindString(5, po->cc().Path()); 10155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindInt64(6, po->cc().ExpiryDate().ToInternalValue()); 10165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindInt(7, po->cc().IsSecure()); 10175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindInt(8, po->cc().IsHttpOnly()); 10185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindInt64(9, po->cc().LastAccessDate().ToInternalValue()); 10195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) add_smt.BindInt(10, po->cc().IsPersistent()); 10205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) add_smt.BindInt(11, po->cc().IsPersistent()); 1021c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) add_smt.BindInt( 10225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12, CookiePriorityToDBCookiePriority(po->cc().Priority())); 10235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!add_smt.Run()) 10245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not add a cookie to the DB."; 10255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PendingOperation::COOKIE_UPDATEACCESS: 10285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_access_smt.Reset(true); 10295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_access_smt.BindInt64(0, 10305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) po->cc().LastAccessDate().ToInternalValue()); 10315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) update_access_smt.BindInt64(1, 10325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) po->cc().CreationDate().ToInternalValue()); 10335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!update_access_smt.Run()) 10345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not update cookie last access time in the DB."; 10355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case PendingOperation::COOKIE_DELETE: 10385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) cookies_per_origin_[ 10395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) CookieOrigin(po->cc().Domain(), po->cc().IsSecure())]--; 10405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del_smt.Reset(true); 10415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del_smt.BindInt64(0, po->cc().CreationDate().ToInternalValue()); 10425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!del_smt.Run()) 10435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not delete a cookie from the DB."; 10445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 10475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 10485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 10495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool succeeded = transaction.Commit(); 10525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_ENUMERATION("Cookie.BackingStoreUpdateResults", 10535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) succeeded ? 0 : 1, 2); 10545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::Flush( 10575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Closure& callback) { 10582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!background_task_runner_->RunsTasksOnCurrentThread()); 10592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind(&Backend::Commit, this)); 10602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 10615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!callback.is_null()) { 10625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We want the completion task to run immediately after Commit() returns. 10635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Posting it from here means there is less chance of another task getting 10645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // onto the message queue first, than if we posted it from Commit() itself. 10652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, callback); 10665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Fire off a close message to the background runner. We could still have a 10705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// pending commit timer or Load operations holding references on us, but if/when 10715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// this fires we will already have been cleaned up and it will be ignored. 10725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::Close() { 10732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (background_task_runner_->RunsTasksOnCurrentThread()) { 10745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InternalBackgroundClose(); 10755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 10762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Must close the backend on the background runner. 10772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, 10782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::Bind(&Backend::InternalBackgroundClose, this)); 10795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::InternalBackgroundClose() { 10832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 10845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Commit any pending operations 10855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Commit(); 10865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1087c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!force_keep_session_state_ && special_storage_policy_.get() && 1088c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) special_storage_policy_->HasSessionOnlyOrigins()) { 10895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DeleteSessionCookiesOnShutdown(); 10905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 10915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 10935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 10945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 10955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 10965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnShutdown() { 10972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 10985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1099c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!db_) 1100c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) return; 1101c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1102868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!special_storage_policy_.get()) 11035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Statement del_smt(db_->GetCachedStatement( 11065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SQL_FROM_HERE, "DELETE FROM cookies WHERE host_key=? AND secure=?")); 11075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!del_smt.is_valid()) { 11085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to delete cookies on shutdown."; 11095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) sql::Transaction transaction(db_.get()); 11135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Begin()) { 11145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to delete cookies on shutdown."; 11155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return; 11165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (CookiesPerOriginMap::iterator it = cookies_per_origin_.begin(); 11195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) it != cookies_per_origin_.end(); ++it) { 11205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (it->second <= 0) { 11215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(0, it->second); 11225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 11235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1124c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const GURL url(net::cookie_util::CookieOriginToURL(it->first.first, 1125c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) it->first.second)); 1126c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (!url.is_valid() || !special_storage_policy_->IsStorageSessionOnly(url)) 11275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) continue; 11285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del_smt.Reset(true); 11305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del_smt.BindString(0, it->first.first); 11315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) del_smt.BindInt(1, it->first.second); 11325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!del_smt.Run()) 11335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "Could not delete a cookie from the DB."; 11345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!transaction.Commit()) 11375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to delete cookies on shutdown."; 11385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1140868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::DatabaseErrorCallback( 1141868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) int error, 1142868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) sql::Statement* stmt) { 11432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 11445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1145868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (!sql::IsErrorCatastrophic(error)) 1146868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1147868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 1148868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(shess): Running KillDatabase() multiple times should be 1149868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // safe. 1150868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (corruption_detected_) 1151868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) return; 1152868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) 11535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) corruption_detected_ = true; 11545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Don't just do the close/delete here, as we are being called by |db| and 11565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // that seems dangerous. 1157868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // TODO(shess): Consider just calling RazeAndClose() immediately. 1158868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // db_ may not be safe to reset at this point, but RazeAndClose() 1159868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) // would cause the stack to unwind safely with errors. 11602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PostBackgroundTask(FROM_HERE, base::Bind(&Backend::KillDatabase, this)); 11615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::KillDatabase() { 11642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 11655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1166c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) if (db_) { 11675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // This Backend will now be in-memory only. In a future run we will recreate 11685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // the database. Hopefully things go better then! 11692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) bool success = db_->RazeAndClose(); 11705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) UMA_HISTOGRAM_BOOLEAN("Cookie.KillDatabaseResult", success); 11715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) meta_table_.Reset(); 11725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) db_.reset(); 11735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 11745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::SetForceKeepSessionState() { 11775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::AutoLock locked(lock_); 11785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) force_keep_session_state_ = true; 11795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Backend::DeleteSessionCookiesOnStartup() { 11822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(background_task_runner_->RunsTasksOnCurrentThread()); 11835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!db_->Execute("DELETE FROM cookies WHERE persistent == 0")) 11845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) LOG(WARNING) << "Unable to delete session cookies."; 11855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 11865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 11872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::PostBackgroundTask( 11882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const tracked_objects::Location& origin, const base::Closure& task) { 11892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!background_task_runner_->PostTask(origin, task)) { 11902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Failed to post task from " << origin.ToString() 11912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " to background_task_runner_."; 11922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 11932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 11942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 11952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void SQLitePersistentCookieStore::Backend::PostClientTask( 11962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const tracked_objects::Location& origin, const base::Closure& task) { 11972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (!client_task_runner_->PostTask(origin, task)) { 11982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) LOG(WARNING) << "Failed to post task from " << origin.ToString() 11992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " to client_task_runner_."; 12002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 12012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 12022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 12035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SQLitePersistentCookieStore::SQLitePersistentCookieStore( 12042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const base::FilePath& path, 12052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& client_task_runner, 12062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const scoped_refptr<base::SequencedTaskRunner>& background_task_runner, 12075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool restore_old_session_cookies, 12085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quota::SpecialStoragePolicy* special_storage_policy, 12095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieCryptoDelegate* crypto_delegate) 12102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : backend_(new Backend(path, 12112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) client_task_runner, 12122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) background_task_runner, 12132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) restore_old_session_cookies, 12145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) special_storage_policy, 12155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_delegate)) { 12165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Load(const LoadedCallback& loaded_callback) { 12195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->Load(loaded_callback); 12205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::LoadCookiesForKey( 12235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& key, 12245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const LoadedCallback& loaded_callback) { 12255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backend_->LoadCookiesForKey(key, loaded_callback); 12265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::AddCookie(const net::CanonicalCookie& cc) { 12292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->AddCookie(cc); 12305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::UpdateCookieAccessTime( 12335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const net::CanonicalCookie& cc) { 12342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->UpdateCookieAccessTime(cc); 12355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::DeleteCookie(const net::CanonicalCookie& cc) { 12382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->DeleteCookie(cc); 12395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::SetForceKeepSessionState() { 12422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->SetForceKeepSessionState(); 12435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void SQLitePersistentCookieStore::Flush(const base::Closure& callback) { 12462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->Flush(callback); 12475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 12485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 12495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)SQLitePersistentCookieStore::~SQLitePersistentCookieStore() { 12502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) backend_->Close(); 12512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // We release our reference to the Backend, though it will probably still have 12522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // a reference if the background runner has not run Close() yet. 12535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1254c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 12555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CookieStoreConfig::CookieStoreConfig() 12565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : session_cookie_mode(EPHEMERAL_SESSION_COOKIES), 12575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_delegate(NULL) { 12585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Default to an in-memory cookie store. 12590f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)} 126090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) 12615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CookieStoreConfig::CookieStoreConfig( 12625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const base::FilePath& path, 12635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SessionCookieMode session_cookie_mode, 12645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) quota::SpecialStoragePolicy* storage_policy, 12655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CookieMonsterDelegate* cookie_delegate) 12665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) : path(path), 12675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) session_cookie_mode(session_cookie_mode), 12685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) storage_policy(storage_policy), 12695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cookie_delegate(cookie_delegate), 12705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) crypto_delegate(NULL) { 12715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CHECK(!path.empty() || session_cookie_mode == EPHEMERAL_SESSION_COOKIES); 12725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)CookieStoreConfig::~CookieStoreConfig() { 12755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 12765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)net::CookieStore* CreateCookieStore(const CookieStoreConfig& config) { 12785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) net::CookieMonster* cookie_monster = NULL; 12795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (config.path.empty()) { 12815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Empty path means in-memory store. 12825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cookie_monster = new net::CookieMonster(NULL, config.cookie_delegate); 12835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } else { 12845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> client_task_runner = 12855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config.client_task_runner; 12865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) scoped_refptr<base::SequencedTaskRunner> background_task_runner = 12875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config.background_task_runner; 12885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!client_task_runner) { 12905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_task_runner = 12915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO); 12925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 12945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (!background_task_runner) { 12955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_task_runner = 12965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::GetBlockingPool()->GetSequencedTaskRunner( 12975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) BrowserThread::GetBlockingPool()->GetSequenceToken()); 12985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 12995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) SQLitePersistentCookieStore* persistent_store = 13015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new SQLitePersistentCookieStore( 13025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config.path, 13035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) client_task_runner, 13045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) background_task_runner, 13055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (config.session_cookie_mode == 13065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieStoreConfig::RESTORED_SESSION_COOKIES), 13075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config.storage_policy, 13085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) config.crypto_delegate); 13095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cookie_monster = 13115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) new net::CookieMonster(persistent_store, config.cookie_delegate); 13125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if ((config.session_cookie_mode == 13135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieStoreConfig::PERSISTANT_SESSION_COOKIES) || 13145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) (config.session_cookie_mode == 13155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CookieStoreConfig::RESTORED_SESSION_COOKIES)) { 13165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cookie_monster->SetPersistSessionCookies(true); 13175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // In the case of Android WebView, the cookie store may be created 13215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // before the browser process fully initializes -- certainly before 13225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // the main loop ever runs. In this situation, the CommandLine singleton 13235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // will not have been set up. Android tests do not need file cookies 13245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // so always ignore them here. 13255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 13265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(ajwong): Remove the InitializedForCurrentProcess() check 13275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // once http://crbug.com/331424 is resolved. 13286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) if (base::CommandLine::InitializedForCurrentProcess() && 13296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) base::CommandLine::ForCurrentProcess()->HasSwitch( 13305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) switches::kEnableFileCookies)) { 13315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) cookie_monster->SetEnableFileScheme(true); 13325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 13335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 13345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) return cookie_monster; 1335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 1336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 1337c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} // namespace content 1338