From 673336b8ef5a8708d7d3fe0dc8c3daa8d12d4097 Mon Sep 17 00:00:00 2001 From: "agl@chromium.org" Date: Thu, 3 Sep 2009 22:01:37 +0000 Subject: ForceTLS: persist to disk With this patch, we'll persist ForceTLS state to disk. It's saved as a JSON file (ForceTLSState) in the user data directory for the moment. You still need the --force-https flag in order to trigger any ForceTLS behaviour, however. For the moment, this state isn't cleared when the rest of the browser state it. That's ok because it's still behind a flag. http://codereview.chromium.org/186014 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@25382 0039d316-1c4b-4281-b951-d872f2087c98 --- chrome/browser/force_tls_persister.cc | 72 +++++++++++++++++++++++++++++++++++ chrome/browser/force_tls_persister.h | 64 +++++++++++++++++++++++++++++++ chrome/browser/profile.cc | 12 ++++-- chrome/browser/profile.h | 6 ++- chrome/chrome.gyp | 2 + 5 files changed, 150 insertions(+), 6 deletions(-) create mode 100644 chrome/browser/force_tls_persister.cc create mode 100644 chrome/browser/force_tls_persister.h (limited to 'chrome') diff --git a/chrome/browser/force_tls_persister.cc b/chrome/browser/force_tls_persister.cc new file mode 100644 index 0000000..a07f523 --- /dev/null +++ b/chrome/browser/force_tls_persister.cc @@ -0,0 +1,72 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/force_tls_persister.h" + +#include "base/file_path.h" +#include "base/file_util.h" +#include "base/message_loop.h" +#include "base/path_service.h" +#include "base/thread.h" +#include "chrome/common/chrome_paths.h" +#include "net/base/force_tls_state.h" + +ForceTLSPersister::ForceTLSPersister(net::ForceTLSState* state, + base::Thread* file_thread) + : state_is_dirty_(false), + force_tls_state_(state), + file_thread_(file_thread) { + state->SetDelegate(this); + + Task* task = NewRunnableMethod(this, &ForceTLSPersister::LoadState); + file_thread->message_loop()->PostDelayedTask(FROM_HERE, task, + 1000 /* 1 second */); +} + +static FilePath GetStateFile() { + FilePath user_data_dir; + PathService::Get(chrome::DIR_USER_DATA, &user_data_dir); + return user_data_dir.Append("ForceTLSState"); +} + +void ForceTLSPersister::LoadState() { + // Runs on |file_thread_| + AutoLock locked_(lock_); + DCHECK(file_thread_->message_loop() == MessageLoop::current()); + + std::string state; + if (!file_util::ReadFileToString(GetStateFile(), &state)) + return; + + force_tls_state_->Deserialise(state); +} + +void ForceTLSPersister::StateIsDirty(net::ForceTLSState* state) { + // Runs on arbitary thread, may not block nor reenter |force_tls_state_| + AutoLock locked_(lock_); + DCHECK(state == force_tls_state_); + + if (state_is_dirty_) + return; // we already have a serialisation scheduled + + Task* task = NewRunnableMethod(this, &ForceTLSPersister::SerialiseState); + file_thread_->message_loop()->PostDelayedTask(FROM_HERE, task, + 1000 /* 1 second */); + state_is_dirty_ = true; +} + +void ForceTLSPersister::SerialiseState() { + // Runs on |file_thread_| + AutoLock locked_(lock_); + DCHECK(file_thread_->message_loop() == MessageLoop::current()); + + DCHECK(state_is_dirty_); + state_is_dirty_ = false; + + std::string state; + if (!force_tls_state_->Serialise(&state)) + return; + + file_util::WriteFile(GetStateFile(), state.data(), state.size()); +} diff --git a/chrome/browser/force_tls_persister.h b/chrome/browser/force_tls_persister.h new file mode 100644 index 0000000..be4c17d --- /dev/null +++ b/chrome/browser/force_tls_persister.h @@ -0,0 +1,64 @@ +// Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// ForceTLSState maintains an in memory database containing the list of hosts +// that currently have ForceTLS enabled. This singleton object deals with +// writing that data out to disk as needed and loading it at startup. + +// At startup we need to load the ForceTLS state from the disk. For the moment, +// we don't want to delay startup for this load, so we let the ForceTLSState +// run for a while without being loaded. This means that it's possible for +// pages opened very quickly not to get the correct ForceTLS information. +// +// To load the state, we schedule a Task on the file thread which loads, +// deserialises and configures the ForceTLSState. +// +// The ForceTLSState object supports running a callback function when it +// changes. This object registers the callback, pointing at itself. +// +// ForceTLSState calls... +// ForceTLSPersister::StateIsDirty +// since the callback isn't allowed to block or reenter, we schedule a Task +// on |file_thread_| after some small amount of time +// +// ... +// +// ForceTLSPersister::SerialiseState +// copies the current state of the ForceTLSState, serialises and writes to +// disk. + +#include "base/lock.h" +#include "base/ref_counted.h" +#include "net/base/force_tls_state.h" + +namespace base { +class Thread; +} + +class ForceTLSPersister : public base::RefCountedThreadSafe, + public net::ForceTLSState::Delegate { + public: + ForceTLSPersister(net::ForceTLSState* state, base::Thread* file_thread); + + // Called by the ForceTLSState when it changes its state. + virtual void StateIsDirty(net::ForceTLSState*); + + private: + // a Task callback for when the state needs to be written out. + void SerialiseState(); + + // a Task callback for when the state needs to be loaded from disk at startup. + void LoadState(); + + Lock lock_; // protects all the members + + // true when the state object has signaled that we're dirty and we haven't + // serialised the state yet. + bool state_is_dirty_; + + scoped_refptr force_tls_state_; + + // This is a thread which can perform file access. + base::Thread* const file_thread_; +}; diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 1aa04e8..a8377d3 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -20,6 +20,7 @@ #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/extensions/user_script_master.h" #include "chrome/browser/favicon_service.h" +#include "chrome/browser/force_tls_persister.h" #include "chrome/browser/history/history.h" #include "chrome/browser/in_process_webkit/webkit_context.h" #include "chrome/browser/net/chrome_url_request_context.h" @@ -264,7 +265,7 @@ class OffTheRecordProfileImpl : public Profile, virtual net::ForceTLSState* GetForceTLSState() { if (!force_tls_state_.get()) - force_tls_state_.reset(new net::ForceTLSState()); + force_tls_state_ = new net::ForceTLSState(); return force_tls_state_.get(); } @@ -521,7 +522,7 @@ class OffTheRecordProfileImpl : public Profile, scoped_ptr ssl_host_state_; // The ForceTLSState that only stores enabled sites in memory. - scoped_ptr force_tls_state_; + scoped_refptr force_tls_state_; // Time we were started. Time start_time_; @@ -823,8 +824,11 @@ SSLHostState* ProfileImpl::GetSSLHostState() { } net::ForceTLSState* ProfileImpl::GetForceTLSState() { - if (!force_tls_state_.get()) - force_tls_state_.reset(new net::ForceTLSState()); + if (!force_tls_state_.get()) { + force_tls_state_ = new net::ForceTLSState(); + force_tls_persister_ = new ForceTLSPersister( + force_tls_state_.get(), g_browser_process->file_thread()); + } return force_tls_state_.get(); } diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h index 83ae64c..97e747b 100644 --- a/chrome/browser/profile.h +++ b/chrome/browser/profile.h @@ -34,6 +34,7 @@ class ExtensionProcessManager; class ExtensionMessageService; class ExtensionsService; class FaviconService; +class ForceTLSPersister; class HistoryService; class NavigationController; class PasswordStore; @@ -154,7 +155,7 @@ class Profile { // called. virtual SSLHostState* GetSSLHostState() = 0; - // Retrieves a pointer to the ForceTLStSate associated with this profile. + // Retrieves a pointer to the ForceTLSState associated with this profile. // The ForceTLSState is lazily created the first time that this method is // called. virtual net::ForceTLSState* GetForceTLSState() = 0; @@ -460,7 +461,8 @@ class ProfileImpl : public Profile, scoped_ptr extension_process_manager_; scoped_refptr extension_message_service_; scoped_ptr ssl_host_state_; - scoped_ptr force_tls_state_; + scoped_refptr force_tls_state_; + scoped_refptr force_tls_persister_; scoped_ptr prefs_; scoped_refptr thumbnail_store_; scoped_ptr template_url_fetcher_; diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index 6563807..c65b15a 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -1163,6 +1163,8 @@ 'browser/external_protocol_handler.h', 'browser/external_tab_container.cc', 'browser/external_tab_container.h', + 'browser/force_tls_persister.cc', + 'browser/force_tls_persister.h', 'browser/global_keyboard_shortcuts_mac.h', 'browser/global_keyboard_shortcuts_mac.mm', 'browser/fav_icon_helper.cc', -- cgit v1.1