diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-10 07:32:53 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-10 07:32:53 +0000 |
commit | 17291a02bb3589d94ceb63fbb14ca59fff75e163 (patch) | |
tree | dff2d5c6919d567ced7dcbfeea6c8daa580b0673 /net | |
parent | cd6e0ba8e0d9435222349ff4d4d7b19d137d9c57 (diff) | |
download | chromium_src-17291a02bb3589d94ceb63fbb14ca59fff75e163.zip chromium_src-17291a02bb3589d94ceb63fbb14ca59fff75e163.tar.gz chromium_src-17291a02bb3589d94ceb63fbb14ca59fff75e163.tar.bz2 |
Migrate HttpAlternateProtocols to HttpServerPropertiesImpl.
Hooks in HttpServerPropertiesManager also. No persistence done yet. This is all plumbing.
Also require HttpServerProperties in HttpNetworkSession::Params.
BUG=98472
TEST=none
Review URL: http://codereview.chromium.org/8211003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@104696 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
30 files changed, 441 insertions, 459 deletions
diff --git a/net/http/http_alternate_protocols.cc b/net/http/http_alternate_protocols.cc deleted file mode 100644 index 42a6a9f..0000000 --- a/net/http/http_alternate_protocols.cc +++ /dev/null @@ -1,137 +0,0 @@ -// Copyright (c) 2010 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_alternate_protocols.h" - -#include "base/logging.h" -#include "base/stringprintf.h" -#include "base/stl_util.h" - -namespace net { - -const char HttpAlternateProtocols::kHeader[] = "Alternate-Protocol"; -const char* const HttpAlternateProtocols::kProtocolStrings[] = { - "npn-spdy/1", - "npn-spdy/2", -}; - -const char* HttpAlternateProtocols::ProtocolToString( - HttpAlternateProtocols::Protocol protocol) { - switch (protocol) { - case HttpAlternateProtocols::NPN_SPDY_1: - case HttpAlternateProtocols::NPN_SPDY_2: - return HttpAlternateProtocols::kProtocolStrings[protocol]; - case HttpAlternateProtocols::BROKEN: - return "Broken"; - case HttpAlternateProtocols::UNINITIALIZED: - return "Uninitialized"; - default: - NOTREACHED(); - return ""; - } -} - - -std::string HttpAlternateProtocols::PortProtocolPair::ToString() const { - return base::StringPrintf("%d:%s", port, - HttpAlternateProtocols::ProtocolToString(protocol)); -} - -// static -HttpAlternateProtocols::PortProtocolPair* - HttpAlternateProtocols::forced_alternate_protocol_ = NULL; - -HttpAlternateProtocols::HttpAlternateProtocols() {} -HttpAlternateProtocols::~HttpAlternateProtocols() {} - -bool HttpAlternateProtocols::HasAlternateProtocolFor( - const HostPortPair& http_host_port_pair) const { - return ContainsKey(protocol_map_, http_host_port_pair) || - forced_alternate_protocol_; -} - -bool HttpAlternateProtocols::HasAlternateProtocolFor( - const std::string& host, uint16 port) const { - HostPortPair http_host_port_pair(host, port); - return HasAlternateProtocolFor(http_host_port_pair); -} - -HttpAlternateProtocols::PortProtocolPair -HttpAlternateProtocols::GetAlternateProtocolFor( - const HostPortPair& http_host_port_pair) const { - DCHECK(HasAlternateProtocolFor(http_host_port_pair)); - - // First check the map. - ProtocolMap::const_iterator it = protocol_map_.find(http_host_port_pair); - if (it != protocol_map_.end()) - return it->second; - - // We must be forcing an alternate. - DCHECK(forced_alternate_protocol_); - return *forced_alternate_protocol_; -} - -HttpAlternateProtocols::PortProtocolPair -HttpAlternateProtocols::GetAlternateProtocolFor( - const std::string& host, uint16 port) const { - HostPortPair http_host_port_pair(host, port); - return GetAlternateProtocolFor(http_host_port_pair); -} - -void HttpAlternateProtocols::SetAlternateProtocolFor( - const HostPortPair& http_host_port_pair, - uint16 alternate_port, - Protocol alternate_protocol) { - if (alternate_protocol == BROKEN) { - LOG(DFATAL) << "Call MarkBrokenAlternateProtocolFor() instead."; - return; - } - - PortProtocolPair alternate; - alternate.port = alternate_port; - alternate.protocol = alternate_protocol; - if (HasAlternateProtocolFor(http_host_port_pair)) { - const PortProtocolPair existing_alternate = - GetAlternateProtocolFor(http_host_port_pair); - - if (existing_alternate.protocol == BROKEN) { - DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; - return; - } - - if (alternate_protocol != BROKEN && !existing_alternate.Equals(alternate)) { - LOG(WARNING) << "Changing the alternate protocol for: " - << http_host_port_pair.ToString() - << " from [Port: " << existing_alternate.port - << ", Protocol: " << existing_alternate.protocol - << "] to [Port: " << alternate_port - << ", Protocol: " << alternate_protocol - << "]."; - } - } - - protocol_map_[http_host_port_pair] = alternate; -} - -void HttpAlternateProtocols::MarkBrokenAlternateProtocolFor( - const HostPortPair& http_host_port_pair) { - protocol_map_[http_host_port_pair].protocol = BROKEN; -} - -// static -void HttpAlternateProtocols::ForceAlternateProtocol( - const PortProtocolPair& pair) { - // Note: we're going to leak this. - if (forced_alternate_protocol_) - delete forced_alternate_protocol_; - forced_alternate_protocol_ = new PortProtocolPair(pair); -} - -// static -void HttpAlternateProtocols::DisableForcedAlternateProtocol() { - delete forced_alternate_protocol_; - forced_alternate_protocol_ = NULL; -} - -} // namespace net diff --git a/net/http/http_alternate_protocols.h b/net/http/http_alternate_protocols.h deleted file mode 100644 index 3e10e08..0000000 --- a/net/http/http_alternate_protocols.h +++ /dev/null @@ -1,94 +0,0 @@ -// 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. -// -// HttpAlternateProtocols is an in-memory data structure used for keeping track -// of which HTTP HostPortPairs have an alternate protocol that can be used -// instead of HTTP on a different port. - -#ifndef NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_ -#define NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_ -#pragma once - -#include <map> -#include <string> -#include <utility> - -#include "base/basictypes.h" -#include "net/base/host_port_pair.h" -#include "net/base/net_export.h" - -namespace net { - -class NET_EXPORT HttpAlternateProtocols { - public: - enum Protocol { - NPN_SPDY_1, - NPN_SPDY_2, - NUM_ALTERNATE_PROTOCOLS, - BROKEN, // The alternate protocol is known to be broken. - UNINITIALIZED, - }; - - struct NET_EXPORT PortProtocolPair { - bool Equals(const PortProtocolPair& other) const { - return port == other.port && protocol == other.protocol; - } - - std::string ToString() const; - - uint16 port; - Protocol protocol; - }; - - typedef std::map<HostPortPair, PortProtocolPair> ProtocolMap; - - static const char kHeader[]; - static const char* const kProtocolStrings[NUM_ALTERNATE_PROTOCOLS]; - - HttpAlternateProtocols(); - ~HttpAlternateProtocols(); - - // Reports whether or not we have received Alternate-Protocol for - // |http_host_port_pair|. - bool HasAlternateProtocolFor(const HostPortPair& http_host_port_pair) const; - bool HasAlternateProtocolFor(const std::string& host, uint16 port) const; - - PortProtocolPair GetAlternateProtocolFor( - const HostPortPair& http_host_port_pair) const; - PortProtocolPair GetAlternateProtocolFor( - const std::string& host, uint16 port) const; - - // SetAlternateProtocolFor() will ignore the request if the alternate protocol - // has already been marked broken via MarkBrokenAlternateProtocolFor(). - void SetAlternateProtocolFor(const HostPortPair& http_host_port_pair, - uint16 alternate_port, - Protocol alternate_protocol); - - // Marks the alternate protocol as broken. Once marked broken, any further - // attempts to set the alternate protocol for |http_host_port_pair| will fail. - void MarkBrokenAlternateProtocolFor(const HostPortPair& http_host_port_pair); - - const ProtocolMap& protocol_map() const { return protocol_map_; } - - // Debugging to simulate presence of an AlternateProtocol. - // If we don't have an alternate protocol in the map for any given host/port - // pair, force this ProtocolPortPair. - static void ForceAlternateProtocol(const PortProtocolPair& pair); - static void DisableForcedAlternateProtocol(); - - private: - ProtocolMap protocol_map_; - - static const char* ProtocolToString(Protocol protocol); - - // The forced alternate protocol. If not-null, there is a protocol being - // forced. - static PortProtocolPair* forced_alternate_protocol_; - - DISALLOW_COPY_AND_ASSIGN(HttpAlternateProtocols); -}; - -} // namespace net - -#endif // NET_HTTP_HTTP_ALTERNATE_PROTOCOLS_H_ diff --git a/net/http/http_alternate_protocols_unittest.cc b/net/http/http_alternate_protocols_unittest.cc deleted file mode 100644 index 8a2ac66..0000000 --- a/net/http/http_alternate_protocols_unittest.cc +++ /dev/null @@ -1,85 +0,0 @@ -// Copyright (c) 2010 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. -// -// HttpAlternateProtocols is an in-memory data structure used for keeping track -// of which HTTP HostPortPairs have an alternate protocol that can be used -// instead of HTTP on a different port. - -#include "net/http/http_alternate_protocols.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace net { -namespace { - -TEST(HttpAlternateProtocols, Basic) { - HttpAlternateProtocols alternate_protocols; - HostPortPair test_host_port_pair("foo", 80); - EXPECT_FALSE( - alternate_protocols.HasAlternateProtocolFor(test_host_port_pair)); - alternate_protocols.SetAlternateProtocolFor( - test_host_port_pair, 443, HttpAlternateProtocols::NPN_SPDY_1); - ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(test_host_port_pair)); - const HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols.GetAlternateProtocolFor(test_host_port_pair); - EXPECT_EQ(443, alternate.port); - EXPECT_EQ(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol); -} - -TEST(HttpAlternateProtocols, SetBroken) { - HttpAlternateProtocols alternate_protocols; - HostPortPair test_host_port_pair("foo", 80); - alternate_protocols.MarkBrokenAlternateProtocolFor(test_host_port_pair); - ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(test_host_port_pair)); - HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols.GetAlternateProtocolFor(test_host_port_pair); - EXPECT_EQ(HttpAlternateProtocols::BROKEN, alternate.protocol); - - alternate_protocols.SetAlternateProtocolFor( - test_host_port_pair, - 1234, - HttpAlternateProtocols::NPN_SPDY_1); - alternate = alternate_protocols.GetAlternateProtocolFor(test_host_port_pair); - EXPECT_EQ(HttpAlternateProtocols::BROKEN, alternate.protocol) - << "Second attempt should be ignored."; -} - -TEST(HttpAlternateProtocols, Forced) { - // Test forced alternate protocols. - - HttpAlternateProtocols::PortProtocolPair default_protocol; - default_protocol.port = 1234; - default_protocol.protocol = HttpAlternateProtocols::NPN_SPDY_2; - HttpAlternateProtocols::ForceAlternateProtocol(default_protocol); - - HttpAlternateProtocols alternate_protocols; - - // Verify the forced protocol. - HostPortPair test_host_port_pair("foo", 80); - EXPECT_TRUE( - alternate_protocols.HasAlternateProtocolFor(test_host_port_pair)); - HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols.GetAlternateProtocolFor(test_host_port_pair); - EXPECT_EQ(default_protocol.port, alternate.port); - EXPECT_EQ(default_protocol.protocol, alternate.protocol); - - // Verify the real protocol overrides the forced protocol. - alternate_protocols.SetAlternateProtocolFor( - test_host_port_pair, 443, HttpAlternateProtocols::NPN_SPDY_1); - ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(test_host_port_pair)); - alternate = alternate_protocols.GetAlternateProtocolFor(test_host_port_pair); - EXPECT_EQ(443, alternate.port); - EXPECT_EQ(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol); - - // Turn off the static, forced alternate protocol so that tests don't - // have this state. - HttpAlternateProtocols::DisableForcedAlternateProtocol(); - - // Verify the forced protocol is off. - HostPortPair test_host_port_pair2("bar", 80); - EXPECT_FALSE( - alternate_protocols.HasAlternateProtocolFor(test_host_port_pair2)); -} - -} // namespace -} // namespace net diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 68bc5f8..e8ee62c 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -10,6 +10,7 @@ #include "base/string_util.h" #include "net/http/http_network_session.h" #include "net/http/http_network_transaction.h" +#include "net/http/http_server_properties_impl.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" @@ -119,10 +120,10 @@ void HttpNetworkLayer::EnableSpdy(const std::string& mode) { } else if (option == kEnableFlowControl) { SpdySession::set_flow_control(true); } else if (option == kForceAltProtocols) { - HttpAlternateProtocols::PortProtocolPair pair; + PortAlternateProtocolPair pair; pair.port = 443; - pair.protocol = HttpAlternateProtocols::NPN_SPDY_2; - HttpAlternateProtocols::ForceAlternateProtocol(pair); + pair.protocol = NPN_SPDY_2; + HttpServerPropertiesImpl::ForceAlternateProtocol(pair); } else if (option == kSingleDomain) { SpdySessionPool::ForceSingleDomain(); LOG(ERROR) << "FORCING SINGLE DOMAIN"; diff --git a/net/http/http_network_layer_unittest.cc b/net/http/http_network_layer_unittest.cc index 118ed20..b598e8e 100644 --- a/net/http/http_network_layer_unittest.cc +++ b/net/http/http_network_layer_unittest.cc @@ -8,6 +8,7 @@ #include "net/base/ssl_config_service_defaults.h" #include "net/http/http_network_layer.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_transaction_unittest.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" @@ -30,6 +31,7 @@ class HttpNetworkLayerTest : public PlatformTest { session_params.cert_verifier = &cert_verifier_; session_params.proxy_service = proxy_service_.get(); session_params.ssl_config_service = ssl_config_service_; + session_params.http_server_properties = &http_server_properties_; network_session_ = new HttpNetworkSession(session_params); factory_.reset(new HttpNetworkLayer(network_session_)); } @@ -41,6 +43,7 @@ class HttpNetworkLayerTest : public PlatformTest { const scoped_refptr<SSLConfigService> ssl_config_service_; scoped_refptr<HttpNetworkSession> network_session_; scoped_ptr<HttpNetworkLayer> factory_; + HttpServerPropertiesImpl http_server_properties_; }; TEST_F(HttpNetworkLayerTest, CreateAndDestroy) { diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 5fed4bf..8346573 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -45,8 +45,9 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) spdy_session_pool_(params.host_resolver, params.ssl_config_service), ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_factory_( new HttpStreamFactoryImpl(this))) { - DCHECK(params.proxy_service); - DCHECK(params.ssl_config_service); + DCHECK(proxy_service_); + DCHECK(ssl_config_service_); + CHECK(http_server_properties_); } HttpNetworkSession::~HttpNetworkSession() { diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 777653b..c65b480 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -13,7 +13,6 @@ #include "net/base/host_resolver.h" #include "net/base/net_export.h" #include "net/base/ssl_client_auth_cache.h" -#include "net/http/http_alternate_protocols.h" #include "net/http/http_auth_cache.h" #include "net/http/http_stream_factory.h" #include "net/socket/client_socket_pool_manager.h" @@ -89,13 +88,6 @@ class NET_EXPORT HttpNetworkSession void RemoveResponseDrainer(HttpResponseBodyDrainer* drainer); - const HttpAlternateProtocols& alternate_protocols() const { - return alternate_protocols_; - } - HttpAlternateProtocols* mutable_alternate_protocols() { - return &alternate_protocols_; - } - TransportClientSocketPool* transport_socket_pool() { return socket_pool_manager_.transport_socket_pool(); } @@ -126,11 +118,9 @@ class NET_EXPORT HttpNetworkSession HttpServerProperties* http_server_properties() { return http_server_properties_; } - HttpStreamFactory* http_stream_factory() { return http_stream_factory_.get(); } - NetLog* net_log() { return net_log_; } @@ -164,7 +154,6 @@ class NET_EXPORT HttpNetworkSession HttpAuthCache http_auth_cache_; SSLClientAuthCache ssl_client_auth_cache_; - HttpAlternateProtocols alternate_protocols_; ClientSocketPoolManager socket_pool_manager_; SpdySessionPool spdy_session_pool_; scoped_ptr<HttpStreamFactory> http_stream_factory_; diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 39fc380..2e6a46c 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -42,6 +42,7 @@ #include "net/http/http_response_body_drainer.h" #include "net/http/http_response_headers.h" #include "net/http/http_response_info.h" +#include "net/http/http_server_properties.h" #include "net/http/http_stream_factory.h" #include "net/http/http_util.h" #include "net/http/url_security_manager.h" @@ -61,18 +62,18 @@ namespace net { namespace { void ProcessAlternateProtocol(HttpStreamFactory* factory, - HttpAlternateProtocols* alternate_protocols, + HttpServerProperties* http_server_properties, const HttpResponseHeaders& headers, const HostPortPair& http_host_port_pair) { std::string alternate_protocol_str; - if (!headers.EnumerateHeader(NULL, HttpAlternateProtocols::kHeader, + if (!headers.EnumerateHeader(NULL, kAlternateProtocolHeader, &alternate_protocol_str)) { // Header is not present. return; } - factory->ProcessAlternateProtocol(alternate_protocols, + factory->ProcessAlternateProtocol(http_server_properties, alternate_protocol_str, http_host_port_pair); } @@ -864,7 +865,7 @@ int HttpNetworkTransaction::DoReadHeadersComplete(int result) { HostPortPair endpoint = HostPortPair(request_->url.HostNoBrackets(), request_->url.EffectiveIntPort()); ProcessAlternateProtocol(session_->http_stream_factory(), - session_->mutable_alternate_protocols(), + session_->http_server_properties(), *response_.headers, endpoint); diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 9449a12..307cf86 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -34,6 +34,7 @@ #include "net/http/http_net_log_params.h" #include "net/http/http_network_session.h" #include "net/http/http_network_session_peer.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_stream.h" #include "net/http/http_stream_factory.h" #include "net/http/http_transaction_unittest.h" @@ -100,6 +101,7 @@ struct SessionDependencies { scoped_refptr<SSLConfigService> ssl_config_service; MockClientSocketFactory socket_factory; scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; + HttpServerPropertiesImpl http_server_properties; NetLog* net_log; }; @@ -112,6 +114,7 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { params.ssl_config_service = session_deps->ssl_config_service; params.http_auth_handler_factory = session_deps->http_auth_handler_factory.get(); + params.http_server_properties = &session_deps->http_server_properties; params.net_log = session_deps->net_log; return new HttpNetworkSession(params); } @@ -5515,11 +5518,11 @@ scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( SessionDependencies* session_deps) { scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); - alternate_protocols->SetAlternateProtocolFor( + HttpServerProperties* http_server_properties = + session->http_server_properties(); + http_server_properties->SetAlternateProtocol( HostPortPair("host.with.alternate", 80), 443, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); return session; } @@ -6499,10 +6502,10 @@ TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { EXPECT_EQ(ERR_IO_PENDING, rv); HostPortPair http_host_port_pair("www.google.com", 80); - const HttpAlternateProtocols& alternate_protocols = - session->alternate_protocols(); + const HttpServerProperties& http_server_properties = + *session->http_server_properties(); EXPECT_FALSE( - alternate_protocols.HasAlternateProtocolFor(http_host_port_pair)); + http_server_properties.HasAlternateProtocol(http_host_port_pair)); EXPECT_EQ(OK, callback.WaitForResult()); @@ -6517,12 +6520,12 @@ TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); EXPECT_EQ("hello world", response_data); - ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(http_host_port_pair)); - const HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols.GetAlternateProtocolFor(http_host_port_pair); - HttpAlternateProtocols::PortProtocolPair expected_alternate; + ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); + const PortAlternateProtocolPair alternate = + http_server_properties.GetAlternateProtocol(http_host_port_pair); + PortAlternateProtocolPair expected_alternate; expected_alternate.port = 443; - expected_alternate.protocol = HttpAlternateProtocols::NPN_SPDY_2; + expected_alternate.protocol = NPN_SPDY_2; EXPECT_TRUE(expected_alternate.Equals(alternate)); HttpStreamFactory::set_use_alternate_protocols(false); @@ -6554,14 +6557,14 @@ TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); + HttpServerProperties* http_server_properties = + session->http_server_properties(); // Port must be < 1024, or the header will be ignored (since initial port was // port 80 (another restricted port). - alternate_protocols->SetAlternateProtocolFor( + http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(request.url), 666 /* port is ignored by MockConnect anyway */, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); TestOldCompletionCallback callback; @@ -6579,12 +6582,12 @@ TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) { ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data)); EXPECT_EQ("hello world", response_data); - ASSERT_TRUE(alternate_protocols->HasAlternateProtocolFor( + ASSERT_TRUE(http_server_properties->HasAlternateProtocol( HostPortPair::FromURL(request.url))); - const HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols->GetAlternateProtocolFor( + const PortAlternateProtocolPair alternate = + http_server_properties->GetAlternateProtocol( HostPortPair::FromURL(request.url)); - EXPECT_EQ(HttpAlternateProtocols::BROKEN, alternate.protocol); + EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); HttpStreamFactory::set_use_alternate_protocols(false); } @@ -6617,13 +6620,13 @@ TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedBlocked) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); + HttpServerProperties* http_server_properties = + session->http_server_properties(); const int kUnrestrictedAlternatePort = 1024; - alternate_protocols->SetAlternateProtocolFor( + http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(restricted_port_request.url), kUnrestrictedAlternatePort, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); TestOldCompletionCallback callback; @@ -6665,13 +6668,13 @@ TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortRestrictedAllowed) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); + HttpServerProperties* http_server_properties = + session->http_server_properties(); const int kRestrictedAlternatePort = 80; - alternate_protocols->SetAlternateProtocolFor( + http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(restricted_port_request.url), kRestrictedAlternatePort, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); TestOldCompletionCallback callback; @@ -6713,13 +6716,13 @@ TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed1) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); + HttpServerProperties* http_server_properties = + session->http_server_properties(); const int kRestrictedAlternatePort = 80; - alternate_protocols->SetAlternateProtocolFor( + http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(unrestricted_port_request.url), kRestrictedAlternatePort, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); TestOldCompletionCallback callback; @@ -6761,13 +6764,13 @@ TEST_F(HttpNetworkTransactionTest, AlternateProtocolPortUnrestrictedAllowed2) { scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps)); - HttpAlternateProtocols* alternate_protocols = - session->mutable_alternate_protocols(); + HttpServerProperties* http_server_properties = + session->http_server_properties(); const int kUnrestrictedAlternatePort = 1024; - alternate_protocols->SetAlternateProtocolFor( + http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(unrestricted_port_request.url), kUnrestrictedAlternatePort, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); TestOldCompletionCallback callback; @@ -8960,6 +8963,7 @@ TEST_F(HttpNetworkTransactionTest, UseIPConnectionPooling) { params.ssl_config_service = session_deps.ssl_config_service; params.http_auth_handler_factory = session_deps.http_auth_handler_factory.get(); + params.http_server_properties = &session_deps.http_server_properties; params.net_log = session_deps.net_log; scoped_refptr<HttpNetworkSession> session(new HttpNetworkSession(params)); SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); @@ -9120,6 +9124,7 @@ TEST_F(HttpNetworkTransactionTest, params.ssl_config_service = session_deps.ssl_config_service; params.http_auth_handler_factory = session_deps.http_auth_handler_factory.get(); + params.http_server_properties = &session_deps.http_server_properties; params.net_log = session_deps.net_log; scoped_refptr<HttpNetworkSession> session(new HttpNetworkSession(params)); SpdySessionPoolPeer pool_peer(session->spdy_session_pool()); diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index b43b8fc..4c42e8d 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -15,6 +15,7 @@ #include "net/http/http_auth_handler_factory.h" #include "net/http/http_network_session.h" #include "net/http/http_proxy_client_socket.h" +#include "net/http/http_server_properties_impl.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_histograms.h" @@ -186,6 +187,7 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { params.client_socket_factory = &socket_factory_; params.ssl_config_service = ssl_config_service_; params.http_auth_handler_factory = http_auth_handler_factory_.get(); + params.http_server_properties = &http_server_properties_; return new HttpNetworkSession(params); } @@ -205,6 +207,7 @@ class HttpProxyClientSocketPoolTest : public TestWithHttpParam { SSLClientSocketPool ssl_socket_pool_; const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; + HttpServerPropertiesImpl http_server_properties_; const scoped_refptr<HttpNetworkSession> session_; ClientSocketPoolHistograms http_proxy_histograms_; diff --git a/net/http/http_response_body_drainer_unittest.cc b/net/http/http_response_body_drainer_unittest.cc index fc3db49..9f774db 100644 --- a/net/http/http_response_body_drainer_unittest.cc +++ b/net/http/http_response_body_drainer_unittest.cc @@ -14,6 +14,7 @@ #include "net/base/ssl_config_service_defaults.h" #include "net/base/test_completion_callback.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_stream.h" #include "net/proxy/proxy_service.h" #include "testing/gtest/include/gtest/gtest.h" @@ -183,6 +184,7 @@ class HttpResponseBodyDrainerTest : public testing::Test { HttpResponseBodyDrainerTest() : proxy_service_(ProxyService::CreateDirect()), ssl_config_service_(new SSLConfigServiceDefaults), + http_server_properties_(new HttpServerPropertiesImpl), session_(CreateNetworkSession()), mock_stream_(new MockHttpStream(&result_waiter_)), drainer_(new HttpResponseBodyDrainer(mock_stream_)) {} @@ -193,11 +195,13 @@ class HttpResponseBodyDrainerTest : public testing::Test { HttpNetworkSession::Params params; params.proxy_service = proxy_service_.get(); params.ssl_config_service = ssl_config_service_; + params.http_server_properties = http_server_properties_.get(); return new HttpNetworkSession(params); } scoped_ptr<ProxyService> proxy_service_; scoped_refptr<SSLConfigService> ssl_config_service_; + scoped_ptr<HttpServerPropertiesImpl> http_server_properties_; const scoped_refptr<HttpNetworkSession> session_; CloseResultWaiter result_waiter_; MockHttpStream* const mock_stream_; // Owned by |drainer_|. diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc new file mode 100644 index 0000000..06f519e --- /dev/null +++ b/net/http/http_server_properties.cc @@ -0,0 +1,38 @@ +// 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.h" + +#include "base/logging.h" +#include "base/stringprintf.h" + +namespace net { + +const char kAlternateProtocolHeader[] = "Alternate-Protocol"; +const char* const kAlternateProtocolStrings[] = { + "npn-spdy/1", + "npn-spdy/2", +}; + +static const char* AlternateProtocolToString(AlternateProtocol protocol) { + switch (protocol) { + case NPN_SPDY_1: + case NPN_SPDY_2: + return kAlternateProtocolStrings[protocol]; + case ALTERNATE_PROTOCOL_BROKEN: + return "Broken"; + case UNINITIALIZED_ALTERNATE_PROTOCOL: + return "Uninitialized"; + default: + NOTREACHED(); + return ""; + } +} + +std::string PortAlternateProtocolPair::ToString() const { + return base::StringPrintf("%d:%s", port, + AlternateProtocolToString(protocol)); +} + +} // namespace net diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index a8dc6bf..a026458 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -5,23 +5,50 @@ #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_H_ #define NET_HTTP_HTTP_SERVER_PROPERTIES_H_ +#include <map> #include <string> -#include <vector> - #include "base/basictypes.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" namespace net { +enum AlternateProtocol { + NPN_SPDY_1, + NPN_SPDY_2, + NUM_ALTERNATE_PROTOCOLS, + ALTERNATE_PROTOCOL_BROKEN, // The alternate protocol is known to be broken. + UNINITIALIZED_ALTERNATE_PROTOCOL, +}; + +struct NET_EXPORT PortAlternateProtocolPair { + bool Equals(const PortAlternateProtocolPair& other) const { + return port == other.port && protocol == other.protocol; + } + + std::string ToString() const; + + uint16 port; + AlternateProtocol protocol; +}; + +typedef std::map<HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap; + +extern const char kAlternateProtocolHeader[]; +extern const char* const kAlternateProtocolStrings[NUM_ALTERNATE_PROTOCOLS]; + // The interface for setting/retrieving the HTTP server properties. +// Currently, this class manages servers': +// * SPDY support (based on NPN results) +// * Alternate-Protocol support class NET_EXPORT HttpServerProperties { public: - typedef std::vector<std::string> StringVector; - HttpServerProperties() {} virtual ~HttpServerProperties() {} + // Deletes all data. + virtual void DeleteAll() = 0; + // Returns true if |server| supports SPDY. virtual bool SupportsSpdy(const HostPortPair& server) const = 0; @@ -30,8 +57,24 @@ class NET_EXPORT HttpServerProperties { virtual void SetSupportsSpdy(const HostPortPair& server, bool support_spdy) = 0; - // Deletes all data. - virtual void DeleteAll() = 0; + // Returns true if |server| has an Alternate-Protocol header. + virtual bool HasAlternateProtocol(const HostPortPair& server) const = 0; + + // Returns the Alternate-Protocol and port for |server|. + // HasAlternateProtocol(server) must be true. + virtual PortAlternateProtocolPair GetAlternateProtocol( + const HostPortPair& server) const = 0; + + // Sets the Alternate-Protocol for |server|. + virtual void SetAlternateProtocol(const HostPortPair& server, + uint16 alternate_port, + AlternateProtocol alternate_protocol) = 0; + + // Sets the Alternate-Protocol for |server| to be BROKEN. + virtual void SetBrokenAlternateProtocol(const HostPortPair& server) = 0; + + // Returns all Alternate-Protocol mappings. + virtual const AlternateProtocolMap& alternate_protocol_map() const = 0; private: DISALLOW_COPY_AND_ASSIGN(HttpServerProperties); diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 9dd341d..1226c9c 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc @@ -17,18 +17,66 @@ HttpServerPropertiesImpl::HttpServerPropertiesImpl() { HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { } -void HttpServerPropertiesImpl::Initialize(StringVector* spdy_servers, - bool support_spdy) { +void HttpServerPropertiesImpl::InitializeSpdyServers( + std::vector<std::string>* spdy_servers, + bool support_spdy) { DCHECK(CalledOnValidThread()); spdy_servers_table_.clear(); if (!spdy_servers) return; - for (StringVector::iterator it = spdy_servers->begin(); + for (std::vector<std::string>::iterator it = spdy_servers->begin(); it != spdy_servers->end(); ++it) { spdy_servers_table_[*it] = support_spdy; } } +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; +} + +static const PortAlternateProtocolPair* g_forced_alternate_protocol = NULL; + +// static +void HttpServerPropertiesImpl::ForceAlternateProtocol( + const PortAlternateProtocolPair& pair) { + // Note: we're going to leak this. + if (g_forced_alternate_protocol) + delete g_forced_alternate_protocol; + g_forced_alternate_protocol = new PortAlternateProtocolPair(pair); +} + +// static +void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { + delete g_forced_alternate_protocol; + g_forced_alternate_protocol = NULL; +} + +void HttpServerPropertiesImpl::DeleteAll() { + DCHECK(CalledOnValidThread()); + spdy_servers_table_.clear(); + alternate_protocol_map_.clear(); +} + bool HttpServerPropertiesImpl::SupportsSpdy( const net::HostPortPair& host_port_pair) const { DCHECK(CalledOnValidThread()); @@ -61,33 +109,72 @@ void HttpServerPropertiesImpl::SetSupportsSpdy( spdy_servers_table_[spdy_server] = support_spdy; } -void HttpServerPropertiesImpl::DeleteAll() { - DCHECK(CalledOnValidThread()); - spdy_servers_table_.clear(); +bool HttpServerPropertiesImpl::HasAlternateProtocol( + const HostPortPair& server) const { + return ContainsKey(alternate_protocol_map_, server) || + g_forced_alternate_protocol; } -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)); +PortAlternateProtocolPair +HttpServerPropertiesImpl::GetAlternateProtocol( + const HostPortPair& server) const { + DCHECK(HasAlternateProtocol(server)); + + // First check the map. + AlternateProtocolMap::const_iterator it = + alternate_protocol_map_.find(server); + if (it != alternate_protocol_map_.end()) + return it->second; + + // We must be forcing an alternate. + DCHECK(g_forced_alternate_protocol); + return *g_forced_alternate_protocol; +} + +void HttpServerPropertiesImpl::SetAlternateProtocol( + const HostPortPair& server, + uint16 alternate_port, + AlternateProtocol alternate_protocol) { + if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { + LOG(DFATAL) << "Call MarkBrokenAlternateProtocolFor() instead."; + return; } + + PortAlternateProtocolPair alternate; + alternate.port = alternate_port; + alternate.protocol = alternate_protocol; + if (HasAlternateProtocol(server)) { + const PortAlternateProtocolPair existing_alternate = + GetAlternateProtocol(server); + + if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { + DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; + return; + } + + if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && + !existing_alternate.Equals(alternate)) { + LOG(WARNING) << "Changing the alternate protocol for: " + << server.ToString() + << " from [Port: " << existing_alternate.port + << ", Protocol: " << existing_alternate.protocol + << "] to [Port: " << alternate_port + << ", Protocol: " << alternate_protocol + << "]."; + } + } + + alternate_protocol_map_[server] = alternate; } -// 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; +void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( + const HostPortPair& server) { + alternate_protocol_map_[server].protocol = ALTERNATE_PROTOCOL_BROKEN; +} + +const AlternateProtocolMap& +HttpServerPropertiesImpl::alternate_protocol_map() const { + return alternate_protocol_map_; } } // namespace net diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index a18b05c..0bdf1f6 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h @@ -6,6 +6,7 @@ #define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ #include <string> +#include <vector> #include "base/basictypes.h" #include "base/gtest_prod_util.h" @@ -32,7 +33,29 @@ class NET_EXPORT 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); + void InitializeSpdyServers(std::vector<std::string>* spdy_servers, + bool support_spdy); + + // 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); + + // Debugging to simulate presence of an AlternateProtocol. + // If we don't have an alternate protocol in the map for any given host/port + // pair, force this ProtocolPortPair. + static void ForceAlternateProtocol(const PortAlternateProtocolPair& pair); + static void DisableForcedAlternateProtocol(); + + // ----------------------------- + // HttpServerProperties methods: + // ----------------------------- + + // Deletes all data. + virtual void DeleteAll() OVERRIDE; // Returns true if |server| supports SPDY. virtual bool SupportsSpdy(const HostPortPair& server) const OVERRIDE; @@ -41,16 +64,25 @@ class NET_EXPORT HttpServerPropertiesImpl virtual void SetSupportsSpdy(const HostPortPair& server, bool support_spdy) OVERRIDE; - // Deletes all data. - virtual void DeleteAll() OVERRIDE; + // Returns true if |server| has an Alternate-Protocol header. + virtual bool HasAlternateProtocol(const HostPortPair& server) const OVERRIDE; - // Get the list of servers (host/port) that support SPDY. - void GetSpdyServerList(base::ListValue* spdy_server_list) const; + // Returns the Alternate-Protocol and port for |server|. + // HasAlternateProtocol(server) must be true. + virtual PortAlternateProtocolPair GetAlternateProtocol( + const HostPortPair& server) const OVERRIDE; - // Returns flattened string representation of the |host_port_pair|. Used by - // unittests. - static std::string GetFlattenedSpdyServer( - const net::HostPortPair& host_port_pair); + // Sets the Alternate-Protocol for |server|. + virtual void SetAlternateProtocol( + const HostPortPair& server, + uint16 alternate_port, + AlternateProtocol alternate_protocol) OVERRIDE; + + // Sets the Alternate-Protocol for |server| to be BROKEN. + virtual void SetBrokenAlternateProtocol(const HostPortPair& server) OVERRIDE; + + // Returns all Alternate-Protocol mappings. + virtual const AlternateProtocolMap& alternate_protocol_map() const OVERRIDE; private: // |spdy_servers_table_| has flattened representation of servers (host/port @@ -58,6 +90,8 @@ class NET_EXPORT HttpServerPropertiesImpl typedef base::hash_map<std::string, bool> SpdyServerHostPortTable; SpdyServerHostPortTable spdy_servers_table_; + AlternateProtocolMap alternate_protocol_map_; + DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl); }; diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index a9f556c..3539ef6 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc @@ -5,6 +5,7 @@ #include "net/http/http_server_properties_impl.h" #include <string> +#include <vector> #include "base/basictypes.h" #include "base/hash_tables.h" @@ -27,7 +28,9 @@ class HttpServerPropertiesImplTest : public testing::Test { HttpServerPropertiesImpl impl_; }; -TEST_F(HttpServerPropertiesImplTest, InitializeTest) { +typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest; + +TEST_F(SpdyServerPropertiesTest, InitializeTest) { HostPortPair spdy_server_google("www.google.com", 443); std::string spdy_server_g = HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google); @@ -37,31 +40,31 @@ TEST_F(HttpServerPropertiesImplTest, InitializeTest) { HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_docs); // Check by initializing NULL spdy servers. - impl_.Initialize(NULL, true); + impl_.InitializeSpdyServers(NULL, true); EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); // Check by initializing empty spdy servers. - HttpServerProperties::StringVector spdy_servers; - impl_.Initialize(&spdy_servers, true); + std::vector<std::string> spdy_servers; + impl_.InitializeSpdyServers(&spdy_servers, true); EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); // Check by initializing with www.google.com:443 spdy server. - HttpServerProperties::StringVector spdy_servers1; + std::vector<std::string> spdy_servers1; spdy_servers1.push_back(spdy_server_g); - impl_.Initialize(&spdy_servers1, true); + impl_.InitializeSpdyServers(&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; + std::vector<std::string> spdy_servers2; spdy_servers2.push_back(spdy_server_g); spdy_servers2.push_back(spdy_server_d); - impl_.Initialize(&spdy_servers2, true); + impl_.InitializeSpdyServers(&spdy_servers2, true); EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google)); EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); } -TEST_F(HttpServerPropertiesImplTest, SupportsSpdyTest) { +TEST_F(SpdyServerPropertiesTest, SupportsSpdyTest) { HostPortPair spdy_server_empty("", 443); EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); @@ -85,7 +88,7 @@ TEST_F(HttpServerPropertiesImplTest, SupportsSpdyTest) { EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs)); } -TEST_F(HttpServerPropertiesImplTest, SetSupportsSpdyTest) { +TEST_F(SpdyServerPropertiesTest, SetSupportsSpdyTest) { HostPortPair spdy_server_empty("", 443); impl_.SetSupportsSpdy(spdy_server_empty, true); EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty)); @@ -108,7 +111,7 @@ TEST_F(HttpServerPropertiesImplTest, SetSupportsSpdyTest) { EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google)); } -TEST_F(HttpServerPropertiesImplTest, DeleteAllTest) { +TEST_F(SpdyServerPropertiesTest, 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); @@ -123,7 +126,7 @@ TEST_F(HttpServerPropertiesImplTest, DeleteAllTest) { EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail)); } -TEST_F(HttpServerPropertiesImplTest, GetSpdyServerListTest) { +TEST_F(SpdyServerPropertiesTest, GetSpdyServerListTest) { base::ListValue spdy_server_list; // Check there are no spdy_servers. @@ -181,6 +184,73 @@ TEST_F(HttpServerPropertiesImplTest, GetSpdyServerListTest) { } } +typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest; + +TEST_F(AlternateProtocolServerPropertiesTest, Basic) { + HostPortPair test_host_port_pair("foo", 80); + EXPECT_FALSE( + impl_.HasAlternateProtocol(test_host_port_pair)); + impl_.SetAlternateProtocol( + test_host_port_pair, 443, NPN_SPDY_1); + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + const PortAlternateProtocolPair alternate = + impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(443, alternate.port); + EXPECT_EQ(NPN_SPDY_1, alternate.protocol); +} + +TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) { + HostPortPair test_host_port_pair("foo", 80); + impl_.SetBrokenAlternateProtocol(test_host_port_pair); + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + PortAlternateProtocolPair alternate = + impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); + + impl_.SetAlternateProtocol( + test_host_port_pair, + 1234, + NPN_SPDY_1); + alternate = impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol) + << "Second attempt should be ignored."; +} + +TEST_F(AlternateProtocolServerPropertiesTest, Forced) { + // Test forced alternate protocols. + + PortAlternateProtocolPair default_protocol; + default_protocol.port = 1234; + default_protocol.protocol = NPN_SPDY_2; + HttpServerPropertiesImpl::ForceAlternateProtocol(default_protocol); + + // Verify the forced protocol. + HostPortPair test_host_port_pair("foo", 80); + EXPECT_TRUE( + impl_.HasAlternateProtocol(test_host_port_pair)); + PortAlternateProtocolPair alternate = + impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(default_protocol.port, alternate.port); + EXPECT_EQ(default_protocol.protocol, alternate.protocol); + + // Verify the real protocol overrides the forced protocol. + impl_.SetAlternateProtocol( + test_host_port_pair, 443, NPN_SPDY_1); + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + alternate = impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(443, alternate.port); + EXPECT_EQ(NPN_SPDY_1, alternate.protocol); + + // Turn off the static, forced alternate protocol so that tests don't + // have this state. + HttpServerPropertiesImpl::DisableForcedAlternateProtocol(); + + // Verify the forced protocol is off. + HostPortPair test_host_port_pair2("bar", 80); + EXPECT_FALSE( + impl_.HasAlternateProtocol(test_host_port_pair2)); +} + } // namespace } // namespace net diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index e5ffc26..9aacbdc 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -10,7 +10,7 @@ #include "googleurl/src/gurl.h" #include "net/base/host_mapping_rules.h" #include "net/base/host_port_pair.h" -#include "net/http/http_alternate_protocols.h" +#include "net/http/http_server_properties.h" namespace net { @@ -34,13 +34,13 @@ bool HttpStreamFactory::ignore_certificate_errors_ = false; HttpStreamFactory::~HttpStreamFactory() {} void HttpStreamFactory::ProcessAlternateProtocol( - HttpAlternateProtocols* alternate_protocols, + HttpServerProperties* http_server_properties, const std::string& alternate_protocol_str, const HostPortPair& http_host_port_pair) { std::vector<std::string> port_protocol_vector; base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); if (port_protocol_vector.size() != 2) { - DLOG(WARNING) << HttpAlternateProtocols::kHeader + DLOG(WARNING) << kAlternateProtocolHeader << " header has too many tokens: " << alternate_protocol_str; return; @@ -49,23 +49,22 @@ void HttpStreamFactory::ProcessAlternateProtocol( int port; if (!base::StringToInt(port_protocol_vector[0], &port) || port <= 0 || port >= 1 << 16) { - DLOG(WARNING) << HttpAlternateProtocols::kHeader + DLOG(WARNING) << kAlternateProtocolHeader << " header has unrecognizable port: " << port_protocol_vector[0]; return; } - HttpAlternateProtocols::Protocol protocol = HttpAlternateProtocols::BROKEN; + AlternateProtocol protocol = ALTERNATE_PROTOCOL_BROKEN; // We skip NPN_SPDY_1 here, because we've rolled the protocol version to 2. - for (int i = HttpAlternateProtocols::NPN_SPDY_2; - i < HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS; ++i) { - if (port_protocol_vector[1] == HttpAlternateProtocols::kProtocolStrings[i]) - protocol = static_cast<HttpAlternateProtocols::Protocol>(i); + for (int i = NPN_SPDY_2; i < NUM_ALTERNATE_PROTOCOLS; ++i) { + if (port_protocol_vector[1] == kAlternateProtocolStrings[i]) + protocol = static_cast<AlternateProtocol>(i); } - if (protocol == HttpAlternateProtocols::BROKEN) { + if (protocol == ALTERNATE_PROTOCOL_BROKEN) { // Currently, we only recognize the npn-spdy protocol. - DLOG(WARNING) << HttpAlternateProtocols::kHeader + DLOG(WARNING) << kAlternateProtocolHeader << " header has unrecognized protocol: " << port_protocol_vector[1]; return; @@ -74,15 +73,15 @@ void HttpStreamFactory::ProcessAlternateProtocol( HostPortPair host_port(http_host_port_pair); host_mapping_rules().RewriteHost(&host_port); - if (alternate_protocols->HasAlternateProtocolFor(host_port)) { - const HttpAlternateProtocols::PortProtocolPair existing_alternate = - alternate_protocols->GetAlternateProtocolFor(host_port); + if (http_server_properties->HasAlternateProtocol(host_port)) { + const PortAlternateProtocolPair existing_alternate = + http_server_properties->GetAlternateProtocol(host_port); // If we think the alternate protocol is broken, don't change it. - if (existing_alternate.protocol == HttpAlternateProtocols::BROKEN) + if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) return; } - alternate_protocols->SetAlternateProtocolFor(host_port, port, protocol); + http_server_properties->SetAlternateProtocol(host_port, port, protocol); } GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url, diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index 66c0a23..ef78a70 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -21,10 +21,10 @@ namespace net { class BoundNetLog; class HostMappingRules; class HostPortPair; -class HttpAlternateProtocols; class HttpAuthController; class HttpNetworkSession; class HttpResponseInfo; +class HttpServerProperties; class HttpStream; class ProxyInfo; class SSLCertRequestInfo; @@ -149,7 +149,7 @@ class NET_EXPORT HttpStreamFactory { virtual ~HttpStreamFactory(); void ProcessAlternateProtocol( - HttpAlternateProtocols* alternate_protocols, + HttpServerProperties* http_server_properties, const std::string& alternate_protocol_str, const HostPortPair& http_host_port_pair); diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 8b7db82..364d202 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc @@ -10,6 +10,7 @@ #include "net/base/net_log.h" #include "net/base/net_util.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties.h" #include "net/http/http_stream_factory_impl_job.h" #include "net/http/http_stream_factory_impl_request.h" #include "net/spdy/spdy_http_stream.h" @@ -133,21 +134,20 @@ bool HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( HostPortPair origin = HostPortPair(original_url.HostNoBrackets(), original_url.EffectiveIntPort()); - const HttpAlternateProtocols& alternate_protocols = - session_->alternate_protocols(); - if (!alternate_protocols.HasAlternateProtocolFor(origin)) + const HttpServerProperties& http_server_properties = + *session_->http_server_properties(); + if (!http_server_properties.HasAlternateProtocol(origin)) return false; - HttpAlternateProtocols::PortProtocolPair alternate = - alternate_protocols.GetAlternateProtocolFor(origin); - if (alternate.protocol == HttpAlternateProtocols::BROKEN) + PortAlternateProtocolPair alternate = + http_server_properties.GetAlternateProtocol(origin); + if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) return false; - DCHECK_LE(HttpAlternateProtocols::NPN_SPDY_1, alternate.protocol); - DCHECK_GT(HttpAlternateProtocols::NUM_ALTERNATE_PROTOCOLS, - alternate.protocol); + DCHECK_LE(NPN_SPDY_1, alternate.protocol); + DCHECK_GT(NUM_ALTERNATE_PROTOCOLS, alternate.protocol); - if (alternate.protocol != HttpAlternateProtocols::NPN_SPDY_2) + if (alternate.protocol != NPN_SPDY_2) return false; // Some shared unix systems may have user home directories (like diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index f496042..74a7895 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -716,7 +716,7 @@ int HttpStreamFactoryImpl::Job::DoInitConnectionComplete(int result) { if (!ssl_started && result < 0 && original_url_.get()) { // Mark the alternate protocol as broken and fallback. - session_->mutable_alternate_protocols()->MarkBrokenAlternateProtocolFor( + session_->http_server_properties()->SetBrokenAlternateProtocol( HostPortPair::FromURL(*original_url_)); return result; } diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index e553ddb..b3d4175 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h @@ -11,7 +11,6 @@ #include "net/base/completion_callback.h" #include "net/base/net_log.h" #include "net/base/ssl_config_service.h" -#include "net/http/http_alternate_protocols.h" #include "net/http/http_auth.h" #include "net/http/http_auth_controller.h" #include "net/http/http_request_info.h" diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index 153b42e..dd08965 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -16,6 +16,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_network_session_peer.h" #include "net/http/http_request_info.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_stream.h" #include "net/proxy/proxy_info.h" #include "net/proxy/proxy_service.h" @@ -129,6 +130,7 @@ struct SessionDependencies { scoped_refptr<SSLConfigService> ssl_config_service; MockClientSocketFactory socket_factory; scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; + HttpServerPropertiesImpl http_server_properties; NetLog* net_log; }; @@ -142,6 +144,7 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) { params.http_auth_handler_factory = session_deps->http_auth_handler_factory.get(); params.net_log = session_deps->net_log; + params.http_server_properties = &session_deps->http_server_properties; return new HttpNetworkSession(params); } diff --git a/net/net.gyp b/net/net.gyp index 8d27cfa..34f1965 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -357,8 +357,6 @@ 'http/des.h', 'http/disk_cache_based_ssl_host_info.cc', 'http/disk_cache_based_ssl_host_info.h', - 'http/http_alternate_protocols.cc', - 'http/http_alternate_protocols.h', 'http/http_atom_list.h', 'http/http_auth.cc', 'http/http_auth.h', @@ -425,6 +423,7 @@ 'http/http_response_headers.h', 'http/http_response_info.cc', 'http/http_response_info.h', + 'http/http_server_properties.cc', 'http/http_server_properties.h', 'http/http_server_properties_impl.cc', 'http/http_server_properties_impl.h', @@ -999,7 +998,6 @@ 'ftp/ftp_network_transaction_unittest.cc', 'ftp/ftp_util_unittest.cc', 'http/des_unittest.cc', - 'http/http_alternate_protocols_unittest.cc', 'http/http_auth_cache_unittest.cc', 'http/http_auth_controller_unittest.cc', 'http/http_auth_filter_unittest.cc', diff --git a/net/proxy/proxy_script_fetcher_impl_unittest.cc b/net/proxy/proxy_script_fetcher_impl_unittest.cc index d706632..6250252 100644 --- a/net/proxy/proxy_script_fetcher_impl_unittest.cc +++ b/net/proxy/proxy_script_fetcher_impl_unittest.cc @@ -17,6 +17,7 @@ #include "net/disk_cache/disk_cache.h" #include "net/http/http_cache.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" #include "net/test/test_server.h" #include "net/url_request/url_request_context_storage.h" #include "net/url_request/url_request_job_factory.h" @@ -74,12 +75,14 @@ class RequestContext : public URLRequestContext { storage_.set_cert_verifier(new CertVerifier); storage_.set_proxy_service(ProxyService::CreateFixed(no_proxy)); storage_.set_ssl_config_service(new SSLConfigServiceDefaults); + storage_.set_http_server_properties(new HttpServerPropertiesImpl); HttpNetworkSession::Params params; params.host_resolver = host_resolver(); params.cert_verifier = cert_verifier(); params.proxy_service = proxy_service(); params.ssl_config_service = ssl_config_service(); + 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/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index de6af006..ce2ca40 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -21,6 +21,7 @@ #include "net/http/http_network_session.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" +#include "net/http/http_server_properties_impl.h" #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_histograms.h" @@ -140,6 +141,7 @@ class SSLClientSocketPoolTest : public testing::Test { params.client_socket_factory = &socket_factory_; params.ssl_config_service = ssl_config_service_; params.http_auth_handler_factory = http_auth_handler_factory_.get(); + params.http_server_properties = &http_server_properties_; return new HttpNetworkSession(params); } @@ -149,6 +151,7 @@ class SSLClientSocketPoolTest : public testing::Test { const scoped_ptr<ProxyService> proxy_service_; const scoped_refptr<SSLConfigService> ssl_config_service_; const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_; + HttpServerPropertiesImpl http_server_properties_; const scoped_refptr<HttpNetworkSession> session_; scoped_refptr<TransportSocketParams> direct_transport_socket_params_; diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 4a9e111..32b5b7c 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -124,9 +124,9 @@ class SpdyNetworkTransactionTest HttpStreamFactory::set_force_spdy_always(false); switch (test_type_) { case SPDYNPN: - session_->mutable_alternate_protocols()->SetAlternateProtocolFor( + session_->http_server_properties()->SetAlternateProtocol( HostPortPair("www.google.com", 80), 443, - HttpAlternateProtocols::NPN_SPDY_2); + NPN_SPDY_2); HttpStreamFactory::set_use_alternate_protocols(true); HttpStreamFactory::set_next_protos(kExpectedNPNString); break; diff --git a/net/spdy/spdy_test_util.cc b/net/spdy/spdy_test_util.cc index efe1efa..ec0f5d7 100644 --- a/net/spdy/spdy_test_util.cc +++ b/net/spdy/spdy_test_util.cc @@ -12,6 +12,7 @@ #include "base/string_util.h" #include "net/http/http_network_session.h" #include "net/http/http_network_transaction.h" +#include "net/http/http_server_properties_impl.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_http_utils.h" @@ -923,6 +924,7 @@ HttpNetworkSession* SpdySessionDependencies::SpdyCreateSession( params.ssl_config_service = session_deps->ssl_config_service; params.http_auth_handler_factory = session_deps->http_auth_handler_factory.get(); + params.http_server_properties = &session_deps->http_server_properties; return new HttpNetworkSession(params); } @@ -938,6 +940,7 @@ HttpNetworkSession* SpdySessionDependencies::SpdyCreateSessionDeterministic( params.ssl_config_service = session_deps->ssl_config_service; params.http_auth_handler_factory = session_deps->http_auth_handler_factory.get(); + params.http_server_properties = &session_deps->http_server_properties; return new HttpNetworkSession(params); } @@ -949,6 +952,7 @@ SpdyURLRequestContext::SpdyURLRequestContext() storage_.set_ssl_config_service(new SSLConfigServiceDefaults); storage_.set_http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault( host_resolver())); + storage_.set_http_server_properties(new HttpServerPropertiesImpl); net::HttpNetworkSession::Params params; params.client_socket_factory = &socket_factory_; params.host_resolver = host_resolver(); diff --git a/net/spdy/spdy_test_util.h b/net/spdy/spdy_test_util.h index 1ccdb37..2d724bd 100644 --- a/net/spdy/spdy_test_util.h +++ b/net/spdy/spdy_test_util.h @@ -17,6 +17,7 @@ #include "net/http/http_cache.h" #include "net/http/http_network_session.h" #include "net/http/http_network_layer.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_transaction_factory.h" #include "net/proxy/proxy_service.h" #include "net/socket/socket_test_util.h" @@ -355,6 +356,7 @@ class SpdySessionDependencies { scoped_ptr<MockClientSocketFactory> socket_factory; scoped_ptr<DeterministicMockClientSocketFactory> deterministic_socket_factory; scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; + HttpServerPropertiesImpl http_server_properties; }; class SpdyURLRequestContext : public URLRequestContext { diff --git a/net/tools/fetch/fetch_client.cc b/net/tools/fetch/fetch_client.cc index 7c1b0f3..fc22bdc 100644 --- a/net/tools/fetch/fetch_client.cc +++ b/net/tools/fetch/fetch_client.cc @@ -22,6 +22,7 @@ #include "net/http/http_network_layer.h" #include "net/http/http_network_session.h" #include "net/http/http_request_info.h" +#include "net/http/http_server_properties_impl.h" #include "net/http/http_transaction.h" #include "net/proxy/proxy_service.h" @@ -150,12 +151,14 @@ int main(int argc, char** argv) { net::HttpTransactionFactory* factory = NULL; scoped_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory( net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); + net::HttpServerPropertiesImpl http_server_properties; net::HttpNetworkSession::Params session_params; session_params.host_resolver = host_resolver.get(); session_params.cert_verifier = cert_verifier.get(); session_params.proxy_service = proxy_service.get(); session_params.http_auth_handler_factory = http_auth_handler_factory.get(); + session_params.http_server_properties = &http_server_properties; session_params.ssl_config_service = ssl_config_service; scoped_refptr<net::HttpNetworkSession> network_session( diff --git a/net/url_request/url_request_test_util.cc b/net/url_request/url_request_test_util.cc index 0fe60fc..768e520 100644 --- a/net/url_request/url_request_test_util.cc +++ b/net/url_request/url_request_test_util.cc @@ -10,6 +10,7 @@ #include "base/threading/thread.h" #include "net/base/host_port_pair.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties_impl.h" #include "net/url_request/url_request_job_factory.h" namespace { @@ -118,6 +119,10 @@ void TestURLRequestContext::Init() { context_storage_.set_http_auth_handler_factory( net::HttpAuthHandlerFactory::CreateDefault(host_resolver())); } + if (!http_server_properties()) { + context_storage_.set_http_server_properties( + new net::HttpServerPropertiesImpl); + } net::HttpNetworkSession::Params params; params.host_resolver = host_resolver(); params.cert_verifier = cert_verifier(); |