summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authormbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-16 19:46:56 +0000
committermbelshe@chromium.org <mbelshe@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-10-16 19:46:56 +0000
commit1f418eedde2047d92089e72265ec3e1706d97c10 (patch)
treeee444e94faae36e30fdc3ec847595e27440ffbbc /net
parent1b1a9221491b3c47b33c4380efeab04a36d98112 (diff)
downloadchromium_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.cc5
-rw-r--r--net/http/http_stream_factory.cc2
-rw-r--r--net/http/http_stream_factory.h7
-rw-r--r--net/http/http_stream_request.cc50
-rw-r--r--net/http/http_stream_request.h3
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc66
-rw-r--r--net/spdy/spdy_session.cc1
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_));