diff options
author | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-16 19:46:56 +0000 |
---|---|---|
committer | mbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-10-16 19:46:56 +0000 |
commit | 1f418eedde2047d92089e72265ec3e1706d97c10 (patch) | |
tree | ee444e94faae36e30fdc3ec847595e27440ffbbc /net | |
parent | 1b1a9221491b3c47b33c4380efeab04a36d98112 (diff) | |
download | chromium_src-1f418eedde2047d92089e72265ec3e1706d97c10.zip chromium_src-1f418eedde2047d92089e72265ec3e1706d97c10.tar.gz chromium_src-1f418eedde2047d92089e72265ec3e1706d97c10.tar.bz2 |
Add an off switch for SPDY:
--use-spdy=off
BUG=none
TEST=SpdyNetworkTransactionTest.SpdyOnOffToggle
Review URL: http://codereview.chromium.org/3807008
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@62870 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r-- | net/http/http_network_layer.cc | 5 | ||||
-rw-r--r-- | net/http/http_stream_factory.cc | 2 | ||||
-rw-r--r-- | net/http/http_stream_factory.h | 7 | ||||
-rw-r--r-- | net/http/http_stream_request.cc | 50 | ||||
-rw-r--r-- | net/http/http_stream_request.h | 3 | ||||
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 66 | ||||
-rw-r--r-- | net/spdy/spdy_session.cc | 1 |
7 files changed, 109 insertions, 25 deletions
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 38f95ef..0f53d4c 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -158,6 +158,7 @@ HttpNetworkSession* HttpNetworkLayer::GetSession() { // static void HttpNetworkLayer::EnableSpdy(const std::string& mode) { + static const char kOff[] = "off"; static const char kSSL[] = "ssl"; static const char kDisableSSL[] = "no-ssl"; static const char kDisableCompression[] = "no-compress"; @@ -201,7 +202,9 @@ void HttpNetworkLayer::EnableSpdy(const std::string& mode) { for (std::vector<std::string>::iterator it = spdy_options.begin(); it != spdy_options.end(); ++it) { const std::string& option = *it; - if (option == kDisableSSL) { + if (option == kOff) { + HttpStreamFactory::set_spdy_enabled(false); + } else if (option == kDisableSSL) { SpdySession::SetSSLMode(false); // Disable SSL HttpStreamFactory::set_force_spdy_over_ssl(false); HttpStreamFactory::set_force_spdy_always(true); diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index 1ddd1c2..35b471a 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -20,6 +20,8 @@ const HostMappingRules* HttpStreamFactory::host_mapping_rules_ = NULL; // static const std::string* HttpStreamFactory::next_protos_ = NULL; // static +bool HttpStreamFactory::spdy_enabled_ = true; +// static bool HttpStreamFactory::use_alternate_protocols_ = false; // static bool HttpStreamFactory::force_spdy_over_ssl_ = true; diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index b619add..e3b9f64 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -63,6 +63,12 @@ class HttpStreamFactory : public StreamFactory, // Static settings + // Turns spdy on or off. + static void set_spdy_enabled(bool value) { + spdy_enabled_ = value; + } + static bool spdy_enabled() { return spdy_enabled_; } + // Controls whether or not we use the Alternate-Protocol header. static void set_use_alternate_protocols(bool value) { use_alternate_protocols_ = value; @@ -116,6 +122,7 @@ class HttpStreamFactory : public StreamFactory, static const HostMappingRules* host_mapping_rules_; static const std::string* next_protos_; + static bool spdy_enabled_; static bool use_alternate_protocols_; static bool force_spdy_over_ssl_; static bool force_spdy_always_; diff --git a/net/http/http_stream_request.cc b/net/http/http_stream_request.cc index dd079a4..abf1e4c 100644 --- a/net/http/http_stream_request.cc +++ b/net/http/http_stream_request.cc @@ -362,7 +362,8 @@ int HttpStreamRequest::DoResolveProxy() { const HttpAlternateProtocols& alternate_protocols = session_->alternate_protocols(); - if (alternate_protocols.HasAlternateProtocolFor(endpoint_)) { + if (HttpStreamFactory::spdy_enabled() && + alternate_protocols.HasAlternateProtocolFor(endpoint_)) { was_alternate_protocol_available_ = true; if (alternate_protocol_mode_ == kUnspecified) { HttpAlternateProtocols::PortProtocolPair alternate = @@ -439,25 +440,29 @@ int HttpStreamRequest::DoInitConnection() { want_spdy_over_npn; using_spdy_ = false; - // Check first if we have a spdy session for this group. If so, then go - // straight to using that. Unless we are preconnecting. - HostPortProxyPair pair(endpoint_, proxy_info()->proxy_server()); - if (!preconnect_delegate_ && - session_->spdy_session_pool()->HasSession(pair)) { - using_spdy_ = true; - next_state_ = STATE_CREATE_STREAM; - return OK; - } - // Check next if we have a spdy session for this proxy. If so, then go - // straight to using that. - if (IsHttpsProxyAndHttpUrl()) { - HostPortProxyPair proxy(proxy_info()->proxy_server().host_port_pair(), - ProxyServer::Direct()); - if (session_->spdy_session_pool()->HasSession(proxy)) { + // If spdy has been turned off on-the-fly, then there may be SpdySessions + // still active. But don't use them unless spdy is currently on. + if (HttpStreamFactory::spdy_enabled()) { + // Check first if we have a spdy session for this group. If so, then go + // straight to using that. + HostPortProxyPair pair(endpoint_, proxy_info()->proxy_server()); + if (!preconnect_delegate_ && + session_->spdy_session_pool()->HasSession(pair)) { using_spdy_ = true; next_state_ = STATE_CREATE_STREAM; return OK; } + // Check next if we have a spdy session for this proxy. If so, then go + // straight to using that. + if (IsHttpsProxyAndHttpUrl()) { + HostPortProxyPair proxy(proxy_info()->proxy_server().host_port_pair(), + ProxyServer::Direct()); + if (session_->spdy_session_pool()->HasSession(proxy)) { + using_spdy_ = true; + next_state_ = STATE_CREATE_STREAM; + return OK; + } + } } // Build the string used to uniquely identify connections of this type. @@ -638,23 +643,23 @@ int HttpStreamRequest::DoInitConnectionComplete(int result) { if (ssl_socket->was_npn_negotiated()) { was_npn_negotiated_ = true; if (ssl_socket->was_spdy_negotiated()) - using_spdy_ = true; + SwitchToSpdyMode(); } if (force_spdy_over_ssl_ && force_spdy_always_) - using_spdy_ = true; + SwitchToSpdyMode(); } else if (proxy_info()->is_https() && connection_->socket() && result == OK) { HttpProxyClientSocket* proxy_socket = static_cast<HttpProxyClientSocket*>(connection_->socket()); if (proxy_socket->using_spdy()) { was_npn_negotiated_ = true; - using_spdy_ = true; + SwitchToSpdyMode(); } } // We may be using spdy without SSL if (!force_spdy_over_ssl_ && force_spdy_always_) - using_spdy_ = true; + SwitchToSpdyMode(); if (result == ERR_PROXY_AUTH_REQUESTED) { DCHECK(!ssl_started); @@ -1010,6 +1015,11 @@ int HttpStreamRequest::HandleSSLHandshakeError(int error) { return error; } +void HttpStreamRequest::SwitchToSpdyMode() { + if (HttpStreamFactory::spdy_enabled()) + using_spdy_ = true; +} + // static void HttpStreamRequest::LogHttpConnectedMetrics( const ClientSocketHandle& handle) { diff --git a/net/http/http_stream_request.h b/net/http/http_stream_request.h index 4769f55..ec3ce04 100644 --- a/net/http/http_stream_request.h +++ b/net/http/http_stream_request.h @@ -177,6 +177,9 @@ class HttpStreamRequest : public StreamRequest { // code is returned. int HandleSSLHandshakeError(int error); + // Moves this stream request into SPDY mode. + void SwitchToSpdyMode(); + // Record histograms of latency until Connect() completes. static void LogHttpConnectedMetrics(const ClientSocketHandle& handle); diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index e9076d3..99b50896 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -26,7 +26,7 @@ static const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2"; enum SpdyNetworkTransactionTestTypes { SPDYNPN, SPDYNOSSL, - SPDYSSL + SPDYSSL, }; class SpdyNetworkTransactionTest : public ::testing::TestWithParam<SpdyNetworkTransactionTestTypes> { @@ -69,7 +69,8 @@ class SpdyNetworkTransactionTest session_deps_.get())), log_(log), test_type_(test_type), - deterministic_(false) { + deterministic_(false), + spdy_enabled_(true) { switch (test_type_) { case SPDYNOSSL: case SPDYSSL: @@ -101,6 +102,10 @@ class SpdyNetworkTransactionTest deterministic_ = true; } + void SetSpdyDisabled() { + spdy_enabled_ = false; + } + void RunPreTestSetup() { if (!session_deps_.get()) session_deps_.reset(new SpdySessionDependencies()); @@ -154,14 +159,20 @@ class SpdyNetworkTransactionTest ASSERT_TRUE(response != NULL); ASSERT_TRUE(response->headers != NULL); EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); - EXPECT_TRUE(response->was_fetched_via_spdy); - if (test_type_ == SPDYNPN) { + EXPECT_EQ(spdy_enabled_, response->was_fetched_via_spdy); + if (test_type_ == SPDYNPN && spdy_enabled_) { 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); } + // If SPDY is not enabled, a HTTP request should not be diverted + // over a SSL session. + if (!spdy_enabled_) { + EXPECT_EQ(request_.url.SchemeIs("https"), + response->was_npn_negotiated); + } 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); @@ -287,6 +298,7 @@ class SpdyNetworkTransactionTest SpdyNetworkTransactionTestTypes test_type_; int port_; bool deterministic_; + bool spdy_enabled_; }; void ConnectStatusHelperWithExpectedStatus(const MockRead& status, @@ -4483,4 +4495,50 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { helper.VerifyDataConsumed(); } } + +// Test that turning SPDY on and off works properly. +TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { + net::HttpStreamFactory::set_spdy_enabled(true); + scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); + MockWrite spdy_writes[] = { CreateMockWrite(*req) }; + + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1)); + scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true)); + MockRead spdy_reads[] = { + CreateMockRead(*resp), + CreateMockRead(*body), + MockRead(true, 0, 0) // EOF + }; + + scoped_refptr<DelayedSocketData> data( + new DelayedSocketData(1, spdy_reads, arraysize(spdy_reads), + spdy_writes, arraysize(spdy_writes))); + NormalSpdyTransactionHelper helper(CreateGetRequest(), + BoundNetLog(), GetParam()); + helper.RunToCompletion(data.get()); + TransactionHelperResult out = helper.output(); + EXPECT_EQ(OK, out.rv); + EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); + EXPECT_EQ("hello!", out.response_data); + + net::HttpStreamFactory::set_spdy_enabled(false); + MockRead http_reads[] = { + MockRead("HTTP/1.1 200 OK\r\n\r\n"), + MockRead("hello from http"), + MockRead(false, OK), + }; + scoped_refptr<DelayedSocketData> data2( + new DelayedSocketData(1, http_reads, arraysize(http_reads), + NULL, 0)); + NormalSpdyTransactionHelper helper2(CreateGetRequest(), + BoundNetLog(), GetParam()); + helper2.SetSpdyDisabled(); + helper2.RunToCompletion(data2.get()); + TransactionHelperResult out2 = helper2.output(); + EXPECT_EQ(OK, out2.rv); + EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line); + EXPECT_EQ("hello from http", out2.response_data); + + net::HttpStreamFactory::set_spdy_enabled(true); +} } // namespace net diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index b6e1529..f94dfd3 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -249,6 +249,7 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, initial_send_window_size_(spdy::kInitialWindowSize), initial_recv_window_size_(spdy::kInitialWindowSize), net_log_(BoundNetLog::Make(net_log, NetLog::SOURCE_SPDY_SESSION)) { + DCHECK(HttpStreamFactory::spdy_enabled()); net_log_.BeginEvent( NetLog::TYPE_SPDY_SESSION, new NetLogSpdySessionParameter(host_port_proxy_pair_)); |