diff options
author | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-05 17:59:58 +0000 |
---|---|---|
committer | erikchen@google.com <erikchen@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-08-05 17:59:58 +0000 |
commit | e3ebba0fbbfb2c7eec286a964717859aa70b9fcf (patch) | |
tree | b2a53d996ca4537fbb6516dcddba122d1cb6cbcd /net/spdy/spdy_network_transaction_unittest.cc | |
parent | 1b7cde151f8e0e922a8c52c6ca48f6f1c6de21ec (diff) | |
download | chromium_src-e3ebba0fbbfb2c7eec286a964717859aa70b9fcf.zip chromium_src-e3ebba0fbbfb2c7eec286a964717859aa70b9fcf.tar.gz chromium_src-e3ebba0fbbfb2c7eec286a964717859aa70b9fcf.tar.bz2 |
Implement server push protocol 2.
TEST=net_unittests
BUG=34761
Review URL: http://codereview.chromium.org/3020032
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@55095 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/spdy/spdy_network_transaction_unittest.cc')
-rw-r--r-- | net/spdy/spdy_network_transaction_unittest.cc | 669 |
1 files changed, 651 insertions, 18 deletions
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index 11d20cb..25a03b2 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; |