diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-30 07:13:32 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-07-30 07:13:32 +0000 |
commit | 88a332620b1316b88bd1569538d81f49d2de6e43 (patch) | |
tree | d1d192dd124b39960a7e8d9abcee0d8aed7f80b2 | |
parent | afa9cd922e16df2d9fb60cc96d01f49b29b7f1e5 (diff) | |
download | chromium_src-88a332620b1316b88bd1569538d81f49d2de6e43.zip chromium_src-88a332620b1316b88bd1569538d81f49d2de6e43.tar.gz chromium_src-88a332620b1316b88bd1569538d81f49d2de6e43.tar.bz2 |
[SPDY] Add strings and constants for HTTP/2 draft 04
There are still differences between SPDY/4 and HTTP/2 draft 04; those
will be ironed out in upcoming CLs.
Add kProtoHTTP2Draft04 to SPDY NextProto-parametrized tests.
Move NextProto -> SpdyMajorVersion conversion to buffered_spdy_framer.h.
Remove unused SpdyMajorVersion -> NextProto conversion.
Clean up HttpResponseInfo::ConnectionInfo a bit and add a TODO to
remove it.
Parametrize SSLClientSocketPoolTest on NextProto.
BUG=265615
R=darin@chromium.org, rch@chromium.org
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=214289
Review URL: https://codereview.chromium.org/21131002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@214309 0039d316-1c4b-4281-b951-d872f2087c98
38 files changed, 281 insertions, 174 deletions
diff --git a/chrome/app/generated_resources.grd b/chrome/app/generated_resources.grd index 4f64b14..e52871b 100644 --- a/chrome/app/generated_resources.grd +++ b/chrome/app/generated_resources.grd @@ -6862,6 +6862,12 @@ Keep your key file in a safe place. You will need it to create new versions of y <message name="IDS_FLAGS_ENABLE_SPDY4A2_DESCRIPTION" desc="Description for the flag to enable SPDY/4 alpha 2."> Enable experimental SPDY/4 alpha 2. </message> + <message name="IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_NAME" desc="Title for the flag to enable HTTP/2 draft 04"> + Enable HTTP/2 draft 04. + </message> + <message name="IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_DESCRIPTION" desc="Description for the flag to enable HTTP/2 draft 04."> + Enable experimental HTTP/2 draft 04. + </message> <message name="IDS_FLAGS_ENABLE_ASYNC_DNS_NAME" desc="Title for the flag to enable asynchronous DNS client."> Built-in Asynchronous DNS </message> diff --git a/chrome/browser/about_flags.cc b/chrome/browser/about_flags.cc index 55fe6e8..48ac34c 100644 --- a/chrome/browser/about_flags.cc +++ b/chrome/browser/about_flags.cc @@ -726,6 +726,13 @@ const Experiment kExperiments[] = { SINGLE_VALUE_TYPE(switches::kEnableSpdy4a2) }, { + "enable-http2-draft-04", + IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_NAME, + IDS_FLAGS_ENABLE_HTTP2_DRAFT_04_DESCRIPTION, + kOsAll, + SINGLE_VALUE_TYPE(switches::kEnableHttp2Draft04) + }, + { "enable-async-dns", IDS_FLAGS_ENABLE_ASYNC_DNS_NAME, IDS_FLAGS_ENABLE_ASYNC_DNS_DESCRIPTION, diff --git a/chrome/browser/io_thread.cc b/chrome/browser/io_thread.cc index 46586a1..62a54b1 100644 --- a/chrome/browser/io_thread.cc +++ b/chrome/browser/io_thread.cc @@ -699,6 +699,8 @@ void IOThread::InitializeNetworkOptions(const CommandLine& command_line) { std::string spdy_mode = command_line.GetSwitchValueASCII(switches::kUseSpdy); EnableSpdy(spdy_mode); + } else if (command_line.HasSwitch(switches::kEnableHttp2Draft04)) { + net::HttpStreamFactory::EnableNpnHttp2Draft04(); } else if (command_line.HasSwitch(switches::kEnableSpdy4a2)) { net::HttpStreamFactory::EnableNpnSpdy4a2(); } else if (command_line.HasSwitch(switches::kDisableSpdy31)) { diff --git a/chrome/common/chrome_switches.cc b/chrome/common/chrome_switches.cc index f288357..9fc1f72 100644 --- a/chrome/common/chrome_switches.cc +++ b/chrome/common/chrome_switches.cc @@ -571,6 +571,9 @@ const char kEnableFileCookies[] = "enable-file-cookies"; // Enables Google Now integration. const char kEnableGoogleNowIntegration[] = "enable-google-now-integration"; +// Enable HTTP/2 draft 04. This is a temporary testing flag. +const char kEnableHttp2Draft04[] = "enable-http2-draft-04"; + // Enable Instant extended API. On mobile, this merely enables query extraction, // not the rest of the instant-extended functionality. const char kEnableInstantExtendedAPI[] = "enable-instant-extended-api"; diff --git a/chrome/common/chrome_switches.h b/chrome/common/chrome_switches.h index 1137205..e9ae0c0 100644 --- a/chrome/common/chrome_switches.h +++ b/chrome/common/chrome_switches.h @@ -168,6 +168,7 @@ extern const char kEnableExtensionActivityLogTesting[]; extern const char kEnableFastUnload[]; extern const char kEnableFileCookies[]; extern const char kEnableGoogleNowIntegration[]; +extern const char kEnableHttp2Draft04[]; extern const char kEnableInstantExtendedAPI[]; extern const char kEnableIPCFuzzing[]; extern const char kEnableIPPooling[]; diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index 64e0026..5f8dac2 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -378,7 +378,8 @@ class HttpNetworkTransactionTest INSTANTIATE_TEST_CASE_P( NextProto, HttpNetworkTransactionTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); namespace { diff --git a/net/http/http_proxy_client_socket_pool_unittest.cc b/net/http/http_proxy_client_socket_pool_unittest.cc index acd60a6..2274f25 100644 --- a/net/http/http_proxy_client_socket_pool_unittest.cc +++ b/net/http/http_proxy_client_socket_pool_unittest.cc @@ -247,7 +247,10 @@ INSTANTIATE_TEST_CASE_P( HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY31), HttpProxyClientSocketPoolTestParams(HTTP, kProtoSPDY4a2), HttpProxyClientSocketPoolTestParams(HTTPS, kProtoSPDY4a2), - HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY4a2))); + HttpProxyClientSocketPoolTestParams(SPDY, kProtoSPDY4a2), + HttpProxyClientSocketPoolTestParams(HTTP, kProtoHTTP2Draft04), + HttpProxyClientSocketPoolTestParams(HTTPS, kProtoHTTP2Draft04), + HttpProxyClientSocketPoolTestParams(SPDY, kProtoHTTP2Draft04))); TEST_P(HttpProxyClientSocketPoolTest, NoTunnel) { Initialize(NULL, 0, NULL, 0, NULL, 0, NULL, 0); diff --git a/net/http/http_response_info.cc b/net/http/http_response_info.cc index 368c1c7..0b57a4e 100644 --- a/net/http/http_response_info.cc +++ b/net/http/http_response_info.cc @@ -328,6 +328,32 @@ void HttpResponseInfo::Persist(Pickle* pickle, pickle->WriteInt(static_cast<int>(connection_info)); } +HttpResponseInfo::ConnectionInfo HttpResponseInfo::ConnectionInfoFromNextProto( + NextProto next_proto) { + switch (next_proto) { + case kProtoSPDY2: + return CONNECTION_INFO_SPDY2; + case kProtoSPDY3: + case kProtoSPDY31: + return CONNECTION_INFO_SPDY3; + case kProtoSPDY4a2: + return CONNECTION_INFO_SPDY4A2; + case kProtoHTTP2Draft04: + return CONNECTION_INFO_HTTP2_DRAFT_04; + case kProtoQUIC1SPDY3: + return CONNECTION_INFO_QUIC1_SPDY3; + + case kProtoUnknown: + case kProtoHTTP11: + case kProtoSPDY1: + case kProtoSPDY21: + break; + } + + NOTREACHED(); + return CONNECTION_INFO_UNKNOWN; +} + // static std::string HttpResponseInfo::ConnectionInfoToString( ConnectionInfo connection_info) { @@ -340,8 +366,10 @@ std::string HttpResponseInfo::ConnectionInfoToString( return "spdy/2"; case CONNECTION_INFO_SPDY3: return "spdy/3"; - case CONNECTION_INFO_SPDY4: - return "spdy/4"; + case CONNECTION_INFO_SPDY4A2: + return "spdy/4a2"; + case CONNECTION_INFO_HTTP2_DRAFT_04: + return "HTTP-draft-04/2.0"; case CONNECTION_INFO_QUIC1_SPDY3: return "quic/1+spdy/3"; case NUM_OF_CONNECTION_INFOS: diff --git a/net/http/http_response_info.h b/net/http/http_response_info.h index 5c15cb9..907ec96 100644 --- a/net/http/http_response_info.h +++ b/net/http/http_response_info.h @@ -11,6 +11,7 @@ #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/http/http_vary_data.h" +#include "net/socket/next_proto.h" #include "net/ssl/ssl_info.h" class Pickle; @@ -25,13 +26,20 @@ class SSLCertRequestInfo; class NET_EXPORT HttpResponseInfo { public: // Describes the kind of connection used to fetch this response. + // + // NOTE: This is persisted to the cache, so make sure not to reorder + // these values. + // + // TODO(akalin): Better yet, just use a string instead of an enum, + // like |npn_negotiated_protocol|. enum ConnectionInfo { CONNECTION_INFO_UNKNOWN = 0, CONNECTION_INFO_HTTP1 = 1, CONNECTION_INFO_SPDY2 = 2, CONNECTION_INFO_SPDY3 = 3, - CONNECTION_INFO_SPDY4 = 4, + CONNECTION_INFO_SPDY4A2 = 4, CONNECTION_INFO_QUIC1_SPDY3 = 5, + CONNECTION_INFO_HTTP2_DRAFT_04 = 6, NUM_OF_CONNECTION_INFOS, }; @@ -127,6 +135,8 @@ class NET_EXPORT HttpResponseInfo { // Any metadata asociated with this resource's cached data. scoped_refptr<IOBufferWithSize> metadata; + static ConnectionInfo ConnectionInfoFromNextProto(NextProto next_proto); + static std::string ConnectionInfoToString(ConnectionInfo connection_info); }; diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index 0441361..bff262a 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc @@ -10,6 +10,9 @@ namespace net { const char kAlternateProtocolHeader[] = "Alternate-Protocol"; + +namespace { + // The order of these strings much match the order of the enum definition // for AlternateProtocol. const char* const kAlternateProtocolStrings[] = { @@ -18,10 +21,16 @@ const char* const kAlternateProtocolStrings[] = { "npn-spdy/3", "npn-spdy/3.1", "npn-spdy/4a2", + "npn-HTTP-draft-04/2.0", "quic" }; const char kBrokenAlternateProtocol[] = "Broken"; +COMPILE_ASSERT(arraysize(kAlternateProtocolStrings) == NUM_ALTERNATE_PROTOCOLS, + kAlternateProtocolStringsSize_NUM_ALTERNATE_PROTOCOLS_nut_equal); + +} // namespace + const char* AlternateProtocolToString(AlternateProtocol protocol) { switch (protocol) { case NPN_SPDY_1: @@ -29,18 +38,20 @@ const char* AlternateProtocolToString(AlternateProtocol protocol) { case NPN_SPDY_3: case NPN_SPDY_3_1: case NPN_SPDY_4A2: + case NPN_HTTP2_DRAFT_04: case QUIC: DCHECK_LT(static_cast<size_t>(protocol), arraysize(kAlternateProtocolStrings)); return kAlternateProtocolStrings[protocol]; + case NUM_ALTERNATE_PROTOCOLS: + break; case ALTERNATE_PROTOCOL_BROKEN: return kBrokenAlternateProtocol; case UNINITIALIZED_ALTERNATE_PROTOCOL: return "Uninitialized"; - default: - NOTREACHED(); - return ""; } + NOTREACHED(); + return ""; } AlternateProtocol AlternateProtocolFromString(const std::string& protocol) { @@ -62,6 +73,8 @@ AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) { return NPN_SPDY_3_1; case kProtoSPDY4a2: return NPN_SPDY_4A2; + case kProtoHTTP2Draft04: + return NPN_HTTP2_DRAFT_04; case kProtoQUIC1SPDY3: return QUIC; diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index b017a3f..654d262 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -24,7 +24,9 @@ enum AlternateProtocol { NPN_SPDY_3, NPN_SPDY_3_1, NPN_SPDY_4A2, - NPN_SPDY_MAXIMUM_VERSION = NPN_SPDY_4A2, + // We lump in HTTP/2 with the SPDY protocols for now. + NPN_HTTP2_DRAFT_04, + NPN_SPDY_MAXIMUM_VERSION = NPN_HTTP2_DRAFT_04, QUIC, NUM_ALTERNATE_PROTOCOLS, ALTERNATE_PROTOCOL_BROKEN, // The alternate protocol is known to be broken. @@ -54,7 +56,6 @@ typedef std::map<HostPortPair, HttpPipelinedHostCapability> PipelineCapabilityMap; 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': diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index cca445e..a55ed07 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -70,13 +70,10 @@ void HttpStreamFactory::ProcessAlternateProtocol( return; } - AlternateProtocol protocol = ALTERNATE_PROTOCOL_BROKEN; - for (int i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i) { - if (enabled_protocols_[i] && - port_protocol_vector[1] == kAlternateProtocolStrings[i]) { - protocol = static_cast<AlternateProtocol>(i); - } - } + AlternateProtocol protocol = + AlternateProtocolFromString(port_protocol_vector[1]); + if (protocol < NUM_ALTERNATE_PROTOCOLS && !enabled_protocols_[protocol]) + protocol = ALTERNATE_PROTOCOL_BROKEN; if (protocol == ALTERNATE_PROTOCOL_BROKEN) { // Currently, we only recognize the npn-spdy protocol. @@ -195,6 +192,20 @@ void HttpStreamFactory::EnableNpnSpdy4a2() { } // static +void HttpStreamFactory::EnableNpnHttp2Draft04() { + set_use_alternate_protocols(true); + std::vector<NextProto> next_protos; + next_protos.push_back(kProtoHTTP11); + next_protos.push_back(kProtoQUIC1SPDY3); + next_protos.push_back(kProtoSPDY2); + next_protos.push_back(kProtoSPDY3); + next_protos.push_back(kProtoSPDY31); + next_protos.push_back(kProtoSPDY4a2); + next_protos.push_back(kProtoHTTP2Draft04); + SetNextProtos(next_protos); +} + +// static void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) { if (!next_protos_) next_protos_ = new std::vector<std::string>; @@ -204,8 +215,8 @@ void HttpStreamFactory::SetNextProtos(const std::vector<NextProto>& value) { for (uint32 i = 0; i < NUM_ALTERNATE_PROTOCOLS; ++i) enabled_protocols_[i] = false; - // TODO(rtenneti): bug 116575 - consider using same strings/enums for SPDY - // versions in next_protos and kAlternateProtocolStrings. + // TODO(rtenneti): bug 116575 - consider combining the NextProto and + // AlternateProtocol. for (uint32 i = 0; i < value.size(); ++i) { NextProto proto = value[i]; // Add the protocol to the TLS next protocol list, except for QUIC diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index bebfb8c..6db6905 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -278,6 +278,11 @@ class NET_EXPORT HttpStreamFactory { // the protocols supported via NPN or Alternate-Protocol. static void EnableNpnSpdy4a2(); + // Sets http/1.1, quic, spdy/2, spdy/3, spdy/3.1, spdy/4a2, and + // http/2 draft 04 as the protocols supported via NPN or + // Alternate-Protocol. + static void EnableNpnHttp2Draft04(); + // Sets the protocols supported by NPN (next protocol negotiation) during the // SSL handshake as well as by HTTP Alternate-Protocol. static void SetNextProtos(const std::vector<NextProto>& value); diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index be3476a..14fbc03 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -392,7 +392,8 @@ class HttpStreamFactoryTest : public ::testing::Test, INSTANTIATE_TEST_CASE_P( NextProto, HttpStreamFactoryTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); TEST_P(HttpStreamFactoryTest, PreconnectDirect) { for (size_t i = 0; i < arraysize(kTests); ++i) { diff --git a/net/socket/next_proto.h b/net/socket/next_proto.h index 00cec80..0bd307a 100644 --- a/net/socket/next_proto.h +++ b/net/socket/next_proto.h @@ -25,9 +25,11 @@ enum NextProto { kProtoSPDY3 = 5, kProtoSPDY31 = 6, kProtoSPDY4a2 = 7, - kProtoSPDYMaximumVersion = kProtoSPDY4a2, + // We lump in HTTP/2 with the SPDY protocols for now. + kProtoHTTP2Draft04 = 8, + kProtoSPDYMaximumVersion = kProtoHTTP2Draft04, - kProtoQUIC1SPDY3 = 8, + kProtoQUIC1SPDY3 = 9, kProtoMaximumVersion = kProtoQUIC1SPDY3, }; diff --git a/net/socket/ssl_client_socket.cc b/net/socket/ssl_client_socket.cc index 70b2a87..54f66a1 100644 --- a/net/socket/ssl_client_socket.cc +++ b/net/socket/ssl_client_socket.cc @@ -30,6 +30,8 @@ NextProto SSLClientSocket::NextProtoFromString( return kProtoSPDY31; } else if (proto_string == "spdy/4a2") { return kProtoSPDY4a2; + } else if (proto_string == "HTTP-draft-04/2.0") { + return kProtoHTTP2Draft04; } else if (proto_string == "quic/1+spdy/3") { return kProtoQUIC1SPDY3; } else { @@ -52,9 +54,12 @@ const char* SSLClientSocket::NextProtoToString(NextProto next_proto) { return "spdy/3.1"; case kProtoSPDY4a2: return "spdy/4a2"; + case kProtoHTTP2Draft04: + return "HTTP-draft-04/2.0"; case kProtoQUIC1SPDY3: return "quic/1+spdy/3"; - default: + case kProtoSPDY21: + case kProtoUnknown: break; } return "unknown"; diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index d237528..280f6e7 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -24,6 +24,7 @@ #include "net/proxy/proxy_service.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool_histograms.h" +#include "net/socket/next_proto.h" #include "net/socket/socket_test_util.h" #include "net/spdy/spdy_session.h" #include "net/spdy/spdy_session_pool.h" @@ -72,7 +73,9 @@ void TestLoadTimingInfoNoDns(const ClientSocketHandle& handle) { ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); } -class SSLClientSocketPoolTest : public testing::Test { +class SSLClientSocketPoolTest + : public testing::Test, + public ::testing::WithParamInterface<NextProto> { protected: SSLClientSocketPoolTest() : proxy_service_(ProxyService::CreateDirect()), @@ -188,6 +191,7 @@ class SSLClientSocketPoolTest : public testing::Test { params.http_server_properties = http_server_properties_.GetWeakPtr(); params.enable_spdy_compression = false; + params.spdy_default_protocol = GetParam(); return new HttpNetworkSession(params); } @@ -222,7 +226,13 @@ class SSLClientSocketPoolTest : public testing::Test { scoped_ptr<SSLClientSocketPool> pool_; }; -TEST_F(SSLClientSocketPoolTest, TCPFail) { +INSTANTIATE_TEST_CASE_P( + NextProto, + SSLClientSocketPoolTest, + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); + +TEST_P(SSLClientSocketPoolTest, TCPFail) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -240,7 +250,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFail) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, TCPFailAsync) { +TEST_P(SSLClientSocketPoolTest, TCPFailAsync) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -263,7 +273,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFailAsync) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, BasicDirect) { +TEST_P(SSLClientSocketPoolTest, BasicDirect) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); socket_factory_.AddSocketDataProvider(&data); @@ -284,7 +294,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirect) { TestLoadTimingInfo(handle); } -TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) { +TEST_P(SSLClientSocketPoolTest, BasicDirectAsync) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); @@ -308,7 +318,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) { TestLoadTimingInfo(handle); } -TEST_F(SSLClientSocketPoolTest, DirectCertError) { +TEST_P(SSLClientSocketPoolTest, DirectCertError) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID); @@ -332,7 +342,7 @@ TEST_F(SSLClientSocketPoolTest, DirectCertError) { TestLoadTimingInfo(handle); } -TEST_F(SSLClientSocketPoolTest, DirectSSLError) { +TEST_P(SSLClientSocketPoolTest, DirectSSLError) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR); @@ -356,7 +366,7 @@ TEST_F(SSLClientSocketPoolTest, DirectSSLError) { EXPECT_TRUE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, DirectWithNPN) { +TEST_P(SSLClientSocketPoolTest, DirectWithNPN) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); @@ -383,7 +393,7 @@ TEST_F(SSLClientSocketPoolTest, DirectWithNPN) { EXPECT_TRUE(ssl_socket->WasNpnNegotiated()); } -TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) { +TEST_P(SSLClientSocketPoolTest, DirectNoSPDY) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); @@ -408,11 +418,11 @@ TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) { EXPECT_TRUE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) { +TEST_P(SSLClientSocketPoolTest, DirectGotSPDY) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoSPDY2); + ssl.SetNextProto(GetParam()); socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -437,15 +447,14 @@ TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) { std::string proto; std::string server_protos; ssl_socket->GetNextProto(&proto, &server_protos); - EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), - kProtoSPDY2); + EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto)); } -TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) { +TEST_P(SSLClientSocketPoolTest, DirectGotBonusSPDY) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); - ssl.SetNextProto(kProtoSPDY2); + ssl.SetNextProto(GetParam()); socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -470,11 +479,10 @@ TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) { std::string proto; std::string server_protos; ssl_socket->GetNextProto(&proto, &server_protos); - EXPECT_EQ(SSLClientSocket::NextProtoFromString(proto), - kProtoSPDY2); + EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto)); } -TEST_F(SSLClientSocketPoolTest, SOCKSFail) { +TEST_P(SSLClientSocketPoolTest, SOCKSFail) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -493,7 +501,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFail) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) { +TEST_P(SSLClientSocketPoolTest, SOCKSFailAsync) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -516,7 +524,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, SOCKSBasic) { +TEST_P(SSLClientSocketPoolTest, SOCKSBasic) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); socket_factory_.AddSocketDataProvider(&data); @@ -539,7 +547,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasic) { TestLoadTimingInfo(handle); } -TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) { +TEST_P(SSLClientSocketPoolTest, SOCKSBasicAsync) { StaticSocketDataProvider data; socket_factory_.AddSocketDataProvider(&data); SSLSocketDataProvider ssl(ASYNC, OK); @@ -565,7 +573,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) { TestLoadTimingInfo(handle); } -TEST_F(SSLClientSocketPoolTest, HttpProxyFail) { +TEST_P(SSLClientSocketPoolTest, HttpProxyFail) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -584,7 +592,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFail) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) { +TEST_P(SSLClientSocketPoolTest, HttpProxyFailAsync) { StaticSocketDataProvider data; data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED)); socket_factory_.AddSocketDataProvider(&data); @@ -607,7 +615,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) { EXPECT_FALSE(handle.is_ssl_error()); } -TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) { +TEST_P(SSLClientSocketPoolTest, HttpProxyBasic) { MockWrite writes[] = { MockWrite(SYNCHRONOUS, "CONNECT host:80 HTTP/1.1\r\n" @@ -640,7 +648,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) { TestLoadTimingInfoNoDns(handle); } -TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) { +TEST_P(SSLClientSocketPoolTest, HttpProxyBasicAsync) { MockWrite writes[] = { MockWrite("CONNECT host:80 HTTP/1.1\r\n" "Host: host\r\n" @@ -675,7 +683,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) { TestLoadTimingInfoNoDns(handle); } -TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) { +TEST_P(SSLClientSocketPoolTest, NeedProxyAuth) { MockWrite writes[] = { MockWrite("CONNECT host:80 HTTP/1.1\r\n" "Host: host\r\n" @@ -717,7 +725,7 @@ TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) { EXPECT_FALSE(tunnel_handle->socket()->IsConnected()); } -TEST_F(SSLClientSocketPoolTest, IPPooling) { +TEST_P(SSLClientSocketPoolTest, IPPooling) { const int kTestPort = 80; struct TestHosts { std::string name; @@ -755,7 +763,7 @@ TEST_F(SSLClientSocketPoolTest, IPPooling) { SSLSocketDataProvider ssl(ASYNC, OK); ssl.cert = X509Certificate::CreateFromBytes( reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); - ssl.SetNextProto(kProtoSPDY2); + ssl.SetNextProto(GetParam()); socket_factory_.AddSSLSocketDataProvider(&ssl); CreatePool(true /* tcp pool */, false, false); @@ -825,20 +833,20 @@ void SSLClientSocketPoolTest::TestIPPoolingDisabled( // Verifies that an SSL connection with client authentication disables SPDY IP // pooling. -TEST_F(SSLClientSocketPoolTest, IPPoolingClientCert) { +TEST_P(SSLClientSocketPoolTest, IPPoolingClientCert) { SSLSocketDataProvider ssl(ASYNC, OK); ssl.cert = X509Certificate::CreateFromBytes( reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); ssl.client_cert_sent = true; - ssl.SetNextProto(kProtoSPDY2); + ssl.SetNextProto(GetParam()); TestIPPoolingDisabled(&ssl); } // Verifies that an SSL connection with channel ID disables SPDY IP pooling. -TEST_F(SSLClientSocketPoolTest, IPPoolingChannelID) { +TEST_P(SSLClientSocketPoolTest, IPPoolingChannelID) { SSLSocketDataProvider ssl(ASYNC, OK); ssl.channel_id_sent = true; - ssl.SetNextProto(kProtoSPDY2); + ssl.SetNextProto(GetParam()); TestIPPoolingDisabled(&ssl); } diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc index 14afaa3..46d0284 100644 --- a/net/spdy/buffered_spdy_framer.cc +++ b/net/spdy/buffered_spdy_framer.cc @@ -8,6 +8,28 @@ namespace net { +SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) { + switch (next_proto) { + case kProtoSPDY2: + case kProtoSPDY21: + return SPDY2; + case kProtoSPDY3: + case kProtoSPDY31: + return SPDY3; + // SPDY/4 and HTTP/2 share the same framing for now. + case kProtoSPDY4a2: + case kProtoHTTP2Draft04: + return SPDY4; + case kProtoUnknown: + case kProtoHTTP11: + case kProtoSPDY1: + case kProtoQUIC1SPDY3: + break; + } + NOTREACHED(); + return SPDY2; +} + BufferedSpdyFramer::BufferedSpdyFramer(SpdyMajorVersion version, bool enable_compression) : spdy_framer_(version), diff --git a/net/spdy/buffered_spdy_framer.h b/net/spdy/buffered_spdy_framer.h index 30466b97..1786067 100644 --- a/net/spdy/buffered_spdy_framer.h +++ b/net/spdy/buffered_spdy_framer.h @@ -11,12 +11,18 @@ #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" +#include "net/socket/next_proto.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_header_block.h" #include "net/spdy/spdy_protocol.h" namespace net { +// Returns the SPDY major version corresponding to the given NextProto +// value, which must represent a SPDY-like protocol. +NET_EXPORT_PRIVATE SpdyMajorVersion NextProtoToSpdyMajorVersion( + NextProto next_proto); + class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface { public: BufferedSpdyFramerVisitorInterface() {} diff --git a/net/spdy/buffered_spdy_framer_unittest.cc b/net/spdy/buffered_spdy_framer_unittest.cc index 0932c64..849138f 100644 --- a/net/spdy/buffered_spdy_framer_unittest.cc +++ b/net/spdy/buffered_spdy_framer_unittest.cc @@ -180,14 +180,15 @@ class BufferedSpdyFramerTest } SpdyMajorVersion spdy_version() { - return SpdyVersionFromNextProto(GetParam()); + return NextProtoToSpdyMajorVersion(GetParam()); } }; INSTANTIATE_TEST_CASE_P( NextProto, BufferedSpdyFramerTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); TEST_P(BufferedSpdyFramerTest, OnSetting) { SpdyFramer framer(spdy_version()); diff --git a/net/spdy/spdy_http_stream.cc b/net/spdy/spdy_http_stream.cc index 8f0f171..08e8b58 100644 --- a/net/spdy/spdy_http_stream.cc +++ b/net/spdy/spdy_http_stream.cc @@ -323,19 +323,8 @@ SpdyResponseHeadersStatus SpdyHttpStream::OnResponseHeadersUpdated( response_info_->npn_negotiated_protocol = SSLClientSocket::NextProtoToString(protocol_negotiated); response_info_->request_time = stream_->GetRequestTime(); - switch (stream_->GetProtocolVersion()) { - case SPDY2: - response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY2; - break; - case SPDY3: - response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY3; - break; - case SPDY4: - response_info_->connection_info = HttpResponseInfo::CONNECTION_INFO_SPDY4; - break; - default: - NOTREACHED(); - } + response_info_->connection_info = + HttpResponseInfo::ConnectionInfoFromNextProto(stream_->GetProtocol()); response_info_->vary_data .Init(*request_info_, *response_info_->headers.get()); diff --git a/net/spdy/spdy_http_stream_unittest.cc b/net/spdy/spdy_http_stream_unittest.cc index 26d87d8..04a8eca 100644 --- a/net/spdy/spdy_http_stream_unittest.cc +++ b/net/spdy/spdy_http_stream_unittest.cc @@ -130,7 +130,8 @@ class SpdyHttpStreamTest : public testing::Test, INSTANTIATE_TEST_CASE_P( NextProto, SpdyHttpStreamTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); // SpdyHttpStream::GetUploadProgress() should still work even before the // stream is initialized. diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index aa55dfe..2f65151 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -61,30 +61,6 @@ struct SpdyNetworkTransactionTestParams { SpdyNetworkTransactionTestSSLType ssl_type; }; -HttpResponseInfo::ConnectionInfo NextProtoToConnectionInfo( - NextProto next_proto) { - switch (next_proto) { - case kProtoSPDY2: - return HttpResponseInfo::CONNECTION_INFO_SPDY2; - case kProtoSPDY3: - case kProtoSPDY31: - return HttpResponseInfo::CONNECTION_INFO_SPDY3; - case kProtoSPDY4a2: - return HttpResponseInfo::CONNECTION_INFO_SPDY4; - case kProtoQUIC1SPDY3: - return HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3; - - case kProtoUnknown: - case kProtoHTTP11: - case kProtoSPDY1: - case kProtoSPDY21: - break; - } - - NOTREACHED(); - return HttpResponseInfo::CONNECTION_INFO_SPDY2; -} - SpdySessionDependencies* CreateSpdySessionDependencies( SpdyNetworkTransactionTestParams test_params) { return new SpdySessionDependencies(test_params.protocol); @@ -243,8 +219,10 @@ class SpdyNetworkTransactionTest EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy); if (HttpStreamFactory::spdy_enabled()) { - EXPECT_EQ(NextProtoToConnectionInfo(test_params_.protocol), - response->connection_info); + EXPECT_EQ( + HttpResponseInfo::ConnectionInfoFromNextProto( + test_params_.protocol), + response->connection_info); } else { EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, response->connection_info); @@ -680,7 +658,10 @@ INSTANTIATE_TEST_CASE_P( SpdyNetworkTransactionTestParams(kProtoSPDY31, SPDYNPN), SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNOSSL), SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYSSL), - SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNPN))); + SpdyNetworkTransactionTestParams(kProtoSPDY4a2, SPDYNPN), + SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNOSSL), + SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYSSL), + SpdyNetworkTransactionTestParams(kProtoHTTP2Draft04, SPDYNPN))); // Verify HttpNetworkTransaction constructor. TEST_P(SpdyNetworkTransactionTest, Constructor) { diff --git a/net/spdy/spdy_proxy_client_socket_unittest.cc b/net/spdy/spdy_proxy_client_socket_unittest.cc index b2bdb3e..c128d9c 100644 --- a/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -140,7 +140,8 @@ class SpdyProxyClientSocketTest INSTANTIATE_TEST_CASE_P( NextProto, SpdyProxyClientSocketTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); SpdyProxyClientSocketTest::SpdyProxyClientSocketTest() : spdy_util_(GetParam()), diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index 6411313..d085a4d 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -54,22 +54,6 @@ const SpdyStreamId kFirstStreamId = 1; // Minimum seconds that unclaimed pushed streams will be kept in memory. const int kMinPushedStreamLifetimeSeconds = 300; -SpdyMajorVersion NPNToSpdyVersion(NextProto next_proto) { - switch (next_proto) { - case kProtoSPDY2: - case kProtoSPDY21: - return SPDY2; - case kProtoSPDY3: - case kProtoSPDY31: - return SPDY3; - case kProtoSPDY4a2: - return SPDY4; - default: - NOTREACHED(); - } - return SPDY2; -} - base::Value* NetLogSpdySynCallback(const SpdyHeaderBlock* headers, bool fin, bool unidirectional, @@ -395,7 +379,7 @@ SpdySession::SpdySession( enable_compression_(enable_compression), enable_ping_based_connection_checking_( enable_ping_based_connection_checking), - default_protocol_(default_protocol), + protocol_(default_protocol), credential_state_(SpdyCredentialState::kDefaultNumSlots), connection_at_risk_of_loss_time_( base::TimeDelta::FromSeconds(kDefaultConnectionAtRiskOfLossSeconds)), @@ -403,6 +387,10 @@ SpdySession::SpdySession( base::TimeDelta::FromSeconds(kHungIntervalSeconds)), trusted_spdy_proxy_(trusted_spdy_proxy), time_func_(time_func) { + // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we + // stop supporting SPDY/1. + DCHECK_GE(protocol_, kProtoSPDY2); + DCHECK_LE(protocol_, kProtoSPDYMaximumVersion); DCHECK(HttpStreamFactory::spdy_enabled()); net_log_.BeginEvent( NetLog::TYPE_SPDY_SESSION, @@ -452,12 +440,15 @@ Error SpdySession::InitializeWithSocket( is_secure_ = is_secure; certificate_error_code_ = certificate_error_code; - NextProto protocol = default_protocol_; NextProto protocol_negotiated = connection_->socket()->GetNegotiatedProtocol(); if (protocol_negotiated != kProtoUnknown) { - protocol = protocol_negotiated; + protocol_ = protocol_negotiated; } + // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we + // stop supporting SPDY/1. + DCHECK_GE(protocol_, kProtoSPDY2); + DCHECK_LE(protocol_, kProtoSPDYMaximumVersion); SSLClientSocket* ssl_socket = GetSSLClientSocket(); if (ssl_socket && ssl_socket->WasChannelIDSent()) { @@ -467,25 +458,22 @@ Error SpdySession::InitializeWithSocket( host_port_pair().ToString())); } - // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we - // stop supporting SPDY/1. - DCHECK_GE(protocol, kProtoSPDY2); - DCHECK_LE(protocol, kProtoSPDYMaximumVersion); - if (protocol >= kProtoSPDY31) { + if (protocol_ >= kProtoSPDY31) { flow_control_state_ = FLOW_CONTROL_STREAM_AND_SESSION; session_send_window_size_ = kSpdySessionInitialWindowSize; session_recv_window_size_ = kSpdySessionInitialWindowSize; - } else if (protocol >= kProtoSPDY3) { + } else if (protocol_ >= kProtoSPDY3) { flow_control_state_ = FLOW_CONTROL_STREAM; } else { flow_control_state_ = FLOW_CONTROL_NONE; } buffered_spdy_framer_.reset( - new BufferedSpdyFramer(NPNToSpdyVersion(protocol), enable_compression_)); + new BufferedSpdyFramer(NextProtoToSpdyMajorVersion(protocol_), + enable_compression_)); buffered_spdy_framer_->set_visitor(this); buffered_spdy_framer_->set_debug_visitor(this); - UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol, kProtoMaximumVersion); + UMA_HISTOGRAM_ENUMERATION("Net.SpdyVersion", protocol_, kProtoMaximumVersion); #if defined(SPDY_PROXY_AUTH_ORIGIN) UMA_HISTOGRAM_BOOLEAN("Net.SpdySessions_DataReductionProxy", host_port_pair().Equals(HostPortPair::FromURL( diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index fedd701..c2d5b10 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -257,6 +257,13 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool is_secure, int certificate_error_code); + // Returns the protocol used by this session. Always between + // kProtoSPDY2 and kProtoSPDYMaximumVersion. + // + // TODO(akalin): Change the lower bound to kProtoSPDYMinimumVersion + // once we stop supporting SPDY/1. + NextProto protocol() const { return protocol_; } + // Check to see if this SPDY session can support an additional domain. // If the session is un-authenticated, then this call always returns true. // For SSL-based sessions, verifies that the server certificate in use by @@ -1082,7 +1089,13 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool enable_credential_frames_; bool enable_compression_; bool enable_ping_based_connection_checking_; - NextProto default_protocol_; + + // The SPDY protocol used. Always between kProtoSPDY2 and + // kProtoSPDYMaximumVersion. + // + // TODO(akalin): Change the lower bound to kProtoSPDYMinimumVersion + // once we stop supporting SPDY/1. + NextProto protocol_; SpdyCredentialState credential_state_; diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index 9efb20c..185ec23 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -53,13 +53,22 @@ SpdySessionPool::SpdySessionPool( enable_compression_(enable_compression), enable_ping_based_connection_checking_( enable_ping_based_connection_checking), - default_protocol_(default_protocol), + // TODO(akalin): Force callers to have a valid value of + // |default_protocol_|. Or at least make the default be + // kProtoSPDY3. + default_protocol_( + (default_protocol == kProtoUnknown) ? + kProtoSPDY2 : default_protocol), stream_initial_recv_window_size_(stream_initial_recv_window_size), initial_max_concurrent_streams_(initial_max_concurrent_streams), max_concurrent_streams_limit_(max_concurrent_streams_limit), time_func_(time_func), trusted_spdy_proxy_( HostPortPair::FromString(trusted_spdy_proxy)) { + // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we + // stop supporting SPDY/1. + DCHECK(default_protocol_ >= kProtoSPDY2 && + default_protocol_ <= kProtoSPDYMaximumVersion); NetworkChangeNotifier::AddIPAddressObserver(this); if (ssl_config_service_.get()) ssl_config_service_->AddObserver(this); @@ -82,6 +91,11 @@ net::Error SpdySessionPool::CreateAvailableSessionFromSocket( int certificate_error_code, base::WeakPtr<SpdySession>* available_session, bool is_secure) { + // TODO(akalin): Change this to kProtoSPDYMinimumVersion once we + // stop supporting SPDY/1. + DCHECK_GE(default_protocol_, kProtoSPDY2); + DCHECK_LE(default_protocol_, kProtoSPDYMaximumVersion); + UMA_HISTOGRAM_ENUMERATION( "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX); diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 362be55..c27d6d5 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h @@ -43,6 +43,9 @@ class NET_EXPORT SpdySessionPool public: typedef base::TimeTicks (*TimeFunc)(void); + // |default_protocol| may be kProtoUnknown (e.g., if SPDY is + // disabled), in which case it's set to a default value. Otherwise, + // it must be a SPDY protocol. SpdySessionPool( HostResolver* host_resolver, SSLConfigService* ssl_config_service, @@ -69,7 +72,8 @@ class NET_EXPORT SpdySessionPool // processing existing streams. // Create a new SPDY session from an existing socket. There must - // not already be a session for the given key. + // not already be a session for the given key. This pool must have + // been constructed with a valid |default_protocol| value. // // |is_secure| can be false for testing or when SPDY is configured // to work with non-secure sockets. If |is_secure| is true, @@ -213,7 +217,7 @@ class NET_EXPORT SpdySessionPool bool enable_credential_frames_; bool enable_compression_; bool enable_ping_based_connection_checking_; - NextProto default_protocol_; + const NextProto default_protocol_; size_t stream_initial_recv_window_size_; size_t initial_max_concurrent_streams_; size_t max_concurrent_streams_limit_; diff --git a/net/spdy/spdy_session_pool_unittest.cc b/net/spdy/spdy_session_pool_unittest.cc index 69ba11b..9d0679d 100644 --- a/net/spdy/spdy_session_pool_unittest.cc +++ b/net/spdy/spdy_session_pool_unittest.cc @@ -50,7 +50,8 @@ class SpdySessionPoolTest : public ::testing::Test, INSTANTIATE_TEST_CASE_P( NextProto, SpdySessionPoolTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); // A delegate that opens a new session when it is closed. class SessionOpeningDelegate : public SpdyStream::Delegate { diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index f0e10eb..ea7a6d1 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc @@ -181,7 +181,8 @@ class SpdySessionTest : public PlatformTest, INSTANTIATE_TEST_CASE_P( NextProto, SpdySessionTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); // Try to create a SPDY session that will fail during // initialization. Nothing should blow up. diff --git a/net/spdy/spdy_stream.cc b/net/spdy/spdy_stream.cc index 63d6a68..db085cf 100644 --- a/net/spdy/spdy_stream.cc +++ b/net/spdy/spdy_stream.cc @@ -630,6 +630,10 @@ bool SpdyStream::IsIdle() const { return io_state_ == STATE_IDLE; } +NextProto SpdyStream::GetProtocol() const { + return session_->protocol(); +} + bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { if (stream_id_ == 0) return false; diff --git a/net/spdy/spdy_stream.h b/net/spdy/spdy_stream.h index 06169d1..06209a1 100644 --- a/net/spdy/spdy_stream.h +++ b/net/spdy/spdy_stream.h @@ -382,6 +382,13 @@ class NET_EXPORT_PRIVATE SpdyStream { // request headers and is ready to send/receive more data. bool IsIdle() const; + // Returns the protocol used by this stream. Always between + // kProtoSPDY2 and kProtoSPDYMaximumVersion. + // + // TODO(akalin): Change the lower bound to kProtoSPDYMinimumVersion + // once we stop supporting SPDY/1. + NextProto GetProtocol() const; + int response_status() const { return response_status_; } bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const; diff --git a/net/spdy/spdy_stream_unittest.cc b/net/spdy/spdy_stream_unittest.cc index 6a14d67..c98ba93 100644 --- a/net/spdy/spdy_stream_unittest.cc +++ b/net/spdy/spdy_stream_unittest.cc @@ -112,7 +112,8 @@ class SpdyStreamTest : public ::testing::Test, INSTANTIATE_TEST_CASE_P( NextProto, SpdyStreamTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); TEST_P(SpdyStreamTest, SendDataAfterOpen) { GURL url(kStreamUrl); diff --git a/net/spdy/spdy_test_util_common.cc b/net/spdy/spdy_test_util_common.cc index 84be098..4c52751 100644 --- a/net/spdy/spdy_test_util_common.cc +++ b/net/spdy/spdy_test_util_common.cc @@ -690,39 +690,9 @@ void SpdySessionPoolPeer::EnableSendingInitialSettings(bool enabled) { pool_->enable_sending_initial_settings_ = enabled; } -NextProto NextProtoFromSpdyVersion(SpdyMajorVersion spdy_version) { - switch (spdy_version) { - case SPDY2: - return kProtoSPDY2; - case SPDY3: - return kProtoSPDY3; - case SPDY4: - return kProtoSPDY4a2; - default: - NOTREACHED(); - return kProtoUnknown; - } -} - -SpdyMajorVersion SpdyVersionFromNextProto(NextProto next_proto) { - switch (next_proto) { - case kProtoSPDY2: - case kProtoSPDY21: - return SPDY2; - case kProtoSPDY3: - case kProtoSPDY31: - return SPDY3; - case kProtoSPDY4a2: - return SPDY4; - default: - NOTREACHED(); - return SPDY2; - } -} - SpdyTestUtil::SpdyTestUtil(NextProto protocol) : protocol_(protocol), - spdy_version_(SpdyVersionFromNextProto(protocol)) { + spdy_version_(NextProtoToSpdyMajorVersion(protocol)) { DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol; } diff --git a/net/spdy/spdy_test_util_common.h b/net/spdy/spdy_test_util_common.h index 88fd678..7f5f2ab 100644 --- a/net/spdy/spdy_test_util_common.h +++ b/net/spdy/spdy_test_util_common.h @@ -288,13 +288,6 @@ class SpdySessionPoolPeer { DISALLOW_COPY_AND_ASSIGN(SpdySessionPoolPeer); }; -// TODO(ttuttle): Move these somewhere more widely-accessible; surely this is -// not the only place that needs such functions. -NextProto NextProtoFromSpdyVersion(SpdyMajorVersion spdy_version); -// TODO(akalin): Merge this with NPNToSpdyVersion() in -// spdy_session.cc. -SpdyMajorVersion SpdyVersionFromNextProto(NextProto next_proto); - class SpdyTestUtil { public: explicit SpdyTestUtil(NextProto protocol); diff --git a/net/spdy/spdy_websocket_stream_unittest.cc b/net/spdy/spdy_websocket_stream_unittest.cc index 42dd95c..f05b34e 100644 --- a/net/spdy/spdy_websocket_stream_unittest.cc +++ b/net/spdy/spdy_websocket_stream_unittest.cc @@ -299,7 +299,8 @@ class SpdyWebSocketStreamTest INSTANTIATE_TEST_CASE_P( NextProto, SpdyWebSocketStreamTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); // TODO(toyoshim): Replace old framing data to new one, then use HEADERS and // data frames. diff --git a/net/websockets/websocket_handshake_handler_spdy_unittest.cc b/net/websockets/websocket_handshake_handler_spdy_unittest.cc index 83c519d..a8276cd 100644 --- a/net/websockets/websocket_handshake_handler_spdy_unittest.cc +++ b/net/websockets/websocket_handshake_handler_spdy_unittest.cc @@ -28,7 +28,8 @@ class WebSocketHandshakeHandlerSpdyTest INSTANTIATE_TEST_CASE_P( NextProto, WebSocketHandshakeHandlerSpdyTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); TEST_P(WebSocketHandshakeHandlerSpdyTest, RequestResponse) { WebSocketHandshakeRequestHandler request_handler; diff --git a/net/websockets/websocket_job_unittest.cc b/net/websockets/websocket_job_unittest.cc index 4ee0132..434796d 100644 --- a/net/websockets/websocket_job_unittest.cc +++ b/net/websockets/websocket_job_unittest.cc @@ -597,7 +597,8 @@ void WebSocketJobTest::TestSlowHandshake() { INSTANTIATE_TEST_CASE_P( NextProto, WebSocketJobTest, - testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2)); + testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2, + kProtoHTTP2Draft04)); TEST_P(WebSocketJobTest, DelayedCookies) { WebSocketJob::set_websocket_over_spdy_enabled(true); |