| Index: net/spdy/spdy_network_transaction_unittest.cc
|
| diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
|
| index 019cc4c8bee9ea10258d4e7cace3b140f6d69ea0..84e19d642b79b23d7c31a7bf391421377e323ef5 100644
|
| --- a/net/spdy/spdy_network_transaction_unittest.cc
|
| +++ b/net/spdy/spdy_network_transaction_unittest.cc
|
| @@ -579,9 +579,10 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
|
| scoped_ptr<spdy::SpdyFrame> body3(ConstructSpdyBodyFrame(5, false));
|
| scoped_ptr<spdy::SpdyFrame> fbody3(ConstructSpdyBodyFrame(5, true));
|
|
|
| - MockWrite writes[] = { CreateMockWrite(*req),
|
| - CreateMockWrite(*req2),
|
| - CreateMockWrite(*req3),
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req),
|
| + CreateMockWrite(*req2),
|
| + CreateMockWrite(*req3),
|
| };
|
| MockRead reads[] = {
|
| CreateMockRead(*resp, 1),
|
| @@ -657,6 +658,193 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
|
| EXPECT_EQ("hello!hello!", out.response_data);
|
| }
|
|
|
| +TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
|
| + 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));
|
| + scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
|
| + scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
|
| + scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
|
| + scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
|
| +
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req),
|
| + CreateMockWrite(*req2),
|
| + };
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 1),
|
| + CreateMockRead(*body),
|
| + CreateMockRead(*resp2, 4),
|
| + CreateMockRead(*body2),
|
| + CreateMockRead(*fbody),
|
| + CreateMockRead(*fbody2),
|
| + MockRead(true, 0, 0), // EOF
|
| + };
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| +
|
| + MockConnect never_finishing_connect(true, ERR_IO_PENDING);
|
| +
|
| + scoped_refptr<OrderedSocketData> data_placeholder(
|
| + new OrderedSocketData(NULL, 0, NULL, 0));
|
| + data_placeholder->set_connect_data(never_finishing_connect);
|
| +
|
| + BoundNetLog log;
|
| + TransactionHelperResult out;
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| + // We require placeholder data because two get requests are sent out, so
|
| + // there needs to be two sets of SSL connection data.
|
| + helper.AddData(data_placeholder.get());
|
| + scoped_ptr<HttpNetworkTransaction> trans1(
|
| + new HttpNetworkTransaction(helper.session()));
|
| + scoped_ptr<HttpNetworkTransaction> trans2(
|
| + new HttpNetworkTransaction(helper.session()));
|
| +
|
| + TestCompletionCallback callback1;
|
| + TestCompletionCallback callback2;
|
| +
|
| + HttpRequestInfo httpreq1 = CreateGetRequest();
|
| + HttpRequestInfo httpreq2 = CreateGetRequest();
|
| +
|
| + out.rv = trans1->Start(&httpreq1, &callback1, log);
|
| + ASSERT_EQ(ERR_IO_PENDING, out.rv);
|
| + out.rv = trans2->Start(&httpreq2, &callback2, log);
|
| + ASSERT_EQ(ERR_IO_PENDING, out.rv);
|
| +
|
| + out.rv = callback1.WaitForResult();
|
| + ASSERT_EQ(OK, out.rv);
|
| + out.rv = callback2.WaitForResult();
|
| + ASSERT_EQ(OK, out.rv);
|
| +
|
| + const HttpResponseInfo* response1 = trans1->GetResponseInfo();
|
| + EXPECT_TRUE(response1->headers != NULL);
|
| + EXPECT_TRUE(response1->was_fetched_via_spdy);
|
| + out.status_line = response1->headers->GetStatusLine();
|
| + out.response_info = *response1;
|
| + out.rv = ReadTransaction(trans1.get(), &out.response_data);
|
| + EXPECT_EQ(OK, out.rv);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| + EXPECT_EQ("hello!hello!", out.response_data);
|
| +
|
| + const HttpResponseInfo* response2 = trans2->GetResponseInfo();
|
| + EXPECT_TRUE(response2->headers != NULL);
|
| + EXPECT_TRUE(response2->was_fetched_via_spdy);
|
| + out.status_line = response2->headers->GetStatusLine();
|
| + out.response_info = *response2;
|
| + out.rv = ReadTransaction(trans2.get(), &out.response_data);
|
| + EXPECT_EQ(OK, out.rv);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| + EXPECT_EQ("hello!hello!", out.response_data);
|
| +
|
| + helper.VerifyDataConsumed();
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
|
| + 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));
|
| + scoped_ptr<spdy::SpdyFrame> fbody(ConstructSpdyBodyFrame(1, true));
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
|
| + scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
|
| + scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(3, false));
|
| + scoped_ptr<spdy::SpdyFrame> fbody2(ConstructSpdyBodyFrame(3, true));
|
| +
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req),
|
| + CreateMockWrite(*req2),
|
| + };
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 1),
|
| + CreateMockRead(*body),
|
| + CreateMockRead(*resp2, 4),
|
| + CreateMockRead(*body2),
|
| + CreateMockRead(*fbody),
|
| + CreateMockRead(*fbody2),
|
| + MockRead(true, 0, 0), // EOF
|
| + };
|
| + scoped_refptr<OrderedSocketData> preconnect_data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| +
|
| + MockConnect never_finishing_connect(true, ERR_IO_PENDING);
|
| +
|
| + scoped_refptr<OrderedSocketData> data_placeholder(
|
| + new OrderedSocketData(NULL, 0, NULL, 0));
|
| + data_placeholder->set_connect_data(never_finishing_connect);
|
| +
|
| + BoundNetLog log;
|
| + TransactionHelperResult out;
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(preconnect_data.get());
|
| + // We require placeholder data because 3 connections are attempted (first is
|
| + // the preconnect, 2nd and 3rd are the never finished connections.
|
| + helper.AddData(data_placeholder.get());
|
| + helper.AddData(data_placeholder.get());
|
| +
|
| + scoped_ptr<HttpNetworkTransaction> trans1(
|
| + new HttpNetworkTransaction(helper.session()));
|
| + scoped_ptr<HttpNetworkTransaction> trans2(
|
| + new HttpNetworkTransaction(helper.session()));
|
| +
|
| + TestCompletionCallback callback1;
|
| + TestCompletionCallback callback2;
|
| +
|
| + HttpRequestInfo httpreq = CreateGetRequest();
|
| +
|
| + // Preconnect the first.
|
| + SSLConfig preconnect_ssl_config;
|
| + helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config);
|
| + HttpStreamFactory* http_stream_factory =
|
| + helper.session()->http_stream_factory();
|
| + if (http_stream_factory->next_protos()) {
|
| + preconnect_ssl_config.next_protos = *http_stream_factory->next_protos();
|
| + }
|
| +
|
| + http_stream_factory->PreconnectStreams(
|
| + 1, httpreq, preconnect_ssl_config, log);
|
| +
|
| + out.rv = trans1->Start(&httpreq, &callback1, log);
|
| + ASSERT_EQ(ERR_IO_PENDING, out.rv);
|
| + out.rv = trans2->Start(&httpreq, &callback2, log);
|
| + ASSERT_EQ(ERR_IO_PENDING, out.rv);
|
| +
|
| + out.rv = callback1.WaitForResult();
|
| + ASSERT_EQ(OK, out.rv);
|
| + out.rv = callback2.WaitForResult();
|
| + ASSERT_EQ(OK, out.rv);
|
| +
|
| + const HttpResponseInfo* response1 = trans1->GetResponseInfo();
|
| + EXPECT_TRUE(response1->headers != NULL);
|
| + EXPECT_TRUE(response1->was_fetched_via_spdy);
|
| + out.status_line = response1->headers->GetStatusLine();
|
| + out.response_info = *response1;
|
| + out.rv = ReadTransaction(trans1.get(), &out.response_data);
|
| + EXPECT_EQ(OK, out.rv);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| + EXPECT_EQ("hello!hello!", out.response_data);
|
| +
|
| + const HttpResponseInfo* response2 = trans2->GetResponseInfo();
|
| + EXPECT_TRUE(response2->headers != NULL);
|
| + EXPECT_TRUE(response2->was_fetched_via_spdy);
|
| + out.status_line = response2->headers->GetStatusLine();
|
| + out.response_info = *response2;
|
| + out.rv = ReadTransaction(trans2.get(), &out.response_data);
|
| + EXPECT_EQ(OK, out.rv);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| + EXPECT_EQ("hello!hello!", out.response_data);
|
| +
|
| + helper.VerifyDataConsumed();
|
| +}
|
| +
|
| // Similar to ThreeGets above, however this test adds a SETTINGS
|
| // frame. The SETTINGS frame is read during the IO loop waiting on
|
| // the first transaction completion, and sets a maximum concurrent
|
|
|