summaryrefslogtreecommitdiffstats
path: root/net/spdy
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-06 16:45:29 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-06 16:45:29 +0000
commit46e1edc4121dda51143becfffbc46674c770def2 (patch)
tree27593717ecc788e3f863e91fcef9ec11f8991697 /net/spdy
parent7a44af79d362f76d2af41a440506eb7fad0792cb (diff)
downloadchromium_src-46e1edc4121dda51143becfffbc46674c770def2.zip
chromium_src-46e1edc4121dda51143becfffbc46674c770def2.tar.gz
chromium_src-46e1edc4121dda51143becfffbc46674c770def2.tar.bz2
Don't block on stream requests on Alternate-Protocol.
Basically, after we get an HTTP header giving an Alternate-Protocol, we'll end up in a state where we're probably going to issue more HTTP requests. We have the already warm single HTTP connection. We probably don't have a SPDY session open. Previously, once we notice Alternate-Protocol, we'd block on trying to set up the new SPDY session, even though we still have the HTTP connection. Change this so we keep using HTTP until the SPDY session on the Alternate-Protocol becomes available, then we switch over to it. BUG=69688,75000 TEST=Browse to belshe.com. Examine net-internals to make sure it works. Test over a variety of connections (direct / various proxy types). Review URL: http://codereview.chromium.org/6610034 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@77075 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy')
-rw-r--r--net/spdy/spdy_http_stream.h1
-rw-r--r--net/spdy/spdy_network_transaction_unittest.cc108
2 files changed, 70 insertions, 39 deletions
diff --git a/net/spdy/spdy_http_stream.h b/net/spdy/spdy_http_stream.h
index bdae342..c165b21 100644
--- a/net/spdy/spdy_http_stream.h
+++ b/net/spdy/spdy_http_stream.h
@@ -65,6 +65,7 @@ class SpdyHttpStream : public SpdyStream::Delegate, public HttpStream {
virtual void SetConnectionReused();
virtual void GetSSLInfo(SSLInfo* ssl_info);
virtual void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info);
+ virtual bool IsSpdyHttpStream() const { return true; }
// SpdyStream::Delegate methods:
virtual bool OnSendHeadersComplete(int status);
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 94ef61d..8fc0913 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -167,10 +167,8 @@ class SpdyNetworkTransactionTest
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.
@@ -237,9 +235,20 @@ class SpdyNetworkTransactionTest
ssl_->was_npn_negotiated = true;
}
ssl_vector_.push_back(ssl_);
- if(test_type_ == SPDYNPN || test_type_ == SPDYSSL)
+ if (test_type_ == SPDYNPN || test_type_ == SPDYSSL)
session_deps_->socket_factory->AddSSLSocketDataProvider(ssl_.get());
session_deps_->socket_factory->AddSocketDataProvider(data);
+ if (test_type_ == SPDYNPN) {
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ linked_ptr<StaticSocketDataProvider>
+ hanging_non_alternate_protocol_socket(
+ new StaticSocketDataProvider(NULL, 0, NULL, 0));
+ hanging_non_alternate_protocol_socket->set_connect_data(
+ never_finishing_connect);
+ session_deps_->socket_factory->AddSocketDataProvider(
+ hanging_non_alternate_protocol_socket.get());
+ alternate_vector_.push_back(hanging_non_alternate_protocol_socket);
+ }
}
void AddDeterministicData(DeterministicSocketData* data) {
@@ -253,10 +262,23 @@ class SpdyNetworkTransactionTest
ssl_->was_npn_negotiated = true;
}
ssl_vector_.push_back(ssl_);
- if(test_type_ == SPDYNPN || test_type_ == SPDYSSL)
+ if (test_type_ == SPDYNPN || test_type_ == SPDYSSL) {
session_deps_->deterministic_socket_factory->
AddSSLSocketDataProvider(ssl_.get());
+ }
session_deps_->deterministic_socket_factory->AddSocketDataProvider(data);
+ if (test_type_ == SPDYNPN) {
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
+ scoped_refptr<DeterministicSocketData>
+ hanging_non_alternate_protocol_socket(
+ new DeterministicSocketData(NULL, 0, NULL, 0));
+ hanging_non_alternate_protocol_socket->set_connect_data(
+ never_finishing_connect);
+ session_deps_->deterministic_socket_factory->AddSocketDataProvider(
+ hanging_non_alternate_protocol_socket);
+ alternate_deterministic_vector_.push_back(
+ hanging_non_alternate_protocol_socket);
+ }
}
// This can only be called after RunPreTestSetup. It adds a Data Provider,
@@ -289,6 +311,9 @@ class SpdyNetworkTransactionTest
private:
typedef std::vector<StaticSocketDataProvider*> DataVector;
typedef std::vector<linked_ptr<SSLSocketDataProvider> > SSLVector;
+ typedef std::vector<linked_ptr<StaticSocketDataProvider> > AlternateVector;
+ typedef std::vector<scoped_refptr<DeterministicSocketData> >
+ AlternateDeterministicVector;
HttpRequestInfo request_;
scoped_ptr<SpdySessionDependencies> session_deps_;
scoped_refptr<HttpNetworkSession> session_;
@@ -299,6 +324,8 @@ class SpdyNetworkTransactionTest
scoped_ptr<HttpNetworkTransaction> trans_;
scoped_ptr<HttpNetworkTransaction> trans_http_;
DataVector data_vector_;
+ AlternateVector alternate_vector_;
+ AlternateDeterministicVector alternate_deterministic_vector_;
const BoundNetLog& log_;
SpdyNetworkTransactionTestTypes test_type_;
int port_;
@@ -704,7 +731,7 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
new OrderedSocketData(reads, arraysize(reads),
writes, arraysize(writes)));
- MockConnect never_finishing_connect(true, ERR_IO_PENDING);
+ MockConnect never_finishing_connect(false, ERR_IO_PENDING);
scoped_refptr<OrderedSocketData> data_placeholder(
new OrderedSocketData(NULL, 0, NULL, 0));
@@ -893,10 +920,12 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
settings.push_back(spdy::SpdySetting(id, max_concurrent_streams));
scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings));
- MockWrite writes[] = { CreateMockWrite(*req),
- CreateMockWrite(*req2),
- CreateMockWrite(*req3),
+ MockWrite writes[] = {
+ CreateMockWrite(*req),
+ CreateMockWrite(*req2),
+ CreateMockWrite(*req3),
};
+
MockRead reads[] = {
CreateMockRead(*settings_frame, 1),
CreateMockRead(*resp),
@@ -921,14 +950,14 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
BoundNetLog log;
TransactionHelperResult out;
{
- NormalSpdyTransactionHelper helper(CreateGetRequest(),
- BoundNetLog(), GetParam());
- helper.RunPreTestSetup();
- helper.AddData(data.get());
- // We require placeholder data because three get requests are sent out, so
- // there needs to be three sets of SSL connection data.
- helper.AddData(data_placeholder.get());
- helper.AddData(data_placeholder.get());
+ NormalSpdyTransactionHelper helper(CreateGetRequest(),
+ BoundNetLog(), GetParam());
+ helper.RunPreTestSetup();
+ helper.AddData(data.get());
+ // We require placeholder data because three get requests are sent out, so
+ // there needs to be three sets of SSL connection data.
+ helper.AddData(data_placeholder.get());
+ helper.AddData(data_placeholder.get());
scoped_ptr<HttpNetworkTransaction> trans1(
new HttpNetworkTransaction(helper.session()));
scoped_ptr<HttpNetworkTransaction> trans2(
@@ -1716,7 +1745,7 @@ TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
scoped_refptr<DeterministicSocketData> data(
new DeterministicSocketData(reads, arraysize(reads),
- writes, arraysize(writes)));
+ writes, arraysize(writes)));
NormalSpdyTransactionHelper helper(CreateGetRequest(),
BoundNetLog(), GetParam());
helper.SetDeterministic();
@@ -2530,20 +2559,6 @@ TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
"version",
"HTTP/1.1"
};
- const char* const kStandardGetHeaders2[] = {
- "host",
- "www.foo.com",
- "method",
- "GET",
- "scheme",
- "http",
- "url",
- "/index.php",
- "user-agent",
- "",
- "version",
- "HTTP/1.1"
- };
// Setup writes/reads to www.google.com
scoped_ptr<spdy::SpdyFrame> req(
@@ -2552,12 +2567,6 @@ TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
arraysize(kExtraHeaders) / 2,
kStandardGetHeaders,
arraysize(kStandardGetHeaders) / 2));
- scoped_ptr<spdy::SpdyFrame> req2(
- ConstructSpdyPacket(kSynStartHeader,
- kExtraHeaders,
- arraysize(kExtraHeaders) / 2,
- kStandardGetHeaders2,
- arraysize(kStandardGetHeaders2) / 2));
scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<spdy::SpdyFrame> rep(
ConstructSpdyPush(NULL,
@@ -2568,18 +2577,40 @@ TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
"301 Moved Permanently",
"http://www.foo.com/index.php"));
scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
+ scoped_ptr<spdy::SpdyFrame> rst(ConstructSpdyRstStream(2, spdy::CANCEL));
MockWrite writes[] = {
CreateMockWrite(*req, 1),
+ CreateMockWrite(*rst, 6),
};
MockRead reads[] = {
CreateMockRead(*resp, 2),
CreateMockRead(*rep, 3),
CreateMockRead(*body, 4),
MockRead(true, ERR_IO_PENDING, 5), // Force a pause
- MockRead(true, 0, 0, 6) // EOF
+ MockRead(true, 0, 0, 7) // EOF
};
// Setup writes/reads to www.foo.com
+ const char* const kStandardGetHeaders2[] = {
+ "host",
+ "www.foo.com",
+ "method",
+ "GET",
+ "scheme",
+ "http",
+ "url",
+ "/index.php",
+ "user-agent",
+ "",
+ "version",
+ "HTTP/1.1"
+ };
+ scoped_ptr<spdy::SpdyFrame> req2(
+ ConstructSpdyPacket(kSynStartHeader,
+ kExtraHeaders,
+ arraysize(kExtraHeaders) / 2,
+ kStandardGetHeaders2,
+ arraysize(kStandardGetHeaders2) / 2));
scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
MockWrite writes2[] = {
@@ -3871,7 +3902,6 @@ TEST_P(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) {
EXPECT_TRUE(!response->was_fetched_via_spdy);
EXPECT_TRUE(!response->was_npn_negotiated);
- EXPECT_TRUE(response->was_alternate_protocol_available);
EXPECT_TRUE(http_fallback->at_read_eof());
EXPECT_EQ(0u, data->read_index());
EXPECT_EQ(0u, data->write_index());