From 662626649fb422d8c1d33cf76774364e9307516a Mon Sep 17 00:00:00 2001 From: "rtenneti@chromium.org" Date: Sat, 25 Jan 2014 00:54:41 +0000 Subject: Renamed disk_cache_based_ssl_host_info.* to disk_cache_based_quic_server_info.*. Renamed ssl_host_info.* to quic_server_info.*. Deleted all SSLConfig and CertVerifier related code. Replaced them with QuicCryptoClientConfig::CachedState. Will fill out the details in quic_server_info (persist/restore code) in the next CL. R=wtc@chromium.org Review URL: https://codereview.chromium.org/140823019 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@247044 0039d316-1c4b-4281-b951-d872f2087c98 --- net/http/disk_cache_based_quic_server_info.cc | 279 ++++++++++++++++++++ net/http/disk_cache_based_quic_server_info.h | 103 ++++++++ .../disk_cache_based_quic_server_info_unittest.cc | 108 ++++++++ net/http/disk_cache_based_ssl_host_info.cc | 281 --------------------- net/http/disk_cache_based_ssl_host_info.h | 106 -------- .../disk_cache_based_ssl_host_info_unittest.cc | 119 --------- net/http/http_cache.cc | 24 +- net/http/http_cache.h | 4 +- net/http/http_cache_transaction.cc | 2 +- net/http/http_network_session.cc | 2 +- net/http/http_network_session.h | 4 +- net/http/http_transaction.h | 8 +- 12 files changed, 509 insertions(+), 531 deletions(-) create mode 100644 net/http/disk_cache_based_quic_server_info.cc create mode 100644 net/http/disk_cache_based_quic_server_info.h create mode 100644 net/http/disk_cache_based_quic_server_info_unittest.cc delete mode 100644 net/http/disk_cache_based_ssl_host_info.cc delete mode 100644 net/http/disk_cache_based_ssl_host_info.h delete mode 100644 net/http/disk_cache_based_ssl_host_info_unittest.cc (limited to 'net/http') diff --git a/net/http/disk_cache_based_quic_server_info.cc b/net/http/disk_cache_based_quic_server_info.cc new file mode 100644 index 0000000..aa322ab --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info.cc @@ -0,0 +1,279 @@ +// Copyright 2014 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 "net/http/disk_cache_based_quic_server_info.h" + +#include "base/bind.h" +#include "base/callback.h" +#include "base/logging.h" +#include "net/base/completion_callback.h" +#include "net/base/io_buffer.h" +#include "net/base/net_errors.h" +#include "net/http/http_cache.h" +#include "net/http/http_network_session.h" + +namespace net { + +// Some APIs inside disk_cache take a handle that the caller must keep alive +// until the API has finished its asynchronous execution. +// +// Unfortunately, DiskCacheBasedQuicServerInfo may be deleted before the +// operation completes causing a use-after-free. +// +// This data shim struct is meant to provide a location for the disk_cache +// APIs to write into even if the originating DiskCacheBasedQuicServerInfo +// object has been deleted. The lifetime for instances of this struct +// should be bound to the CompletionCallback that is passed to the disk_cache +// API. We do this by binding an instance of this struct to an unused +// parameter for OnIOComplete() using base::Owned(). +// +// This is a hack. A better fix is to make it so that the disk_cache APIs +// take a Callback to a mutator for setting the output value rather than +// writing into a raw handle. Then the caller can just pass in a Callback +// bound to WeakPtr for itself. This callback would correctly "no-op" itself +// when the DiskCacheBasedQuicServerInfo object is deleted. +// +// TODO(ajwong): Change disk_cache's API to return results via Callback. +struct DiskCacheBasedQuicServerInfo::CacheOperationDataShim { + CacheOperationDataShim() : backend(NULL), entry(NULL) {} + + disk_cache::Backend* backend; + disk_cache::Entry* entry; +}; + +DiskCacheBasedQuicServerInfo::DiskCacheBasedQuicServerInfo( + const std::string& hostname, + HttpCache* http_cache) + : QuicServerInfo(hostname), + weak_factory_(this), + data_shim_(new CacheOperationDataShim()), + io_callback_( + base::Bind(&DiskCacheBasedQuicServerInfo::OnIOComplete, + weak_factory_.GetWeakPtr(), + base::Owned(data_shim_))), // Ownership assigned. + state_(GET_BACKEND), + ready_(false), + found_entry_(false), + hostname_(hostname), + http_cache_(http_cache), + backend_(NULL), + entry_(NULL) { +} + +void DiskCacheBasedQuicServerInfo::Start() { + DCHECK(CalledOnValidThread()); + DCHECK_EQ(GET_BACKEND, state_); + DoLoop(OK); +} + +int DiskCacheBasedQuicServerInfo::WaitForDataReady( + const CompletionCallback& callback) { + DCHECK(CalledOnValidThread()); + DCHECK(state_ != GET_BACKEND); + + if (ready_) + return OK; + + if (!callback.is_null()) { + DCHECK(user_callback_.is_null()); + user_callback_ = callback; + } + + return ERR_IO_PENDING; +} + +void DiskCacheBasedQuicServerInfo::Persist() { + DCHECK(CalledOnValidThread()); + DCHECK(state_ != GET_BACKEND); + + DCHECK(new_data_.empty()); + CHECK(ready_); + DCHECK(user_callback_.is_null()); + new_data_ = Serialize(); + + if (!backend_) + return; + + state_ = CREATE_OR_OPEN; + DoLoop(OK); +} + +DiskCacheBasedQuicServerInfo::~DiskCacheBasedQuicServerInfo() { + DCHECK(user_callback_.is_null()); + if (entry_) + entry_->Close(); +} + +std::string DiskCacheBasedQuicServerInfo::key() const { + return "quicserverinfo:" + hostname_; +} + +void DiskCacheBasedQuicServerInfo::OnIOComplete(CacheOperationDataShim* unused, + int rv) { + rv = DoLoop(rv); + if (rv != ERR_IO_PENDING && !user_callback_.is_null()) { + CompletionCallback callback = user_callback_; + user_callback_.Reset(); + callback.Run(rv); + } +} + +int DiskCacheBasedQuicServerInfo::DoLoop(int rv) { + do { + switch (state_) { + case GET_BACKEND: + rv = DoGetBackend(); + break; + case GET_BACKEND_COMPLETE: + rv = DoGetBackendComplete(rv); + break; + case OPEN: + rv = DoOpen(); + break; + case OPEN_COMPLETE: + rv = DoOpenComplete(rv); + break; + case READ: + rv = DoRead(); + break; + case READ_COMPLETE: + rv = DoReadComplete(rv); + break; + case WAIT_FOR_DATA_READY_DONE: + rv = DoWaitForDataReadyDone(); + break; + case CREATE_OR_OPEN: + rv = DoCreateOrOpen(); + break; + case CREATE_OR_OPEN_COMPLETE: + rv = DoCreateOrOpenComplete(rv); + break; + case WRITE: + rv = DoWrite(); + break; + case WRITE_COMPLETE: + rv = DoWriteComplete(rv); + break; + case SET_DONE: + rv = DoSetDone(); + break; + default: + rv = OK; + NOTREACHED(); + } + } while (rv != ERR_IO_PENDING && state_ != NONE); + + return rv; +} + +int DiskCacheBasedQuicServerInfo::DoGetBackendComplete(int rv) { + if (rv == OK) { + backend_ = data_shim_->backend; + state_ = OPEN; + } else { + state_ = WAIT_FOR_DATA_READY_DONE; + } + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoOpenComplete(int rv) { + if (rv == OK) { + entry_ = data_shim_->entry; + state_ = READ; + found_entry_ = true; + } else { + state_ = WAIT_FOR_DATA_READY_DONE; + } + + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoReadComplete(int rv) { + if (rv > 0) + data_.assign(read_buffer_->data(), rv); + + state_ = WAIT_FOR_DATA_READY_DONE; + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoWriteComplete(int rv) { + state_ = SET_DONE; + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoCreateOrOpenComplete(int rv) { + if (rv != OK) { + state_ = SET_DONE; + } else { + entry_ = data_shim_->entry; + state_ = WRITE; + } + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoGetBackend() { + state_ = GET_BACKEND_COMPLETE; + return http_cache_->GetBackend(&data_shim_->backend, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoOpen() { + state_ = OPEN_COMPLETE; + return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoRead() { + const int32 size = entry_->GetDataSize(0 /* index */); + if (!size) { + state_ = WAIT_FOR_DATA_READY_DONE; + return OK; + } + + read_buffer_ = new IOBuffer(size); + state_ = READ_COMPLETE; + return entry_->ReadData( + 0 /* index */, 0 /* offset */, read_buffer_, size, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoWrite() { + write_buffer_ = new IOBuffer(new_data_.size()); + memcpy(write_buffer_->data(), new_data_.data(), new_data_.size()); + state_ = WRITE_COMPLETE; + + return entry_->WriteData( + 0 /* index */, 0 /* offset */, write_buffer_, new_data_.size(), + io_callback_, true /* truncate */); +} + +int DiskCacheBasedQuicServerInfo::DoCreateOrOpen() { + DCHECK(entry_ == NULL); + state_ = CREATE_OR_OPEN_COMPLETE; + if (found_entry_) { + return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); + } + + return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); +} + +int DiskCacheBasedQuicServerInfo::DoWaitForDataReadyDone() { + DCHECK(!ready_); + state_ = NONE; + ready_ = true; + // We close the entry because, if we shutdown before ::Persist is called, + // then we might leak a cache reference, which causes a DCHECK on shutdown. + if (entry_) + entry_->Close(); + entry_ = NULL; + Parse(data_); + return OK; +} + +int DiskCacheBasedQuicServerInfo::DoSetDone() { + if (entry_) + entry_->Close(); + entry_ = NULL; + state_ = NONE; + return OK; +} + +} // namespace net diff --git a/net/http/disk_cache_based_quic_server_info.h b/net/http/disk_cache_based_quic_server_info.h new file mode 100644 index 0000000..578756c --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info.h @@ -0,0 +1,103 @@ +// Copyright 2014 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. + +#ifndef NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_ +#define NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_ + +#include + +#include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" +#include "base/threading/non_thread_safe.h" +#include "net/base/completion_callback.h" +#include "net/disk_cache/disk_cache.h" +#include "net/quic/crypto/quic_server_info.h" + +namespace net { + +class HttpCache; +class IOBuffer; + +// DiskCacheBasedQuicServerInfo fetches information about a QUIC server from +// our standard disk cache. Since the information is defined to be +// non-sensitive, it's ok for us to keep it on disk. +class NET_EXPORT_PRIVATE DiskCacheBasedQuicServerInfo + : public QuicServerInfo, + public NON_EXPORTED_BASE(base::NonThreadSafe) { + public: + DiskCacheBasedQuicServerInfo(const std::string& hostname, + HttpCache* http_cache); + + // QuicServerInfo implementation. + virtual void Start() OVERRIDE; + virtual int WaitForDataReady(const CompletionCallback& callback) OVERRIDE; + virtual void Persist() OVERRIDE; + + private: + struct CacheOperationDataShim; + enum State { + GET_BACKEND, + GET_BACKEND_COMPLETE, + OPEN, + OPEN_COMPLETE, + READ, + READ_COMPLETE, + WAIT_FOR_DATA_READY_DONE, + CREATE_OR_OPEN, + CREATE_OR_OPEN_COMPLETE, + WRITE, + WRITE_COMPLETE, + SET_DONE, + NONE, + }; + + virtual ~DiskCacheBasedQuicServerInfo(); + + std::string key() const; + + // The |unused| parameter is a small hack so that we can have the + // CacheOperationDataShim object owned by the Callback that is created for + // this method. See comment above CacheOperationDataShim for details. + void OnIOComplete(CacheOperationDataShim* unused, int rv); + + int DoLoop(int rv); + + int DoGetBackendComplete(int rv); + int DoOpenComplete(int rv); + int DoReadComplete(int rv); + int DoWriteComplete(int rv); + int DoCreateOrOpenComplete(int rv); + + int DoGetBackend(); + int DoOpen(); + int DoRead(); + int DoWrite(); + int DoCreateOrOpen(); + + // DoWaitForDataReadyDone is the terminal state of the read operation. + int DoWaitForDataReadyDone(); + + // DoSetDone is the terminal state of the write operation. + int DoSetDone(); + + base::WeakPtrFactory weak_factory_; + CacheOperationDataShim* data_shim_; // Owned by |io_callback_|. + CompletionCallback io_callback_; + State state_; + bool ready_; + bool found_entry_; // Controls the behavior of DoCreateOrOpen. + std::string new_data_; + const std::string hostname_; + HttpCache* const http_cache_; + disk_cache::Backend* backend_; + disk_cache::Entry* entry_; + CompletionCallback user_callback_; + scoped_refptr read_buffer_; + scoped_refptr write_buffer_; + std::string data_; +}; + +} // namespace net + +#endif // NET_HTTP_DISK_CACHE_BASED_QUIC_SERVER_INFO_H_ diff --git a/net/http/disk_cache_based_quic_server_info_unittest.cc b/net/http/disk_cache_based_quic_server_info_unittest.cc new file mode 100644 index 0000000..9d5af3f --- /dev/null +++ b/net/http/disk_cache_based_quic_server_info_unittest.cc @@ -0,0 +1,108 @@ +// Copyright 2014 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 "base/bind.h" +#include "base/bind_helpers.h" +#include "base/compiler_specific.h" +#include "base/message_loop/message_loop.h" +#include "net/base/net_errors.h" +#include "net/http/disk_cache_based_quic_server_info.h" +#include "net/http/mock_http_cache.h" +#include "net/quic/crypto/quic_server_info.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace { + +// This is an empty transaction, needed to register the URL and the test mode. +const MockTransaction kHostInfoTransaction = { + "quicserverinfo:https://www.google.com", + "", + base::Time(), + "", + net::LOAD_NORMAL, + "", + "", + base::Time(), + "", + TEST_MODE_NORMAL, + NULL, + 0 +}; + +// Tests that we can delete a DiskCacheBasedQuicServerInfo object in a +// completion callback for DiskCacheBasedQuicServerInfo::WaitForDataReady. +TEST(DiskCacheBasedQuicServerInfo, DeleteInCallback) { + // Use the blocking mock backend factory to force asynchronous completion + // of quic_server_info->WaitForDataReady(), so that the callback will run. + MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); + MockHttpCache cache(factory); + scoped_ptr quic_server_info( + new net::DiskCacheBasedQuicServerInfo("https://www.verisign.com", + cache.http_cache())); + quic_server_info->Start(); + net::TestCompletionCallback callback; + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_EQ(net::ERR_IO_PENDING, rv); + // Now complete the backend creation and let the callback run. + factory->FinishCreation(); + EXPECT_EQ(net::OK, callback.GetResult(rv)); +} + +// Tests the basic logic of storing, retrieving and updating data. +TEST(DiskCacheBasedQuicServerInfo, Update) { + MockHttpCache cache; + AddMockTransaction(&kHostInfoTransaction); + net::TestCompletionCallback callback; + + scoped_ptr quic_server_info( + new net::DiskCacheBasedQuicServerInfo("https://www.google.com", + cache.http_cache())); + quic_server_info->Start(); + int rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_EQ(net::OK, callback.GetResult(rv)); + + net::QuicServerInfo::State* state = quic_server_info->mutable_state(); + // TODO(rtenneti): Flesh out details of net::QuicServerInfo::State. + EXPECT_TRUE(state->data.empty()); + state->data.push_back(std::string("foo")); + quic_server_info->Persist(); + + // Wait until Persist() does the work. + base::MessageLoop::current()->RunUntilIdle(); + + // Open the stored net::QuicCryptoClientConfig::CachedState. + quic_server_info.reset( + new net::DiskCacheBasedQuicServerInfo("https://www.google.com", + cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_EQ(net::OK, callback.GetResult(rv)); + + // And now update the data. + state = quic_server_info->mutable_state(); + // TODO(rtenneti): Flesh out details of net::QuicServerInfo::State. + // Verify the data after we implement save and restore of the data. + state->data.push_back(std::string("bar")); + + // Fail instead of DCHECKing double creates. + cache.disk_cache()->set_double_create_check(false); + quic_server_info->Persist(); + base::MessageLoop::current()->RunUntilIdle(); + + // Verify that the state was updated. + quic_server_info.reset( + new net::DiskCacheBasedQuicServerInfo("https://www.google.com", + cache.http_cache())); + quic_server_info->Start(); + rv = quic_server_info->WaitForDataReady(callback.callback()); + EXPECT_EQ(net::OK, callback.GetResult(rv)); + + state = quic_server_info->mutable_state(); + // TODO(rtenneti): Flesh out details of net::QuicServerInfo::State. + // Verify the data after we implement save and restore of the data. + + RemoveMockTransaction(&kHostInfoTransaction); +} + +} // namespace diff --git a/net/http/disk_cache_based_ssl_host_info.cc b/net/http/disk_cache_based_ssl_host_info.cc deleted file mode 100644 index c847c74..0000000 --- a/net/http/disk_cache_based_ssl_host_info.cc +++ /dev/null @@ -1,281 +0,0 @@ -// Copyright 2014 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 "net/http/disk_cache_based_ssl_host_info.h" - -#include "base/bind.h" -#include "base/callback.h" -#include "base/logging.h" -#include "net/base/completion_callback.h" -#include "net/base/io_buffer.h" -#include "net/base/net_errors.h" -#include "net/http/http_cache.h" -#include "net/http/http_network_session.h" - -namespace net { - -// Some APIs inside disk_cache take a handle that the caller must keep alive -// until the API has finished its asynchronous execution. -// -// Unfortunately, DiskCacheBasedSSLHostInfo may be deleted before the -// operation completes causing a use-after-free. -// -// This data shim struct is meant to provide a location for the disk_cache -// APIs to write into even if the originating DiskCacheBasedSSLHostInfo -// object has been deleted. The lifetime for instances of this struct -// should be bound to the CompletionCallback that is passed to the disk_cache -// API. We do this by binding an instance of this struct to an unused -// parameter for OnIOComplete() using base::Owned(). -// -// This is a hack. A better fix is to make it so that the disk_cache APIs -// take a Callback to a mutator for setting the output value rather than -// writing into a raw handle. Then the caller can just pass in a Callback -// bound to WeakPtr for itself. This callback would correctly "no-op" itself -// when the DiskCacheBasedSSLHostInfo object is deleted. -// -// TODO(ajwong): Change disk_cache's API to return results via Callback. -struct DiskCacheBasedSSLHostInfo::CacheOperationDataShim { - CacheOperationDataShim() : backend(NULL), entry(NULL) {} - - disk_cache::Backend* backend; - disk_cache::Entry* entry; -}; - -DiskCacheBasedSSLHostInfo::DiskCacheBasedSSLHostInfo( - const std::string& hostname, - const SSLConfig& ssl_config, - CertVerifier* cert_verifier, - HttpCache* http_cache) - : SSLHostInfo(hostname, ssl_config, cert_verifier), - weak_factory_(this), - data_shim_(new CacheOperationDataShim()), - io_callback_( - base::Bind(&DiskCacheBasedSSLHostInfo::OnIOComplete, - weak_factory_.GetWeakPtr(), - base::Owned(data_shim_))), // Ownership assigned. - state_(GET_BACKEND), - ready_(false), - found_entry_(false), - hostname_(hostname), - http_cache_(http_cache), - backend_(NULL), - entry_(NULL) { -} - -void DiskCacheBasedSSLHostInfo::Start() { - DCHECK(CalledOnValidThread()); - DCHECK_EQ(GET_BACKEND, state_); - DoLoop(OK); -} - -int DiskCacheBasedSSLHostInfo::WaitForDataReady( - const CompletionCallback& callback) { - DCHECK(CalledOnValidThread()); - DCHECK(state_ != GET_BACKEND); - - if (ready_) - return OK; - - if (!callback.is_null()) { - DCHECK(user_callback_.is_null()); - user_callback_ = callback; - } - - return ERR_IO_PENDING; -} - -void DiskCacheBasedSSLHostInfo::Persist() { - DCHECK(CalledOnValidThread()); - DCHECK(state_ != GET_BACKEND); - - DCHECK(new_data_.empty()); - CHECK(ready_); - DCHECK(user_callback_.is_null()); - new_data_ = Serialize(); - - if (!backend_) - return; - - state_ = CREATE_OR_OPEN; - DoLoop(OK); -} - -DiskCacheBasedSSLHostInfo::~DiskCacheBasedSSLHostInfo() { - DCHECK(user_callback_.is_null()); - if (entry_) - entry_->Close(); -} - -std::string DiskCacheBasedSSLHostInfo::key() const { - return "sslhostinfo:" + hostname_; -} - -void DiskCacheBasedSSLHostInfo::OnIOComplete(CacheOperationDataShim* unused, - int rv) { - rv = DoLoop(rv); - if (rv != ERR_IO_PENDING && !user_callback_.is_null()) { - CompletionCallback callback = user_callback_; - user_callback_.Reset(); - callback.Run(rv); - } -} - -int DiskCacheBasedSSLHostInfo::DoLoop(int rv) { - do { - switch (state_) { - case GET_BACKEND: - rv = DoGetBackend(); - break; - case GET_BACKEND_COMPLETE: - rv = DoGetBackendComplete(rv); - break; - case OPEN: - rv = DoOpen(); - break; - case OPEN_COMPLETE: - rv = DoOpenComplete(rv); - break; - case READ: - rv = DoRead(); - break; - case READ_COMPLETE: - rv = DoReadComplete(rv); - break; - case WAIT_FOR_DATA_READY_DONE: - rv = DoWaitForDataReadyDone(); - break; - case CREATE_OR_OPEN: - rv = DoCreateOrOpen(); - break; - case CREATE_OR_OPEN_COMPLETE: - rv = DoCreateOrOpenComplete(rv); - break; - case WRITE: - rv = DoWrite(); - break; - case WRITE_COMPLETE: - rv = DoWriteComplete(rv); - break; - case SET_DONE: - rv = DoSetDone(); - break; - default: - rv = OK; - NOTREACHED(); - } - } while (rv != ERR_IO_PENDING && state_ != NONE); - - return rv; -} - -int DiskCacheBasedSSLHostInfo::DoGetBackendComplete(int rv) { - if (rv == OK) { - backend_ = data_shim_->backend; - state_ = OPEN; - } else { - state_ = WAIT_FOR_DATA_READY_DONE; - } - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoOpenComplete(int rv) { - if (rv == OK) { - entry_ = data_shim_->entry; - state_ = READ; - found_entry_ = true; - } else { - state_ = WAIT_FOR_DATA_READY_DONE; - } - - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoReadComplete(int rv) { - if (rv > 0) - data_.assign(read_buffer_->data(), rv); - - state_ = WAIT_FOR_DATA_READY_DONE; - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoWriteComplete(int rv) { - state_ = SET_DONE; - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoCreateOrOpenComplete(int rv) { - if (rv != OK) { - state_ = SET_DONE; - } else { - entry_ = data_shim_->entry; - state_ = WRITE; - } - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoGetBackend() { - state_ = GET_BACKEND_COMPLETE; - return http_cache_->GetBackend(&data_shim_->backend, io_callback_); -} - -int DiskCacheBasedSSLHostInfo::DoOpen() { - state_ = OPEN_COMPLETE; - return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); -} - -int DiskCacheBasedSSLHostInfo::DoRead() { - const int32 size = entry_->GetDataSize(0 /* index */); - if (!size) { - state_ = WAIT_FOR_DATA_READY_DONE; - return OK; - } - - read_buffer_ = new IOBuffer(size); - state_ = READ_COMPLETE; - return entry_->ReadData( - 0 /* index */, 0 /* offset */, read_buffer_, size, io_callback_); -} - -int DiskCacheBasedSSLHostInfo::DoWrite() { - write_buffer_ = new IOBuffer(new_data_.size()); - memcpy(write_buffer_->data(), new_data_.data(), new_data_.size()); - state_ = WRITE_COMPLETE; - - return entry_->WriteData( - 0 /* index */, 0 /* offset */, write_buffer_, new_data_.size(), - io_callback_, true /* truncate */); -} - -int DiskCacheBasedSSLHostInfo::DoCreateOrOpen() { - DCHECK(entry_ == NULL); - state_ = CREATE_OR_OPEN_COMPLETE; - if (found_entry_) { - return backend_->OpenEntry(key(), &data_shim_->entry, io_callback_); - } - - return backend_->CreateEntry(key(), &data_shim_->entry, io_callback_); -} - -int DiskCacheBasedSSLHostInfo::DoWaitForDataReadyDone() { - DCHECK(!ready_); - state_ = NONE; - ready_ = true; - // We close the entry because, if we shutdown before ::Persist is called, - // then we might leak a cache reference, which causes a DCHECK on shutdown. - if (entry_) - entry_->Close(); - entry_ = NULL; - Parse(data_); - return OK; -} - -int DiskCacheBasedSSLHostInfo::DoSetDone() { - if (entry_) - entry_->Close(); - entry_ = NULL; - state_ = NONE; - return OK; -} - -} // namespace net diff --git a/net/http/disk_cache_based_ssl_host_info.h b/net/http/disk_cache_based_ssl_host_info.h deleted file mode 100644 index 223ba62..0000000 --- a/net/http/disk_cache_based_ssl_host_info.h +++ /dev/null @@ -1,106 +0,0 @@ -// Copyright 2014 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. - -#ifndef NET_HTTP_DISK_CACHE_BASED_SSL_HOST_INFO_H_ -#define NET_HTTP_DISK_CACHE_BASED_SSL_HOST_INFO_H_ - -#include - -#include "base/memory/ref_counted.h" -#include "base/memory/weak_ptr.h" -#include "base/threading/non_thread_safe.h" -#include "net/base/completion_callback.h" -#include "net/disk_cache/disk_cache.h" -#include "net/socket/ssl_host_info.h" - -namespace net { - -class HttpCache; -class IOBuffer; -struct SSLConfig; - -// DiskCacheBasedSSLHostInfo fetches information about an SSL host from our -// standard disk cache. Since the information is defined to be non-sensitive, -// it's ok for us to keep it on disk. -class NET_EXPORT_PRIVATE DiskCacheBasedSSLHostInfo - : public SSLHostInfo, - public NON_EXPORTED_BASE(base::NonThreadSafe) { - public: - DiskCacheBasedSSLHostInfo(const std::string& hostname, - const SSLConfig& ssl_config, - CertVerifier* cert_verifier, - HttpCache* http_cache); - - // SSLHostInfo implementation. - virtual void Start() OVERRIDE; - virtual int WaitForDataReady(const CompletionCallback& callback) OVERRIDE; - virtual void Persist() OVERRIDE; - - private: - struct CacheOperationDataShim; - enum State { - GET_BACKEND, - GET_BACKEND_COMPLETE, - OPEN, - OPEN_COMPLETE, - READ, - READ_COMPLETE, - WAIT_FOR_DATA_READY_DONE, - CREATE_OR_OPEN, - CREATE_OR_OPEN_COMPLETE, - WRITE, - WRITE_COMPLETE, - SET_DONE, - NONE, - }; - - virtual ~DiskCacheBasedSSLHostInfo(); - - std::string key() const; - - // The |unused| parameter is a small hack so that we can have the - // CacheOperationDataShim object owned by the Callback that is created for - // this method. See comment above CacheOperationDataShim for details. - void OnIOComplete(CacheOperationDataShim* unused, int rv); - - int DoLoop(int rv); - - int DoGetBackendComplete(int rv); - int DoOpenComplete(int rv); - int DoReadComplete(int rv); - int DoWriteComplete(int rv); - int DoCreateOrOpenComplete(int rv); - - int DoGetBackend(); - int DoOpen(); - int DoRead(); - int DoWrite(); - int DoCreateOrOpen(); - - // DoWaitForDataReadyDone is the terminal state of the read operation. - int DoWaitForDataReadyDone(); - - // DoSetDone is the terminal state of the write operation. - int DoSetDone(); - - base::WeakPtrFactory weak_factory_; - CacheOperationDataShim* data_shim_; // Owned by |io_callback_|. - CompletionCallback io_callback_; - State state_; - bool ready_; - bool found_entry_; // Controls the behavior of DoCreateOrOpen. - std::string new_data_; - const std::string hostname_; - HttpCache* const http_cache_; - disk_cache::Backend* backend_; - disk_cache::Entry* entry_; - CompletionCallback user_callback_; - scoped_refptr read_buffer_; - scoped_refptr write_buffer_; - std::string data_; -}; - -} // namespace net - -#endif // NET_HTTP_DISK_CACHE_BASED_SSL_HOST_INFO_H_ diff --git a/net/http/disk_cache_based_ssl_host_info_unittest.cc b/net/http/disk_cache_based_ssl_host_info_unittest.cc deleted file mode 100644 index a415f0e..0000000 --- a/net/http/disk_cache_based_ssl_host_info_unittest.cc +++ /dev/null @@ -1,119 +0,0 @@ -// Copyright 2014 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 "base/bind.h" -#include "base/bind_helpers.h" -#include "base/compiler_specific.h" -#include "base/message_loop/message_loop.h" -#include "net/base/net_errors.h" -#include "net/cert/mock_cert_verifier.h" -#include "net/http/disk_cache_based_ssl_host_info.h" -#include "net/http/mock_http_cache.h" -#include "net/socket/ssl_host_info.h" -#include "net/ssl/ssl_config_service.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace { - -// This is an empty transaction, needed to register the URL and the test mode. -const MockTransaction kHostInfoTransaction = { - "sslhostinfo:https://www.google.com", - "", - base::Time(), - "", - net::LOAD_NORMAL, - "", - "", - base::Time(), - "", - TEST_MODE_NORMAL, - NULL, - 0 -}; - -// Tests that we can delete a DiskCacheBasedSSLHostInfo object in a -// completion callback for DiskCacheBasedSSLHostInfo::WaitForDataReady. -TEST(DiskCacheBasedSSLHostInfo, DeleteInCallback) { - scoped_ptr cert_verifier(new net::MockCertVerifier); - // Use the blocking mock backend factory to force asynchronous completion - // of ssl_host_info->WaitForDataReady(), so that the callback will run. - MockBlockingBackendFactory* factory = new MockBlockingBackendFactory(); - MockHttpCache cache(factory); - net::SSLConfig ssl_config; - scoped_ptr ssl_host_info( - new net::DiskCacheBasedSSLHostInfo("https://www.verisign.com", ssl_config, - cert_verifier.get(), - cache.http_cache())); - ssl_host_info->Start(); - net::TestCompletionCallback callback; - int rv = ssl_host_info->WaitForDataReady(callback.callback()); - EXPECT_EQ(net::ERR_IO_PENDING, rv); - // Now complete the backend creation and let the callback run. - factory->FinishCreation(); - EXPECT_EQ(net::OK, callback.GetResult(rv)); -} - -// Tests the basic logic of storing, retrieving and updating data. -TEST(DiskCacheBasedSSLHostInfo, Update) { - MockHttpCache cache; - AddMockTransaction(&kHostInfoTransaction); - net::TestCompletionCallback callback; - - // Store a certificate chain. - scoped_ptr cert_verifier(new net::MockCertVerifier); - net::SSLConfig ssl_config; - scoped_ptr ssl_host_info( - new net::DiskCacheBasedSSLHostInfo("https://www.google.com", ssl_config, - cert_verifier.get(), - cache.http_cache())); - ssl_host_info->Start(); - int rv = ssl_host_info->WaitForDataReady(callback.callback()); - EXPECT_EQ(net::OK, callback.GetResult(rv)); - - net::SSLHostInfo::State* state = ssl_host_info->mutable_state(); - EXPECT_TRUE(state->certs.empty()); - state->certs.push_back(std::string("foo")); - ssl_host_info->Persist(); - - // Wait until Persist() does the work. - base::MessageLoop::current()->RunUntilIdle(); - - // Open the stored certificate chain. - ssl_host_info.reset( - new net::DiskCacheBasedSSLHostInfo("https://www.google.com", ssl_config, - cert_verifier.get(), - cache.http_cache())); - ssl_host_info->Start(); - rv = ssl_host_info->WaitForDataReady(callback.callback()); - EXPECT_EQ(net::OK, callback.GetResult(rv)); - - // And now update the data. - state = ssl_host_info->mutable_state(); - EXPECT_EQ(1U, state->certs.size()); - EXPECT_EQ("foo", state->certs.front()); - state->certs.push_back(std::string("bar")); - - // Fail instead of DCHECKing double creates. - cache.disk_cache()->set_double_create_check(false); - ssl_host_info->Persist(); - base::MessageLoop::current()->RunUntilIdle(); - - // Verify that the state was updated. - ssl_host_info.reset( - new net::DiskCacheBasedSSLHostInfo("https://www.google.com", ssl_config, - cert_verifier.get(), - cache.http_cache())); - ssl_host_info->Start(); - rv = ssl_host_info->WaitForDataReady(callback.callback()); - EXPECT_EQ(net::OK, callback.GetResult(rv)); - - state = ssl_host_info->mutable_state(); - EXPECT_EQ(2U, state->certs.size()); - EXPECT_EQ("foo", state->certs[0]); - EXPECT_EQ("bar", state->certs[1]); - - RemoveMockTransaction(&kHostInfoTransaction); -} - -} // namespace diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 4402da8..6c5fda8 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -33,7 +33,7 @@ #include "net/base/net_errors.h" #include "net/base/upload_data_stream.h" #include "net/disk_cache/disk_cache.h" -#include "net/http/disk_cache_based_ssl_host_info.h" +#include "net/http/disk_cache_based_quic_server_info.h" #include "net/http/http_cache_transaction.h" #include "net/http/http_network_layer.h" #include "net/http/http_network_session.h" @@ -41,7 +41,7 @@ #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" #include "net/http/http_util.h" -#include "net/socket/ssl_host_info.h" +#include "net/quic/crypto/quic_server_info.h" namespace { @@ -269,21 +269,17 @@ void HttpCache::MetadataWriter::OnIOComplete(int result) { //----------------------------------------------------------------------------- -class HttpCache::SSLHostInfoFactoryAdaptor : public SSLHostInfoFactory { +class HttpCache::QuicServerInfoFactoryAdaptor : public QuicServerInfoFactory { public: - SSLHostInfoFactoryAdaptor(CertVerifier* cert_verifier, HttpCache* http_cache) - : cert_verifier_(cert_verifier), - http_cache_(http_cache) { + QuicServerInfoFactoryAdaptor(HttpCache* http_cache) + : http_cache_(http_cache) { } - virtual SSLHostInfo* GetForHost(const std::string& hostname, - const SSLConfig& ssl_config) OVERRIDE { - return new DiskCacheBasedSSLHostInfo( - hostname, ssl_config, cert_verifier_, http_cache_); + virtual QuicServerInfo* GetForHost(const std::string& hostname) OVERRIDE { + return new DiskCacheBasedQuicServerInfo(hostname, http_cache_); } private: - CertVerifier* const cert_verifier_; HttpCache* const http_cache_; }; @@ -294,8 +290,7 @@ HttpCache::HttpCache(const net::HttpNetworkSession::Params& params, backend_factory_(backend_factory), building_backend_(false), mode_(NORMAL), - ssl_host_info_factory_(new SSLHostInfoFactoryAdaptor( - params.cert_verifier, this)), + quic_server_info_factory_(new QuicServerInfoFactoryAdaptor(this)), network_layer_(new HttpNetworkLayer(new HttpNetworkSession(params))) { } @@ -306,8 +301,7 @@ HttpCache::HttpCache(HttpNetworkSession* session, backend_factory_(backend_factory), building_backend_(false), mode_(NORMAL), - ssl_host_info_factory_(new SSLHostInfoFactoryAdaptor( - session->cert_verifier(), this)), + quic_server_info_factory_(new QuicServerInfoFactoryAdaptor(this)), network_layer_(new HttpNetworkLayer(session)) { } diff --git a/net/http/http_cache.h b/net/http/http_cache.h index 2b04e81..1b89d46 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h @@ -211,7 +211,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, // Types -------------------------------------------------------------------- class MetadataWriter; - class SSLHostInfoFactoryAdaptor; + class QuicServerInfoFactoryAdaptor; class Transaction; class WorkItem; friend class Transaction; @@ -382,7 +382,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, Mode mode_; - const scoped_ptr ssl_host_info_factory_; + const scoped_ptr quic_server_info_factory_; const scoped_ptr network_layer_; scoped_ptr disk_cache_; diff --git a/net/http/http_cache_transaction.cc b/net/http/http_cache_transaction.cc index c4fe9aa..0ec9558 100644 --- a/net/http/http_cache_transaction.cc +++ b/net/http/http_cache_transaction.cc @@ -32,7 +32,7 @@ #include "net/base/upload_data_stream.h" #include "net/cert/cert_status_flags.h" #include "net/disk_cache/disk_cache.h" -#include "net/http/disk_cache_based_ssl_host_info.h" +#include "net/http/disk_cache_based_quic_server_info.h" #include "net/http/http_network_session.h" #include "net/http/http_request_info.h" #include "net/http/http_response_headers.h" diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 48d75ff..9c0e8ae 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -61,7 +61,7 @@ HttpNetworkSession::Params::Params() transport_security_state(NULL), cert_transparency_verifier(NULL), proxy_service(NULL), - ssl_host_info_factory(NULL), + quic_server_info_factory(NULL), ssl_config_service(NULL), http_auth_handler_factory(NULL), network_delegate(NULL), diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 0d5e592..60c8189 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -42,10 +42,10 @@ class ServerBoundCertService; class ProxyService; class QuicClock; class QuicCryptoClientStreamFactory; +class QuicServerInfoFactory; class SOCKSClientSocketPool; class SSLClientSocketPool; class SSLConfigService; -class SSLHostInfoFactory; class TransportClientSocketPool; class TransportSecurityState; @@ -65,7 +65,7 @@ class NET_EXPORT HttpNetworkSession TransportSecurityState* transport_security_state; CTVerifier* cert_transparency_verifier; ProxyService* proxy_service; - SSLHostInfoFactory* ssl_host_info_factory; + QuicServerInfoFactory* quic_server_info_factory; std::string ssl_session_cache_shard; SSLConfigService* ssl_config_service; HttpAuthHandlerFactory* http_auth_handler_factory; diff --git a/net/http/http_transaction.h b/net/http/http_transaction.h index b532760..58ea3e0 100644 --- a/net/http/http_transaction.h +++ b/net/http/http_transaction.h @@ -21,8 +21,8 @@ struct HttpRequestInfo; class HttpResponseInfo; class IOBuffer; struct LoadTimingInfo; +class QuicServerInfo; class X509Certificate; -class SSLHostInfo; // Represents a single HTTP transaction (i.e., a single request/response pair). // HTTP redirects are not followed and authentication challenges are not @@ -134,9 +134,9 @@ class NET_EXPORT_PRIVATE HttpTransaction { // zero will be returned. This does not include the request headers. virtual UploadProgress GetUploadProgress() const = 0; - // SetSSLHostInfo sets a object which reads and writes public information - // about an SSL server. - virtual void SetSSLHostInfo(SSLHostInfo*) {}; + // SetQuicServerInfo sets a object which reads and writes public information + // about a QUIC server. + virtual void SetQuicServerInfo(QuicServerInfo* quic_server_info) {}; // Populates all of load timing, except for request start times and receive // headers time. -- cgit v1.1