| 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 24ad8ad0604276fac430cfdde4a86471c6811ee1..4b07ff522cc5a2d08fea046ffdb7a5573bd70e33 100644
|
| --- a/net/spdy/spdy_network_transaction_unittest.cc
|
| +++ b/net/spdy/spdy_network_transaction_unittest.cc
|
| @@ -9,6 +9,7 @@
|
| #include "net/spdy/spdy_http_stream.h"
|
| #include "net/spdy/spdy_network_transaction.h"
|
| #include "net/spdy/spdy_test_util.h"
|
| +#include "net/url_request/url_request_unittest.h"
|
| #include "testing/platform_test.h"
|
|
|
| //-----------------------------------------------------------------------------
|
| @@ -83,7 +84,6 @@ class SpdyNetworkTransactionTest
|
| if (!session_.get())
|
| session_ = SpdySessionDependencies::SpdyCreateSession(
|
| session_deps_.get());
|
| -
|
| HttpNetworkTransaction::SetUseAlternateProtocols(false);
|
| HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
|
| HttpNetworkTransaction::SetUseSpdyWithoutNPN(false);
|
| @@ -181,8 +181,8 @@ class SpdyNetworkTransactionTest
|
| }
|
|
|
| void RunToCompletion(StaticSocketDataProvider* data) {
|
| - AddData(data);
|
| RunPreTestSetup();
|
| + AddData(data);
|
| RunDefaultTest();
|
| VerifyDataConsumed();
|
| }
|
| @@ -244,6 +244,13 @@ class SpdyNetworkTransactionTest
|
|
|
| void ConnectStatusHelper(const MockRead& status);
|
|
|
| + const HttpRequestInfo& CreateGetPushRequest() {
|
| + google_get_push_request_.method = "GET";
|
| + google_get_push_request_.url = GURL("http://www.google.com/foo.dat");
|
| + google_get_push_request_.load_flags = 0;
|
| + return google_get_push_request_;
|
| + }
|
| +
|
| const HttpRequestInfo& CreateGetRequest() {
|
| if (!google_get_request_initialized_) {
|
| google_get_request_.method = "GET";
|
| @@ -254,9 +261,99 @@ class SpdyNetworkTransactionTest
|
| return google_get_request_;
|
| }
|
|
|
| + class RunServerPushTestCallback : public CallbackRunner< Tuple1<int> > {
|
| + public:
|
| + RunServerPushTestCallback(scoped_refptr<net::IOBufferWithSize> buffer,
|
| + std::string& result, bool& need_read_callback)
|
| + : buffer_(buffer), result_(result),
|
| + need_read_callback_(need_read_callback) {}
|
| +
|
| + virtual void RunWithParams(const Tuple1<int>& params) {
|
| + // Indicates some type of error.
|
| + if(params.a <= 0)
|
| + return;
|
| +
|
| + std::string temp(buffer_->data(), params.a);
|
| + result_.append(temp);
|
| + need_read_callback_ = true;
|
| + }
|
| +
|
| + private:
|
| + scoped_refptr<net::IOBufferWithSize> buffer_;
|
| + std::string& result_;
|
| + bool need_read_callback_;
|
| + };
|
| +
|
| + void RunServerPushTest(MockWrite writes[], int writes_length,
|
| + MockRead reads[], int reads_length,
|
| + HttpResponseInfo* response,
|
| + HttpResponseInfo* response2,
|
| + std::string& expected) {
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, reads_length,
|
| + writes, writes_length));
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| +
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| +
|
| + HttpNetworkTransaction* trans = helper.trans();
|
| +
|
| + // Start the transaction with basic parameters.
|
| + TestCompletionCallback callback;
|
| + int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback.WaitForResult();
|
| +
|
| + // Request the pushed path.
|
| + const int kSize = 3000;
|
| + scoped_refptr<net::IOBufferWithSize> buf = new net::IOBufferWithSize(kSize);
|
| + scoped_ptr<HttpNetworkTransaction> trans2(
|
| + new HttpNetworkTransaction(helper.session()));
|
| + rv = trans2->Start(&CreateGetPushRequest(), &callback, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + MessageLoop::current()->RunAllPending();
|
| +
|
| + // The data for the pushed path may be coming in more than 1 packet. Compile
|
| + // the results into a single string.
|
| + std::string result;
|
| + bool need_read_callback = true;
|
| + RunServerPushTestCallback callback2(buf, result, need_read_callback);
|
| + while(!data->at_read_eof())
|
| + {
|
| + if(need_read_callback) {
|
| + while((rv = trans2->Read(buf, kSize, &callback2)) > 0) {
|
| + std::string result1(buf->data(),rv);
|
| + result.append(result1);
|
| + }
|
| + need_read_callback = false;
|
| + }
|
| + else
|
| + data->CompleteRead();
|
| + MessageLoop::current()->RunAllPending();
|
| + }
|
| +
|
| + // Verify that we consumed all test data.
|
| + EXPECT_TRUE(data->at_read_eof());
|
| + EXPECT_TRUE(data->at_write_eof());
|
| +
|
| + // Verify that the received push data is same as the expected push data.
|
| + EXPECT_EQ(result.compare(expected),0) << "Received data: "
|
| + << result
|
| + << "||||| Expected data: "
|
| + << expected;
|
| +
|
| + // Verify the SYN_REPLY.
|
| + // Copy the response info, because trans goes away.
|
| + *response = *trans->GetResponseInfo();
|
| + *response2 = *trans2->GetResponseInfo();
|
| + }
|
| +
|
| private:
|
| bool google_get_request_initialized_;
|
| HttpRequestInfo google_get_request_;
|
| + HttpRequestInfo google_get_push_request_;
|
| };
|
|
|
| //-----------------------------------------------------------------------------
|
| @@ -264,7 +361,7 @@ class SpdyNetworkTransactionTest
|
| // negotiation, SPDY without SSL, and SPDY with SSL.
|
| INSTANTIATE_TEST_CASE_P(SpdyNetworkingTest,
|
| SpdyNetworkTransactionTest,
|
| - ::testing::Values(SPDYNPN, SPDYNOSSL, SPDYSSL));
|
| + ::testing::Values(SPDYNOSSL, SPDYSSL, SPDYNPN));
|
|
|
|
|
| // Verify HttpNetworkTransaction constructor.
|
| @@ -1014,8 +1111,8 @@ TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
|
| writes, arraysize(writes)));
|
| NormalSpdyTransactionHelper helper(request,
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| helper.RunDefaultTest();
|
| TransactionHelperResult out = helper.output();
|
| EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
|
| @@ -1097,8 +1194,8 @@ TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
|
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| @@ -1291,8 +1388,8 @@ TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(&data);
|
| helper.RunPreTestSetup();
|
| + helper.AddData(&data);
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
| @@ -1329,8 +1426,8 @@ TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(),
|
| GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
| @@ -1413,9 +1510,9 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| + helper.RunPreTestSetup();
|
| helper.AddData(data.get());
|
| helper.AddData(data2.get());
|
| - helper.RunPreTestSetup();
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| // Start the transaction with basic parameters.
|
| @@ -1472,8 +1569,8 @@ TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| // Start the transaction with basic parameters.
|
| @@ -1496,6 +1593,536 @@ TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
|
| helper.VerifyDataConsumed();
|
| }
|
|
|
| +// Send a spdy request to www.google.com that gets redirected to www.foo.com.
|
| +TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
|
| + // These are headers which the URLRequest tacks on.
|
| + const char* const kExtraHeaders[] = {
|
| + "accept-charset",
|
| + "",
|
| + "accept-encoding",
|
| + "gzip,deflate",
|
| + "accept-language",
|
| + "",
|
| + };
|
| + const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM);
|
| + const char* const kStandardGetHeaders[] = {
|
| + "host",
|
| + "www.google.com",
|
| + "method",
|
| + "GET",
|
| + "scheme",
|
| + "http",
|
| + "url",
|
| + "/",
|
| + "user-agent",
|
| + "",
|
| + "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(ConstructSpdyPacket(
|
| + kSynStartHeader, kExtraHeaders, 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(ConstructSpdyGetSynReplyRedirect(1));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + };
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + MockRead(true, 0, 0, 3) // EOF
|
| + };
|
| +
|
| + // Setup writes/reads to www.foo.com
|
| + scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
|
| + MockWrite writes2[] = {
|
| + CreateMockWrite(*req2, 1),
|
| + };
|
| + MockRead reads2[] = {
|
| + CreateMockRead(*resp2, 2),
|
| + CreateMockRead(*body2, 3),
|
| + MockRead(true, 0, 0, 4) // EOF
|
| + };
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| + scoped_refptr<OrderedSocketData> data2(
|
| + new OrderedSocketData(reads2, arraysize(reads2),
|
| + writes2, arraysize(writes2)));
|
| +
|
| + // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
|
| + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
|
| + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
|
| + TestDelegate d;
|
| + {
|
| + URLRequest r(GURL("http://www.google.com/"), &d);
|
| + SpdyURLRequestContext* spdy_url_request_context =
|
| + new SpdyURLRequestContext();
|
| + r.set_context(spdy_url_request_context);
|
| + spdy_url_request_context->socket_factory().
|
| + AddSocketDataProvider(data.get());
|
| + spdy_url_request_context->socket_factory().
|
| + AddSocketDataProvider(data2.get());
|
| +
|
| + d.set_quit_on_redirect(true);
|
| + r.Start();
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_EQ(1, d.received_redirect_count());
|
| +
|
| + r.FollowDeferredRedirect();
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(1, d.response_started_count());
|
| + EXPECT_FALSE(d.received_data_before_response());
|
| + EXPECT_EQ(URLRequestStatus::SUCCESS, r.status().status());
|
| + std::string contents("hello!");
|
| + EXPECT_EQ(contents, d.data_received());
|
| + }
|
| + EXPECT_TRUE(data->at_read_eof());
|
| + EXPECT_TRUE(data->at_write_eof());
|
| + EXPECT_TRUE(data2->at_read_eof());
|
| + EXPECT_TRUE(data2->at_write_eof());
|
| +}
|
| +
|
| +// Send a spdy request to www.google.com. Get a pushed stream that redirects to
|
| +// www.foo.com.
|
| +TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
|
| + // These are headers which the URLRequest tacks on.
|
| + const char* const kExtraHeaders[] = {
|
| + "accept-charset",
|
| + "",
|
| + "accept-encoding",
|
| + "gzip,deflate",
|
| + "accept-language",
|
| + "",
|
| + };
|
| + const SpdyHeaderInfo kSynStartHeader = make_spdy_header(spdy::SYN_STREAM);
|
| + const char* const kStandardGetHeaders[] = {
|
| + "host",
|
| + "www.google.com",
|
| + "method",
|
| + "GET",
|
| + "scheme",
|
| + "http",
|
| + "url",
|
| + "/",
|
| + "user-agent",
|
| + "",
|
| + "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(ConstructSpdyPacket(
|
| + kSynStartHeader, kExtraHeaders, 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, 0, 2, 1, "/foo.dat",
|
| + "301 Moved Permanently", "http://www.foo.com/index.php",
|
| + "http://www.foo.com/index.php"));
|
| + scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
|
| + scoped_ptr<spdy::SpdyFrame> res(
|
| + ConstructSpdyRstStream(2, spdy::CANCEL));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + CreateMockWrite(*res, 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, 7) // EOF
|
| + };
|
| +
|
| + // Setup writes/reads to www.foo.com
|
| + scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> body2(ConstructSpdyBodyFrame(1, true));
|
| + MockWrite writes2[] = {
|
| + CreateMockWrite(*req2, 1),
|
| + };
|
| + MockRead reads2[] = {
|
| + CreateMockRead(*resp2, 2),
|
| + CreateMockRead(*body2, 3),
|
| + MockRead(true, 0, 0, 5) // EOF
|
| + };
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| + scoped_refptr<OrderedSocketData> data2(
|
| + new OrderedSocketData(reads2, arraysize(reads2),
|
| + writes2, arraysize(writes2)));
|
| +
|
| + // TODO(erikchen): Make test support SPDYSSL, SPDYNPN
|
| + HttpNetworkTransaction::SetUseSSLOverSpdyWithoutNPN(false);
|
| + HttpNetworkTransaction::SetUseSpdyWithoutNPN(true);
|
| + TestDelegate d;
|
| + TestDelegate d2;
|
| + {
|
| + URLRequest r(GURL("http://www.google.com/"), &d);
|
| + SpdyURLRequestContext* spdy_url_request_context =
|
| + new SpdyURLRequestContext();
|
| + r.set_context(spdy_url_request_context);
|
| + spdy_url_request_context->socket_factory().
|
| + AddSocketDataProvider(data.get());
|
| +
|
| + r.Start();
|
| + MessageLoop::current()->Run();
|
| +
|
| + EXPECT_EQ(0, d.received_redirect_count());
|
| + std::string contents("hello!");
|
| + EXPECT_EQ(contents, d.data_received());
|
| +
|
| + URLRequest r2(GURL("http://www.google.com/foo.dat"), &d2);
|
| + r2.set_context(spdy_url_request_context);
|
| + spdy_url_request_context->socket_factory().
|
| + AddSocketDataProvider(data2.get());
|
| +
|
| + d2.set_quit_on_redirect(true);
|
| + r2.Start();
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(1, d2.received_redirect_count());
|
| +
|
| + r2.FollowDeferredRedirect();
|
| + MessageLoop::current()->Run();
|
| + EXPECT_EQ(1, d2.response_started_count());
|
| + EXPECT_FALSE(d2.received_data_before_response());
|
| + EXPECT_EQ(URLRequestStatus::SUCCESS, r2.status().status());
|
| + std::string contents2("hello!");
|
| + EXPECT_EQ(contents2, d2.data_received());
|
| + }
|
| + data->CompleteRead();
|
| + data2->CompleteRead();
|
| + EXPECT_TRUE(data->at_read_eof());
|
| + EXPECT_TRUE(data->at_write_eof());
|
| + EXPECT_TRUE(data2->at_read_eof());
|
| + EXPECT_TRUE(data2->at_write_eof());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
|
| + static const unsigned char kPushBodyFrame[] = {
|
| + 0x00, 0x00, 0x00, 0x02, // header, ID
|
| + 0x01, 0x00, 0x00, 0x05, // FIN, length
|
| + 'h', 'e', 'l', 'l', 'o', // "hello"
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 1, "/foo.dat"));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame),
|
| + arraysize(kPushBodyFrame), 4),
|
| + MockRead(true, ERR_IO_PENDING, 5), // Force a pause
|
| + MockRead(true, 0, 0, 6) // EOF
|
| + };
|
| +
|
| + HttpResponseInfo response;
|
| + HttpResponseInfo response2;
|
| + std::string expected_push_result("hello");
|
| + RunServerPushTest(writes, arraysize(writes), reads, arraysize(reads),
|
| + &response, &response2, expected_push_result);
|
| +
|
| + // Verify the SYN_REPLY.
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +
|
| + // Verify the pushed stream.
|
| + EXPECT_TRUE(response2.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
|
| + static const unsigned char kPushBodyFrame1[] = {
|
| + 0x00, 0x00, 0x00, 0x02, // header, ID
|
| + 0x01, 0x00, 0x00, 0x1E, // FIN, length
|
| + 'h', 'e', 'l', 'l', 'o', // "hello"
|
| + };
|
| + static const char kPushBodyFrame2[] = " my darling";
|
| + static const char kPushBodyFrame3[] = " hello";
|
| + static const char kPushBodyFrame4[] = " my baby";
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> req(
|
| + ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 1, "/foo.dat"));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1),
|
| + arraysize(kPushBodyFrame1), 4),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2),
|
| + arraysize(kPushBodyFrame2) - 1, 5),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3),
|
| + arraysize(kPushBodyFrame3) - 1, 6),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4),
|
| + arraysize(kPushBodyFrame4) - 1, 7),
|
| + MockRead(true, ERR_IO_PENDING, 8), // Force a pause
|
| + MockRead(true, 0, 0, 9) // EOF
|
| + };
|
| +
|
| + HttpResponseInfo response;
|
| + HttpResponseInfo response2;
|
| + std::string expected_push_result("hello my darling hello my baby");
|
| + RunServerPushTest(writes, arraysize(writes), reads, arraysize(reads),
|
| + &response, &response2, expected_push_result);
|
| +
|
| + // Verify the SYN_REPLY.
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +
|
| + // Verify the pushed stream.
|
| + EXPECT_TRUE(response2.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
|
| + static const unsigned char kPushBodyFrame1[] = {
|
| + 0x00, 0x00, 0x00, 0x02, // header, ID
|
| + 0x01, 0x00, 0x00, 0x1E, // FIN, length
|
| + 'h', 'e', 'l', 'l', 'o', // "hello"
|
| + };
|
| + static const char kPushBodyFrame2[] = " my darling";
|
| + static const char kPushBodyFrame3[] = " hello";
|
| + static const char kPushBodyFrame4[] = " my baby";
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> req(
|
| + ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 1, "/foo.dat"));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame1),
|
| + arraysize(kPushBodyFrame1), 4),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame2),
|
| + arraysize(kPushBodyFrame2) - 1, 5),
|
| + MockRead(true, ERR_IO_PENDING, 6), // Force a pause
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame3),
|
| + arraysize(kPushBodyFrame3) - 1, 7),
|
| + MockRead(true, reinterpret_cast<const char*>(kPushBodyFrame4),
|
| + arraysize(kPushBodyFrame4) - 1, 8),
|
| + MockRead(true, 0, 0, 9) // EOF
|
| + };
|
| +
|
| + HttpResponseInfo response;
|
| + HttpResponseInfo response2;
|
| + std::string expected_push_result("hello my darling hello my baby");
|
| + RunServerPushTest(writes, arraysize(writes), reads, arraysize(reads),
|
| + &response, &response2, expected_push_result);
|
| +
|
| + // Verify the SYN_REPLY.
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +
|
| + // Verify the pushed stream.
|
| + EXPECT_TRUE(response2.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
|
| + scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + scoped_ptr<spdy::SpdyFrame> res(
|
| + ConstructSpdyRstStream(2, spdy::INVALID_STREAM));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + CreateMockWrite(*res, 4),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 0, "/foo.dat"));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, 0, 0, 5) // EOF
|
| + };
|
| +
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| +
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| +
|
| + HttpNetworkTransaction* trans = helper.trans();
|
| +
|
| + // Start the transaction with basic parameters.
|
| + TestCompletionCallback callback;
|
| + int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback.WaitForResult();
|
| + data->CompleteRead();
|
| + EXPECT_EQ(OK, rv);
|
| +
|
| + // Verify that we consumed all test data.
|
| + EXPECT_TRUE(data->at_read_eof()) << "Read count: "
|
| + << data->read_count()
|
| + << " Read index: "
|
| + << data->read_index();
|
| + EXPECT_TRUE(data->at_write_eof()) << "Write count: "
|
| + << data->write_count()
|
| + << " Write index: "
|
| + << data->write_index();
|
| +
|
| + // Verify the SYN_REPLY.
|
| + HttpResponseInfo response = *trans->GetResponseInfo();
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
|
| + scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + scoped_ptr<spdy::SpdyFrame> res(
|
| + ConstructSpdyRstStream(2, spdy::INVALID_ASSOCIATED_STREAM));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + CreateMockWrite(*res, 4),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 9, "/foo.dat"));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, 0, 0, 5) // EOF
|
| + };
|
| +
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| +
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| +
|
| + HttpNetworkTransaction* trans = helper.trans();
|
| +
|
| + // Start the transaction with basic parameters.
|
| + TestCompletionCallback callback;
|
| + int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback.WaitForResult();
|
| + data->CompleteRead();
|
| + EXPECT_EQ(OK, rv);
|
| +
|
| + // Verify that we consumed all test data.
|
| + EXPECT_TRUE(data->at_read_eof()) << "Read count: "
|
| + << data->read_count()
|
| + << " Read index: "
|
| + << data->read_index();
|
| + EXPECT_TRUE(data->at_write_eof()) << "Write count: "
|
| + << data->write_count()
|
| + << " Write index: "
|
| + << data->write_index();
|
| +
|
| + // Verify the SYN_REPLY.
|
| + HttpResponseInfo response = *trans->GetResponseInfo();
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +}
|
| +
|
| +TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
|
| + scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
|
| + scoped_ptr<spdy::SpdyFrame> res(
|
| + ConstructSpdyRstStream(2, spdy::PROTOCOL_ERROR));
|
| + MockWrite writes[] = {
|
| + CreateMockWrite(*req, 1),
|
| + CreateMockWrite(*res, 4),
|
| + };
|
| +
|
| + scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
|
| + scoped_ptr<spdy::SpdyFrame> rep(ConstructSpdyPush(NULL, 0, 2, 1));
|
| + MockRead reads[] = {
|
| + CreateMockRead(*resp, 2),
|
| + CreateMockRead(*rep, 3),
|
| + MockRead(true, 0, 0, 5) // EOF
|
| + };
|
| +
|
| + scoped_refptr<OrderedSocketData> data(
|
| + new OrderedSocketData(reads, arraysize(reads),
|
| + writes, arraysize(writes)));
|
| + NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| + BoundNetLog(), GetParam());
|
| +
|
| + helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| +
|
| + HttpNetworkTransaction* trans = helper.trans();
|
| +
|
| + // Start the transaction with basic parameters.
|
| + TestCompletionCallback callback;
|
| + int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
|
| + EXPECT_EQ(ERR_IO_PENDING, rv);
|
| + rv = callback.WaitForResult();
|
| + data->CompleteRead();
|
| + EXPECT_EQ(OK, rv);
|
| + // Verify that we consumed all test data.
|
| + EXPECT_TRUE(data->at_read_eof()) << "Read count: "
|
| + << data->read_count()
|
| + << " Read index: "
|
| + << data->read_index();
|
| + EXPECT_TRUE(data->at_write_eof()) << "Write count: "
|
| + << data->write_count()
|
| + << " Write index: "
|
| + << data->write_index();
|
| +
|
| + // Verify the SYN_REPLY.
|
| + HttpResponseInfo response = *trans->GetResponseInfo();
|
| + EXPECT_TRUE(response.headers != NULL);
|
| + EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
|
| +}
|
| +
|
| // Verify that various SynReply headers parse correctly through the
|
| // HTTP layer.
|
| TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
|
| @@ -2041,8 +2668,8 @@ TEST_P(SpdyNetworkTransactionTest, BufferFull) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
| int rv = trans->Start(&CreateGetRequest(), &callback, BoundNetLog());
|
| EXPECT_EQ(ERR_IO_PENDING, rv);
|
| @@ -2120,8 +2747,8 @@ TEST_P(SpdyNetworkTransactionTest, ConnectFailureFallbackToHttp) {
|
| writes, arraysize(writes)));
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
|
|
| // Set up http fallback data.
|
| MockRead http_fallback_data[] = {
|
| @@ -2204,8 +2831,8 @@ TEST_P(SpdyNetworkTransactionTest, Buffering) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
| @@ -2299,8 +2926,8 @@ TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
| @@ -2387,8 +3014,8 @@ TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
| @@ -2467,8 +3094,8 @@ TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
| TestCompletionCallback callback;
|
|
|
| @@ -2535,6 +3162,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| + helper.RunPreTestSetup();
|
|
|
| // Verify that no settings exist initially.
|
| HostPortPair host_port_pair("www.google.com", helper.port());
|
| @@ -2589,7 +3217,9 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
|
| scoped_refptr<DelayedSocketData> data(
|
| new DelayedSocketData(1, reads, arraysize(reads),
|
| writes, arraysize(writes)));
|
| - helper.RunToCompletion(data.get());
|
| + helper.AddData(data.get());
|
| + helper.RunDefaultTest();
|
| + helper.VerifyDataConsumed();
|
| TransactionHelperResult out = helper.output();
|
| EXPECT_EQ(OK, out.rv);
|
| EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| @@ -2640,6 +3270,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
|
|
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| BoundNetLog(), GetParam());
|
| + helper.RunPreTestSetup();
|
|
|
| // Verify that no settings exist initially.
|
| HostPortPair host_port_pair("www.google.com", helper.port());
|
| @@ -2698,7 +3329,9 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
|
| scoped_refptr<DelayedSocketData> data(
|
| new DelayedSocketData(2, reads, arraysize(reads),
|
| writes, arraysize(writes)));
|
| - helper.RunToCompletion(data.get());
|
| + helper.AddData(data.get());
|
| + helper.RunDefaultTest();
|
| + helper.VerifyDataConsumed();
|
| TransactionHelperResult out = helper.output();
|
| EXPECT_EQ(OK, out.rv);
|
| EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
|
| @@ -2809,8 +3442,8 @@ TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
|
| BoundNetLog log;
|
| NormalSpdyTransactionHelper helper(CreateGetRequest(),
|
| log, GetParam());
|
| - helper.AddData(data.get());
|
| helper.RunPreTestSetup();
|
| + helper.AddData(data.get());
|
| HttpNetworkTransaction* trans = helper.trans();
|
|
|
| TestCompletionCallback callback;
|
|
|