diff options
39 files changed, 1166 insertions, 24 deletions
diff --git a/chrome/browser/browsing_data_remover.cc b/chrome/browser/browsing_data_remover.cc index 0cfc15d..ee38cc1 100644 --- a/chrome/browser/browsing_data_remover.cc +++ b/chrome/browser/browsing_data_remover.cc @@ -296,8 +296,9 @@ void BrowsingDataRemover::Remove(int remove_mask) { } } - // Also delete cached TransportSecurityState data. - profile_->DeleteTransportSecurityStateSince(delete_begin_); + // Also delete cached network related data (like TransportSecurityState, + // HttpServerProperties data). + profile_->ClearNetworkingHistorySince(delete_begin_); NotifyAndDeleteIfDone(); } diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index a4edcf2..c0e0159 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -260,6 +260,9 @@ ConstructProxyScriptFetcherContext(IOThread::Globals* globals, context->set_origin_bound_cert_service( globals->system_origin_bound_cert_service.get()); context->set_network_delegate(globals->system_network_delegate.get()); + // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the + // system URLRequestContext too. There's no reason this should be tied to a + // profile. return context; } @@ -453,6 +456,9 @@ void IOThread::Init() { session_params.http_auth_handler_factory = globals_->http_auth_handler_factory.get(); session_params.network_delegate = globals_->system_network_delegate.get(); + // TODO(rtenneti): We should probably use HttpServerPropertiesManager for the + // system URLRequestContext too. There's no reason this should be tied to a + // profile. session_params.net_log = net_log_; session_params.ssl_config_service = globals_->ssl_config_service; scoped_refptr<net::HttpNetworkSession> network_session( diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc new file mode 100644 index 0000000..0d3b669 --- /dev/null +++ b/chrome/browser/net/http_server_properties_manager.cc @@ -0,0 +1,220 @@ +// Copyright (c) 2011 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/net/http_server_properties_manager.h" + +#include "base/bind.h" +#include "base/stl_util.h" +#include "base/values.h" +#include "chrome/browser/prefs/pref_service.h" +#include "chrome/common/chrome_notification_types.h" +#include "chrome/common/pref_names.h" +#include "content/browser/browser_thread.h" +#include "content/common/notification_details.h" +#include "content/common/notification_source.h" + +namespace chrome_browser_net { + +namespace { + +// Time to wait before starting an update the spdy_servers_table_ cache from +// preferences. Scheduling another update during this period will reset the +// timer. +const int64 kUpdateCacheDelayMs = 1000; + +// Time to wait before starting an update the preferences from the +// spdy_servers cache. Scheduling another update during this period will +// reset the timer. +const int64 kUpdatePrefsDelayMs = 5000; + +typedef std::vector<std::string> StringVector; + +// String is host/port pair of spdy server. +StringVector* ListValueToStringVector(const base::ListValue* list) { + StringVector* vector = new StringVector; + + if (!list) + return vector; + + vector->reserve(list->GetSize()); + std::string s; + for (base::ListValue::const_iterator it = list->begin(); + it != list->end(); ++it) { + if ((*it)->GetAsString(&s)) + vector->push_back(s); + } + + return vector; +} + +} // namespace + +//////////////////////////////////////////////////////////////////////////////// +// HttpServerPropertiesManager + +HttpServerPropertiesManager::HttpServerPropertiesManager( + PrefService* pref_service) + : ALLOW_THIS_IN_INITIALIZER_LIST(ui_method_factory_(this)), + pref_service_(pref_service) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(pref_service); + ui_weak_ptr_factory_.reset( + new base::WeakPtrFactory<HttpServerPropertiesManager>(this)); + ui_weak_ptr_ = ui_weak_ptr_factory_->GetWeakPtr(); + pref_change_registrar_.Init(pref_service_); + pref_change_registrar_.Add(prefs::kSpdyServers, this); +} + +HttpServerPropertiesManager::~HttpServerPropertiesManager() { +} + +void HttpServerPropertiesManager::InitializeOnIOThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl()); + + io_method_factory_.reset( + new ScopedRunnableMethodFactory<HttpServerPropertiesManager>(this)); + + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefs, + ui_weak_ptr_)); +} + +void HttpServerPropertiesManager::ShutdownOnUIThread() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Cancel any pending updates, and stop listening for pref change updates. + ui_method_factory_.RevokeAll(); + ui_weak_ptr_factory_.reset(); + pref_change_registrar_.RemoveAll(); +} + +bool HttpServerPropertiesManager::SupportsSpdy( + const net::HostPortPair& server) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return http_server_properties_impl_->SupportsSpdy(server); +} + +void HttpServerPropertiesManager::SetSupportsSpdy( + const net::HostPortPair& server, + bool support_spdy) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + http_server_properties_impl_->SetSupportsSpdy(server, support_spdy); + ScheduleUpdatePrefsOnIO(); +} + +void HttpServerPropertiesManager::DeleteAll() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + http_server_properties_impl_->DeleteAll(); + ScheduleUpdatePrefsOnIO(); +} + +// static +void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) { + prefs->RegisterListPref(prefs::kSpdyServers, PrefService::UNSYNCABLE_PREF); +} + +// +// Update spdy_servers (the cached data) with data from preferences. +// +void HttpServerPropertiesManager::ScheduleUpdateCacheOnUI() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Cancel pending updates, if any. + ui_method_factory_.RevokeAll(); + PostUpdateTaskOnUI( + ui_method_factory_.NewRunnableMethod( + &HttpServerPropertiesManager::UpdateCacheFromPrefs)); +} + +void HttpServerPropertiesManager::PostUpdateTaskOnUI(Task* task) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // This is overridden in tests to post the task without the delay. + MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdateCacheDelayMs); +} + +void HttpServerPropertiesManager::UpdateCacheFromPrefs() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (!pref_service_->HasPrefPath(prefs::kSpdyServers)) + return; + + // The preferences can only be read on the UI thread. + StringVector* spdy_servers = + ListValueToStringVector(pref_service_->GetList(prefs::kSpdyServers)); + + // Go through the IO thread to grab a WeakPtr to |this|. This is safe from + // here, since this task will always execute before a potential deletion of + // ProfileIOData on IO. + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO, + base::Unretained(this), spdy_servers, true)); +} + +void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( + StringVector* spdy_servers, + bool support_spdy) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // Preferences have the master data because admins might have pushed new + // preferences. Clear the cached data and use the new spdy server list from + // preferences. + scoped_ptr<StringVector> scoped_spdy_servers(spdy_servers); + http_server_properties_impl_->Initialize(spdy_servers, support_spdy); +} + +// +// Update Preferences with data from spdy_servers (the cached data). +// +void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // Cancel pending updates, if any. + io_method_factory_->RevokeAll(); + PostUpdateTaskOnIO( + io_method_factory_->NewRunnableMethod( + &HttpServerPropertiesManager::UpdatePrefsFromCache)); +} + +void HttpServerPropertiesManager::PostUpdateTaskOnIO(Task* task) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // This is overridden in tests to post the task without the delay. + MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdatePrefsDelayMs); +} + +void HttpServerPropertiesManager::UpdatePrefsFromCache() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + scoped_refptr<RefCountedListValue> spdy_server_list = + new RefCountedListValue(); + http_server_properties_impl_->GetSpdyServerList(&spdy_server_list->data); + + // Update the preferences on the UI thread. + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI, + ui_weak_ptr_, spdy_server_list)); +} + +void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI( + scoped_refptr<RefCountedListValue> spdy_server_list) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data); +} + +void HttpServerPropertiesManager::Observe(int type, + const NotificationSource& source, + const NotificationDetails& details) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + DCHECK(type == chrome::NOTIFICATION_PREF_CHANGED); + PrefService* prefs = Source<PrefService>(source).ptr(); + DCHECK(prefs == pref_service_); + std::string* pref_name = Details<std::string>(details).ptr(); + DCHECK(*pref_name == prefs::kSpdyServers); + ScheduleUpdateCacheOnUI(); +} + +} // namespace chrome_browser_net diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h new file mode 100644 index 0000000..f19f68d --- /dev/null +++ b/chrome/browser/net/http_server_properties_manager.h @@ -0,0 +1,154 @@ +// Copyright (c) 2011 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 CHROME_BROWSER_NET_HTTP_SERVER_PROPERTIES_MANAGER_H_ +#define CHROME_BROWSER_NET_HTTP_SERVER_PROPERTIES_MANAGER_H_ +#pragma once + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" +#include "base/memory/weak_ptr.h" +#include "base/task.h" +#include "base/values.h" +#include "chrome/browser/prefs/pref_change_registrar.h" +#include "content/common/notification_observer.h" +#include "net/base/host_port_pair.h" +#include "net/http/http_server_properties.h" +#include "net/http/http_server_properties_impl.h" + +class NotificationDetails; +class NotificationSource; +class PrefService; + +namespace chrome_browser_net { + +//////////////////////////////////////////////////////////////////////////////// +// HttpServerPropertiesManager + +// The manager for creating and updating an HttpServerProperties (for example it +// tracks if a server supports SPDY or not). +// +// This class interacts with both the UI thread, where notifications of pref +// changes are received from, and the IO thread, which owns it (in the +// ProfileIOData) and it persists the changes from network stack that if a +// server supports SPDY or not. +// +// It must be constructed on the UI thread, to set up |ui_method_factory_| and +// the prefs listeners. +// +// ShutdownOnUIThread must be called from UI before destruction, to release +// the prefs listeners on the UI thread. This is done from ProfileIOData. +// +// Update tasks from the UI thread can post safely to the IO thread, since the +// destruction order of Profile and ProfileIOData guarantees that if this +// exists in UI, then a potential destruction on IO will come after any task +// posted to IO from that method on UI. This is used to go through IO before +// the actual update starts, and grab a WeakPtr. +class HttpServerPropertiesManager + : public net::HttpServerProperties, + public NotificationObserver { + public: + // Create an instance of the HttpServerPropertiesManager. The lifetime of the + // PrefService objects must be longer than that of the + // HttpServerPropertiesManager object. Must be constructed on the UI thread. + explicit HttpServerPropertiesManager(PrefService* pref_service); + virtual ~HttpServerPropertiesManager(); + + // Initialize |http_server_properties_impl_| and |io_method_factory_| on IO + // thread. It also posts a task to UI thread to get SPDY Server preferences + // from |pref_service_|. + void InitializeOnIOThread(); + + // Prepare for shutdown. Must be called on the UI thread, before destruction. + void ShutdownOnUIThread(); + + // Returns true if |server| supports SPDY. Should only be called from IO + // thread. + virtual bool SupportsSpdy(const net::HostPortPair& server) const OVERRIDE; + + // Add |server| as the SPDY server which supports SPDY protocol into the + // persisitent store. Should only be called from IO thread. + virtual void SetSupportsSpdy(const net::HostPortPair& server, + bool support_spdy) OVERRIDE; + + // Deletes all data. + virtual void DeleteAll() OVERRIDE; + + // Register |prefs| SPDY preferences. + static void RegisterPrefs(PrefService* prefs); + + protected: + typedef base::RefCountedData<base::ListValue> RefCountedListValue; + + // These are used to delay updating the spdy servers in + // |http_server_properties_impl_| while the preferences are changing, and + // execute only one update per simultaneous prefs changes. + void ScheduleUpdateCacheOnUI(); + + // Update spdy servers (the cached data in |http_server_properties_impl_|) + // with data from preferences. Virtual for testing. + virtual void UpdateCacheFromPrefs(); + + // Starts the |spdy_servers| update on the IO thread. Protected for testing. + void UpdateCacheFromPrefsOnIO(StringVector* spdy_servers, bool support_spdy); + + // These are used to delay updating the preferences when spdy servers_ are + // changing, and execute only one update per simultaneous spdy server changes. + void ScheduleUpdatePrefsOnIO(); + + // Update spdy servers in preferences with the cached data from + // |http_server_properties_impl_|. Virtual for testing. + virtual void UpdatePrefsFromCache(); // Virtual for testing. + + // Update |prefs::kSpdyServers| preferences with |spdy_server_list| on UI + // thread. Protected for testing. + void SetSpdyServersInPrefsOnUI( + scoped_refptr<RefCountedListValue> spdy_server_list); + + private: + // Post the tasks with the delay. These are overridden in tests to post the + // task without the delay. + virtual void PostUpdateTaskOnUI(Task* task); // Virtual for testing. + virtual void PostUpdateTaskOnIO(Task* task); // Virtual for testing. + + // Callback for preference changes. + virtual void Observe(int type, + const NotificationSource& source, + const NotificationDetails& details); + + // --------- + // UI thread + // --------- + + // Used to post update tasks to the UI thread. + ScopedRunnableMethodFactory<HttpServerPropertiesManager> ui_method_factory_; + + // Used to get |weak_ptr_| to self on the UI thread. + scoped_ptr<base::WeakPtrFactory<HttpServerPropertiesManager> > + ui_weak_ptr_factory_; + + base::WeakPtr<HttpServerPropertiesManager> ui_weak_ptr_; + + // Used to track the spdy servers changes. + PrefChangeRegistrar pref_change_registrar_; + PrefService* pref_service_; // Weak. + + // --------- + // IO thread + // --------- + + // Used to post update tasks to the IO thread. + scoped_ptr<ScopedRunnableMethodFactory<HttpServerPropertiesManager> > + io_method_factory_; + + scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_impl_; + + DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManager); +}; + +} // namespace chrome_browser_net + +#endif // CHROME_BROWSER_NET_HTTP_SERVER_PROPERTIES_MANAGER_H_ diff --git a/chrome/browser/net/http_server_properties_manager_unittest.cc b/chrome/browser/net/http_server_properties_manager_unittest.cc new file mode 100644 index 0000000..cda95e0 --- /dev/null +++ b/chrome/browser/net/http_server_properties_manager_unittest.cc @@ -0,0 +1,276 @@ +// Copyright (c) 2011 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/net/http_server_properties_manager.h" + +#include "base/basictypes.h" +#include "base/message_loop.h" +#include "base/values.h" +#include "chrome/common/pref_names.h" +#include "chrome/test/base/testing_pref_service.h" +#include "content/browser/browser_thread.h" +#include "content/common/notification_service.h" +#include "googleurl/src/gurl.h" +#include "testing/gmock/include/gmock/gmock.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace chrome_browser_net { + +namespace { + +using ::testing::_; +using ::testing::Invoke; +using ::testing::Mock; + +class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager { + public: + explicit TestingHttpServerPropertiesManager(PrefService* pref_service) + : HttpServerPropertiesManager(pref_service) { + InitializeOnIOThread(); + } + + virtual ~TestingHttpServerPropertiesManager() { + } + + // Make this method public for testing. + using HttpServerPropertiesManager::ScheduleUpdateCacheOnUI; + using HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO; + + // Post tasks without a delay during tests. + virtual void PostUpdateTaskOnUI(Task* task) OVERRIDE { + MessageLoop::current()->PostTask(FROM_HERE, task); + } + + // Makes a direct call to UpdateCacheFromPrefsOnIO during tests. + void UpdateCacheFromPrefsOnIO() { + StringVector* spdy_servers = new StringVector; + spdy_servers->push_back("www.google.com:443"); + HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(spdy_servers, true); + } + + void UpdateCacheFromPrefsConcrete() { + HttpServerPropertiesManager::UpdateCacheFromPrefs(); + } + + // Post tasks without a delay during tests. + virtual void PostUpdateTaskOnIO(Task* task) OVERRIDE { + MessageLoop::current()->PostTask(FROM_HERE, task); + } + + // Makes a direct call to SetSpdyServersInPrefsOnUI during tests. + void SetSpdyServersInPrefsOnUI() { + net::HostPortPair spdy_server_mail("mail.google.com", 443); + std::string spdy_server_m = + net::HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_mail); + + scoped_refptr<RefCountedListValue> spdy_server_list = + new RefCountedListValue(); + spdy_server_list->data.Append(new StringValue(spdy_server_m)); + + HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI(spdy_server_list); + } + + void UpdatePrefsFromCacheConcrete() { + HttpServerPropertiesManager::UpdatePrefsFromCache(); + } + + MOCK_METHOD0(UpdateCacheFromPrefs, void()); + MOCK_METHOD0(UpdatePrefsFromCache, void()); + MOCK_METHOD2(UpdateCacheFromPrefsOnIO, + void(StringVector* spdy_servers, bool support_spdy)); + MOCK_METHOD1(SetSpdyServersInPrefsOnUI, + void(scoped_refptr<RefCountedListValue> spdy_server_list)); + + private: + DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager); +}; + +class HttpServerPropertiesManagerTest : public testing::Test { + protected: + HttpServerPropertiesManagerTest() + : ui_thread_(BrowserThread::UI, &loop_), + io_thread_(BrowserThread::IO, &loop_) { + } + + virtual void SetUp() OVERRIDE { + pref_service_.RegisterListPref(prefs::kSpdyServers); + http_server_props_manager_.reset( + new TestingHttpServerPropertiesManager(&pref_service_)); + loop_.RunAllPending(); + } + + virtual void TearDown() OVERRIDE { + if (http_server_props_manager_.get()) + http_server_props_manager_->ShutdownOnUIThread(); + loop_.RunAllPending(); + // Delete |http_server_props_manager_| while |io_thread_| is mapping IO to + // |loop_|. + http_server_props_manager_.reset(); + } + + void ExpectCacheUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs()) + .WillOnce( + Invoke(http_server_props_manager_.get(), + &TestingHttpServerPropertiesManager::UpdateCacheFromPrefsConcrete)); + } + + void ExpectPrefsUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCache()) + .WillOnce( + Invoke(http_server_props_manager_.get(), + &TestingHttpServerPropertiesManager::UpdatePrefsFromCacheConcrete)); + } + + MessageLoop loop_; + TestingPrefService pref_service_; + scoped_ptr<TestingHttpServerPropertiesManager> http_server_props_manager_; + + private: + BrowserThread ui_thread_; + BrowserThread io_thread_; + + DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest); +}; + +TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoPrefChanges) { + ExpectCacheUpdate(); + + ListValue* http_server_props = new ListValue; + http_server_props->Append(new StringValue("www.google.com:443")); + http_server_props->Append(new StringValue("mail.google.com:443")); + pref_service_.SetManagedPref(prefs::kSpdyServers, http_server_props); + loop_.RunAllPending(); + + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); +} + +TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) { + ExpectPrefsUpdate(); + + // Post an update task to the IO thread. SetSupportsSpdy calls + // ScheduleUpdatePrefsOnIO. + + // Add mail.google.com:443 as a supporting spdy server. + net::HostPortPair spdy_server_mail("mail.google.com", 443); + EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true); + + // Run the task. + loop_.RunAllPending(); + + EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); +} + +TEST_F(HttpServerPropertiesManagerTest, DeleteAll) { + ExpectPrefsUpdate(); + + // Add mail.google.com:443 as a supporting spdy server. + net::HostPortPair spdy_server_mail("mail.google.com", 443); + http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true); + + // Run the task. + loop_.RunAllPending(); + + EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + + // DeleteAll http server data. + http_server_props_manager_->DeleteAll(); + + // Run the task. + loop_.RunAllPending(); + + EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); +} + +// +// Tests for shutdown when updating cache. +// +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) { + EXPECT_CALL(*http_server_props_manager_, + UpdateCacheFromPrefsOnIO(_, _)).Times(0); + // Post an update task to the UI thread. + http_server_props_manager_->ScheduleUpdateCacheOnUI(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + http_server_props_manager_.reset(); + // Run the task after shutdown and deletion. + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) { + EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs()).Times(0); + // Post an update task. + http_server_props_manager_->ScheduleUpdateCacheOnUI(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) { + EXPECT_CALL(*http_server_props_manager_, + UpdateCacheFromPrefsOnIO(_, _)).Times(0); + http_server_props_manager_->UpdateCacheFromPrefsConcrete(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +// +// Tests for shutdown when updating prefs. +// +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) { + EXPECT_CALL(*http_server_props_manager_, + SetSpdyServersInPrefsOnUI(_)).Times(0); + // Post an update task to the IO thread. + http_server_props_manager_->ScheduleUpdatePrefsOnIO(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + http_server_props_manager_.reset(); + // Run the task after shutdown and deletion. + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) { + EXPECT_CALL(*http_server_props_manager_, + SetSpdyServersInPrefsOnUI(_)).Times(0); + // Post an update task. + http_server_props_manager_->ScheduleUpdatePrefsOnIO(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) { + EXPECT_CALL(*http_server_props_manager_, + SetSpdyServersInPrefsOnUI(_)).Times(0); + // This posts a task to the UI thread. + http_server_props_manager_->UpdatePrefsFromCacheConcrete(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +} // namespace + +} // namespace chrome_browser_net diff --git a/chrome/browser/prefs/browser_prefs.cc b/chrome/browser/prefs/browser_prefs.cc index fa46123..1222f95 100644 --- a/chrome/browser/prefs/browser_prefs.cc +++ b/chrome/browser/prefs/browser_prefs.cc @@ -25,6 +25,7 @@ #include "chrome/browser/intranet_redirect_detector.h" #include "chrome/browser/metrics/metrics_log.h" #include "chrome/browser/metrics/metrics_service.h" +#include "chrome/browser/net/http_server_properties_manager.h" #include "chrome/browser/net/net_pref_observer.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/pref_proxy_config_service.h" @@ -186,6 +187,7 @@ void RegisterUserPrefs(PrefService* user_prefs) { #if defined(ENABLE_CONFIGURATION_POLICY) policy::URLBlacklistManager::RegisterPrefs(user_prefs); #endif + chrome_browser_net::HttpServerPropertiesManager::RegisterPrefs(user_prefs); } void MigrateBrowserPrefs(PrefService* user_prefs, PrefService* local_state) { diff --git a/chrome/browser/profiles/off_the_record_profile_impl.cc b/chrome/browser/profiles/off_the_record_profile_impl.cc index 20d1c11..3d0c960 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.cc +++ b/chrome/browser/profiles/off_the_record_profile_impl.cc @@ -53,6 +53,7 @@ #include "content/browser/tab_contents/tab_contents.h" #include "content/common/notification_service.h" #include "net/base/transport_security_state.h" +#include "net/http/http_server_properties.h" #include "webkit/database/database_tracker.h" #include "webkit/quota/quota_manager.h" @@ -584,8 +585,7 @@ chrome_browser_net::Predictor* OffTheRecordProfileImpl::GetNetworkPredictor() { return NULL; } -void OffTheRecordProfileImpl::DeleteTransportSecurityStateSince( - base::Time time) { +void OffTheRecordProfileImpl::ClearNetworkingHistorySince(base::Time time) { // No need to do anything here, our transport security state is read-only. } diff --git a/chrome/browser/profiles/off_the_record_profile_impl.h b/chrome/browser/profiles/off_the_record_profile_impl.h index 032d451..9c5187a 100644 --- a/chrome/browser/profiles/off_the_record_profile_impl.h +++ b/chrome/browser/profiles/off_the_record_profile_impl.h @@ -128,7 +128,7 @@ class OffTheRecordProfileImpl : public Profile, virtual PrefProxyConfigTracker* GetProxyConfigTracker() OVERRIDE; virtual chrome_browser_net::Predictor* GetNetworkPredictor() OVERRIDE; - virtual void DeleteTransportSecurityStateSince(base::Time time) OVERRIDE; + virtual void ClearNetworkingHistorySince(base::Time time) OVERRIDE; // NotificationObserver implementation. virtual void Observe(int type, diff --git a/chrome/browser/profiles/off_the_record_profile_io_data.cc b/chrome/browser/profiles/off_the_record_profile_io_data.cc index 7ab19fb..1c6b0ec 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.cc +++ b/chrome/browser/profiles/off_the_record_profile_io_data.cc @@ -197,6 +197,7 @@ void OffTheRecordProfileIOData::LazyInitializeInternal( main_context->ssl_config_service(), main_context->http_auth_handler_factory(), main_context->network_delegate(), + main_context->http_server_properties(), main_context->net_log(), main_backend); diff --git a/chrome/browser/profiles/profile.h b/chrome/browser/profiles/profile.h index ee1c908..053c4ef 100644 --- a/chrome/browser/profiles/profile.h +++ b/chrome/browser/profiles/profile.h @@ -482,10 +482,11 @@ class Profile : public content::BrowserContext { // Returns the Predictor object used for dns prefetch. virtual chrome_browser_net::Predictor* GetNetworkPredictor() = 0; - // Deletes transport security state since |time|. The implementation - // is free to run this on a background thread, so when this method - // returns data is not guaranteed to be deleted. - virtual void DeleteTransportSecurityStateSince(base::Time time) = 0; + // Deletes all network related data since |time|. It deletes transport + // security state since |time| and it also delete HttpServerProperties data. + // The implementation is free to run this on a background thread, so when this + // method returns data is not guaranteed to be deleted. + virtual void ClearNetworkingHistorySince(base::Time time) = 0; std::string GetDebugName(); diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc index f3eedcf9..44c7774 100644 --- a/chrome/browser/profiles/profile_impl.cc +++ b/chrome/browser/profiles/profile_impl.cc @@ -106,6 +106,7 @@ #include "grit/browser_resources.h" #include "grit/locale_settings.h" #include "net/base/transport_security_state.h" +#include "net/http/http_server_properties.h" #include "ui/base/resource/resource_bundle.h" #include "webkit/database/database_tracker.h" #include "webkit/quota/quota_manager.h" @@ -1752,8 +1753,8 @@ chrome_browser_net::Predictor* ProfileImpl::GetNetworkPredictor() { return predictor_; } -void ProfileImpl::DeleteTransportSecurityStateSince(base::Time time) { - io_data_.DeleteTransportSecurityStateSince(time); +void ProfileImpl::ClearNetworkingHistorySince(base::Time time) { + io_data_.ClearNetworkingHistorySince(time); } SpellCheckProfile* ProfileImpl::GetSpellCheckProfile() { diff --git a/chrome/browser/profiles/profile_impl.h b/chrome/browser/profiles/profile_impl.h index c4cfebf..2d01453 100644 --- a/chrome/browser/profiles/profile_impl.h +++ b/chrome/browser/profiles/profile_impl.h @@ -130,7 +130,7 @@ class ProfileImpl : public Profile, virtual PromoCounter* GetInstantPromoCounter() OVERRIDE; virtual ChromeURLDataManager* GetChromeURLDataManager() OVERRIDE; virtual chrome_browser_net::Predictor* GetNetworkPredictor() OVERRIDE; - virtual void DeleteTransportSecurityStateSince(base::Time time) OVERRIDE; + virtual void ClearNetworkingHistorySince(base::Time time) OVERRIDE; #if defined(OS_CHROMEOS) virtual void ChangeAppLocale(const std::string& locale, diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc index b2ba615..90f3502 100644 --- a/chrome/browser/profiles/profile_impl_io_data.cc +++ b/chrome/browser/profiles/profile_impl_io_data.cc @@ -13,6 +13,7 @@ #include "chrome/browser/net/chrome_net_log.h" #include "chrome/browser/net/chrome_network_delegate.h" #include "chrome/browser/net/connect_interceptor.h" +#include "chrome/browser/net/http_server_properties_manager.h" #include "chrome/browser/net/predictor.h" #include "chrome/browser/net/sqlite_origin_bound_cert_store.h" #include "chrome/browser/net/sqlite_persistent_cookie_store.h" @@ -31,10 +32,11 @@ namespace { -void DeleteTransportSecurityStateSinceOnIOThread( +void ClearNetworkingHistorySinceOnIOThread( ProfileImplIOData* io_data, base::Time time) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); io_data->transport_security_state()->DeleteSince(time); + io_data->http_server_properties()->DeleteAll(); } } // namespace @@ -71,6 +73,8 @@ ProfileImplIOData::Handle::~Handle() { iter->second->CleanupOnUIThread(); } + if (io_data_->http_server_properties_manager_.get()) + io_data_->http_server_properties_manager_->ShutdownOnUIThread(); io_data_->ShutdownOnUIThread(); } @@ -186,7 +190,7 @@ ProfileImplIOData::Handle::GetIsolatedAppRequestContextGetter( return context; } -void ProfileImplIOData::Handle::DeleteTransportSecurityStateSince( +void ProfileImplIOData::Handle::ClearNetworkingHistorySince( base::Time time) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); LazyInitialize(); @@ -194,7 +198,7 @@ void ProfileImplIOData::Handle::DeleteTransportSecurityStateSince( BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, base::Bind( - &DeleteTransportSecurityStateSinceOnIOThread, + &ClearNetworkingHistorySinceOnIOThread, io_data_, time)); } @@ -202,14 +206,17 @@ void ProfileImplIOData::Handle::DeleteTransportSecurityStateSince( void ProfileImplIOData::Handle::LazyInitialize() const { if (!initialized_) { io_data_->InitializeOnUIThread(profile_); + PrefService* pref_service = profile_->GetPrefs(); + io_data_->http_server_properties_manager_.reset( + new chrome_browser_net::HttpServerPropertiesManager(pref_service)); ChromeNetworkDelegate::InitializeReferrersEnabled( - io_data_->enable_referrers(), profile_->GetPrefs()); + io_data_->enable_referrers(), pref_service); io_data_->clear_local_state_on_exit()->Init( - prefs::kClearSiteDataOnExit, profile_->GetPrefs(), NULL); + prefs::kClearSiteDataOnExit, pref_service, NULL); io_data_->clear_local_state_on_exit()->MoveToThread(BrowserThread::IO); #if defined(ENABLE_SAFE_BROWSING) io_data_->safe_browsing_enabled()->Init(prefs::kSafeBrowsingEnabled, - profile_->GetPrefs(), NULL); + pref_service, NULL); io_data_->safe_browsing_enabled()->MoveToThread(BrowserThread::IO); #endif initialized_ = true; @@ -248,6 +255,9 @@ void ProfileImplIOData::LazyInitializeInternal( ApplyProfileParamsToContext(media_request_context_); ApplyProfileParamsToContext(extensions_context); + if (http_server_properties_manager_.get()) + http_server_properties_manager_->InitializeOnIOThread(); + main_context->set_transport_security_state(transport_security_state()); media_request_context_->set_transport_security_state( transport_security_state()); @@ -260,6 +270,9 @@ void ProfileImplIOData::LazyInitializeInternal( main_context->set_network_delegate(network_delegate()); media_request_context_->set_network_delegate(network_delegate()); + main_context->set_http_server_properties(http_server_properties()); + media_request_context_->set_http_server_properties(http_server_properties()); + main_context->set_host_resolver( io_thread_globals->host_resolver.get()); media_request_context_->set_host_resolver( @@ -353,6 +366,7 @@ void ProfileImplIOData::LazyInitializeInternal( main_context->ssl_config_service(), main_context->http_auth_handler_factory(), main_context->network_delegate(), + main_context->http_server_properties(), main_context->net_log(), main_backend); @@ -391,6 +405,10 @@ void ProfileImplIOData::LazyInitializeInternal( lazy_params_.reset(); } +net::HttpServerProperties* ProfileImplIOData::http_server_properties() const { + return http_server_properties_manager_.get(); +} + scoped_refptr<ChromeURLRequestContext> ProfileImplIOData::InitializeAppRequestContext( scoped_refptr<ChromeURLRequestContext> main_context, diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h index 2a2ba08..417fa78 100644 --- a/chrome/browser/profiles/profile_impl_io_data.h +++ b/chrome/browser/profiles/profile_impl_io_data.h @@ -13,10 +13,12 @@ #include "chrome/browser/profiles/profile_io_data.h" namespace chrome_browser_net { +class HttpServerPropertiesManager; class Predictor; } namespace net { +class HttpServerProperties; class HttpTransactionFactory; } // namespace net @@ -58,7 +60,7 @@ class ProfileImplIOData : public ProfileIOData { GetIsolatedAppRequestContextGetter( const std::string& app_id) const; - void DeleteTransportSecurityStateSince(base::Time time); + void ClearNetworkingHistorySince(base::Time time); private: typedef base::hash_map<std::string, @@ -94,6 +96,8 @@ class ProfileImplIOData : public ProfileIOData { DISALLOW_COPY_AND_ASSIGN(Handle); }; + net::HttpServerProperties* http_server_properties() const; + private: friend class base::RefCountedThreadSafe<ProfileImplIOData>; @@ -137,6 +141,8 @@ class ProfileImplIOData : public ProfileIOData { mutable scoped_ptr<net::HttpTransactionFactory> media_http_factory_; mutable scoped_ptr<chrome_browser_net::Predictor> predictor_; + mutable scoped_ptr<chrome_browser_net::HttpServerPropertiesManager> + http_server_properties_manager_; // Parameters needed for isolated apps. FilePath app_path_; diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 6378c61..cc57bbd 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1582,6 +1582,8 @@ 'browser/net/sqlite_origin_bound_cert_store.h', 'browser/net/sqlite_persistent_cookie_store.cc', 'browser/net/sqlite_persistent_cookie_store.h', + 'browser/net/http_server_properties_manager.h', + 'browser/net/http_server_properties_manager.cc', 'browser/net/ssl_config_service_manager.h', 'browser/net/ssl_config_service_manager_pref.cc', 'browser/net/url_fixer_upper.cc', diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index f62df66..cb45f81 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1371,6 +1371,7 @@ 'browser/net/gaia/gaia_oauth_fetcher_unittest.cc', 'browser/net/gaia/token_service_unittest.cc', 'browser/net/gaia/token_service_unittest.h', + 'browser/net/http_server_properties_manager_unittest.cc', 'browser/net/load_timing_observer_unittest.cc', 'browser/net/network_stats_unittest.cc', 'browser/net/passive_log_collector_unittest.cc', diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index 6bd9a6d..1a6415d 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -327,6 +327,9 @@ const char kDnsPrefetchingHostReferralList[] = // Disables the SPDY protocol. const char kDisableSpdy[] = "spdy.disabled"; +// Prefs for server names that support SPDY protocol. +const char kSpdyServers[] = "spdy.servers"; + // Disables the listed protocol schemes. const char kDisabledSchemes[] = "protocol.disabled_schemes"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index 5524115..9bc1deb 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -128,6 +128,7 @@ extern const char kDnsPrefetchingStartupList[]; extern const char kDnsHostReferralList[]; // OBSOLETE extern const char kDnsPrefetchingHostReferralList[]; extern const char kDisableSpdy[]; +extern const char kSpdyServers[]; extern const char kDisabledSchemes[]; extern const char kUrlBlacklist[]; extern const char kUrlWhitelist[]; diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc index 4d65247..bb27d07 100644 --- a/chrome/test/base/testing_profile.cc +++ b/chrome/test/base/testing_profile.cc @@ -788,7 +788,7 @@ chrome_browser_net::Predictor* TestingProfile::GetNetworkPredictor() { return NULL; } -void TestingProfile::DeleteTransportSecurityStateSince(base::Time time) { +void TestingProfile::ClearNetworkingHistorySince(base::Time time) { NOTIMPLEMENTED(); } diff --git a/chrome/test/base/testing_profile.h b/chrome/test/base/testing_profile.h index e13436d..7174785 100644 --- a/chrome/test/base/testing_profile.h +++ b/chrome/test/base/testing_profile.h @@ -279,7 +279,7 @@ class TestingProfile : public Profile { virtual PromoCounter* GetInstantPromoCounter(); virtual ChromeURLDataManager* GetChromeURLDataManager(); virtual chrome_browser_net::Predictor* GetNetworkPredictor(); - virtual void DeleteTransportSecurityStateSince(base::Time time); + virtual void ClearNetworkingHistorySince(base::Time time) OVERRIDE; virtual PrefService* GetOffTheRecordPrefs(); // TODO(jam): remove me once webkit_context_unittest.cc doesn't use Profile diff --git a/content/shell/shell_url_request_context_getter.cc b/content/shell/shell_url_request_context_getter.cc index 96fc8f8..f3e1c99 100644 --- a/content/shell/shell_url_request_context_getter.cc +++ b/content/shell/shell_url_request_context_getter.cc @@ -94,7 +94,8 @@ net::URLRequestContext* ShellURLRequestContextGetter::GetURLRequestContext() { proxy_service_.get(), new net::SSLConfigServiceDefaults(), http_auth_handler_factory_.get(), - NULL, // network_delegate + NULL, // network_delegate + NULL, // http_server_properties net_log, main_backend); main_http_factory_.reset(main_cache); diff --git a/jingle/notifier/base/proxy_resolving_client_socket.cc b/jingle/notifier/base/proxy_resolving_client_socket.cc index d922a44..b4cc70c 100644 --- a/jingle/notifier/base/proxy_resolving_client_socket.cc +++ b/jingle/notifier/base/proxy_resolving_client_socket.cc @@ -56,6 +56,8 @@ ProxyResolvingClientSocket::ProxyResolvingClientSocket( session_params.http_auth_handler_factory = request_context->http_auth_handler_factory(); session_params.network_delegate = request_context->network_delegate(); + session_params.http_server_properties = + request_context->http_server_properties(); session_params.net_log = request_context->net_log(); network_session_ = new net::HttpNetworkSession(session_params); } diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc index 9a23aab..23002d8 100644 --- a/net/http/http_cache.cc +++ b/net/http/http_cache.cc @@ -51,6 +51,7 @@ HttpNetworkSession* CreateNetworkSession( SSLConfigService* ssl_config_service, HttpAuthHandlerFactory* http_auth_handler_factory, NetworkDelegate* network_delegate, + HttpServerProperties* http_server_properties, NetLog* net_log) { HttpNetworkSession::Params params; params.host_resolver = host_resolver; @@ -63,6 +64,7 @@ HttpNetworkSession* CreateNetworkSession( params.ssl_config_service = ssl_config_service; params.http_auth_handler_factory = http_auth_handler_factory; params.network_delegate = network_delegate; + params.http_server_properties = http_server_properties; params.net_log = net_log; return new HttpNetworkSession(params); } @@ -321,6 +323,7 @@ HttpCache::HttpCache(HostResolver* host_resolver, SSLConfigService* ssl_config_service, HttpAuthHandlerFactory* http_auth_handler_factory, NetworkDelegate* network_delegate, + HttpServerProperties* http_server_properties, NetLog* net_log, BackendFactory* backend_factory) : net_log_(net_log), @@ -343,6 +346,7 @@ HttpCache::HttpCache(HostResolver* host_resolver, ssl_config_service, http_auth_handler_factory, network_delegate, + http_server_properties, net_log))), ALLOW_THIS_IN_INITIALIZER_LIST(task_factory_(this)) { } diff --git a/net/http/http_cache.h b/net/http/http_cache.h index f6b7ffe..1a7a51d 100644 --- a/net/http/http_cache.h +++ b/net/http/http_cache.h @@ -51,6 +51,7 @@ class HttpAuthHandlerFactory; class HttpNetworkSession; struct HttpRequestInfo; class HttpResponseInfo; +class HttpServerProperties; class IOBuffer; class NetLog; class NetworkDelegate; @@ -129,6 +130,7 @@ class NET_EXPORT HttpCache : public HttpTransactionFactory, SSLConfigService* ssl_config_service, HttpAuthHandlerFactory* http_auth_handler_factory, NetworkDelegate* network_delegate, + HttpServerProperties* http_server_properties, NetLog* net_log, BackendFactory* backend_factory); diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index b5a104d..5fed4bf 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -25,6 +25,7 @@ namespace net { HttpNetworkSession::HttpNetworkSession(const Params& params) : net_log_(params.net_log), network_delegate_(params.network_delegate), + http_server_properties_(params.http_server_properties), cert_verifier_(params.cert_verifier), http_auth_handler_factory_(params.http_auth_handler_factory), proxy_service_(params.proxy_service), diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index d4e391e..777653b 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -35,6 +35,7 @@ class HttpAuthHandlerFactory; class HttpNetworkSessionPeer; class HttpProxyClientSocketPool; class HttpResponseBodyDrainer; +class HttpServerProperties; class NetLog; class NetworkDelegate; class ProxyService; @@ -59,6 +60,7 @@ class NET_EXPORT HttpNetworkSession ssl_config_service(NULL), http_auth_handler_factory(NULL), network_delegate(NULL), + http_server_properties(NULL), net_log(NULL) {} ClientSocketFactory* client_socket_factory; @@ -72,6 +74,7 @@ class NET_EXPORT HttpNetworkSession SSLConfigService* ssl_config_service; HttpAuthHandlerFactory* http_auth_handler_factory; NetworkDelegate* network_delegate; + HttpServerProperties* http_server_properties; NetLog* net_log; }; @@ -120,6 +123,9 @@ class NET_EXPORT HttpNetworkSession NetworkDelegate* network_delegate() { return network_delegate_; } + HttpServerProperties* http_server_properties() { + return http_server_properties_; + } HttpStreamFactory* http_stream_factory() { return http_stream_factory_.get(); @@ -148,6 +154,7 @@ class NET_EXPORT HttpNetworkSession NetLog* const net_log_; NetworkDelegate* const network_delegate_; + HttpServerProperties* const http_server_properties_; CertVerifier* const cert_verifier_; HttpAuthHandlerFactory* const http_auth_handler_factory_; diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h new file mode 100644 index 0000000..a8dc6bf --- /dev/null +++ b/net/http/http_server_properties.h @@ -0,0 +1,42 @@ +// Copyright (c) 2011 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_HTTP_SERVER_PROPERTIES_H_ +#define NET_HTTP_HTTP_SERVER_PROPERTIES_H_ + +#include <string> +#include <vector> + +#include "base/basictypes.h" +#include "net/base/host_port_pair.h" +#include "net/base/net_export.h" + +namespace net { + +// The interface for setting/retrieving the HTTP server properties. +class NET_EXPORT HttpServerProperties { + public: + typedef std::vector<std::string> StringVector; + + HttpServerProperties() {} + virtual ~HttpServerProperties() {} + + // Returns true if |server| supports SPDY. + virtual bool SupportsSpdy(const HostPortPair& server) const = 0; + + // Add |server| into the persistent store. Should only be called from IO + // thread. + virtual void SetSupportsSpdy(const HostPortPair& server, + bool support_spdy) = 0; + + // Deletes all data. + virtual void DeleteAll() = 0; + + private: + DISALLOW_COPY_AND_ASSIGN(HttpServerProperties); +}; + +} // namespace net + +#endif // NET_HTTP_HTTP_SERVER_PROPERTIES_H_ diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc new file mode 100644 index 0000000..9dd341d --- /dev/null +++ b/net/http/http_server_properties_impl.cc @@ -0,0 +1,93 @@ +// Copyright (c) 2011 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/http_server_properties_impl.h" + +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/stl_util.h" +#include "base/stringprintf.h" + +namespace net { + +HttpServerPropertiesImpl::HttpServerPropertiesImpl() { +} + +HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { +} + +void HttpServerPropertiesImpl::Initialize(StringVector* spdy_servers, + bool support_spdy) { + DCHECK(CalledOnValidThread()); + spdy_servers_table_.clear(); + if (!spdy_servers) + return; + for (StringVector::iterator it = spdy_servers->begin(); + it != spdy_servers->end(); ++it) { + spdy_servers_table_[*it] = support_spdy; + } +} + +bool HttpServerPropertiesImpl::SupportsSpdy( + const net::HostPortPair& host_port_pair) const { + DCHECK(CalledOnValidThread()); + if (host_port_pair.host().empty()) + return false; + std::string spdy_server = GetFlattenedSpdyServer(host_port_pair); + + SpdyServerHostPortTable::const_iterator spdy_host_port = + spdy_servers_table_.find(spdy_server); + if (spdy_host_port != spdy_servers_table_.end()) + return spdy_host_port->second; + return false; +} + +void HttpServerPropertiesImpl::SetSupportsSpdy( + const net::HostPortPair& host_port_pair, + bool support_spdy) { + DCHECK(CalledOnValidThread()); + if (host_port_pair.host().empty()) + return; + std::string spdy_server = GetFlattenedSpdyServer(host_port_pair); + + SpdyServerHostPortTable::iterator spdy_host_port = + spdy_servers_table_.find(spdy_server); + if ((spdy_host_port != spdy_servers_table_.end()) && + (spdy_host_port->second == support_spdy)) { + return; + } + // Cache the data. + spdy_servers_table_[spdy_server] = support_spdy; +} + +void HttpServerPropertiesImpl::DeleteAll() { + DCHECK(CalledOnValidThread()); + spdy_servers_table_.clear(); +} + +void HttpServerPropertiesImpl::GetSpdyServerList( + base::ListValue* spdy_server_list) const { + DCHECK(CalledOnValidThread()); + DCHECK(spdy_server_list); + spdy_server_list->Clear(); + // Get the list of servers (host/port) that support SPDY. + for (SpdyServerHostPortTable::const_iterator it = spdy_servers_table_.begin(); + it != spdy_servers_table_.end(); ++it) { + const std::string spdy_server_host_port = it->first; + if (it->second) + spdy_server_list->Append(new StringValue(spdy_server_host_port)); + } +} + +// static +std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( + const net::HostPortPair& host_port_pair) { + std::string spdy_server; + spdy_server.append(host_port_pair.host()); + spdy_server.append(":"); + base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); + return spdy_server; +} + +} // namespace net diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h new file mode 100644 index 0000000..a18b05c --- /dev/null +++ b/net/http/http_server_properties_impl.h @@ -0,0 +1,66 @@ +// Copyright (c) 2011 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_HTTP_SERVER_PROPERTIES_IMPL_H_ +#define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ + +#include <string> + +#include "base/basictypes.h" +#include "base/gtest_prod_util.h" +#include "base/hash_tables.h" +#include "base/threading/non_thread_safe.h" +#include "base/values.h" +#include "net/base/host_port_pair.h" +#include "net/base/net_export.h" +#include "net/http/http_server_properties.h" + +namespace base { +class ListValue; +} + +namespace net { + +// The implementation for setting/retrieving the HTTP server properties. +class NET_EXPORT HttpServerPropertiesImpl + : public HttpServerProperties, + NON_EXPORTED_BASE(public base::NonThreadSafe) { + public: + HttpServerPropertiesImpl(); + virtual ~HttpServerPropertiesImpl(); + + // Initializes |spdy_servers_table_| with the servers (host/port) from + // |spdy_servers| that either support SPDY or not. + void Initialize(StringVector* spdy_servers, bool support_spdy); + + // Returns true if |server| supports SPDY. + virtual bool SupportsSpdy(const HostPortPair& server) const OVERRIDE; + + // Add |server| into the persistent store. + virtual void SetSupportsSpdy(const HostPortPair& server, + bool support_spdy) OVERRIDE; + + // Deletes all data. + virtual void DeleteAll() OVERRIDE; + + // Get the list of servers (host/port) that support SPDY. + void GetSpdyServerList(base::ListValue* spdy_server_list) const; + + // Returns flattened string representation of the |host_port_pair|. Used by + // unittests. + static std::string GetFlattenedSpdyServer( + const net::HostPortPair& host_port_pair); + + private: + // |spdy_servers_table_| has flattened representation of servers (host/port + // pair) that either support or not support SPDY protocol. + typedef base::hash_map<std::string, bool> SpdyServerHostPortTable; + SpdyServerHostPortTable spdy_servers_table_; + + DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl); +}; + +} // namespace net + +#endif // NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc new file mode 100644 index 0000000..a9f556c --- /dev/null +++ b/net/http/http_server_properties_impl_unittest.cc @@ -0,0 +1,186 @@ +// Copyright (c) 2011 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/http_server_properties_impl.h" + +#include <string> + +#include "base/basictypes.h" +#include "base/hash_tables.h" +#include "base/logging.h" +#include "base/memory/scoped_ptr.h" +#include "base/values.h" +#include "net/base/host_port_pair.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace base { +class ListValue; +} + +namespace net { + +namespace { + +class HttpServerPropertiesImplTest : public testing::Test { + protected: + HttpServerPropertiesImpl impl_; +}; + +TEST_F(HttpServerPropertiesImplTest, InitializeTest) { + HostPortPair spdy_server_google("www.google.com", 443); + std::string spdy_server_g = + HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google); + + HostPortPair spdy_server_docs("docs.google.com", 443); + std::string spdy_server_d = + HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_docs); + + // Check by initializing NULL spdy servers. + impl_.Initialize(NULL, true); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); + + // Check by initializing empty spdy servers. + HttpServerProperties::StringVector spdy_servers; + impl_.Initialize(&spdy_servers, true); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); + + // Check by initializing with www.google.com:443 spdy server. + HttpServerProperties::StringVector spdy_servers1; + spdy_servers1.push_back(spdy_server_g); + impl_.Initialize(&spdy_servers1, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + + // Check by initializing with www.google.com:443 and docs.google.com:443 spdy + // servers. + HttpServerProperties::StringVector spdy_servers2; + spdy_servers2.push_back(spdy_server_g); + spdy_servers2.push_back(spdy_server_d); + impl_.Initialize(&spdy_servers2, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); +} + +TEST_F(HttpServerPropertiesImplTest, SupportsSpdyTest) { + HostPortPair spdy_server_empty("", 443); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); + + // Add www.google.com:443 as supporting SPDY. + HostPortPair spdy_server_google("www.google.com", 443); + impl_.SetSupportsSpdy(spdy_server_google, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + + // Add mail.google.com:443 as not supporting SPDY. + HostPortPair spdy_server_mail("mail.google.com", 443); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); + + // Add docs.google.com:443 as supporting SPDY. + HostPortPair spdy_server_docs("docs.google.com", 443); + impl_.SetSupportsSpdy(spdy_server_docs, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); + + // Verify all the entries are the same after additions. + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); +} + +TEST_F(HttpServerPropertiesImplTest, SetSupportsSpdyTest) { + HostPortPair spdy_server_empty("", 443); + impl_.SetSupportsSpdy(spdy_server_empty, true); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); + + // Add www.google.com:443 as supporting SPDY. + HostPortPair spdy_server_google("www.google.com", 443); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); + impl_.SetSupportsSpdy(spdy_server_google, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + + // Make www.google.com:443 as not supporting SPDY. + impl_.SetSupportsSpdy(spdy_server_google, false); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); + + // Add mail.google.com:443 as supporting SPDY. + HostPortPair spdy_server_mail("mail.google.com", 443); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); + impl_.SetSupportsSpdy(spdy_server_mail, true); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_mail)); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); +} + +TEST_F(HttpServerPropertiesImplTest, DeleteAllTest) { + // Add www.google.com:443 and mail.google.com:443 as supporting SPDY. + HostPortPair spdy_server_google("www.google.com", 443); + impl_.SetSupportsSpdy(spdy_server_google, true); + HostPortPair spdy_server_mail("mail.google.com", 443); + impl_.SetSupportsSpdy(spdy_server_mail, true); + + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); + EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_mail)); + + impl_.DeleteAll(); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); + EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); +} + +TEST_F(HttpServerPropertiesImplTest, GetSpdyServerListTest) { + base::ListValue spdy_server_list; + + // Check there are no spdy_servers. + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(0u, spdy_server_list.GetSize()); + + // Check empty server is not added. + HostPortPair spdy_server_empty("", 443); + impl_.SetSupportsSpdy(spdy_server_empty, true); + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(0u, spdy_server_list.GetSize()); + + std::string string_value_g; + std::string string_value_m; + HostPortPair spdy_server_google("www.google.com", 443); + std::string spdy_server_g = + HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google); + HostPortPair spdy_server_mail("mail.google.com", 443); + std::string spdy_server_m = + HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_mail); + + // Add www.google.com:443 as not supporting SPDY. + impl_.SetSupportsSpdy(spdy_server_google, false); + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(0u, spdy_server_list.GetSize()); + + // Add www.google.com:443 as supporting SPDY. + impl_.SetSupportsSpdy(spdy_server_google, true); + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(1u, spdy_server_list.GetSize()); + ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); + ASSERT_EQ(spdy_server_g, string_value_g); + + // Add mail.google.com:443 as not supporting SPDY. + impl_.SetSupportsSpdy(spdy_server_mail, false); + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(1u, spdy_server_list.GetSize()); + ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); + ASSERT_EQ(spdy_server_g, string_value_g); + + // Add mail.google.com:443 as supporting SPDY. + impl_.SetSupportsSpdy(spdy_server_mail, true); + impl_.GetSpdyServerList(&spdy_server_list); + EXPECT_EQ(2u, spdy_server_list.GetSize()); + + // Verify www.google.com:443 and mail.google.com:443 are in the list. + ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); + ASSERT_TRUE(spdy_server_list.GetString(1, &string_value_m)); + if (string_value_g.compare(spdy_server_g) == 0) { + ASSERT_EQ(spdy_server_g, string_value_g); + ASSERT_EQ(spdy_server_m, string_value_m); + } else { + ASSERT_EQ(spdy_server_g, string_value_m); + ASSERT_EQ(spdy_server_m, string_value_g); + } +} + +} // namespace + +} // namespace net diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index b55d1ac..f496042 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -19,6 +19,7 @@ #include "net/http/http_proxy_client_socket.h" #include "net/http/http_proxy_client_socket_pool.h" #include "net/http/http_request_info.h" +#include "net/http/http_server_properties.h" #include "net/http/http_stream_factory_impl_request.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool.h" @@ -119,7 +120,17 @@ void HttpStreamFactoryImpl::Job::Start(Request* request) { int HttpStreamFactoryImpl::Job::Preconnect(int num_streams) { DCHECK_GT(num_streams, 0); - num_streams_ = num_streams; + HostPortPair origin_server = + HostPortPair(request_info_.url.HostNoBrackets(), + request_info_.url.EffectiveIntPort()); + HttpServerProperties* http_server_properties = + session_->http_server_properties(); + if (http_server_properties && + http_server_properties->SupportsSpdy(origin_server)) { + num_streams_ = 1; + } else { + num_streams_ = num_streams; + } return StartInternal(); } @@ -821,6 +832,11 @@ int HttpStreamFactoryImpl::Job::DoCreateStream() { &new_spdy_session_, using_ssl_); if (error != OK) return error; + const HostPortPair& host_port_pair = pair.first; + HttpServerProperties* http_server_properties = + session_->http_server_properties(); + if (http_server_properties) + http_server_properties->SetSupportsSpdy(host_port_pair, true); spdy_session_direct_ = direct; return OK; } diff --git a/net/net.gyp b/net/net.gyp index fdde802..8d27cfa 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -425,6 +425,9 @@ 'http/http_response_headers.h', 'http/http_response_info.cc', 'http/http_response_info.h', + 'http/http_server_properties.h', + 'http/http_server_properties_impl.cc', + 'http/http_server_properties_impl.h', 'http/http_stream.h', 'http/http_stream_factory.cc', 'http/http_stream_factory.h', @@ -1020,6 +1023,7 @@ 'http/http_request_headers_unittest.cc', 'http/http_response_body_drainer_unittest.cc', 'http/http_response_headers_unittest.cc', + 'http/http_server_properties_impl_unittest.cc', 'http/http_stream_factory_impl_unittest.cc', 'http/http_transaction_unittest.cc', 'http/http_transaction_unittest.h', diff --git a/net/spdy/spdy_test_util.cc b/net/spdy/spdy_test_util.cc index e8c5138..efe1efa 100644 --- a/net/spdy/spdy_test_util.cc +++ b/net/spdy/spdy_test_util.cc @@ -957,6 +957,7 @@ SpdyURLRequestContext::SpdyURLRequestContext() params.ssl_config_service = ssl_config_service(); params.http_auth_handler_factory = http_auth_handler_factory(); params.network_delegate = network_delegate(); + params.http_server_properties = http_server_properties(); scoped_refptr<HttpNetworkSession> network_session( new HttpNetworkSession(params)); storage_.set_http_transaction_factory(new HttpCache( diff --git a/net/url_request/url_request_context.cc b/net/url_request/url_request_context.cc index e808a0e..868532e 100644 --- a/net/url_request/url_request_context.cc +++ b/net/url_request/url_request_context.cc @@ -24,6 +24,7 @@ URLRequestContext::URLRequestContext() http_auth_handler_factory_(NULL), proxy_service_(NULL), network_delegate_(NULL), + http_server_properties_(NULL), transport_security_state_(NULL), ftp_auth_cache_(new FtpAuthCache), http_transaction_factory_(NULL), @@ -43,6 +44,7 @@ void URLRequestContext::CopyFrom(URLRequestContext* other) { set_proxy_service(other->proxy_service()); set_ssl_config_service(other->ssl_config_service()); set_network_delegate(other->network_delegate()); + set_http_server_properties(other->http_server_properties()); set_cookie_store(other->cookie_store()); set_transport_security_state(other->transport_security_state()); // FTPAuthCache is unique per context. diff --git a/net/url_request/url_request_context.h b/net/url_request/url_request_context.h index 35c4a82..1168ec5 100644 --- a/net/url_request/url_request_context.h +++ b/net/url_request/url_request_context.h @@ -19,6 +19,7 @@ #include "net/base/net_log.h" #include "net/base/ssl_config_service.h" #include "net/base/transport_security_state.h" +#include "net/http/http_server_properties.h" #include "net/ftp/ftp_auth_cache.h" namespace net { @@ -143,6 +144,14 @@ class NET_EXPORT URLRequestContext } NetworkDelegate* network_delegate() const { return network_delegate_; } + void set_http_server_properties( + HttpServerProperties* http_server_properties) { + http_server_properties_ = http_server_properties; + } + HttpServerProperties* http_server_properties() const { + return http_server_properties_; + } + // Gets the cookie store for this context (may be null, in which case // cookies are not stored). CookieStore* cookie_store() const { return cookie_store_.get(); } @@ -213,6 +222,7 @@ class NET_EXPORT URLRequestContext ProxyService* proxy_service_; scoped_refptr<SSLConfigService> ssl_config_service_; NetworkDelegate* network_delegate_; + HttpServerProperties* http_server_properties_; scoped_refptr<CookieStore> cookie_store_; TransportSecurityState* transport_security_state_; scoped_ptr<FtpAuthCache> ftp_auth_cache_; diff --git a/net/url_request/url_request_context_storage.cc b/net/url_request/url_request_context_storage.cc index e555987..337f3ad 100644 --- a/net/url_request/url_request_context_storage.cc +++ b/net/url_request/url_request_context_storage.cc @@ -14,6 +14,7 @@ #include "net/base/origin_bound_cert_service.h" #include "net/ftp/ftp_transaction_factory.h" #include "net/http/http_auth_handler_factory.h" +#include "net/http/http_server_properties.h" #include "net/http/http_transaction_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/dns_cert_provenance_checker.h" @@ -85,6 +86,12 @@ void URLRequestContextStorage::set_network_delegate( network_delegate_.reset(network_delegate); } +void URLRequestContextStorage::set_http_server_properties( + HttpServerProperties* http_server_properties) { + context_->set_http_server_properties(http_server_properties); + http_server_properties_ = http_server_properties; +} + void URLRequestContextStorage::set_cookie_store(CookieStore* cookie_store) { context_->set_cookie_store(cookie_store); cookie_store_ = cookie_store; diff --git a/net/url_request/url_request_context_storage.h b/net/url_request/url_request_context_storage.h index a7583d1..7449766 100644 --- a/net/url_request/url_request_context_storage.h +++ b/net/url_request/url_request_context_storage.h @@ -20,6 +20,7 @@ class DnsRRResolver; class FtpTransactionFactory; class HostResolver; class HttpAuthHandlerFactory; +class HttpServerProperties; class HttpTransactionFactory; class NetLog; class NetworkDelegate; @@ -55,6 +56,7 @@ class NET_EXPORT URLRequestContextStorage { void set_proxy_service(ProxyService* proxy_service); void set_ssl_config_service(SSLConfigService* ssl_config_service); void set_network_delegate(NetworkDelegate* network_delegate); + void set_http_server_properties(HttpServerProperties* http_server_properties); void set_cookie_store(CookieStore* cookie_store); void set_transport_security_state( TransportSecurityState* transport_security_state); @@ -82,6 +84,7 @@ class NET_EXPORT URLRequestContextStorage { // TODO(willchan): Remove refcounting on these members. scoped_refptr<SSLConfigService> ssl_config_service_; scoped_ptr<NetworkDelegate> network_delegate_; + HttpServerProperties* http_server_properties_; scoped_refptr<CookieStore> cookie_store_; scoped_ptr<TransportSecurityState> transport_security_state_; diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index a0fd90f..0fe60fc 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -125,6 +125,7 @@ void TestURLRequestContext::Init() { params.ssl_config_service = ssl_config_service(); params.http_auth_handler_factory = http_auth_handler_factory(); params.network_delegate = network_delegate(); + params.http_server_properties = http_server_properties(); if (!http_transaction_factory()) { context_storage_.set_http_transaction_factory(new net::HttpCache( diff --git a/webkit/tools/test_shell/test_shell_request_context.cc b/webkit/tools/test_shell/test_shell_request_context.cc index 82495b6..a8df78f 100644 --- a/webkit/tools/test_shell/test_shell_request_context.cc +++ b/webkit/tools/test_shell/test_shell_request_context.cc @@ -93,7 +93,8 @@ void TestShellRequestContext::Init( new net::HttpCache(host_resolver(), cert_verifier(), origin_bound_cert_service(), NULL, NULL, proxy_service(), ssl_config_service(), - http_auth_handler_factory(), NULL, NULL, backend); + http_auth_handler_factory(), NULL, NULL, NULL, + backend); cache->set_mode(cache_mode); storage_.set_http_transaction_factory(cache); |