diff options
author | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-23 23:09:15 +0000 |
---|---|---|
committer | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-07-23 23:09:15 +0000 |
commit | 9e9e842e287f9f949aa59bcf88321fa7f94fd524 (patch) | |
tree | b84963a14d5c7a4a7908d268320d29bb40b726b2 | |
parent | 148971b8a6efa47182662a17c8e7b455043fb632 (diff) | |
download | chromium_src-9e9e842e287f9f949aa59bcf88321fa7f94fd524.zip chromium_src-9e9e842e287f9f949aa59bcf88321fa7f94fd524.tar.gz chromium_src-9e9e842e287f9f949aa59bcf88321fa7f94fd524.tar.bz2 |
SPDY now always uses http_network_transaction instead of spdy_network_transaction.
It was previously possible to use spdy_network_transaction using the command line flags:
--use-spdy=no-ssl
--use-spdy=no-compress
This does not affect instances of chrome that are not run with --use-spdy.
Also changed spdy_network_transaction_unittest so that all tests are run with 3 different connection configurations: spdy over npn, spdy over ssl, and spdy without ssl.
TEST=net_unittests
BUG=49082
Review URL: http://codereview.chromium.org/3048003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@53548 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/net/preconnect.cc | 2 | ||||
-rw-r--r-- | net/http/http_network_layer.cc | 18 | ||||
-rw-r--r-- | net/http/http_network_layer.h | 1 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 72 | ||||
-rw-r--r-- | net/http/http_network_transaction.h | 16 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_pool.cc | 17 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_pool.h | 9 | ||||
-rw-r--r-- | net/socket/ssl_client_socket_pool_unittest.cc | 42 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 265 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 5 | ||||
-rw-r--r-- | net/spdy/spdy_session.h | 9 | ||||
-rw-r--r-- | net/spdy/spdy_session_pool.cc | 7 | ||||
-rw-r--r-- | net/spdy/spdy_session_pool.h | 7 |
13 files changed, 282 insertions, 188 deletions
diff --git a/chrome/browser/net/preconnect.cc b/chrome/browser/net/preconnect.cc index 7930a68..af0c308 100644 --- a/chrome/browser/net/preconnect.cc +++ b/chrome/browser/net/preconnect.cc @@ -110,7 +110,7 @@ void Preconnect::PreconnectOnIOThread(const GURL& url) { new net::SSLSocketParams(tcp_params, NULL, NULL, net::ProxyServer::SCHEME_DIRECT, url.HostNoBrackets(), ssl_config, - 0, false); + 0, false, false); const scoped_refptr<net::SSLClientSocketPool>& pool = session->ssl_socket_pool(); diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 4950a7b..30feddc 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -45,8 +45,6 @@ HttpTransactionFactory* HttpNetworkLayer::CreateFactory( } //----------------------------------------------------------------------------- -bool HttpNetworkLayer::force_spdy_ = false; - HttpNetworkLayer::HttpNetworkLayer( ClientSocketFactory* socket_factory, HostResolver* host_resolver, @@ -88,10 +86,7 @@ int HttpNetworkLayer::CreateTransaction(scoped_ptr<HttpTransaction>* trans) { if (suspended_) return ERR_NETWORK_IO_SUSPENDED; - if (force_spdy_) - trans->reset(new SpdyNetworkTransaction(GetSession())); - else - trans->reset(new HttpNetworkTransaction(GetSession())); + trans->reset(new HttpNetworkTransaction(GetSession())); return OK; } @@ -126,6 +121,7 @@ HttpNetworkSession* HttpNetworkLayer::GetSession() { // static void HttpNetworkLayer::EnableSpdy(const std::string& mode) { + static const char kSSL[] = "ssl"; static const char kDisableSSL[] = "no-ssl"; static const char kDisableCompression[] = "no-compress"; static const char kDisableAltProtocols[] = "no-alt-protocols"; @@ -160,9 +156,6 @@ void HttpNetworkLayer::EnableSpdy(const std::string& mode) { std::vector<std::string> spdy_options; SplitString(mode, ',', &spdy_options); - // Force spdy mode (use SpdyNetworkTransaction for all http requests). - force_spdy_ = true; - bool use_alt_protocols = true; for (std::vector<std::string>::iterator it = spdy_options.begin(); @@ -170,18 +163,21 @@ void HttpNetworkLayer::EnableSpdy(const std::string& mode) { const std::string& option = *it; if (option == kDisableSSL) { SpdySession::SetSSLMode(false); // Disable SSL + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false); + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true); + } else if (option == kSSL) { + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(true); + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true); } else if (option == kDisableCompression) { spdy::SpdyFramer::set_enable_compression_default(false); } else if (option == kEnableNPN) { HttpNetworkTransaction::SetUseAlternateProtocols(use_alt_protocols); HttpNetworkTransaction::SetNextProtos(kNpnProtosFull); - force_spdy_ = false; } else if (option == kEnableNpnHttpOnly) { // Avoid alternate protocol in this case. Otherwise, browser will try SSL // and then fallback to http. This introduces extra load. HttpNetworkTransaction::SetUseAlternateProtocols(false); HttpNetworkTransaction::SetNextProtos(kNpnProtosHttpOnly); - force_spdy_ = false; } else if (option == kDisableAltProtocols) { use_alt_protocols = false; HttpNetworkTransaction::SetUseAlternateProtocols(false); diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h index 657fcd3..b7229de 100644 --- a/net/http/http_network_layer.h +++ b/net/http/http_network_layer.h @@ -94,7 +94,6 @@ class HttpNetworkLayer : public HttpTransactionFactory, public NonThreadSafe { NetLog* net_log_; bool suspended_; - static bool force_spdy_; }; } // namespace net diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 2e5b437..ae1e86f 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -59,6 +59,8 @@ namespace { const HostMappingRules* g_host_mapping_rules = NULL; const std::string* g_next_protos = NULL; bool g_use_alternate_protocols = false; +bool g_want_ssl_over_spdy_without_npn = true; +bool g_want_spdy_without_npn = false; // A set of host:port strings. These are servers which we have needed to back // off to SSLv3 for. @@ -207,6 +209,8 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session) logged_response_time_(false), using_ssl_(false), using_spdy_(false), + want_spdy_without_npn_(g_want_spdy_without_npn), + want_ssl_over_spdy_without_npn_(g_want_ssl_over_spdy_without_npn), spdy_certificate_error_(OK), alternate_protocol_mode_( g_use_alternate_protocols ? kUnspecified : @@ -235,6 +239,16 @@ void HttpNetworkTransaction::SetUseAlternateProtocols(bool value) { } // static +void HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(bool value) { + g_want_ssl_over_spdy_without_npn = value; +} + +// static +void HttpNetworkTransaction::SetUseSpdyWithoutNPN(bool value) { + g_want_spdy_without_npn = value; +} + +// static void HttpNetworkTransaction::SetNextProtos(const std::string& next_protos) { delete g_next_protos; g_next_protos = new std::string(next_protos); @@ -711,9 +725,11 @@ int HttpNetworkTransaction::DoInitConnection() { session_); } - bool want_spdy = alternate_protocol_mode_ == kUsingAlternateProtocol + bool want_spdy_over_npn = alternate_protocol_mode_ == kUsingAlternateProtocol && alternate_protocol_ == HttpAlternateProtocols::NPN_SPDY_1; - using_ssl_ = request_->url.SchemeIs("https") || want_spdy; + using_ssl_ = request_->url.SchemeIs("https") || + (want_spdy_without_npn_ && want_ssl_over_spdy_without_npn_) || + want_spdy_over_npn; using_spdy_ = false; response_.was_fetched_via_proxy = !proxy_info_.is_direct(); @@ -814,7 +830,10 @@ int HttpNetworkTransaction::DoInitConnection() { new SSLSocketParams(tcp_params, http_proxy_params, socks_params, proxy_info_.proxy_server().scheme(), request_->url.HostNoBrackets(), ssl_config_, - load_flags, want_spdy); + load_flags, + want_spdy_without_npn_ && + want_ssl_over_spdy_without_npn_, + want_spdy_over_npn); scoped_refptr<SSLClientSocketPool> ssl_pool; if (proxy_info_.is_direct()) @@ -868,8 +887,14 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) { SSLClientSocket::kProtoSPDY1) using_spdy_ = true; } + if(want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) + using_spdy_ = true; } + // We may be using spdy without SSL + if(!want_ssl_over_spdy_without_npn_ && want_spdy_without_npn_) + using_spdy_ = true; + if (result == ERR_PROXY_AUTH_REQUESTED) { DCHECK(!ssl_started); const HttpResponseInfo& tunnel_auth_response = @@ -902,12 +927,19 @@ int HttpNetworkTransaction::DoInitConnectionComplete(int result) { // trying to reuse a keep-alive connection. reused_socket_ = connection_->is_reused(); // TODO(vandebo) should we exclude SPDY in the following if? - if (!reused_socket_) - UpdateConnectionTypeHistograms(CONNECTION_HTTP); + if (!reused_socket_) { + if (using_spdy_) + UpdateConnectionTypeHistograms(CONNECTION_SPDY); + else + UpdateConnectionTypeHistograms(CONNECTION_HTTP); + } if (!using_ssl_) { DCHECK_EQ(OK, result); - next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; + if (using_spdy_) + next_state_ = STATE_SPDY_GET_STREAM; + else + next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN; return result; } } @@ -1243,15 +1275,25 @@ int HttpNetworkTransaction::DoSpdyGetStream() { if (spdy_pool->HasSession(endpoint_)) { spdy_session = spdy_pool->Get(endpoint_, session_, net_log_); } else { - // SPDY is negotiated using the TLS next protocol negotiation (NPN) - // extension, so |connection_| must contain an SSLClientSocket. - DCHECK(using_ssl_); - CHECK(connection_->socket()); - int error = spdy_pool->GetSpdySessionFromSSLSocket( - endpoint_, session_, connection_.release(), net_log_, - spdy_certificate_error_, &spdy_session); - if (error != OK) - return error; + if(using_ssl_) { + // SPDY can be negotiated using the TLS next protocol negotiation (NPN) + // extension, or just directly using SSL. Either way, |connection_| must + // contain an SSLClientSocket. + CHECK(connection_->socket()); + int error = spdy_pool->GetSpdySessionFromSocket( + endpoint_, session_, connection_.release(), net_log_, + spdy_certificate_error_, &spdy_session, true); + if (error != OK) + return error; + } + else { + // We may want SPDY without SSL + int error = spdy_pool->GetSpdySessionFromSocket( + endpoint_, session_, connection_.release(), net_log_, + spdy_certificate_error_, &spdy_session, false); + if (error != OK) + return error; + } } CHECK(spdy_session.get()); diff --git a/net/http/http_network_transaction.h b/net/http/http_network_transaction.h index 7c32bd3..4d3cf4e 100644 --- a/net/http/http_network_transaction.h +++ b/net/http/http_network_transaction.h @@ -47,6 +47,12 @@ class HttpNetworkTransaction : public HttpTransaction { // Controls whether or not we use the Alternate-Protocol header. static void SetUseAlternateProtocols(bool value); + // Controls whether or not we use ssl when in spdy mode. + static void SetUseSSLOverSpdyWithoutNPN(bool value); + + // Controls whether or not we use spdy without npn. + static void SetUseSpdyWithoutNPN(bool value); + // Sets the next protocol negotiation value used during the SSL handshake. static void SetNextProtos(const std::string& next_protos); @@ -274,11 +280,19 @@ class HttpNetworkTransaction : public HttpTransaction { // responses. bool logged_response_time_; - bool using_ssl_; // True if handling a HTTPS request + // True if handling a HTTPS request, or using SPDY with SSL + bool using_ssl_; // True if this network transaction is using SPDY instead of HTTP. bool using_spdy_; + // True if this network transaction wants to use SPDY (not over npn) + bool want_spdy_without_npn_; + + // True if this network transaction wants to use SSL with SPDY (not over npn) + bool want_ssl_over_spdy_without_npn_; + + // The certificate error while using SPDY over SSL for insecure URLs. int spdy_certificate_error_; diff --git a/net/socket/ssl_client_socket_pool.cc b/net/socket/ssl_client_socket_pool.cc index 3fd960c..f13c1cf 100644 --- a/net/socket/ssl_client_socket_pool.cc +++ b/net/socket/ssl_client_socket_pool.cc @@ -18,7 +18,8 @@ SSLSocketParams::SSLSocketParams( const std::string& hostname, const SSLConfig& ssl_config, int load_flags, - bool want_spdy) + bool force_spdy_over_ssl, + bool want_spdy_over_npn) : tcp_params_(tcp_params), http_proxy_params_(http_proxy_params), socks_params_(socks_params), @@ -26,7 +27,8 @@ SSLSocketParams::SSLSocketParams( hostname_(hostname), ssl_config_(ssl_config), load_flags_(load_flags), - want_spdy_(want_spdy) { + force_spdy_over_ssl_(force_spdy_over_ssl), + want_spdy_over_npn_(want_spdy_over_npn) { switch (proxy_) { case ProxyServer::SCHEME_DIRECT: DCHECK(tcp_params_.get() != NULL); @@ -281,17 +283,22 @@ int SSLConnectJob::DoSSLConnectComplete(int result) { if (result == OK || IsCertificateError(result)) status = ssl_socket_->GetNextProto(&proto); - bool using_spdy = false; + // If we want spdy over npn, make sure it succeeded. + bool spdy_over_npn_succeeded = false; if (status == SSLClientSocket::kNextProtoNegotiated) { ssl_socket_->setWasNpnNegotiated(true); if (SSLClientSocket::NextProtoFromString(proto) == SSLClientSocket::kProtoSPDY1) { - using_spdy = true; + spdy_over_npn_succeeded = true; } } - if (params_->want_spdy() && !using_spdy) + if (params_->want_spdy_over_npn() && !spdy_over_npn_succeeded) return ERR_NPN_NEGOTIATION_FAILED; + // Spdy might be turned on by default, or it might be over npn. + bool using_spdy = params_->force_spdy_over_ssl() || + params_->want_spdy_over_npn(); + if (result == OK || ssl_socket_->IgnoreCertError(result, params_->load_flags())) { DCHECK(ssl_connect_start_time_ != base::TimeTicks()); diff --git a/net/socket/ssl_client_socket_pool.h b/net/socket/ssl_client_socket_pool.h index fd5bbb3..7a33b62 100644 --- a/net/socket/ssl_client_socket_pool.h +++ b/net/socket/ssl_client_socket_pool.h @@ -39,7 +39,8 @@ class SSLSocketParams : public base::RefCounted<SSLSocketParams> { const std::string& hostname, const SSLConfig& ssl_config, int load_flags, - bool want_spdy); + bool force_spdy_over_ssl, + bool want_spdy_over_npn); const scoped_refptr<TCPSocketParams>& tcp_params() { return tcp_params_; } const scoped_refptr<HttpProxySocketParams>& http_proxy_params () { @@ -52,7 +53,8 @@ class SSLSocketParams : public base::RefCounted<SSLSocketParams> { const std::string& hostname() const { return hostname_; } const SSLConfig& ssl_config() const { return ssl_config_; } int load_flags() const { return load_flags_; } - bool want_spdy() const { return want_spdy_; } + bool force_spdy_over_ssl() const { return force_spdy_over_ssl_; } + bool want_spdy_over_npn() const { return want_spdy_over_npn_; } private: friend class base::RefCounted<SSLSocketParams>; @@ -65,7 +67,8 @@ class SSLSocketParams : public base::RefCounted<SSLSocketParams> { const std::string hostname_; const SSLConfig ssl_config_; const int load_flags_; - const bool want_spdy_; + const bool force_spdy_over_ssl_; + const bool want_spdy_over_npn_; DISALLOW_COPY_AND_ASSIGN(SSLSocketParams); }; diff --git a/net/socket/ssl_client_socket_pool_unittest.cc b/net/socket/ssl_client_socket_pool_unittest.cc index 972f7d8..64cae4c 100644 --- a/net/socket/ssl_client_socket_pool_unittest.cc +++ b/net/socket/ssl_client_socket_pool_unittest.cc @@ -76,7 +76,7 @@ class SSLClientSocketPoolTest : public ClientSocketPoolTest { scoped_refptr<SSLSocketParams> SSLParams( ProxyServer::Scheme proxy, struct MockHttpAuthControllerData* auth_data, - size_t auth_data_len, bool want_spdy) { + size_t auth_data_len, bool want_spdy_over_ssl, bool want_spdy_over_npn) { scoped_refptr<HttpProxySocketParams> http_proxy_params; if (proxy == ProxyServer::SCHEME_HTTP) { @@ -97,7 +97,8 @@ class SSLClientSocketPoolTest : public ClientSocketPoolTest { "host", ssl_config_, 0, - want_spdy)); + want_spdy_over_ssl, + want_spdy_over_npn)); } MockClientSocketFactory socket_factory_; @@ -123,7 +124,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFail) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; int rv = handle.Init("a", params, MEDIUM, NULL, pool_, BoundNetLog()); @@ -140,7 +141,7 @@ TEST_F(SSLClientSocketPoolTest, TCPFailAsync) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -164,7 +165,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirect) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -182,7 +183,7 @@ TEST_F(SSLClientSocketPoolTest, BasicDirectAsync) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -204,7 +205,7 @@ TEST_F(SSLClientSocketPoolTest, DirectCertError) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -226,7 +227,7 @@ TEST_F(SSLClientSocketPoolTest, DirectSSLError) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -251,7 +252,7 @@ TEST_F(SSLClientSocketPoolTest, DirectWithNPN) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -277,7 +278,7 @@ TEST_F(SSLClientSocketPoolTest, DirectNoSPDY) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, true); + NULL, 0, false, true); ClientSocketHandle handle; TestCompletionCallback callback; @@ -302,7 +303,7 @@ TEST_F(SSLClientSocketPoolTest, DirectGotSPDY) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, true); + NULL, 0, false, true); ClientSocketHandle handle; TestCompletionCallback callback; @@ -333,7 +334,7 @@ TEST_F(SSLClientSocketPoolTest, DirectGotBonusSPDY) { CreatePool(true /* tcp pool */, false, false); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT, - NULL, 0, false); + NULL, 0, false, true); ClientSocketHandle handle; TestCompletionCallback callback; @@ -361,7 +362,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFail) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -379,7 +380,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSFailAsync) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -403,7 +404,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasic) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -421,7 +422,7 @@ TEST_F(SSLClientSocketPoolTest, SOCKSBasicAsync) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -442,7 +443,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFail) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -460,7 +461,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyFailAsync) { CreatePool(false, true /* http proxy pool */, true /* socks pool */); scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, - NULL, 0, false); + NULL, 0, false, false); ClientSocketHandle handle; TestCompletionCallback callback; @@ -500,6 +501,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasic) { scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, auth_data, arraysize(auth_data), + false, false); ClientSocketHandle handle; @@ -533,6 +535,7 @@ TEST_F(SSLClientSocketPoolTest, HttpProxyBasicAsync) { scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, auth_data, arraysize(auth_data), + false, false); ClientSocketHandle handle; @@ -572,6 +575,7 @@ TEST_F(SSLClientSocketPoolTest, NeedProxyAuth) { scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, auth_data, arraysize(auth_data), + false, false); ClientSocketHandle handle; @@ -620,6 +624,7 @@ TEST_F(SSLClientSocketPoolTest, DoProxyAuth) { scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, auth_data, arraysize(auth_data), + false, false); ClientSocketHandle handle; @@ -688,6 +693,7 @@ TEST_F(SSLClientSocketPoolTest, DoProxyAuthNoKeepAlive) { scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP, auth_data, arraysize(auth_data), + false, false); ClientSocketHandle handle; diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 2100e92..bce3feb 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -12,26 +12,25 @@ //----------------------------------------------------------------------------- namespace net { - -class SpdyNetworkTransactionTest : public PlatformTest { +enum SpdyNetworkTransactionTestTypes { + SPDYNPN, + SPDYNOSSL, + SPDYSSL +}; +class SpdyNetworkTransactionTest + : public ::testing::TestWithParam<SpdyNetworkTransactionTestTypes> { protected: virtual void SetUp() { // By default, all tests turn off compression. EnableCompression(false); google_get_request_initialized_ = false; - HttpNetworkTransaction::SetUseAlternateProtocols(true); - HttpNetworkTransaction::SetNextProtos( - "\x08http/1.1\x07http1.1\x06spdy/1\x04spdy"); } virtual void TearDown() { // Empty the current queue. MessageLoop::current()->RunAllPending(); - PlatformTest::TearDown(); } - void KeepAliveConnectionResendRequestTest(const MockRead& read_failure); - struct TransactionHelperResult { int rv; std::string status_line; @@ -50,56 +49,50 @@ class SpdyNetworkTransactionTest : public PlatformTest { class NormalSpdyTransactionHelper { public: NormalSpdyTransactionHelper(const HttpRequestInfo& request, - const BoundNetLog& log) + const BoundNetLog& log, + SpdyNetworkTransactionTestTypes test_type) : request_(request), session_(SpdySessionDependencies::SpdyCreateSession(&session_deps_)), - log_(log), add_data_allowed_(true) {} + log_(log), + test_type_(test_type) { + switch(test_type_) { + case SPDYNOSSL: + case SPDYSSL: + port_ = 80; + break; + case SPDYNPN: + port_ = 443; + break; + default: + NOTREACHED(); + } + } void RunPreTestSetup() { - // Disallow future calls to AddData - add_data_allowed_ = false; - - // Set up http data. - MockRead data_reads[] = { - MockRead("HTTP/1.1 200 OK\r\n"), - MockRead("Alternate-Protocol: 443:npn-spdy/1\r\n\r\n"), - MockRead("hello world"), - MockRead(true, OK), - }; - first_transaction_.reset( - new StaticSocketDataProvider(data_reads, arraysize(data_reads), - NULL, 0)); - session_deps_.socket_factory.AddSocketDataProvider( - first_transaction_.get()); - - // Set up actual test data. Also add one SSLSocketDataProvider per - // DataProvider. - for(DataVector::iterator it = data_vector_.begin(); - it != data_vector_.end(); ++it) { - linked_ptr<SSLSocketDataProvider> ssl_( - new SSLSocketDataProvider(true, OK)); - ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; - ssl_->next_proto = "spdy/1"; - ssl_->was_npn_negotiated = true; - ssl_vector_.push_back(ssl_); - session_deps_.socket_factory.AddSSLSocketDataProvider(ssl_.get()); - session_deps_.socket_factory.AddSocketDataProvider(*it); + HttpNetworkTransaction::SetUseAlternateProtocols(false); + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false); + HttpNetworkTransaction::SetUseSpdyWithoutNPN(false); + switch(test_type_) { + case SPDYNPN: + session_->mutable_alternate_protocols()->SetAlternateProtocolFor( + HostPortPair("www.google.com", 80), 443, + HttpAlternateProtocols::NPN_SPDY_1); + HttpNetworkTransaction::SetUseAlternateProtocols(true); + HttpNetworkTransaction::SetNextProtos( + "\x08http/1.1\x07http1.1\x06spdy/1\x04spdy"); + break; + case SPDYNOSSL: + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false); + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true); + break; + case SPDYSSL: + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(true); + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true); + break; + default: + NOTREACHED(); } - // We first send an http request. The Alternate-Protocol header switches - // the HttpNetworkTransaction into SSL/SPDY mode. - trans_http_.reset(new HttpNetworkTransaction(session_)); - int rv = trans_http_->Start(&request_, &callback, log_); - EXPECT_EQ(ERR_IO_PENDING, rv); - EXPECT_EQ(OK, callback.WaitForResult()); - const HttpResponseInfo* response = trans_http_->GetResponseInfo(); - EXPECT_TRUE(response != NULL); - EXPECT_TRUE(response->headers != NULL); - EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); - std::string response_data; - EXPECT_EQ(OK, ReadTransaction(trans_http_.get(), &response_data)); - EXPECT_EQ("hello world", response_data); - // We're now ready to use SSL-npn SPDY. trans_.reset(new HttpNetworkTransaction(session_)); } @@ -125,8 +118,14 @@ class SpdyNetworkTransactionTest : public PlatformTest { ASSERT_TRUE(response->headers != NULL); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); EXPECT_TRUE(response->was_fetched_via_spdy); - EXPECT_TRUE(response->was_npn_negotiated); - EXPECT_TRUE(response->was_alternate_protocol_available); + if(test_type_ == SPDYNPN) { + EXPECT_TRUE(response->was_npn_negotiated); + EXPECT_TRUE(response->was_alternate_protocol_available); + } + else { + EXPECT_TRUE(!response->was_npn_negotiated); + EXPECT_TRUE(!response->was_alternate_protocol_available); + } output_.status_line = response->headers->GetStatusLine(); output_.response_info = *response; // Make a copy so we can verify. output_.rv = ReadTransaction(trans_.get(), &output_.response_data); @@ -176,12 +175,19 @@ class SpdyNetworkTransactionTest : public PlatformTest { VerifyDataConsumed(); } - // Only call AddData before calling RunPreTestSetup!! When RunPreTestSetup - // is run, it will add this Data Provider, and a corresponding SSL data - // provider. void AddData(StaticSocketDataProvider* data) { - EXPECT_TRUE(add_data_allowed_); data_vector_.push_back(data); + linked_ptr<SSLSocketDataProvider> ssl_( + new SSLSocketDataProvider(true, OK)); + if(test_type_ == SPDYNPN) { + ssl_->next_proto_status = SSLClientSocket::kNextProtoNegotiated; + ssl_->next_proto = "spdy/1"; + ssl_->was_npn_negotiated = true; + } + ssl_vector_.push_back(ssl_); + if(test_type_ == SPDYNPN || test_type_ == SPDYSSL) + session_deps_.socket_factory.AddSSLSocketDataProvider(ssl_.get()); + session_deps_.socket_factory.AddSocketDataProvider(data); } // This can only be called after RunPreTestSetup. It adds a Data Provider, @@ -198,6 +204,7 @@ class SpdyNetworkTransactionTest : public PlatformTest { TransactionHelperResult& output() { return output_; } HttpRequestInfo& request() { return request_; } scoped_refptr<HttpNetworkSession>& session() { return session_; } + int port() { return port_; } private: typedef std::vector<StaticSocketDataProvider*> DataVector; @@ -213,7 +220,8 @@ class SpdyNetworkTransactionTest : public PlatformTest { scoped_ptr<HttpNetworkTransaction> trans_http_; DataVector data_vector_; const BoundNetLog& log_; - bool add_data_allowed_; + SpdyNetworkTransactionTestTypes test_type_; + int port_; }; void ConnectStatusHelperWithExpectedStatus(const MockRead& status, @@ -237,16 +245,22 @@ class SpdyNetworkTransactionTest : public PlatformTest { }; //----------------------------------------------------------------------------- +// All tests are run with three different connection types: SPDY after NPN +// negotiation, SPDY without SSL, and SPDY with SSL. +INSTANTIATE_TEST_CASE_P(SpdyNetworkingTest, + SpdyNetworkTransactionTest, + ::testing::Values(SPDYNPN, SPDYNOSSL, SPDYSSL)); + // Verify HttpNetworkTransaction constructor. -TEST_F(SpdyNetworkTransactionTest, Constructor) { +TEST_P(SpdyNetworkTransactionTest, Constructor) { SpdySessionDependencies session_deps; scoped_refptr<HttpNetworkSession> session = SpdySessionDependencies::SpdyCreateSession(&session_deps); scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session)); } -TEST_F(SpdyNetworkTransactionTest, Get) { +TEST_P(SpdyNetworkTransactionTest, Get) { // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -263,7 +277,7 @@ TEST_F(SpdyNetworkTransactionTest, Get) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); @@ -281,7 +295,7 @@ TEST_F(SpdyNetworkTransactionTest, Get) { // TODO(gavinp): create a working generalized TransactionHelper that // can allow multiple streams in flight. -TEST_F(SpdyNetworkTransactionTest, ThreeGets) { +TEST_P(SpdyNetworkTransactionTest, ThreeGets) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, false)); @@ -382,7 +396,7 @@ TEST_F(SpdyNetworkTransactionTest, ThreeGets) { // the first transaction completion, and sets a maximum concurrent // stream limit of 1. This means that our IO loop exists after the // second transaction completes, so we can assert on read_index(). -TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { +TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); @@ -508,7 +522,7 @@ TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // different data ("hello!" vs "hello!hello!") and because of the // user specified priority, we expect to see them inverted in // the response from the server. -TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { +TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); @@ -663,7 +677,7 @@ TEST_F(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // deletes a session in the middle of the transaction to insure // that we properly remove pendingcreatestream objects from // the spdy_session -TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { +TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); @@ -770,7 +784,7 @@ TEST_F(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { } // Test that a simple POST works. -TEST_F(SpdyNetworkTransactionTest, Post) { +TEST_P(SpdyNetworkTransactionTest, Post) { static const char upload[] = { "hello!" }; // Setup the request @@ -798,7 +812,7 @@ TEST_F(SpdyNetworkTransactionTest, Post) { new DelayedSocketData(2, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(request, - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); @@ -807,7 +821,7 @@ TEST_F(SpdyNetworkTransactionTest, Post) { } // Test that a simple POST works. -TEST_F(SpdyNetworkTransactionTest, EmptyPost) { +TEST_P(SpdyNetworkTransactionTest, EmptyPost) { // Setup the request HttpRequestInfo request; request.method = "POST"; @@ -835,7 +849,7 @@ TEST_F(SpdyNetworkTransactionTest, EmptyPost) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(request, - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); @@ -844,7 +858,7 @@ TEST_F(SpdyNetworkTransactionTest, EmptyPost) { } // While we're doing a post, the server sends back a SYN_REPLY. -TEST_F(SpdyNetworkTransactionTest, PostWithEarlySynReply) { +TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) { static const char upload[] = { "hello!" }; // Setup the request @@ -872,7 +886,7 @@ TEST_F(SpdyNetworkTransactionTest, PostWithEarlySynReply) { new DelayedSocketData(0, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(request, - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); helper.RunDefaultTest(); @@ -882,7 +896,7 @@ TEST_F(SpdyNetworkTransactionTest, PostWithEarlySynReply) { } // Test that the transaction doesn't crash when we don't have a reply. -TEST_F(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { +TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*body), @@ -892,7 +906,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { scoped_refptr<DelayedSocketData> data( new DelayedSocketData(1, reads, arraysize(reads), NULL, 0)); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); @@ -900,7 +914,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { // Test that the transaction doesn't crash when we get two replies on the same // stream ID. See http://crbug.com/45639. -TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { +TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -918,7 +932,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); @@ -942,7 +956,7 @@ TEST_F(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { // Test that sent data frames and received WINDOW_UPDATE frames change // the send_window_size_ correctly. -TEST_F(SpdyNetworkTransactionTest, WindowUpdate) { +TEST_P(SpdyNetworkTransactionTest, WindowUpdate) { SpdySessionDependencies session_deps; scoped_refptr<HttpNetworkSession> session = SpdySessionDependencies::SpdyCreateSession(&session_deps); @@ -1009,7 +1023,7 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdate) { } // Test that WINDOW_UPDATE frame causing overflow is handled correctly. -TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) { +TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { SpdySessionDependencies session_deps; scoped_refptr<HttpNetworkSession> session = SpdySessionDependencies::SpdyCreateSession(&session_deps); @@ -1077,7 +1091,7 @@ TEST_F(SpdyNetworkTransactionTest, WindowUpdateOverflow) { SpdySession::SetFlowControl(false); } -TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { +TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { @@ -1098,7 +1112,7 @@ TEST_F(SpdyNetworkTransactionTest, CancelledTransaction) { writes, arraysize(writes)); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(&data); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -1144,7 +1158,7 @@ class SpdyNetworkTransactionTest::StartTransactionCallback // Verify that the client can correctly deal with the user callback attempting // to start another transaction on a session that is closing down. See // http://crbug.com/47455 -TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { +TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; MockWrite writes2[] = { CreateMockWrite(*req) }; @@ -1180,7 +1194,7 @@ TEST_F(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { writes2, arraysize(writes2))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.AddData(data2.get()); helper.RunPreTestSetup(); @@ -1221,7 +1235,7 @@ class SpdyNetworkTransactionTest::DeleteSessionCallback // Verify that the client can correctly deal with the user callback deleting the // transaction. Failures will usually be valgrind errors. See // http://crbug.com/46925 -TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { +TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -1239,7 +1253,7 @@ TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -1266,7 +1280,7 @@ TEST_F(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { // Verify that various SynReply headers parse correctly through the // HTTP layer. -TEST_F(SpdyNetworkTransactionTest, SynReplyHeaders) { +TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { struct SynReplyHeadersTests { int num_headers; const char* extra_headers[5]; @@ -1326,7 +1340,7 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeaders) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); @@ -1350,7 +1364,7 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeaders) { // Verify that various SynReply headers parse vary fields correctly // through the HTTP layer, and the response matches the request. -TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) { +TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { static const SpdyHeaderInfo syn_reply_info = { spdy::SYN_REPLY, // Syn Reply 1, // Stream ID @@ -1474,7 +1488,7 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(request, - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); @@ -1518,7 +1532,7 @@ TEST_F(SpdyNetworkTransactionTest, SynReplyHeadersVary) { } // Verify that we don't crash on invalid SynReply responses. -TEST_F(SpdyNetworkTransactionTest, InvalidSynReply) { +TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { const SpdyHeaderInfo kSynStartHeader = { spdy::SYN_REPLY, // Kind = SynReply 1, // Stream ID @@ -1579,7 +1593,7 @@ TEST_F(SpdyNetworkTransactionTest, InvalidSynReply) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_INVALID_RESPONSE, out.rv); @@ -1588,7 +1602,7 @@ TEST_F(SpdyNetworkTransactionTest, InvalidSynReply) { // Verify that we don't crash on some corrupt frames. // TODO(eroman): Renable this test, see http://crbug.com/48588 -TEST_F(SpdyNetworkTransactionTest, DISABLED_CorruptFrameSessionError) { +TEST_P(SpdyNetworkTransactionTest, DISABLED_CorruptFrameSessionError) { // This is the length field with a big number scoped_ptr<spdy::SpdyFrame> syn_reply_massive_length( ConstructSpdyGetSynReply(NULL, 0, 1)); @@ -1619,7 +1633,7 @@ TEST_F(SpdyNetworkTransactionTest, DISABLED_CorruptFrameSessionError) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); @@ -1627,7 +1641,7 @@ TEST_F(SpdyNetworkTransactionTest, DISABLED_CorruptFrameSessionError) { } // Test that we shutdown correctly on write errors. -TEST_F(SpdyNetworkTransactionTest, WriteError) { +TEST_P(SpdyNetworkTransactionTest, WriteError) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { // We'll write 10 bytes successfully @@ -1640,7 +1654,7 @@ TEST_F(SpdyNetworkTransactionTest, WriteError) { new DelayedSocketData(2, NULL, 0, writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_FAILED, out.rv); @@ -1648,7 +1662,7 @@ TEST_F(SpdyNetworkTransactionTest, WriteError) { } // Test that partial writes work. -TEST_F(SpdyNetworkTransactionTest, PartialWrite) { +TEST_P(SpdyNetworkTransactionTest, PartialWrite) { // Chop the SYN_STREAM frame into 5 chunks. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); const int kChunks = 5; @@ -1666,7 +1680,7 @@ TEST_F(SpdyNetworkTransactionTest, PartialWrite) { new DelayedSocketData(kChunks, reads, arraysize(reads), writes.get(), kChunks)); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); @@ -1676,7 +1690,7 @@ TEST_F(SpdyNetworkTransactionTest, PartialWrite) { // In this test, we enable compression, but get a uncompressed SynReply from // the server. Verify that teardown is all clean. -TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { +TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { // For this test, we turn on the normal compression. EnableCompression(true); @@ -1698,7 +1712,7 @@ TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_SYN_REPLY_NOT_RECEIVED, out.rv); @@ -1708,7 +1722,7 @@ TEST_F(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { } // Test that the NetLog contains good data for a simple GET request. -TEST_F(SpdyNetworkTransactionTest, NetLog) { +TEST_P(SpdyNetworkTransactionTest, NetLog) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -1726,7 +1740,7 @@ TEST_F(SpdyNetworkTransactionTest, NetLog) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - log.bound()); + log.bound(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(OK, out.rv); @@ -1763,7 +1777,7 @@ TEST_F(SpdyNetworkTransactionTest, NetLog) { // that when we read out the maximum amount of data (e.g. we received 50 bytes // on the network, but issued a Read for only 5 of those bytes) that the data // flow still works correctly. -TEST_F(SpdyNetworkTransactionTest, BufferFull) { +TEST_P(SpdyNetworkTransactionTest, BufferFull) { spdy::SpdyFramer framer; scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -1803,7 +1817,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferFull) { TestCompletionCallback callback; NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -1854,7 +1868,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferFull) { EXPECT_EQ("goodbye world", out.response_data); } -TEST_F(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { +TEST_P(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { MockConnect connects[] = { MockConnect(true, ERR_NAME_NOT_RESOLVED), MockConnect(false, ERR_NAME_NOT_RESOLVED), @@ -1882,7 +1896,7 @@ TEST_F(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { new DelayedSocketData(connects[index], 1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); @@ -1905,6 +1919,12 @@ TEST_F(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { EXPECT_EQ(rv, ERR_IO_PENDING); rv = callback.WaitForResult(); const HttpResponseInfo* response = trans->GetResponseInfo(); + if (GetParam() == SPDYNOSSL || GetParam() == SPDYSSL) { + ASSERT_TRUE(response == NULL); + return; + } + if (GetParam() != SPDYNPN) + NOTREACHED(); ASSERT_TRUE(response != NULL); ASSERT_TRUE(response->headers != NULL); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); @@ -1925,7 +1945,7 @@ TEST_F(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) { // Verify that basic buffering works; when multiple data frames arrive // at the same time, ensure that we don't notify a read completion for // each data frame individually. -TEST_F(SpdyNetworkTransactionTest, Buffering) { +TEST_P(SpdyNetworkTransactionTest, Buffering) { spdy::SpdyFramer framer; scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -1960,7 +1980,7 @@ TEST_F(SpdyNetworkTransactionTest, Buffering) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -2019,7 +2039,7 @@ TEST_F(SpdyNetworkTransactionTest, Buffering) { } // Verify the case where we buffer data but read it after it has been buffered. -TEST_F(SpdyNetworkTransactionTest, BufferedAll) { +TEST_P(SpdyNetworkTransactionTest, BufferedAll) { spdy::SpdyFramer framer; scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -2055,7 +2075,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedAll) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -2110,7 +2130,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedAll) { } // Verify the case where we buffer data and close the connection. -TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { +TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { spdy::SpdyFramer framer; scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -2143,7 +2163,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -2200,7 +2220,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedClosed) { } // Verify the case where we buffer data and cancel the transaction. -TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { +TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { spdy::SpdyFramer framer; scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -2223,7 +2243,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -2271,7 +2291,7 @@ TEST_F(SpdyNetworkTransactionTest, BufferedCancelled) { // Test that if the server requests persistence of settings, that we save // the settings in the SpdySettingsStorage. -TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { +TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { static const SpdyHeaderInfo kSynReplyInfo = { spdy::SYN_REPLY, // Syn Reply 1, // Stream ID @@ -2290,10 +2310,10 @@ TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { }; NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); // Verify that no settings exist initially. - HostPortPair host_port_pair("www.google.com", 443); + HostPortPair host_port_pair("www.google.com", helper.port()); EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); // Construct the request. @@ -2375,7 +2395,7 @@ TEST_F(SpdyNetworkTransactionTest, SettingsSaved) { // Test that when there are settings saved that they are sent back to the // server upon session establishment. -TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { +TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { static const SpdyHeaderInfo kSynReplyInfo = { spdy::SYN_REPLY, // Syn Reply 1, // Stream ID @@ -2394,10 +2414,10 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { }; NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); // Verify that no settings exist initially. - HostPortPair host_port_pair("www.google.com", 443); + HostPortPair host_port_pair("www.google.com", helper.port()); EXPECT_TRUE(helper.session()->spdy_settings().Get(host_port_pair).empty()); unsigned int kSampleId1 = 0x1; @@ -2481,7 +2501,7 @@ TEST_F(SpdyNetworkTransactionTest, SettingsPlayback) { } } -TEST_F(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { +TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -2495,13 +2515,13 @@ TEST_F(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { new DelayedSocketData(1, reads, arraysize(reads), writes, arraysize(writes))); NormalSpdyTransactionHelper helper(CreateGetRequest(), - BoundNetLog()); + BoundNetLog(), GetParam()); helper.RunToCompletion(data.get()); TransactionHelperResult out = helper.output(); EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); } -TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { +TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req) }; @@ -2516,7 +2536,7 @@ TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { writes, arraysize(writes))); BoundNetLog log; NormalSpdyTransactionHelper helper(CreateGetRequest(), - log); + log, GetParam()); helper.AddData(data.get()); helper.RunPreTestSetup(); HttpNetworkTransaction* trans = helper.trans(); @@ -2538,5 +2558,4 @@ TEST_F(SpdyNetworkTransactionTest, CloseWithActiveStream) { // Verify that we consumed all test data. helper.VerifyDataConsumed(); } - } // namespace net diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index a5bebf5..26b6a10 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -198,8 +198,9 @@ SpdySession::~SpdySession() { net_log_.EndEvent(NetLog::TYPE_SPDY_SESSION, NULL); } -net::Error SpdySession::InitializeWithSSLSocket( +net::Error SpdySession::InitializeWithSocket( ClientSocketHandle* connection, + bool is_secure, int certificate_error_code) { static StatsCounter spdy_sessions("spdy.sessions"); spdy_sessions.Increment(); @@ -208,7 +209,7 @@ net::Error SpdySession::InitializeWithSSLSocket( state_ = CONNECTED; connection_.reset(connection); - is_secure_ = true; // |connection| contains an SSLClientSocket. + is_secure_ = is_secure; certificate_error_code_ = certificate_error_code; // This is a newly initialized session that no client should have a handle to diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index 16f4517..b25d3b4 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -85,10 +85,13 @@ class SpdySession : public base::RefCounted<SpdySession>, // Remove PendingCreateStream objects on transaction deletion void CancelPendingCreateStreams(const scoped_refptr<SpdyStream>* spdy_stream); - // Used by SpdySessionPool to initialize with a pre-existing SSL socket. + // Used by SpdySessionPool to initialize with a pre-existing SSL socket. For + // testing, setting is_secure to false allows initialization with a + // pre-existing TCP socket. // Returns OK on success, or an error on failure. - net::Error InitializeWithSSLSocket(ClientSocketHandle* connection, - int certificate_error_code); + net::Error InitializeWithSocket(ClientSocketHandle* connection, + bool is_secure, + int certificate_error_code); // Send the SYN frame for |stream_id|. int WriteSynStream( diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index 8caa040..da8b358 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -48,13 +48,14 @@ scoped_refptr<SpdySession> SpdySessionPool::Get( return spdy_session; } -net::Error SpdySessionPool::GetSpdySessionFromSSLSocket( +net::Error SpdySessionPool::GetSpdySessionFromSocket( const HostPortPair& host_port_pair, HttpNetworkSession* session, ClientSocketHandle* connection, const BoundNetLog& net_log, int certificate_error_code, - scoped_refptr<SpdySession>* spdy_session) { + scoped_refptr<SpdySession>* spdy_session, + bool is_secure) { // Create the SPDY session and add it to the pool. *spdy_session = new SpdySession(host_port_pair, session, net_log.net_log()); SpdySessionList* list = GetSessionList(host_port_pair); @@ -64,7 +65,7 @@ net::Error SpdySessionPool::GetSpdySessionFromSSLSocket( list->push_back(*spdy_session); // Now we can initialize the session with the SSL socket. - return (*spdy_session)->InitializeWithSSLSocket(connection, + return (*spdy_session)->InitializeWithSocket(connection, is_secure, certificate_error_code); } diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 1004169..0819b71 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h @@ -50,15 +50,18 @@ class SpdySessionPool // transferred from the caller to the SpdySession. // |certificate_error_code| is used to indicate the certificate error // encountered when connecting the SSL socket. OK means there was no error. + // For testing, setting is_secure to false allows Spdy to connect with a + // pre-existing TCP socket. // Returns OK on success, and the |spdy_session| will be provided. // Returns an error on failure, and |spdy_session| will be NULL. - net::Error GetSpdySessionFromSSLSocket( + net::Error GetSpdySessionFromSocket( const HostPortPair& host_port_pair, HttpNetworkSession* session, ClientSocketHandle* connection, const BoundNetLog& net_log, int certificate_error_code, - scoped_refptr<SpdySession>* spdy_session); + scoped_refptr<SpdySession>* spdy_session, + bool is_secure); // TODO(willchan): Consider renaming to HasReusableSession, since perhaps we // should be creating a new session. |