Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(137)

Side by Side Diff: net/spdy/spdy_network_transaction_unittest.cc

Issue 17760008: [SPDY] Enable tests for SPDY/3.1 and SPDY/4 (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Fix more tests Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <string> 5 #include <string>
6 #include <vector> 6 #include <vector>
7 7
8 #include "base/bind.h" 8 #include "base/bind.h"
9 #include "base/bind_helpers.h" 9 #include "base/bind_helpers.h"
10 #include "base/file_util.h" 10 #include "base/file_util.h"
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 case kProtoHTTP11: 76 case kProtoHTTP11:
77 case kProtoSPDY1: 77 case kProtoSPDY1:
78 case kProtoSPDY21: 78 case kProtoSPDY21:
79 break; 79 break;
80 } 80 }
81 81
82 NOTREACHED(); 82 NOTREACHED();
83 return HttpResponseInfo::CONNECTION_INFO_SPDY2; 83 return HttpResponseInfo::CONNECTION_INFO_SPDY2;
84 } 84 }
85 85
86 AlternateProtocol NextProtoToAlternateProtocol(NextProto next_proto) {
87 switch (next_proto) {
88 case kProtoSPDY2:
89 return NPN_SPDY_2;
90 case kProtoSPDY3:
91 return NPN_SPDY_3;
92 case kProtoSPDY31:
93 return NPN_SPDY_3_1;
94 case kProtoSPDY4a2:
95 return NPN_SPDY_4A2;
96
97 case kProtoUnknown:
98 case kProtoHTTP11:
99 case kProtoSPDY1:
100 case kProtoSPDY21:
101 break;
102 }
103
104 NOTREACHED();
105 return NPN_SPDY_2;
106 }
107
108 SpdySessionDependencies* CreateSpdySessionDependencies( 86 SpdySessionDependencies* CreateSpdySessionDependencies(
109 SpdyNetworkTransactionTestParams test_params) { 87 SpdyNetworkTransactionTestParams test_params) {
110 return new SpdySessionDependencies(test_params.protocol); 88 return new SpdySessionDependencies(test_params.protocol);
111 } 89 }
112 90
113 SpdySessionDependencies* CreateSpdySessionDependencies( 91 SpdySessionDependencies* CreateSpdySessionDependencies(
114 SpdyNetworkTransactionTestParams test_params, 92 SpdyNetworkTransactionTestParams test_params,
115 ProxyService* proxy_service) { 93 ProxyService* proxy_service) {
116 return new SpdySessionDependencies(test_params.protocol, proxy_service); 94 return new SpdySessionDependencies(test_params.protocol, proxy_service);
117 } 95 }
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
201 void RunPreTestSetup() { 179 void RunPreTestSetup() {
202 if (!session_deps_.get()) 180 if (!session_deps_.get())
203 session_deps_.reset(CreateSpdySessionDependencies(test_params_)); 181 session_deps_.reset(CreateSpdySessionDependencies(test_params_));
204 if (!session_.get()) 182 if (!session_.get())
205 session_ = SpdySessionDependencies::SpdyCreateSession( 183 session_ = SpdySessionDependencies::SpdyCreateSession(
206 session_deps_.get()); 184 session_deps_.get());
207 HttpStreamFactory::set_use_alternate_protocols(false); 185 HttpStreamFactory::set_use_alternate_protocols(false);
208 HttpStreamFactory::set_force_spdy_over_ssl(false); 186 HttpStreamFactory::set_force_spdy_over_ssl(false);
209 HttpStreamFactory::set_force_spdy_always(false); 187 HttpStreamFactory::set_force_spdy_always(false);
210 188
211 std::vector<std::string> next_protos; 189 std::vector<std::string> next_protos = SpdyNextProtos();
212 next_protos.push_back("http/1.1");
213 next_protos.push_back("spdy/2");
214 190
215 switch (test_params_.ssl_type) { 191 switch (test_params_.ssl_type) {
216 case SPDYNPN: 192 case SPDYNPN:
217 session_->http_server_properties()->SetAlternateProtocol( 193 session_->http_server_properties()->SetAlternateProtocol(
218 HostPortPair("www.google.com", 80), 443, 194 HostPortPair("www.google.com", 80), 443,
219 NextProtoToAlternateProtocol(test_params_.protocol)); 195 AlternateProtocolFromNextProto(test_params_.protocol));
220 HttpStreamFactory::set_use_alternate_protocols(true); 196 HttpStreamFactory::set_use_alternate_protocols(true);
221 HttpStreamFactory::SetNextProtos(next_protos); 197 HttpStreamFactory::SetNextProtos(next_protos);
222 break; 198 break;
223 case SPDYNOSSL: 199 case SPDYNOSSL:
224 HttpStreamFactory::set_force_spdy_over_ssl(false); 200 HttpStreamFactory::set_force_spdy_over_ssl(false);
225 HttpStreamFactory::set_force_spdy_always(true); 201 HttpStreamFactory::set_force_spdy_always(true);
226 break; 202 break;
227 case SPDYSSL: 203 case SPDYSSL:
228 HttpStreamFactory::set_force_spdy_over_ssl(true); 204 HttpStreamFactory::set_force_spdy_over_ssl(true);
229 HttpStreamFactory::set_force_spdy_always(true); 205 HttpStreamFactory::set_force_spdy_always(true);
(...skipping 360 matching lines...) Expand 10 before | Expand all | Expand 10 after
590 EXPECT_TRUE(pool->HasSession(key)); 566 EXPECT_TRUE(pool->HasSession(key));
591 scoped_refptr<SpdySession> spdy_session(pool->Get(key, log)); 567 scoped_refptr<SpdySession> spdy_session(pool->Get(key, log));
592 ASSERT_TRUE(spdy_session.get() != NULL); 568 ASSERT_TRUE(spdy_session.get() != NULL);
593 EXPECT_EQ(0u, spdy_session->num_active_streams()); 569 EXPECT_EQ(0u, spdy_session->num_active_streams());
594 EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams()); 570 EXPECT_EQ(0u, spdy_session->num_unclaimed_pushed_streams());
595 } 571 }
596 572
597 void RunServerPushTest(OrderedSocketData* data, 573 void RunServerPushTest(OrderedSocketData* data,
598 HttpResponseInfo* response, 574 HttpResponseInfo* response,
599 HttpResponseInfo* push_response, 575 HttpResponseInfo* push_response,
600 std::string& expected) { 576 const std::string& expected) {
601 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 577 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
602 BoundNetLog(), GetParam(), NULL); 578 BoundNetLog(), GetParam(), NULL);
603 helper.RunPreTestSetup(); 579 helper.RunPreTestSetup();
604 helper.AddData(data); 580 helper.AddData(data);
605 581
606 HttpNetworkTransaction* trans = helper.trans(); 582 HttpNetworkTransaction* trans = helper.trans();
607 583
608 // Start the transaction with basic parameters. 584 // Start the transaction with basic parameters.
609 TestCompletionCallback callback; 585 TestCompletionCallback callback;
610 int rv = trans->Start( 586 int rv = trans->Start(
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
708 // Verify HttpNetworkTransaction constructor. 684 // Verify HttpNetworkTransaction constructor.
709 TEST_P(SpdyNetworkTransactionTest, Constructor) { 685 TEST_P(SpdyNetworkTransactionTest, Constructor) {
710 scoped_ptr<SpdySessionDependencies> session_deps( 686 scoped_ptr<SpdySessionDependencies> session_deps(
711 CreateSpdySessionDependencies(GetParam())); 687 CreateSpdySessionDependencies(GetParam()));
712 scoped_refptr<HttpNetworkSession> session( 688 scoped_refptr<HttpNetworkSession> session(
713 SpdySessionDependencies::SpdyCreateSession(session_deps.get())); 689 SpdySessionDependencies::SpdyCreateSession(session_deps.get()));
714 scoped_ptr<HttpTransaction> trans( 690 scoped_ptr<HttpTransaction> trans(
715 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); 691 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
716 } 692 }
717 693
718 // TODO(akalin): Don't early-exit in the tests below for values >
719 // kProtoSPDY3.
720
721 TEST_P(SpdyNetworkTransactionTest, Get) { 694 TEST_P(SpdyNetworkTransactionTest, Get) {
722 if (GetParam().protocol > kProtoSPDY3)
723 return;
724
725 // Construct the request. 695 // Construct the request.
726 scoped_ptr<SpdyFrame> req( 696 scoped_ptr<SpdyFrame> req(
727 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 697 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
728 MockWrite writes[] = { CreateMockWrite(*req) }; 698 MockWrite writes[] = { CreateMockWrite(*req) };
729 699
730 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 700 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
731 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 701 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
732 MockRead reads[] = { 702 MockRead reads[] = {
733 CreateMockRead(*resp), 703 CreateMockRead(*resp),
734 CreateMockRead(*body), 704 CreateMockRead(*body),
735 MockRead(ASYNC, 0, 0) // EOF 705 MockRead(ASYNC, 0, 0) // EOF
736 }; 706 };
737 707
738 DelayedSocketData data(1, reads, arraysize(reads), 708 DelayedSocketData data(1, reads, arraysize(reads),
739 writes, arraysize(writes)); 709 writes, arraysize(writes));
740 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 710 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
741 BoundNetLog(), GetParam(), NULL); 711 BoundNetLog(), GetParam(), NULL);
742 helper.RunToCompletion(&data); 712 helper.RunToCompletion(&data);
743 TransactionHelperResult out = helper.output(); 713 TransactionHelperResult out = helper.output();
744 EXPECT_EQ(OK, out.rv); 714 EXPECT_EQ(OK, out.rv);
745 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 715 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
746 EXPECT_EQ("hello!", out.response_data); 716 EXPECT_EQ("hello!", out.response_data);
747 } 717 }
748 718
749 TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { 719 TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) {
750 if (GetParam().protocol > kProtoSPDY3)
751 return;
752
753 for (RequestPriority p = MINIMUM_PRIORITY; p < NUM_PRIORITIES; 720 for (RequestPriority p = MINIMUM_PRIORITY; p < NUM_PRIORITIES;
754 p = RequestPriority(p + 1)) { 721 p = RequestPriority(p + 1)) {
755 // Construct the request. 722 // Construct the request.
756 scoped_ptr<SpdyFrame> req( 723 scoped_ptr<SpdyFrame> req(
757 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true)); 724 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, p, true));
758 MockWrite writes[] = { CreateMockWrite(*req) }; 725 MockWrite writes[] = { CreateMockWrite(*req) };
759 726
760 SpdyPriority spdy_prio = 0; 727 SpdyPriority spdy_prio = 0;
761 EXPECT_TRUE(GetSpdyPriority(spdy_util_.spdy_version(), *req, &spdy_prio)); 728 EXPECT_TRUE(GetSpdyPriority(spdy_util_.spdy_version(), *req, &spdy_prio));
762 // this repeats the RequestPriority-->SpdyPriority mapping from 729 // this repeats the RequestPriority-->SpdyPriority mapping from
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 // streams work properly. 795 // streams work properly.
829 796
830 // This can't use the TransactionHelper method, since it only 797 // This can't use the TransactionHelper method, since it only
831 // handles a single transaction, and finishes them as soon 798 // handles a single transaction, and finishes them as soon
832 // as it launches them. 799 // as it launches them.
833 800
834 // TODO(gavinp): create a working generalized TransactionHelper that 801 // TODO(gavinp): create a working generalized TransactionHelper that
835 // can allow multiple streams in flight. 802 // can allow multiple streams in flight.
836 803
837 TEST_P(SpdyNetworkTransactionTest, ThreeGets) { 804 TEST_P(SpdyNetworkTransactionTest, ThreeGets) {
838 if (GetParam().protocol > kProtoSPDY3)
839 return;
840
841 scoped_ptr<SpdyFrame> req( 805 scoped_ptr<SpdyFrame> req(
842 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 806 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
843 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 807 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
844 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 808 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
845 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 809 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
846 810
847 scoped_ptr<SpdyFrame> req2( 811 scoped_ptr<SpdyFrame> req2(
848 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 812 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
849 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 813 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
850 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 814 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
927 out.rv = ReadTransaction(trans1.get(), &out.response_data); 891 out.rv = ReadTransaction(trans1.get(), &out.response_data);
928 helper.VerifyDataConsumed(); 892 helper.VerifyDataConsumed();
929 EXPECT_EQ(OK, out.rv); 893 EXPECT_EQ(OK, out.rv);
930 894
931 EXPECT_EQ(OK, out.rv); 895 EXPECT_EQ(OK, out.rv);
932 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 896 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
933 EXPECT_EQ("hello!hello!", out.response_data); 897 EXPECT_EQ("hello!hello!", out.response_data);
934 } 898 }
935 899
936 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { 900 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) {
937 if (GetParam().protocol > kProtoSPDY3)
938 return;
939
940 scoped_ptr<SpdyFrame> req( 901 scoped_ptr<SpdyFrame> req(
941 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 902 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
942 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 903 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
943 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 904 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
944 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 905 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
945 906
946 scoped_ptr<SpdyFrame> req2( 907 scoped_ptr<SpdyFrame> req2(
947 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 908 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
948 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 909 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
949 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 910 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1017 out.response_info = *response2; 978 out.response_info = *response2;
1018 out.rv = ReadTransaction(trans2.get(), &out.response_data); 979 out.rv = ReadTransaction(trans2.get(), &out.response_data);
1019 EXPECT_EQ(OK, out.rv); 980 EXPECT_EQ(OK, out.rv);
1020 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 981 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1021 EXPECT_EQ("hello!hello!", out.response_data); 982 EXPECT_EQ("hello!hello!", out.response_data);
1022 983
1023 helper.VerifyDataConsumed(); 984 helper.VerifyDataConsumed();
1024 } 985 }
1025 986
1026 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { 987 TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) {
1027 if (GetParam().protocol > kProtoSPDY3)
1028 return;
1029
1030 scoped_ptr<SpdyFrame> req( 988 scoped_ptr<SpdyFrame> req(
1031 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 989 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1032 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 990 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1033 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 991 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1034 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 992 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1035 993
1036 scoped_ptr<SpdyFrame> req2( 994 scoped_ptr<SpdyFrame> req2(
1037 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 995 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1038 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 996 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
1039 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false)); 997 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, false));
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
1126 1084
1127 helper.VerifyDataConsumed(); 1085 helper.VerifyDataConsumed();
1128 } 1086 }
1129 1087
1130 // Similar to ThreeGets above, however this test adds a SETTINGS 1088 // Similar to ThreeGets above, however this test adds a SETTINGS
1131 // frame. The SETTINGS frame is read during the IO loop waiting on 1089 // frame. The SETTINGS frame is read during the IO loop waiting on
1132 // the first transaction completion, and sets a maximum concurrent 1090 // the first transaction completion, and sets a maximum concurrent
1133 // stream limit of 1. This means that our IO loop exists after the 1091 // stream limit of 1. This means that our IO loop exists after the
1134 // second transaction completes, so we can assert on read_index(). 1092 // second transaction completes, so we can assert on read_index().
1135 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { 1093 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) {
1136 if (GetParam().protocol > kProtoSPDY3)
1137 return;
1138
1139 // Construct the request. 1094 // Construct the request.
1140 scoped_ptr<SpdyFrame> req( 1095 scoped_ptr<SpdyFrame> req(
1141 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 1096 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1142 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1097 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1143 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1098 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1144 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1099 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1145 1100
1146 scoped_ptr<SpdyFrame> req2( 1101 scoped_ptr<SpdyFrame> req2(
1147 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 1102 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1148 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1103 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after
1262 } 1217 }
1263 EXPECT_EQ(OK, out.rv); 1218 EXPECT_EQ(OK, out.rv);
1264 } 1219 }
1265 1220
1266 // Similar to ThreeGetsWithMaxConcurrent above, however this test adds 1221 // Similar to ThreeGetsWithMaxConcurrent above, however this test adds
1267 // a fourth transaction. The third and fourth transactions have 1222 // a fourth transaction. The third and fourth transactions have
1268 // different data ("hello!" vs "hello!hello!") and because of the 1223 // different data ("hello!" vs "hello!hello!") and because of the
1269 // user specified priority, we expect to see them inverted in 1224 // user specified priority, we expect to see them inverted in
1270 // the response from the server. 1225 // the response from the server.
1271 TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { 1226 TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) {
1272 if (GetParam().protocol > kProtoSPDY3)
1273 return;
1274
1275 // Construct the request. 1227 // Construct the request.
1276 scoped_ptr<SpdyFrame> req( 1228 scoped_ptr<SpdyFrame> req(
1277 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 1229 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1278 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1230 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1279 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1231 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1280 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1232 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1281 1233
1282 scoped_ptr<SpdyFrame> req2( 1234 scoped_ptr<SpdyFrame> req2(
1283 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 1235 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1284 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1236 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
1418 EXPECT_EQ("hello!", out.response_data); 1370 EXPECT_EQ("hello!", out.response_data);
1419 helper.VerifyDataConsumed(); 1371 helper.VerifyDataConsumed();
1420 EXPECT_EQ(OK, out.rv); 1372 EXPECT_EQ(OK, out.rv);
1421 } 1373 }
1422 1374
1423 // Similar to ThreeGetsMaxConcurrrent above, however, this test 1375 // Similar to ThreeGetsMaxConcurrrent above, however, this test
1424 // deletes a session in the middle of the transaction to insure 1376 // deletes a session in the middle of the transaction to insure
1425 // that we properly remove pendingcreatestream objects from 1377 // that we properly remove pendingcreatestream objects from
1426 // the spdy_session 1378 // the spdy_session
1427 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { 1379 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) {
1428 if (GetParam().protocol > kProtoSPDY3)
1429 return;
1430
1431 // Construct the request. 1380 // Construct the request.
1432 scoped_ptr<SpdyFrame> req( 1381 scoped_ptr<SpdyFrame> req(
1433 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 1382 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1434 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1383 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1435 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1384 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1436 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1385 scoped_ptr<SpdyFrame> fbody(spdy_util_.ConstructSpdyBodyFrame(1, true));
1437 1386
1438 scoped_ptr<SpdyFrame> req2( 1387 scoped_ptr<SpdyFrame> req2(
1439 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 1388 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1440 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1389 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1557 HttpNetworkTransaction* transaction_; 1506 HttpNetworkTransaction* transaction_;
1558 CompletionCallback callback_; 1507 CompletionCallback callback_;
1559 }; 1508 };
1560 1509
1561 } // namespace 1510 } // namespace
1562 1511
1563 // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test 1512 // Similar to ThreeGetsMaxConcurrrentDelete above, however, this test
1564 // closes the socket while we have a pending transaction waiting for 1513 // closes the socket while we have a pending transaction waiting for
1565 // a pending stream creation. http://crbug.com/52901 1514 // a pending stream creation. http://crbug.com/52901
1566 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { 1515 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) {
1567 if (GetParam().protocol > kProtoSPDY3)
1568 return;
1569
1570 // Construct the request. 1516 // Construct the request.
1571 scoped_ptr<SpdyFrame> req( 1517 scoped_ptr<SpdyFrame> req(
1572 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 1518 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
1573 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 1519 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
1574 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1520 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, false));
1575 scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1521 scoped_ptr<SpdyFrame> fin_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1576 1522
1577 scoped_ptr<SpdyFrame> req2( 1523 scoped_ptr<SpdyFrame> req2(
1578 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); 1524 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
1579 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 1525 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
1653 out.status_line = response2->headers->GetStatusLine(); 1599 out.status_line = response2->headers->GetStatusLine();
1654 out.response_info = *response2; 1600 out.response_info = *response2;
1655 out.rv = ReadTransaction(&trans2, &out.response_data); 1601 out.rv = ReadTransaction(&trans2, &out.response_data);
1656 EXPECT_EQ(ERR_CONNECTION_RESET, out.rv); 1602 EXPECT_EQ(ERR_CONNECTION_RESET, out.rv);
1657 1603
1658 helper.VerifyDataConsumed(); 1604 helper.VerifyDataConsumed();
1659 } 1605 }
1660 1606
1661 // Test that a simple PUT request works. 1607 // Test that a simple PUT request works.
1662 TEST_P(SpdyNetworkTransactionTest, Put) { 1608 TEST_P(SpdyNetworkTransactionTest, Put) {
1663 if (GetParam().protocol > kProtoSPDY3)
1664 return;
1665
1666 // Setup the request 1609 // Setup the request
1667 HttpRequestInfo request; 1610 HttpRequestInfo request;
1668 request.method = "PUT"; 1611 request.method = "PUT";
1669 request.url = GURL("http://www.google.com/"); 1612 request.url = GURL("http://www.google.com/");
1670 1613
1671 const SpdyHeaderInfo kSynStartHeader = { 1614 const SpdyHeaderInfo kSynStartHeader = {
1672 SYN_STREAM, // Kind = Syn 1615 SYN_STREAM, // Kind = Syn
1673 1, // Stream ID 1616 1, // Stream ID
1674 0, // Associated stream ID 1617 0, // Associated stream ID
1675 ConvertRequestPriorityToSpdyPriority( 1618 ConvertRequestPriorityToSpdyPriority(
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1723 BoundNetLog(), GetParam(), NULL); 1666 BoundNetLog(), GetParam(), NULL);
1724 helper.RunToCompletion(&data); 1667 helper.RunToCompletion(&data);
1725 TransactionHelperResult out = helper.output(); 1668 TransactionHelperResult out = helper.output();
1726 1669
1727 EXPECT_EQ(OK, out.rv); 1670 EXPECT_EQ(OK, out.rv);
1728 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1671 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1729 } 1672 }
1730 1673
1731 // Test that a simple HEAD request works. 1674 // Test that a simple HEAD request works.
1732 TEST_P(SpdyNetworkTransactionTest, Head) { 1675 TEST_P(SpdyNetworkTransactionTest, Head) {
1733 if (GetParam().protocol > kProtoSPDY3)
1734 return;
1735
1736 // Setup the request 1676 // Setup the request
1737 HttpRequestInfo request; 1677 HttpRequestInfo request;
1738 request.method = "HEAD"; 1678 request.method = "HEAD";
1739 request.url = GURL("http://www.google.com/"); 1679 request.url = GURL("http://www.google.com/");
1740 1680
1741 const SpdyHeaderInfo kSynStartHeader = { 1681 const SpdyHeaderInfo kSynStartHeader = {
1742 SYN_STREAM, // Kind = Syn 1682 SYN_STREAM, // Kind = Syn
1743 1, // Stream ID 1683 1, // Stream ID
1744 0, // Associated stream ID 1684 0, // Associated stream ID
1745 ConvertRequestPriorityToSpdyPriority( 1685 ConvertRequestPriorityToSpdyPriority(
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
1794 BoundNetLog(), GetParam(), NULL); 1734 BoundNetLog(), GetParam(), NULL);
1795 helper.RunToCompletion(&data); 1735 helper.RunToCompletion(&data);
1796 TransactionHelperResult out = helper.output(); 1736 TransactionHelperResult out = helper.output();
1797 1737
1798 EXPECT_EQ(OK, out.rv); 1738 EXPECT_EQ(OK, out.rv);
1799 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1739 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1800 } 1740 }
1801 1741
1802 // Test that a simple POST works. 1742 // Test that a simple POST works.
1803 TEST_P(SpdyNetworkTransactionTest, Post) { 1743 TEST_P(SpdyNetworkTransactionTest, Post) {
1804 if (GetParam().protocol > kProtoSPDY3)
1805 return;
1806
1807 scoped_ptr<SpdyFrame> req( 1744 scoped_ptr<SpdyFrame> req(
1808 spdy_util_.ConstructSpdyPost( 1745 spdy_util_.ConstructSpdyPost(
1809 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 1746 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1810 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1747 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1811 MockWrite writes[] = { 1748 MockWrite writes[] = {
1812 CreateMockWrite(*req), 1749 CreateMockWrite(*req),
1813 CreateMockWrite(*body), // POST upload frame 1750 CreateMockWrite(*body), // POST upload frame
1814 }; 1751 };
1815 1752
1816 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 1753 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1817 MockRead reads[] = { 1754 MockRead reads[] = {
1818 CreateMockRead(*resp), 1755 CreateMockRead(*resp),
1819 CreateMockRead(*body), 1756 CreateMockRead(*body),
1820 MockRead(ASYNC, 0, 0) // EOF 1757 MockRead(ASYNC, 0, 0) // EOF
1821 }; 1758 };
1822 1759
1823 DelayedSocketData data(2, reads, arraysize(reads), 1760 DelayedSocketData data(2, reads, arraysize(reads),
1824 writes, arraysize(writes)); 1761 writes, arraysize(writes));
1825 NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY, 1762 NormalSpdyTransactionHelper helper(CreatePostRequest(), DEFAULT_PRIORITY,
1826 BoundNetLog(), GetParam(), NULL); 1763 BoundNetLog(), GetParam(), NULL);
1827 helper.RunToCompletion(&data); 1764 helper.RunToCompletion(&data);
1828 TransactionHelperResult out = helper.output(); 1765 TransactionHelperResult out = helper.output();
1829 EXPECT_EQ(OK, out.rv); 1766 EXPECT_EQ(OK, out.rv);
1830 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1767 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1831 EXPECT_EQ("hello!", out.response_data); 1768 EXPECT_EQ("hello!", out.response_data);
1832 } 1769 }
1833 1770
1834 // Test that a POST with a file works. 1771 // Test that a POST with a file works.
1835 TEST_P(SpdyNetworkTransactionTest, FilePost) { 1772 TEST_P(SpdyNetworkTransactionTest, FilePost) {
1836 if (GetParam().protocol > kProtoSPDY3)
1837 return;
1838
1839 scoped_ptr<SpdyFrame> req( 1773 scoped_ptr<SpdyFrame> req(
1840 spdy_util_.ConstructSpdyPost( 1774 spdy_util_.ConstructSpdyPost(
1841 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 1775 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1842 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1776 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1843 MockWrite writes[] = { 1777 MockWrite writes[] = {
1844 CreateMockWrite(*req), 1778 CreateMockWrite(*req),
1845 CreateMockWrite(*body), // POST upload frame 1779 CreateMockWrite(*body), // POST upload frame
1846 }; 1780 };
1847 1781
1848 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 1782 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1849 MockRead reads[] = { 1783 MockRead reads[] = {
1850 CreateMockRead(*resp), 1784 CreateMockRead(*resp),
1851 CreateMockRead(*body), 1785 CreateMockRead(*body),
1852 MockRead(ASYNC, 0, 0) // EOF 1786 MockRead(ASYNC, 0, 0) // EOF
1853 }; 1787 };
1854 1788
1855 DelayedSocketData data(2, reads, arraysize(reads), 1789 DelayedSocketData data(2, reads, arraysize(reads),
1856 writes, arraysize(writes)); 1790 writes, arraysize(writes));
1857 NormalSpdyTransactionHelper helper(CreateFilePostRequest(), DEFAULT_PRIORITY, 1791 NormalSpdyTransactionHelper helper(CreateFilePostRequest(), DEFAULT_PRIORITY,
1858 BoundNetLog(), GetParam(), NULL); 1792 BoundNetLog(), GetParam(), NULL);
1859 helper.RunToCompletion(&data); 1793 helper.RunToCompletion(&data);
1860 TransactionHelperResult out = helper.output(); 1794 TransactionHelperResult out = helper.output();
1861 EXPECT_EQ(OK, out.rv); 1795 EXPECT_EQ(OK, out.rv);
1862 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1796 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1863 EXPECT_EQ("hello!", out.response_data); 1797 EXPECT_EQ("hello!", out.response_data);
1864 } 1798 }
1865 1799
1866 // Test that a complex POST works. 1800 // Test that a complex POST works.
1867 TEST_P(SpdyNetworkTransactionTest, ComplexPost) { 1801 TEST_P(SpdyNetworkTransactionTest, ComplexPost) {
1868 if (GetParam().protocol > kProtoSPDY3)
1869 return;
1870
1871 scoped_ptr<SpdyFrame> req( 1802 scoped_ptr<SpdyFrame> req(
1872 spdy_util_.ConstructSpdyPost( 1803 spdy_util_.ConstructSpdyPost(
1873 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0)); 1804 kRequestUrl, 1, kUploadDataSize, LOWEST, NULL, 0));
1874 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1805 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1875 MockWrite writes[] = { 1806 MockWrite writes[] = {
1876 CreateMockWrite(*req), 1807 CreateMockWrite(*req),
1877 CreateMockWrite(*body), // POST upload frame 1808 CreateMockWrite(*body), // POST upload frame
1878 }; 1809 };
1879 1810
1880 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 1811 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
(...skipping 10 matching lines...) Expand all
1891 BoundNetLog(), GetParam(), NULL); 1822 BoundNetLog(), GetParam(), NULL);
1892 helper.RunToCompletion(&data); 1823 helper.RunToCompletion(&data);
1893 TransactionHelperResult out = helper.output(); 1824 TransactionHelperResult out = helper.output();
1894 EXPECT_EQ(OK, out.rv); 1825 EXPECT_EQ(OK, out.rv);
1895 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1826 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1896 EXPECT_EQ("hello!", out.response_data); 1827 EXPECT_EQ("hello!", out.response_data);
1897 } 1828 }
1898 1829
1899 // Test that a chunked POST works. 1830 // Test that a chunked POST works.
1900 TEST_P(SpdyNetworkTransactionTest, ChunkedPost) { 1831 TEST_P(SpdyNetworkTransactionTest, ChunkedPost) {
1901 if (GetParam().protocol > kProtoSPDY3)
1902 return;
1903
1904 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); 1832 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
1905 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1833 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
1906 MockWrite writes[] = { 1834 MockWrite writes[] = {
1907 CreateMockWrite(*req), 1835 CreateMockWrite(*req),
1908 CreateMockWrite(*body), 1836 CreateMockWrite(*body),
1909 }; 1837 };
1910 1838
1911 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); 1839 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
1912 MockRead reads[] = { 1840 MockRead reads[] = {
1913 CreateMockRead(*resp), 1841 CreateMockRead(*resp),
(...skipping 16 matching lines...) Expand all
1930 1858
1931 helper.RunToCompletion(&data); 1859 helper.RunToCompletion(&data);
1932 TransactionHelperResult out = helper.output(); 1860 TransactionHelperResult out = helper.output();
1933 EXPECT_EQ(OK, out.rv); 1861 EXPECT_EQ(OK, out.rv);
1934 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1862 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1935 EXPECT_EQ(kUploadData, out.response_data); 1863 EXPECT_EQ(kUploadData, out.response_data);
1936 } 1864 }
1937 1865
1938 // Test that a chunked POST works with chunks appended after transaction starts. 1866 // Test that a chunked POST works with chunks appended after transaction starts.
1939 TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) { 1867 TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) {
1940 if (GetParam().protocol > kProtoSPDY3)
1941 return;
1942
1943 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); 1868 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0));
1944 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1869 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false));
1945 scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(1, false)); 1870 scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame(1, false));
1946 scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true)); 1871 scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true));
1947 MockWrite writes[] = { 1872 MockWrite writes[] = {
1948 CreateMockWrite(*req), 1873 CreateMockWrite(*req),
1949 CreateMockWrite(*chunk1), 1874 CreateMockWrite(*chunk1),
1950 CreateMockWrite(*chunk2), 1875 CreateMockWrite(*chunk2),
1951 CreateMockWrite(*chunk3), 1876 CreateMockWrite(*chunk3),
1952 }; 1877 };
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1989 expected_response += kUploadData; 1914 expected_response += kUploadData;
1990 1915
1991 TransactionHelperResult out = helper.output(); 1916 TransactionHelperResult out = helper.output();
1992 EXPECT_EQ(OK, out.rv); 1917 EXPECT_EQ(OK, out.rv);
1993 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1918 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
1994 EXPECT_EQ(expected_response, out.response_data); 1919 EXPECT_EQ(expected_response, out.response_data);
1995 } 1920 }
1996 1921
1997 // Test that a POST without any post data works. 1922 // Test that a POST without any post data works.
1998 TEST_P(SpdyNetworkTransactionTest, NullPost) { 1923 TEST_P(SpdyNetworkTransactionTest, NullPost) {
1999 if (GetParam().protocol > kProtoSPDY3)
2000 return;
2001
2002 // Setup the request 1924 // Setup the request
2003 HttpRequestInfo request; 1925 HttpRequestInfo request;
2004 request.method = "POST"; 1926 request.method = "POST";
2005 request.url = GURL(kRequestUrl); 1927 request.url = GURL(kRequestUrl);
2006 // Create an empty UploadData. 1928 // Create an empty UploadData.
2007 request.upload_data_stream = NULL; 1929 request.upload_data_stream = NULL;
2008 1930
2009 // When request.upload_data_stream is NULL for post, content-length is 1931 // When request.upload_data_stream is NULL for post, content-length is
2010 // expected to be 0. 1932 // expected to be 0.
2011 scoped_ptr<SpdyFrame> req( 1933 scoped_ptr<SpdyFrame> req(
(...skipping 19 matching lines...) Expand all
2031 BoundNetLog(), GetParam(), NULL); 1953 BoundNetLog(), GetParam(), NULL);
2032 helper.RunToCompletion(&data); 1954 helper.RunToCompletion(&data);
2033 TransactionHelperResult out = helper.output(); 1955 TransactionHelperResult out = helper.output();
2034 EXPECT_EQ(OK, out.rv); 1956 EXPECT_EQ(OK, out.rv);
2035 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1957 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
2036 EXPECT_EQ("hello!", out.response_data); 1958 EXPECT_EQ("hello!", out.response_data);
2037 } 1959 }
2038 1960
2039 // Test that a simple POST works. 1961 // Test that a simple POST works.
2040 TEST_P(SpdyNetworkTransactionTest, EmptyPost) { 1962 TEST_P(SpdyNetworkTransactionTest, EmptyPost) {
2041 if (GetParam().protocol > kProtoSPDY3)
2042 return;
2043
2044 // Create an empty UploadDataStream. 1963 // Create an empty UploadDataStream.
2045 ScopedVector<UploadElementReader> element_readers; 1964 ScopedVector<UploadElementReader> element_readers;
2046 UploadDataStream stream(&element_readers, 0); 1965 UploadDataStream stream(&element_readers, 0);
2047 1966
2048 // Setup the request 1967 // Setup the request
2049 HttpRequestInfo request; 1968 HttpRequestInfo request;
2050 request.method = "POST"; 1969 request.method = "POST";
2051 request.url = GURL(kRequestUrl); 1970 request.url = GURL(kRequestUrl);
2052 request.upload_data_stream = &stream; 1971 request.upload_data_stream = &stream;
2053 1972
(...skipping 21 matching lines...) Expand all
2075 BoundNetLog(), GetParam(), NULL); 1994 BoundNetLog(), GetParam(), NULL);
2076 helper.RunToCompletion(&data); 1995 helper.RunToCompletion(&data);
2077 TransactionHelperResult out = helper.output(); 1996 TransactionHelperResult out = helper.output();
2078 EXPECT_EQ(OK, out.rv); 1997 EXPECT_EQ(OK, out.rv);
2079 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 1998 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
2080 EXPECT_EQ("hello!", out.response_data); 1999 EXPECT_EQ("hello!", out.response_data);
2081 } 2000 }
2082 2001
2083 // While we're doing a post, the server sends back a SYN_REPLY. 2002 // While we're doing a post, the server sends back a SYN_REPLY.
2084 TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) { 2003 TEST_P(SpdyNetworkTransactionTest, PostWithEarlySynReply) {
2085 if (GetParam().protocol > kProtoSPDY3)
2086 return;
2087
2088 static const char upload[] = { "hello!" }; 2004 static const char upload[] = { "hello!" };
2089 ScopedVector<UploadElementReader> element_readers; 2005 ScopedVector<UploadElementReader> element_readers;
2090 element_readers.push_back( 2006 element_readers.push_back(
2091 new UploadBytesElementReader(upload, sizeof(upload))); 2007 new UploadBytesElementReader(upload, sizeof(upload)));
2092 UploadDataStream stream(&element_readers, 0); 2008 UploadDataStream stream(&element_readers, 0);
2093 2009
2094 // Setup the request 2010 // Setup the request
2095 HttpRequestInfo request; 2011 HttpRequestInfo request;
2096 request.method = "POST"; 2012 request.method = "POST";
2097 request.url = GURL(kRequestUrl); 2013 request.url = GURL(kRequestUrl);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
2131 data.RunFor(2); 2047 data.RunFor(2);
2132 rv = callback.WaitForResult(); 2048 rv = callback.WaitForResult();
2133 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 2049 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2134 data.RunFor(1); 2050 data.RunFor(1);
2135 } 2051 }
2136 2052
2137 // The client upon cancellation tries to send a RST_STREAM frame. The mock 2053 // The client upon cancellation tries to send a RST_STREAM frame. The mock
2138 // socket causes the TCP write to return zero. This test checks that the client 2054 // socket causes the TCP write to return zero. This test checks that the client
2139 // tries to queue up the RST_STREAM frame again. 2055 // tries to queue up the RST_STREAM frame again.
2140 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { 2056 TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) {
2141 if (GetParam().protocol > kProtoSPDY3)
2142 return;
2143
2144 scoped_ptr<SpdyFrame> req( 2057 scoped_ptr<SpdyFrame> req(
2145 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2058 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2146 scoped_ptr<SpdyFrame> rst( 2059 scoped_ptr<SpdyFrame> rst(
2147 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 2060 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2148 MockWrite writes[] = { 2061 MockWrite writes[] = {
2149 CreateMockWrite(*req.get(), 0, SYNCHRONOUS), 2062 CreateMockWrite(*req.get(), 0, SYNCHRONOUS),
2150 MockWrite(SYNCHRONOUS, 0, 0, 2), 2063 MockWrite(SYNCHRONOUS, 0, 0, 2),
2151 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), 2064 CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
2152 }; 2065 };
2153 2066
(...skipping 21 matching lines...) Expand all
2175 data.Run(); 2088 data.Run();
2176 helper.ResetTrans(); 2089 helper.ResetTrans();
2177 data.SetStop(20); 2090 data.SetStop(20);
2178 data.Run(); 2091 data.Run();
2179 2092
2180 helper.VerifyDataConsumed(); 2093 helper.VerifyDataConsumed();
2181 } 2094 }
2182 2095
2183 // Test that the transaction doesn't crash when we don't have a reply. 2096 // Test that the transaction doesn't crash when we don't have a reply.
2184 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { 2097 TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) {
2185 if (GetParam().protocol > kProtoSPDY3)
2186 return;
2187
2188 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2098 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2189 MockRead reads[] = { 2099 MockRead reads[] = {
2190 CreateMockRead(*body), 2100 CreateMockRead(*body),
2191 MockRead(ASYNC, 0, 0) // EOF 2101 MockRead(ASYNC, 0, 0) // EOF
2192 }; 2102 };
2193 2103
2194 DelayedSocketData data(1, reads, arraysize(reads), NULL, 0); 2104 DelayedSocketData data(1, reads, arraysize(reads), NULL, 0);
2195 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 2105 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2196 BoundNetLog(), GetParam(), NULL); 2106 BoundNetLog(), GetParam(), NULL);
2197 helper.RunToCompletion(&data); 2107 helper.RunToCompletion(&data);
2198 TransactionHelperResult out = helper.output(); 2108 TransactionHelperResult out = helper.output();
2199 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 2109 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2200 } 2110 }
2201 2111
2202 // Test that the transaction doesn't crash when we get two replies on the same 2112 // Test that the transaction doesn't crash when we get two replies on the same
2203 // stream ID. See http://crbug.com/45639. 2113 // stream ID. See http://crbug.com/45639.
2204 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { 2114 TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) {
2205 if (GetParam().protocol > kProtoSPDY3)
2206 return;
2207
2208 scoped_ptr<SpdyFrame> req( 2115 scoped_ptr<SpdyFrame> req(
2209 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2116 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2210 scoped_ptr<SpdyFrame> rst( 2117 scoped_ptr<SpdyFrame> rst(
2211 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_STREAM_IN_USE)); 2118 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_STREAM_IN_USE));
2212 MockWrite writes[] = { 2119 MockWrite writes[] = {
2213 CreateMockWrite(*req), 2120 CreateMockWrite(*req),
2214 CreateMockWrite(*rst), 2121 CreateMockWrite(*rst),
2215 }; 2122 };
2216 2123
2217 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2124 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
(...skipping 25 matching lines...) Expand all
2243 ASSERT_TRUE(response != NULL); 2150 ASSERT_TRUE(response != NULL);
2244 EXPECT_TRUE(response->headers.get() != NULL); 2151 EXPECT_TRUE(response->headers.get() != NULL);
2245 EXPECT_TRUE(response->was_fetched_via_spdy); 2152 EXPECT_TRUE(response->was_fetched_via_spdy);
2246 std::string response_data; 2153 std::string response_data;
2247 rv = ReadTransaction(trans, &response_data); 2154 rv = ReadTransaction(trans, &response_data);
2248 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv); 2155 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, rv);
2249 2156
2250 helper.VerifyDataConsumed(); 2157 helper.VerifyDataConsumed();
2251 } 2158 }
2252 2159
2253 // Test that sent data frames and received WINDOW_UPDATE frames change
Ryan Hamilton 2013/06/27 17:23:50 So this block appears to have been moved but it lo
akalin 2013/06/27 20:00:06 Moved back.
2254 // the send_window_size_ correctly.
2255
2256 // WINDOW_UPDATE is different than most other frames in that it can arrive
2257 // while the client is still sending the request body. In order to enforce
2258 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
2259 // socket data provider, so that initial read that is done as soon as the
2260 // stream is created, succeeds and schedules another read. This way reads
2261 // and writes are interleaved; after doing a full frame write, SpdyStream
2262 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
2263 // Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
2264 // since request has not been completely written, therefore we feed
2265 // enough number of WINDOW_UPDATEs to finish the first read and cause a
2266 // write, leading to a complete write of request body; after that we send
2267 // a reply with a body, to cause a graceful shutdown.
2268
2269 // TODO(agayev): develop a socket data provider where both, reads and
2270 // writes are ordered so that writing tests like these are easy and rewrite
2271 // all these tests using it. Right now we are working around the
2272 // limitations as described above and it's not deterministic, tests may
2273 // fail under specific circumstances.
2274 TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
2275 if (GetParam().protocol != kProtoSPDY3)
2276 return;
2277
2278 static int kFrameCount = 2;
2279 scoped_ptr<std::string> content(
2280 new std::string(kMaxSpdyFrameChunkSize, 'a'));
2281 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
2282 kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
2283 scoped_ptr<SpdyFrame> body(
2284 spdy_util_.ConstructSpdyBodyFrame(
2285 1, content->c_str(), content->size(), false));
2286 scoped_ptr<SpdyFrame> body_end(
2287 spdy_util_.ConstructSpdyBodyFrame(
2288 1, content->c_str(), content->size(), true));
2289
2290 MockWrite writes[] = {
2291 CreateMockWrite(*req, 0),
2292 CreateMockWrite(*body, 1),
2293 CreateMockWrite(*body_end, 2),
2294 };
2295
2296 static const int32 kDeltaWindowSize = 0xff;
2297 static const int kDeltaCount = 4;
2298 scoped_ptr<SpdyFrame> window_update(
2299 spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
2300 scoped_ptr<SpdyFrame> window_update_dummy(
2301 spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
2302 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2303 MockRead reads[] = {
2304 CreateMockRead(*window_update_dummy, 3),
2305 CreateMockRead(*window_update_dummy, 4),
2306 CreateMockRead(*window_update_dummy, 5),
2307 CreateMockRead(*window_update, 6), // Four updates, therefore window
2308 CreateMockRead(*window_update, 7), // size should increase by
2309 CreateMockRead(*window_update, 8), // kDeltaWindowSize * 4
2310 CreateMockRead(*window_update, 9),
2311 CreateMockRead(*resp, 10),
2312 CreateMockRead(*body_end, 11),
2313 MockRead(ASYNC, 0, 0, 12) // EOF
2314 };
2315
2316 DeterministicSocketData data(reads, arraysize(reads),
2317 writes, arraysize(writes));
2318
2319 ScopedVector<UploadElementReader> element_readers;
2320 for (int i = 0; i < kFrameCount; ++i) {
2321 element_readers.push_back(
2322 new UploadBytesElementReader(content->c_str(), content->size()));
2323 }
2324 UploadDataStream upload_data_stream(&element_readers, 0);
2325
2326 // Setup the request
2327 HttpRequestInfo request;
2328 request.method = "POST";
2329 request.url = GURL(kDefaultURL);
2330 request.upload_data_stream = &upload_data_stream;
2331
2332 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
2333 BoundNetLog(), GetParam(), NULL);
2334 helper.SetDeterministic();
2335 helper.AddDeterministicData(&data);
2336 helper.RunPreTestSetup();
2337
2338 HttpNetworkTransaction* trans = helper.trans();
2339
2340 TestCompletionCallback callback;
2341 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2342
2343 EXPECT_EQ(ERR_IO_PENDING, rv);
2344
2345 data.RunFor(11);
2346
2347 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
2348 ASSERT_TRUE(stream != NULL);
2349 ASSERT_TRUE(stream->stream() != NULL);
2350 EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) +
2351 kDeltaWindowSize * kDeltaCount -
2352 kMaxSpdyFrameChunkSize * kFrameCount,
2353 stream->stream()->send_window_size());
2354
2355 data.RunFor(1);
2356
2357 rv = callback.WaitForResult();
2358 EXPECT_EQ(OK, rv);
2359
2360 helper.VerifyDataConsumed();
2361 }
2362
2363 // Test that received data frames and sent WINDOW_UPDATE frames change
2364 // the recv_window_size_ correctly.
2365 TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
2366 if (GetParam().protocol != kProtoSPDY3)
2367 return;
2368
2369 // Set the data in the body frame large enough to trigger sending a
2370 // WINDOW_UPDATE by the stream.
2371 const std::string body_data(kSpdyStreamInitialWindowSize / 2 + 1, 'x');
2372
2373 scoped_ptr<SpdyFrame> req(
2374 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2375 scoped_ptr<SpdyFrame> window_update(
2376 spdy_util_.ConstructSpdyWindowUpdate(1, body_data.size()));
2377
2378 MockWrite writes[] = {
2379 CreateMockWrite(*req),
2380 CreateMockWrite(*window_update),
2381 };
2382
2383 scoped_ptr<SpdyFrame> resp(
2384 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2385 scoped_ptr<SpdyFrame> body_no_fin(
2386 spdy_util_.ConstructSpdyBodyFrame(
2387 1, body_data.data(), body_data.size(), false));
2388 scoped_ptr<SpdyFrame> body_fin(
2389 spdy_util_.ConstructSpdyBodyFrame(1, NULL, 0, true));
2390 MockRead reads[] = {
2391 CreateMockRead(*resp),
2392 CreateMockRead(*body_no_fin),
2393 MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause
2394 CreateMockRead(*body_fin),
2395 MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause
2396 MockRead(ASYNC, 0, 0) // EOF
2397 };
2398
2399 DelayedSocketData data(1, reads, arraysize(reads),
2400 writes, arraysize(writes));
2401
2402 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2403 BoundNetLog(), GetParam(), NULL);
2404 helper.AddData(&data);
2405 helper.RunPreTestSetup();
2406 HttpNetworkTransaction* trans = helper.trans();
2407
2408 TestCompletionCallback callback;
2409 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2410
2411 EXPECT_EQ(ERR_IO_PENDING, rv);
2412 rv = callback.WaitForResult();
2413 EXPECT_EQ(OK, rv);
2414
2415 SpdyHttpStream* stream =
2416 static_cast<SpdyHttpStream*>(trans->stream_.get());
2417 ASSERT_TRUE(stream != NULL);
2418 ASSERT_TRUE(stream->stream() != NULL);
2419
2420 EXPECT_EQ(
2421 static_cast<int>(kSpdyStreamInitialWindowSize - body_data.size()),
2422 stream->stream()->recv_window_size());
2423
2424 const HttpResponseInfo* response = trans->GetResponseInfo();
2425 ASSERT_TRUE(response != NULL);
2426 ASSERT_TRUE(response->headers.get() != NULL);
2427 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
2428 EXPECT_TRUE(response->was_fetched_via_spdy);
2429
2430 // Issue a read which will cause a WINDOW_UPDATE to be sent and window
2431 // size increased to default.
2432 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(body_data.size()));
2433 rv = trans->Read(buf.get(), body_data.size(), CompletionCallback());
2434 EXPECT_EQ(static_cast<int>(body_data.size()), rv);
2435 std::string content(buf->data(), buf->data() + body_data.size());
2436 EXPECT_EQ(body_data, content);
2437
2438 // Schedule the reading of empty data frame with FIN
2439 data.CompleteRead();
2440
2441 // Force write of WINDOW_UPDATE which was scheduled during the above
2442 // read.
2443 base::MessageLoop::current()->RunUntilIdle();
2444
2445 // Read EOF.
2446 data.CompleteRead();
2447
2448 helper.VerifyDataConsumed();
2449 }
2450
2451 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
2452 TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
2453 if (GetParam().protocol != kProtoSPDY3)
2454 return;
2455
2456 // Number of full frames we hope to write (but will not, used to
2457 // set content-length header correctly)
2458 static int kFrameCount = 3;
2459
2460 scoped_ptr<std::string> content(
2461 new std::string(kMaxSpdyFrameChunkSize, 'a'));
2462 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
2463 kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
2464 scoped_ptr<SpdyFrame> body(
2465 spdy_util_.ConstructSpdyBodyFrame(
2466 1, content->c_str(), content->size(), false));
2467 scoped_ptr<SpdyFrame> rst(
2468 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
2469
2470 // We're not going to write a data frame with FIN, we'll receive a bad
2471 // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
2472 MockWrite writes[] = {
2473 CreateMockWrite(*req, 0),
2474 CreateMockWrite(*body, 2),
2475 CreateMockWrite(*rst, 3),
2476 };
2477
2478 static const int32 kDeltaWindowSize = 0x7fffffff; // cause an overflow
2479 scoped_ptr<SpdyFrame> window_update(
2480 spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
2481 MockRead reads[] = {
2482 CreateMockRead(*window_update, 1),
2483 MockRead(ASYNC, 0, 4) // EOF
2484 };
2485
2486 DeterministicSocketData data(reads, arraysize(reads),
2487 writes, arraysize(writes));
2488
2489 ScopedVector<UploadElementReader> element_readers;
2490 for (int i = 0; i < kFrameCount; ++i) {
2491 element_readers.push_back(
2492 new UploadBytesElementReader(content->c_str(), content->size()));
2493 }
2494 UploadDataStream upload_data_stream(&element_readers, 0);
2495
2496 // Setup the request
2497 HttpRequestInfo request;
2498 request.method = "POST";
2499 request.url = GURL("http://www.google.com/");
2500 request.upload_data_stream = &upload_data_stream;
2501
2502 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
2503 BoundNetLog(), GetParam(), NULL);
2504 helper.SetDeterministic();
2505 helper.RunPreTestSetup();
2506 helper.AddDeterministicData(&data);
2507 HttpNetworkTransaction* trans = helper.trans();
2508
2509 TestCompletionCallback callback;
2510 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2511 ASSERT_EQ(ERR_IO_PENDING, rv);
2512
2513 data.RunFor(5);
2514 ASSERT_TRUE(callback.have_result());
2515 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
2516 helper.VerifyDataConsumed();
2517 }
2518
2519 // Test that after hitting a send window size of 0, the write process
2520 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
2521
2522 // This test constructs a POST request followed by enough data frames
2523 // containing 'a' that would make the window size 0, followed by another
2524 // data frame containing default content (which is "hello!") and this frame
2525 // also contains a FIN flag. DelayedSocketData is used to enforce all
2526 // writes go through before a read could happen. However, the last frame
2527 // ("hello!") is not supposed to go through since by the time its turn
2528 // arrives, window size is 0. At this point MessageLoop::Run() called via
2529 // callback would block. Therefore we call MessageLoop::RunUntilIdle()
2530 // which returns after performing all possible writes. We use DCHECKS to
2531 // ensure that last data frame is still there and stream has stalled.
2532 // After that, next read is artifically enforced, which causes a
2533 // WINDOW_UPDATE to be read and I/O process resumes.
2534 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
2535 if (GetParam().protocol != kProtoSPDY3)
2536 return;
2537
2538 // Number of frames we need to send to zero out the window size: data
2539 // frames plus SYN_STREAM plus the last data frame; also we need another
2540 // data frame that we will send once the WINDOW_UPDATE is received,
2541 // therefore +3.
2542 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
2543
2544 // Calculate last frame's size; 0 size data frame is legal.
2545 size_t last_frame_size =
2546 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
2547
2548 // Construct content for a data frame of maximum size.
2549 std::string content(kMaxSpdyFrameChunkSize, 'a');
2550
2551 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
2552 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
2553 LOWEST, NULL, 0));
2554
2555 // Full frames.
2556 scoped_ptr<SpdyFrame> body1(
2557 spdy_util_.ConstructSpdyBodyFrame(
2558 1, content.c_str(), content.size(), false));
2559
2560 // Last frame to zero out the window size.
2561 scoped_ptr<SpdyFrame> body2(
2562 spdy_util_.ConstructSpdyBodyFrame(
2563 1, content.c_str(), last_frame_size, false));
2564
2565 // Data frame to be sent once WINDOW_UPDATE frame is received.
2566 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
2567
2568 // Fill in mock writes.
2569 scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
2570 size_t i = 0;
2571 writes[i] = CreateMockWrite(*req);
2572 for (i = 1; i < num_writes - 2; i++)
2573 writes[i] = CreateMockWrite(*body1);
2574 writes[i++] = CreateMockWrite(*body2);
2575 writes[i] = CreateMockWrite(*body3);
2576
2577 // Construct read frame, give enough space to upload the rest of the
2578 // data.
2579 scoped_ptr<SpdyFrame> window_update(
2580 spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
2581 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2582 MockRead reads[] = {
2583 CreateMockRead(*window_update),
2584 CreateMockRead(*window_update),
2585 CreateMockRead(*reply),
2586 CreateMockRead(*body2),
2587 CreateMockRead(*body3),
2588 MockRead(ASYNC, 0, 0) // EOF
2589 };
2590
2591 // Force all writes to happen before any read, last write will not
2592 // actually queue a frame, due to window size being 0.
2593 DelayedSocketData data(num_writes, reads, arraysize(reads),
2594 writes.get(), num_writes);
2595
2596 ScopedVector<UploadElementReader> element_readers;
2597 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
2598 upload_data_string.append(kUploadData, kUploadDataSize);
2599 element_readers.push_back(new UploadBytesElementReader(
2600 upload_data_string.c_str(), upload_data_string.size()));
2601 UploadDataStream upload_data_stream(&element_readers, 0);
2602
2603 HttpRequestInfo request;
2604 request.method = "POST";
2605 request.url = GURL("http://www.google.com/");
2606 request.upload_data_stream = &upload_data_stream;
2607 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
2608 BoundNetLog(), GetParam(), NULL);
2609 helper.AddData(&data);
2610 helper.RunPreTestSetup();
2611
2612 HttpNetworkTransaction* trans = helper.trans();
2613
2614 TestCompletionCallback callback;
2615 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2616 EXPECT_EQ(ERR_IO_PENDING, rv);
2617
2618 base::MessageLoop::current()->RunUntilIdle(); // Write as much as we can.
2619
2620 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
2621 ASSERT_TRUE(stream != NULL);
2622 ASSERT_TRUE(stream->stream() != NULL);
2623 EXPECT_EQ(0, stream->stream()->send_window_size());
2624 // All the body data should have been read.
2625 // TODO(satorux): This is because of the weirdness in reading the request
2626 // body in OnSendBodyComplete(). See crbug.com/113107.
2627 EXPECT_TRUE(upload_data_stream.IsEOF());
2628 // But the body is not yet fully sent (kUploadData is not yet sent)
2629 // since we're send-stalled.
2630 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
2631
2632 data.ForceNextRead(); // Read in WINDOW_UPDATE frame.
2633 rv = callback.WaitForResult();
2634 helper.VerifyDataConsumed();
2635 }
2636
2637 // Test we correctly handle the case where the SETTINGS frame results in
2638 // unstalling the send window.
2639 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
2640 if (GetParam().protocol != kProtoSPDY3)
2641 return;
2642
2643 // Number of frames we need to send to zero out the window size: data
2644 // frames plus SYN_STREAM plus the last data frame; also we need another
2645 // data frame that we will send once the SETTING is received, therefore +3.
2646 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
2647
2648 // Calculate last frame's size; 0 size data frame is legal.
2649 size_t last_frame_size =
2650 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
2651
2652 // Construct content for a data frame of maximum size.
2653 std::string content(kMaxSpdyFrameChunkSize, 'a');
2654
2655 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
2656 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
2657 LOWEST, NULL, 0));
2658
2659 // Full frames.
2660 scoped_ptr<SpdyFrame> body1(
2661 spdy_util_.ConstructSpdyBodyFrame(
2662 1, content.c_str(), content.size(), false));
2663
2664 // Last frame to zero out the window size.
2665 scoped_ptr<SpdyFrame> body2(
2666 spdy_util_.ConstructSpdyBodyFrame(
2667 1, content.c_str(), last_frame_size, false));
2668
2669 // Data frame to be sent once SETTINGS frame is received.
2670 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
2671
2672 // Fill in mock reads/writes.
2673 std::vector<MockRead> reads;
2674 std::vector<MockWrite> writes;
2675 size_t i = 0;
2676 writes.push_back(CreateMockWrite(*req, i++));
2677 while (i < num_writes - 2)
2678 writes.push_back(CreateMockWrite(*body1, i++));
2679 writes.push_back(CreateMockWrite(*body2, i++));
2680
2681 // Construct read frame for SETTINGS that gives enough space to upload the
2682 // rest of the data.
2683 SettingsMap settings;
2684 settings[SETTINGS_INITIAL_WINDOW_SIZE] =
2685 SettingsFlagsAndValue(
2686 SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2);
2687 scoped_ptr<SpdyFrame> settings_frame_large(
2688 spdy_util_.ConstructSpdySettings(settings));
2689
2690 reads.push_back(CreateMockRead(*settings_frame_large, i++));
2691
2692 writes.push_back(CreateMockWrite(*body3, i++));
2693
2694 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2695 reads.push_back(CreateMockRead(*reply, i++));
2696 reads.push_back(CreateMockRead(*body2, i++));
2697 reads.push_back(CreateMockRead(*body3, i++));
2698 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
2699
2700 // Force all writes to happen before any read, last write will not
2701 // actually queue a frame, due to window size being 0.
2702 DeterministicSocketData data(vector_as_array(&reads), reads.size(),
2703 vector_as_array(&writes), writes.size());
2704
2705 ScopedVector<UploadElementReader> element_readers;
2706 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
2707 upload_data_string.append(kUploadData, kUploadDataSize);
2708 element_readers.push_back(new UploadBytesElementReader(
2709 upload_data_string.c_str(), upload_data_string.size()));
2710 UploadDataStream upload_data_stream(&element_readers, 0);
2711
2712 HttpRequestInfo request;
2713 request.method = "POST";
2714 request.url = GURL("http://www.google.com/");
2715 request.upload_data_stream = &upload_data_stream;
2716 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
2717 BoundNetLog(), GetParam(), NULL);
2718 helper.SetDeterministic();
2719 helper.RunPreTestSetup();
2720 helper.AddDeterministicData(&data);
2721
2722 HttpNetworkTransaction* trans = helper.trans();
2723
2724 TestCompletionCallback callback;
2725 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2726 EXPECT_EQ(ERR_IO_PENDING, rv);
2727
2728 data.RunFor(num_writes - 1); // Write as much as we can.
2729
2730 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
2731 ASSERT_TRUE(stream != NULL);
2732 ASSERT_TRUE(stream->stream() != NULL);
2733 EXPECT_EQ(0, stream->stream()->send_window_size());
2734
2735 // All the body data should have been read.
2736 // TODO(satorux): This is because of the weirdness in reading the request
2737 // body in OnSendBodyComplete(). See crbug.com/113107.
2738 EXPECT_TRUE(upload_data_stream.IsEOF());
2739 // But the body is not yet fully sent (kUploadData is not yet sent)
2740 // since we're send-stalled.
2741 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
2742
2743 data.RunFor(6); // Read in SETTINGS frame to unstall.
2744 rv = callback.WaitForResult();
2745 helper.VerifyDataConsumed();
2746 // If stream is NULL, that means it was unstalled and closed.
2747 EXPECT_TRUE(stream->stream() == NULL);
2748 }
2749
2750 // Test we correctly handle the case where the SETTINGS frame results in a
2751 // negative send window size.
2752 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
2753 if (GetParam().protocol != kProtoSPDY3)
2754 return;
2755
2756 // Number of frames we need to send to zero out the window size: data
2757 // frames plus SYN_STREAM plus the last data frame; also we need another
2758 // data frame that we will send once the SETTING is received, therefore +3.
2759 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
2760
2761 // Calculate last frame's size; 0 size data frame is legal.
2762 size_t last_frame_size =
2763 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
2764
2765 // Construct content for a data frame of maximum size.
2766 std::string content(kMaxSpdyFrameChunkSize, 'a');
2767
2768 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
2769 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
2770 LOWEST, NULL, 0));
2771
2772 // Full frames.
2773 scoped_ptr<SpdyFrame> body1(
2774 spdy_util_.ConstructSpdyBodyFrame(
2775 1, content.c_str(), content.size(), false));
2776
2777 // Last frame to zero out the window size.
2778 scoped_ptr<SpdyFrame> body2(
2779 spdy_util_.ConstructSpdyBodyFrame(
2780 1, content.c_str(), last_frame_size, false));
2781
2782 // Data frame to be sent once SETTINGS frame is received.
2783 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
2784
2785 // Fill in mock reads/writes.
2786 std::vector<MockRead> reads;
2787 std::vector<MockWrite> writes;
2788 size_t i = 0;
2789 writes.push_back(CreateMockWrite(*req, i++));
2790 while (i < num_writes - 2)
2791 writes.push_back(CreateMockWrite(*body1, i++));
2792 writes.push_back(CreateMockWrite(*body2, i++));
2793
2794 // Construct read frame for SETTINGS that makes the send_window_size
2795 // negative.
2796 SettingsMap new_settings;
2797 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
2798 SettingsFlagsAndValue(
2799 SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2);
2800 scoped_ptr<SpdyFrame> settings_frame_small(
2801 spdy_util_.ConstructSpdySettings(new_settings));
2802 // Construct read frame for WINDOW_UPDATE that makes the send_window_size
2803 // postive.
2804 scoped_ptr<SpdyFrame> window_update_init_size(
2805 spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
2806
2807 reads.push_back(CreateMockRead(*settings_frame_small, i++));
2808 reads.push_back(CreateMockRead(*window_update_init_size, i++));
2809
2810 writes.push_back(CreateMockWrite(*body3, i++));
2811
2812 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
2813 reads.push_back(CreateMockRead(*reply, i++));
2814 reads.push_back(CreateMockRead(*body2, i++));
2815 reads.push_back(CreateMockRead(*body3, i++));
2816 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
2817
2818 // Force all writes to happen before any read, last write will not
2819 // actually queue a frame, due to window size being 0.
2820 DeterministicSocketData data(vector_as_array(&reads), reads.size(),
2821 vector_as_array(&writes), writes.size());
2822
2823 ScopedVector<UploadElementReader> element_readers;
2824 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
2825 upload_data_string.append(kUploadData, kUploadDataSize);
2826 element_readers.push_back(new UploadBytesElementReader(
2827 upload_data_string.c_str(), upload_data_string.size()));
2828 UploadDataStream upload_data_stream(&element_readers, 0);
2829
2830 HttpRequestInfo request;
2831 request.method = "POST";
2832 request.url = GURL("http://www.google.com/");
2833 request.upload_data_stream = &upload_data_stream;
2834 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
2835 BoundNetLog(), GetParam(), NULL);
2836 helper.SetDeterministic();
2837 helper.RunPreTestSetup();
2838 helper.AddDeterministicData(&data);
2839
2840 HttpNetworkTransaction* trans = helper.trans();
2841
2842 TestCompletionCallback callback;
2843 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
2844 EXPECT_EQ(ERR_IO_PENDING, rv);
2845
2846 data.RunFor(num_writes - 1); // Write as much as we can.
2847
2848 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
2849 ASSERT_TRUE(stream != NULL);
2850 ASSERT_TRUE(stream->stream() != NULL);
2851 EXPECT_EQ(0, stream->stream()->send_window_size());
2852
2853 // All the body data should have been read.
2854 // TODO(satorux): This is because of the weirdness in reading the request
2855 // body in OnSendBodyComplete(). See crbug.com/113107.
2856 EXPECT_TRUE(upload_data_stream.IsEOF());
2857 // But the body is not yet fully sent (kUploadData is not yet sent)
2858 // since we're send-stalled.
2859 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
2860
2861 data.RunFor(7); // Read in WINDOW_UPDATE or SETTINGS frame.
2862 rv = callback.WaitForResult();
2863 helper.VerifyDataConsumed();
2864 }
2865
2866 TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { 2160 TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) {
2867 if (GetParam().protocol > kProtoSPDY3)
2868 return;
2869
2870 // Construct the request. 2161 // Construct the request.
2871 scoped_ptr<SpdyFrame> req( 2162 scoped_ptr<SpdyFrame> req(
2872 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2163 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2873 scoped_ptr<SpdyFrame> rst( 2164 scoped_ptr<SpdyFrame> rst(
2874 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 2165 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
2875 MockWrite writes[] = { 2166 MockWrite writes[] = {
2876 CreateMockWrite(*req), 2167 CreateMockWrite(*req),
2877 CreateMockWrite(*rst), 2168 CreateMockWrite(*rst),
2878 }; 2169 };
2879 2170
(...skipping 16 matching lines...) Expand all
2896 BoundNetLog(), GetParam(), NULL); 2187 BoundNetLog(), GetParam(), NULL);
2897 helper.RunToCompletion(&data); 2188 helper.RunToCompletion(&data);
2898 TransactionHelperResult out = helper.output(); 2189 TransactionHelperResult out = helper.output();
2899 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 2190 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
2900 2191
2901 helper.session()->spdy_session_pool()->CloseAllSessions(); 2192 helper.session()->spdy_session_pool()->CloseAllSessions();
2902 helper.VerifyDataConsumed(); 2193 helper.VerifyDataConsumed();
2903 } 2194 }
2904 2195
2905 TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { 2196 TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) {
2906 if (GetParam().protocol > kProtoSPDY3)
2907 return;
2908
2909 // Construct the request. 2197 // Construct the request.
2910 scoped_ptr<SpdyFrame> req( 2198 scoped_ptr<SpdyFrame> req(
2911 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2199 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2912 scoped_ptr<SpdyFrame> rst( 2200 scoped_ptr<SpdyFrame> rst(
2913 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 2201 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2914 MockWrite writes[] = { 2202 MockWrite writes[] = {
2915 CreateMockWrite(*req), 2203 CreateMockWrite(*req),
2916 CreateMockWrite(*rst), 2204 CreateMockWrite(*rst),
2917 }; 2205 };
2918 2206
(...skipping 20 matching lines...) Expand all
2939 TransactionHelperResult out = helper.output(); 2227 TransactionHelperResult out = helper.output();
2940 EXPECT_EQ(OK, out.rv); 2228 EXPECT_EQ(OK, out.rv);
2941 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 2229 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
2942 EXPECT_EQ("hello!", out.response_data); 2230 EXPECT_EQ("hello!", out.response_data);
2943 2231
2944 helper.session()->spdy_session_pool()->CloseAllSessions(); 2232 helper.session()->spdy_session_pool()->CloseAllSessions();
2945 helper.VerifyDataConsumed(); 2233 helper.VerifyDataConsumed();
2946 } 2234 }
2947 2235
2948 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { 2236 TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) {
2949 if (GetParam().protocol > kProtoSPDY3)
2950 return;
2951
2952 // Construct the request. 2237 // Construct the request.
2953 scoped_ptr<SpdyFrame> req( 2238 scoped_ptr<SpdyFrame> req(
2954 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2239 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2955 MockWrite writes[] = { 2240 MockWrite writes[] = {
2956 CreateMockWrite(*req), 2241 CreateMockWrite(*req),
2957 }; 2242 };
2958 2243
2959 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2244 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2960 MockRead reads[] = { 2245 MockRead reads[] = {
2961 CreateMockRead(*resp), 2246 CreateMockRead(*resp),
(...skipping 20 matching lines...) Expand all
2982 helper.ResetTrans(); // Cancel the transaction. 2267 helper.ResetTrans(); // Cancel the transaction.
2983 2268
2984 // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 2269 // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
2985 // MockClientSocketFactory) are still alive. 2270 // MockClientSocketFactory) are still alive.
2986 base::MessageLoop::current()->RunUntilIdle(); 2271 base::MessageLoop::current()->RunUntilIdle();
2987 helper.VerifyDataNotConsumed(); 2272 helper.VerifyDataNotConsumed();
2988 } 2273 }
2989 2274
2990 // Verify that the client sends a Rst Frame upon cancelling the stream. 2275 // Verify that the client sends a Rst Frame upon cancelling the stream.
2991 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { 2276 TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) {
2992 if (GetParam().protocol > kProtoSPDY3)
2993 return;
2994
2995 scoped_ptr<SpdyFrame> req( 2277 scoped_ptr<SpdyFrame> req(
2996 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2278 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2997 scoped_ptr<SpdyFrame> rst( 2279 scoped_ptr<SpdyFrame> rst(
2998 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); 2280 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
2999 MockWrite writes[] = { 2281 MockWrite writes[] = {
3000 CreateMockWrite(*req, 0, SYNCHRONOUS), 2282 CreateMockWrite(*req, 0, SYNCHRONOUS),
3001 CreateMockWrite(*rst, 2, SYNCHRONOUS), 2283 CreateMockWrite(*rst, 2, SYNCHRONOUS),
3002 }; 2284 };
3003 2285
3004 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2286 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
(...skipping 25 matching lines...) Expand all
3030 data.SetStop(20); 2312 data.SetStop(20);
3031 data.Run(); 2313 data.Run();
3032 2314
3033 helper.VerifyDataConsumed(); 2315 helper.VerifyDataConsumed();
3034 } 2316 }
3035 2317
3036 // Verify that the client can correctly deal with the user callback attempting 2318 // Verify that the client can correctly deal with the user callback attempting
3037 // to start another transaction on a session that is closing down. See 2319 // to start another transaction on a session that is closing down. See
3038 // http://crbug.com/47455 2320 // http://crbug.com/47455
3039 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { 2321 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) {
3040 if (GetParam().protocol > kProtoSPDY3)
3041 return;
3042
3043 scoped_ptr<SpdyFrame> req( 2322 scoped_ptr<SpdyFrame> req(
3044 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2323 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3045 MockWrite writes[] = { CreateMockWrite(*req) }; 2324 MockWrite writes[] = { CreateMockWrite(*req) };
3046 MockWrite writes2[] = { CreateMockWrite(*req) }; 2325 MockWrite writes2[] = { CreateMockWrite(*req) };
3047 2326
3048 // The indicated length of this frame is longer than its actual length. When 2327 // The indicated length of this frame is longer than its actual length. When
3049 // the session receives an empty frame after this one, it shuts down the 2328 // the session receives an empty frame after this one, it shuts down the
3050 // session, and calls the read callback with the incomplete data. 2329 // session, and calls the read callback with the incomplete data.
3051 const uint8 kGetBodyFrame2[] = { 2330 const uint8 kGetBodyFrame2[] = {
3052 0x00, 0x00, 0x00, 0x01, 2331 0x00, 0x00, 0x00, 0x01,
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
3097 data.CompleteRead(); 2376 data.CompleteRead();
3098 // This finishes the read. 2377 // This finishes the read.
3099 data.CompleteRead(); 2378 data.CompleteRead();
3100 helper.VerifyDataConsumed(); 2379 helper.VerifyDataConsumed();
3101 } 2380 }
3102 2381
3103 // Verify that the client can correctly deal with the user callback deleting the 2382 // Verify that the client can correctly deal with the user callback deleting the
3104 // transaction. Failures will usually be valgrind errors. See 2383 // transaction. Failures will usually be valgrind errors. See
3105 // http://crbug.com/46925 2384 // http://crbug.com/46925
3106 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { 2385 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) {
3107 if (GetParam().protocol > kProtoSPDY3)
3108 return;
3109
3110 scoped_ptr<SpdyFrame> req( 2386 scoped_ptr<SpdyFrame> req(
3111 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2387 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3112 MockWrite writes[] = { CreateMockWrite(*req) }; 2388 MockWrite writes[] = { CreateMockWrite(*req) };
3113 2389
3114 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2390 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3115 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 2391 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3116 MockRead reads[] = { 2392 MockRead reads[] = {
3117 CreateMockRead(*resp.get(), 2), 2393 CreateMockRead(*resp.get(), 2),
3118 MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause 2394 MockRead(ASYNC, ERR_IO_PENDING, 3), // Force a pause
3119 CreateMockRead(*body.get(), 4), 2395 CreateMockRead(*body.get(), 4),
(...skipping 27 matching lines...) Expand all
3147 ASSERT_EQ(ERR_IO_PENDING, rv); 2423 ASSERT_EQ(ERR_IO_PENDING, rv);
3148 data.CompleteRead(); 2424 data.CompleteRead();
3149 2425
3150 // Finish running rest of tasks. 2426 // Finish running rest of tasks.
3151 base::MessageLoop::current()->RunUntilIdle(); 2427 base::MessageLoop::current()->RunUntilIdle();
3152 helper.VerifyDataConsumed(); 2428 helper.VerifyDataConsumed();
3153 } 2429 }
3154 2430
3155 // Send a spdy request to www.google.com that gets redirected to www.foo.com. 2431 // Send a spdy request to www.google.com that gets redirected to www.foo.com.
3156 TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) { 2432 TEST_P(SpdyNetworkTransactionTest, RedirectGetRequest) {
3157 if (GetParam().protocol > kProtoSPDY3)
3158 return;
3159
3160 const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM); 2433 const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
3161 scoped_ptr<SpdyHeaderBlock> headers( 2434 scoped_ptr<SpdyHeaderBlock> headers(
3162 spdy_util_.ConstructGetHeaderBlock("http://www.google.com/")); 2435 spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
3163 (*headers)["user-agent"] = ""; 2436 (*headers)["user-agent"] = "";
3164 (*headers)["accept-encoding"] = "gzip,deflate"; 2437 (*headers)["accept-encoding"] = "gzip,deflate";
3165 scoped_ptr<SpdyHeaderBlock> headers2( 2438 scoped_ptr<SpdyHeaderBlock> headers2(
3166 spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php")); 2439 spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php"));
3167 (*headers2)["user-agent"] = ""; 2440 (*headers2)["user-agent"] = "";
3168 (*headers2)["accept-encoding"] = "gzip,deflate"; 2441 (*headers2)["accept-encoding"] = "gzip,deflate";
3169 2442
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
3226 } 2499 }
3227 EXPECT_TRUE(data.at_read_eof()); 2500 EXPECT_TRUE(data.at_read_eof());
3228 EXPECT_TRUE(data.at_write_eof()); 2501 EXPECT_TRUE(data.at_write_eof());
3229 EXPECT_TRUE(data2.at_read_eof()); 2502 EXPECT_TRUE(data2.at_read_eof());
3230 EXPECT_TRUE(data2.at_write_eof()); 2503 EXPECT_TRUE(data2.at_write_eof());
3231 } 2504 }
3232 2505
3233 // Send a spdy request to www.google.com. Get a pushed stream that redirects to 2506 // Send a spdy request to www.google.com. Get a pushed stream that redirects to
3234 // www.foo.com. 2507 // www.foo.com.
3235 TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) { 2508 TEST_P(SpdyNetworkTransactionTest, RedirectServerPush) {
3236 if (GetParam().protocol > kProtoSPDY3)
3237 return;
3238
3239 const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM); 2509 const SpdyHeaderInfo kSynStartHeader = spdy_util_.MakeSpdyHeader(SYN_STREAM);
3240 2510
3241 scoped_ptr<SpdyHeaderBlock> headers( 2511 scoped_ptr<SpdyHeaderBlock> headers(
3242 spdy_util_.ConstructGetHeaderBlock("http://www.google.com/")); 2512 spdy_util_.ConstructGetHeaderBlock("http://www.google.com/"));
3243 (*headers)["user-agent"] = ""; 2513 (*headers)["user-agent"] = "";
3244 (*headers)["accept-encoding"] = "gzip,deflate"; 2514 (*headers)["accept-encoding"] = "gzip,deflate";
3245 2515
3246 // Setup writes/reads to www.google.com 2516 // Setup writes/reads to www.google.com
3247 scoped_ptr<SpdyFrame> req( 2517 scoped_ptr<SpdyFrame> req(
3248 spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers.Pass())); 2518 spdy_util_.ConstructSpdyFrame(kSynStartHeader, headers.Pass()));
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
3331 } 2601 }
3332 data.CompleteRead(); 2602 data.CompleteRead();
3333 data2.CompleteRead(); 2603 data2.CompleteRead();
3334 EXPECT_TRUE(data.at_read_eof()); 2604 EXPECT_TRUE(data.at_read_eof());
3335 EXPECT_TRUE(data.at_write_eof()); 2605 EXPECT_TRUE(data.at_write_eof());
3336 EXPECT_TRUE(data2.at_read_eof()); 2606 EXPECT_TRUE(data2.at_read_eof());
3337 EXPECT_TRUE(data2.at_write_eof()); 2607 EXPECT_TRUE(data2.at_write_eof());
3338 } 2608 }
3339 2609
3340 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { 2610 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) {
3341 if (GetParam().protocol > kProtoSPDY3)
3342 return;
3343
3344 static const unsigned char kPushBodyFrame[] = {
3345 0x00, 0x00, 0x00, 0x02, // header, ID
3346 0x01, 0x00, 0x00, 0x06, // FIN, length
3347 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3348 };
3349 scoped_ptr<SpdyFrame> stream1_syn( 2611 scoped_ptr<SpdyFrame> stream1_syn(
3350 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2612 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3351 scoped_ptr<SpdyFrame> stream1_body( 2613 scoped_ptr<SpdyFrame> stream1_body(
2614 spdy_util_.ConstructSpdyBodyFrame(1, true));
2615 MockWrite writes[] = {
2616 CreateMockWrite(*stream1_syn, 1),
2617 };
2618
2619 scoped_ptr<SpdyFrame>
2620 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2621 scoped_ptr<SpdyFrame>
2622 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2623 0,
2624 2,
2625 1,
2626 "http://www.google.com/foo.dat"));
2627 const char kPushedData[] = "pushed";
2628 scoped_ptr<SpdyFrame> stream2_body(
2629 spdy_util_.ConstructSpdyBodyFrame(
2630 2, kPushedData, strlen(kPushedData), true));
2631 MockRead reads[] = {
2632 CreateMockRead(*stream1_reply, 2),
2633 CreateMockRead(*stream2_syn, 3),
2634 CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2635 CreateMockRead(*stream2_body, 5),
2636 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
2637 };
2638
2639 HttpResponseInfo response;
2640 HttpResponseInfo response2;
2641 std::string expected_push_result("pushed");
2642 OrderedSocketData data(reads, arraysize(reads),
2643 writes, arraysize(writes));
2644 RunServerPushTest(&data,
2645 &response,
2646 &response2,
2647 expected_push_result);
2648
2649 // Verify the SYN_REPLY.
2650 EXPECT_TRUE(response.headers.get() != NULL);
2651 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2652
2653 // Verify the pushed stream.
2654 EXPECT_TRUE(response2.headers.get() != NULL);
2655 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2656 }
2657
2658 TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) {
2659 scoped_ptr<SpdyFrame> stream1_syn(
2660 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2661 scoped_ptr<SpdyFrame> stream1_body(
2662 spdy_util_.ConstructSpdyBodyFrame(1, true));
2663 MockWrite writes[] = {
2664 CreateMockWrite(*stream1_syn, 1),
2665 };
2666
2667 scoped_ptr<SpdyFrame>
2668 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2669 scoped_ptr<SpdyFrame>
2670 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2671 0,
2672 2,
2673 1,
2674 "http://www.google.com/foo.dat"));
2675 const char kPushedData[] = "pushed";
2676 scoped_ptr<SpdyFrame> stream2_body(
2677 spdy_util_.ConstructSpdyBodyFrame(
2678 2, kPushedData, strlen(kPushedData), true));
2679 MockRead reads[] = {
2680 CreateMockRead(*stream2_syn, 2),
2681 CreateMockRead(*stream1_reply, 3),
2682 CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
2683 CreateMockRead(*stream2_body, 5),
2684 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
2685 };
2686
2687 HttpResponseInfo response;
2688 HttpResponseInfo response2;
2689 std::string expected_push_result("pushed");
2690 OrderedSocketData data(reads, arraysize(reads),
2691 writes, arraysize(writes));
2692 RunServerPushTest(&data,
2693 &response,
2694 &response2,
2695 expected_push_result);
2696
2697 // Verify the SYN_REPLY.
2698 EXPECT_TRUE(response.headers.get() != NULL);
2699 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2700
2701 // Verify the pushed stream.
2702 EXPECT_TRUE(response2.headers.get() != NULL);
2703 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2704 }
2705
2706 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
2707 scoped_ptr<SpdyFrame> stream1_syn(
2708 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2709 MockWrite writes[] = { CreateMockWrite(*stream1_syn, 1), };
2710
2711 scoped_ptr<SpdyFrame>
2712 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2713 scoped_ptr<SpdyFrame>
2714 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2715 0,
2716 2,
2717 1,
2718 "http://www.google.com/foo.dat"));
2719 const char kPushedData[] = "pushed";
2720 scoped_ptr<SpdyFrame> stream2_body(
2721 spdy_util_.ConstructSpdyBodyFrame(
2722 2, kPushedData, strlen(kPushedData), true));
2723 scoped_ptr<SpdyFrame>
2724 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
2725 MockRead reads[] = {
2726 CreateMockRead(*stream1_reply, 2),
2727 CreateMockRead(*stream2_syn, 3),
2728 CreateMockRead(*stream2_body, 4),
2729 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2730 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
2731 };
2732
2733 HttpResponseInfo response;
2734 HttpResponseInfo response2;
2735 std::string expected_push_result("pushed");
2736 OrderedSocketData data(reads, arraysize(reads),
2737 writes, arraysize(writes));
2738 RunServerPushTest(&data,
2739 &response,
2740 &response2,
2741 expected_push_result);
2742
2743 // Verify the SYN_REPLY.
2744 EXPECT_TRUE(response.headers.get() != NULL);
2745 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2746
2747 // Verify the pushed stream.
2748 EXPECT_TRUE(response2.headers.get() != NULL);
2749 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2750 }
2751
2752 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
2753 scoped_ptr<SpdyFrame> stream1_syn(
2754 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2755 scoped_ptr<SpdyFrame> stream1_body(
2756 spdy_util_.ConstructSpdyBodyFrame(1, true));
2757 MockWrite writes[] = {
2758 CreateMockWrite(*stream1_syn, 1),
2759 };
2760
2761 scoped_ptr<SpdyFrame>
2762 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2763 scoped_ptr<SpdyFrame>
2764 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2765 0,
2766 2,
2767 1,
2768 "http://www.google.com/foo.dat"));
2769 scoped_ptr<SpdyFrame> stream2_rst(
2770 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
2771 MockRead reads[] = {
2772 CreateMockRead(*stream1_reply, 2),
2773 CreateMockRead(*stream2_syn, 3),
2774 CreateMockRead(*stream2_rst, 4),
2775 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
2776 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
2777 };
2778
2779 OrderedSocketData data(reads, arraysize(reads),
2780 writes, arraysize(writes));
2781 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
2782 BoundNetLog(), GetParam(), NULL);
2783
2784 helper.RunPreTestSetup();
2785 helper.AddData(&data);
2786
2787 HttpNetworkTransaction* trans = helper.trans();
2788
2789 // Start the transaction with basic parameters.
2790 TestCompletionCallback callback;
2791 int rv = trans->Start(
2792 &CreateGetRequest(), callback.callback(), BoundNetLog());
2793 EXPECT_EQ(ERR_IO_PENDING, rv);
2794 rv = callback.WaitForResult();
2795 EXPECT_EQ(OK, rv);
2796
2797 // Verify that we consumed all test data.
2798 EXPECT_TRUE(data.at_read_eof()) << "Read count: "
2799 << data.read_count()
2800 << " Read index: "
2801 << data.read_index();
2802 EXPECT_TRUE(data.at_write_eof()) << "Write count: "
2803 << data.write_count()
2804 << " Write index: "
2805 << data.write_index();
2806
2807 // Verify the SYN_REPLY.
2808 HttpResponseInfo response = *trans->GetResponseInfo();
2809 EXPECT_TRUE(response.headers.get() != NULL);
2810 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2811 }
2812
2813 // Verify that we don't leak streams and that we properly send a reset
2814 // if the server pushes the same stream twice.
2815 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) {
2816 scoped_ptr<SpdyFrame> stream1_syn(
2817 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2818 scoped_ptr<SpdyFrame> stream1_body(
2819 spdy_util_.ConstructSpdyBodyFrame(1, true));
2820 scoped_ptr<SpdyFrame> stream3_rst(
2821 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR));
2822 MockWrite writes[] = {
2823 CreateMockWrite(*stream1_syn, 1),
2824 CreateMockWrite(*stream3_rst, 5),
2825 };
2826
2827 scoped_ptr<SpdyFrame>
2828 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2829 scoped_ptr<SpdyFrame>
2830 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2831 0,
2832 2,
2833 1,
2834 "http://www.google.com/foo.dat"));
2835 const char kPushedData[] = "pushed";
2836 scoped_ptr<SpdyFrame> stream2_body(
2837 spdy_util_.ConstructSpdyBodyFrame(
2838 2, kPushedData, strlen(kPushedData), true));
2839 scoped_ptr<SpdyFrame>
2840 stream3_syn(spdy_util_.ConstructSpdyPush(NULL,
2841 0,
2842 4,
2843 1,
2844 "http://www.google.com/foo.dat"));
2845 MockRead reads[] = {
2846 CreateMockRead(*stream1_reply, 2),
2847 CreateMockRead(*stream2_syn, 3),
2848 CreateMockRead(*stream3_syn, 4),
2849 CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
2850 CreateMockRead(*stream2_body, 7),
2851 MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause
2852 };
2853
2854 HttpResponseInfo response;
2855 HttpResponseInfo response2;
2856 std::string expected_push_result("pushed");
2857 OrderedSocketData data(reads, arraysize(reads),
2858 writes, arraysize(writes));
2859 RunServerPushTest(&data,
2860 &response,
2861 &response2,
2862 expected_push_result);
2863
2864 // Verify the SYN_REPLY.
2865 EXPECT_TRUE(response.headers.get() != NULL);
2866 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2867
2868 // Verify the pushed stream.
2869 EXPECT_TRUE(response2.headers.get() != NULL);
2870 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2871 }
2872
2873 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
2874 scoped_ptr<SpdyFrame> stream1_syn(
2875 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2876 scoped_ptr<SpdyFrame> stream1_body(
2877 spdy_util_.ConstructSpdyBodyFrame(1, true));
2878 MockWrite writes[] = {
2879 CreateMockWrite(*stream1_syn, 1),
2880 };
2881
2882 scoped_ptr<SpdyFrame>
2883 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
2884 scoped_ptr<SpdyFrame>
2885 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
2886 0,
2887 2,
2888 1,
2889 "http://www.google.com/foo.dat"));
2890 static const char kPushedData[] = "pushed my darling hello my baby";
2891 scoped_ptr<SpdyFrame> stream2_body_base(
2892 spdy_util_.ConstructSpdyBodyFrame(
2893 2, kPushedData, strlen(kPushedData), true));
2894 const size_t kChunkSize = strlen(kPushedData) / 4;
2895 scoped_ptr<SpdyFrame> stream2_body1(
2896 new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
2897 scoped_ptr<SpdyFrame> stream2_body2(
2898 new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
2899 scoped_ptr<SpdyFrame> stream2_body3(
2900 new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
2901 kChunkSize, false));
2902 scoped_ptr<SpdyFrame> stream2_body4(
2903 new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
2904 stream2_body_base->size() - 3 * kChunkSize, false));
2905 MockRead reads[] = {
2906 CreateMockRead(*stream1_reply, 2),
2907 CreateMockRead(*stream2_syn, 3),
2908 CreateMockRead(*stream2_body1, 4),
2909 CreateMockRead(*stream2_body2, 5),
2910 CreateMockRead(*stream2_body3, 6),
2911 CreateMockRead(*stream2_body4, 7),
2912 CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
2913 MockRead(ASYNC, ERR_IO_PENDING, 9), // Force a pause
2914 };
2915
2916 HttpResponseInfo response;
2917 HttpResponseInfo response2;
2918 std::string expected_push_result("pushed my darling hello my baby");
2919 OrderedSocketData data(reads, arraysize(reads),
2920 writes, arraysize(writes));
2921 RunServerPushTest(&data, &response, &response2, kPushedData);
2922
2923 // Verify the SYN_REPLY.
2924 EXPECT_TRUE(response.headers.get() != NULL);
2925 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
2926
2927 // Verify the pushed stream.
2928 EXPECT_TRUE(response2.headers.get() != NULL);
2929 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
2930 }
2931
2932 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
2933 scoped_ptr<SpdyFrame> stream1_syn(
2934 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
2935 scoped_ptr<SpdyFrame> stream1_body(
3352 spdy_util_.ConstructSpdyBodyFrame(1, true)); 2936 spdy_util_.ConstructSpdyBodyFrame(1, true));
3353 MockWrite writes[] = { 2937 MockWrite writes[] = {
3354 CreateMockWrite(*stream1_syn, 1), 2938 CreateMockWrite(*stream1_syn, 1),
3355 }; 2939 };
3356 2940
3357 scoped_ptr<SpdyFrame> 2941 scoped_ptr<SpdyFrame>
3358 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 2942 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3359 scoped_ptr<SpdyFrame> 2943 scoped_ptr<SpdyFrame>
3360 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 2944 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3361 0, 2945 0,
3362 2, 2946 2,
3363 1, 2947 1,
3364 "http://www.google.com/foo.dat")); 2948 "http://www.google.com/foo.dat"));
2949 static const char kPushedData[] = "pushed my darling hello my baby";
2950 scoped_ptr<SpdyFrame> stream2_body_base(
2951 spdy_util_.ConstructSpdyBodyFrame(
2952 2, kPushedData, strlen(kPushedData), true));
2953 const size_t kChunkSize = strlen(kPushedData) / 4;
2954 scoped_ptr<SpdyFrame> stream2_body1(
2955 new SpdyFrame(stream2_body_base->data(), kChunkSize, false));
2956 scoped_ptr<SpdyFrame> stream2_body2(
2957 new SpdyFrame(stream2_body_base->data() + kChunkSize, kChunkSize, false));
2958 scoped_ptr<SpdyFrame> stream2_body3(
2959 new SpdyFrame(stream2_body_base->data() + 2 * kChunkSize,
2960 kChunkSize, false));
2961 scoped_ptr<SpdyFrame> stream2_body4(
2962 new SpdyFrame(stream2_body_base->data() + 3 * kChunkSize,
2963 stream2_body_base->size() - 3 * kChunkSize, false));
3365 MockRead reads[] = { 2964 MockRead reads[] = {
3366 CreateMockRead(*stream1_reply, 2), 2965 CreateMockRead(*stream1_reply, 2),
3367 CreateMockRead(*stream2_syn, 3), 2966 CreateMockRead(*stream2_syn, 3),
3368 CreateMockRead(*stream1_body, 4, SYNCHRONOUS), 2967 CreateMockRead(*stream2_body1, 4),
3369 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame), 2968 CreateMockRead(*stream2_body2, 5),
3370 arraysize(kPushBodyFrame), 5),
3371 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause 2969 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
2970 CreateMockRead(*stream2_body3, 7),
2971 CreateMockRead(*stream2_body4, 8),
2972 CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
2973 MockRead(ASYNC, ERR_IO_PENDING, 10) // Force a pause.
3372 }; 2974 };
3373 2975
3374 HttpResponseInfo response; 2976 HttpResponseInfo response;
3375 HttpResponseInfo response2; 2977 HttpResponseInfo response2;
3376 std::string expected_push_result("pushed");
3377 OrderedSocketData data(reads, arraysize(reads), 2978 OrderedSocketData data(reads, arraysize(reads),
3378 writes, arraysize(writes)); 2979 writes, arraysize(writes));
3379 RunServerPushTest(&data, 2980 RunServerPushTest(&data, &response, &response2, kPushedData);
3380 &response,
3381 &response2,
3382 expected_push_result);
3383 2981
3384 // Verify the SYN_REPLY. 2982 // Verify the SYN_REPLY.
3385 EXPECT_TRUE(response.headers.get() != NULL); 2983 EXPECT_TRUE(response.headers.get() != NULL);
3386 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 2984 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3387 2985
3388 // Verify the pushed stream. 2986 // Verify the pushed stream.
3389 EXPECT_TRUE(response2.headers.get() != NULL); 2987 EXPECT_TRUE(response2.headers.get() != NULL);
3390 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 2988 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3391 } 2989 }
3392 2990
3393 TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) { 2991 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
3394 if (GetParam().protocol > kProtoSPDY3)
3395 return;
3396
3397 static const unsigned char kPushBodyFrame[] = {
3398 0x00, 0x00, 0x00, 0x02, // header, ID
3399 0x01, 0x00, 0x00, 0x06, // FIN, length
3400 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3401 };
3402 scoped_ptr<SpdyFrame> stream1_syn( 2992 scoped_ptr<SpdyFrame> stream1_syn(
3403 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 2993 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3404 scoped_ptr<SpdyFrame> stream1_body( 2994 scoped_ptr<SpdyFrame> stream1_body(
3405 spdy_util_.ConstructSpdyBodyFrame(1, true)); 2995 spdy_util_.ConstructSpdyBodyFrame(1, true));
2996 scoped_ptr<SpdyFrame> stream2_rst(
2997 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
3406 MockWrite writes[] = { 2998 MockWrite writes[] = {
3407 CreateMockWrite(*stream1_syn, 1), 2999 CreateMockWrite(*stream1_syn, 1),
3000 CreateMockWrite(*stream2_rst, 4),
3408 }; 3001 };
3409 3002
3410 scoped_ptr<SpdyFrame> 3003 scoped_ptr<SpdyFrame>
3411 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3004 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3412 scoped_ptr<SpdyFrame> 3005 scoped_ptr<SpdyFrame>
3413 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 3006 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3414 0, 3007 0,
3415 2, 3008 2,
3416 1, 3009 0,
3417 "http://www.google.com/foo.dat")); 3010 "http://www.google.com/foo.dat"));
3418 MockRead reads[] = { 3011 MockRead reads[] = {
3419 CreateMockRead(*stream2_syn, 2),
3420 CreateMockRead(*stream1_reply, 3),
3421 CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
3422 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
3423 arraysize(kPushBodyFrame), 5),
3424 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
3425 };
3426
3427 HttpResponseInfo response;
3428 HttpResponseInfo response2;
3429 std::string expected_push_result("pushed");
3430 OrderedSocketData data(reads, arraysize(reads),
3431 writes, arraysize(writes));
3432 RunServerPushTest(&data,
3433 &response,
3434 &response2,
3435 expected_push_result);
3436
3437 // Verify the SYN_REPLY.
3438 EXPECT_TRUE(response.headers.get() != NULL);
3439 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3440
3441 // Verify the pushed stream.
3442 EXPECT_TRUE(response2.headers.get() != NULL);
3443 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3444 }
3445
3446 TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) {
3447 if (GetParam().protocol > kProtoSPDY3)
3448 return;
3449
3450 static const unsigned char kPushBodyFrame[] = {
3451 0x00, 0x00, 0x00, 0x02, // header, ID
3452 0x01, 0x00, 0x00, 0x06, // FIN, length
3453 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3454 };
3455 scoped_ptr<SpdyFrame> stream1_syn(
3456 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3457 MockWrite writes[] = { CreateMockWrite(*stream1_syn, 1), };
3458
3459 scoped_ptr<SpdyFrame>
3460 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3461 scoped_ptr<SpdyFrame>
3462 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3463 0,
3464 2,
3465 1,
3466 "http://www.google.com/foo.dat"));
3467 scoped_ptr<SpdyFrame>
3468 stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
3469 MockRead reads[] = {
3470 CreateMockRead(*stream1_reply, 2), 3012 CreateMockRead(*stream1_reply, 2),
3471 CreateMockRead(*stream2_syn, 3), 3013 CreateMockRead(*stream2_syn, 3),
3472 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame), 3014 CreateMockRead(*stream1_body, 4),
3473 arraysize(kPushBodyFrame), 5), 3015 MockRead(ASYNC, ERR_IO_PENDING, 5) // Force a pause
3474 CreateMockRead(*stream1_body, 4, SYNCHRONOUS),
3475 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
3476 };
3477
3478 HttpResponseInfo response;
3479 HttpResponseInfo response2;
3480 std::string expected_push_result("pushed");
3481 OrderedSocketData data(reads, arraysize(reads),
3482 writes, arraysize(writes));
3483 RunServerPushTest(&data,
3484 &response,
3485 &response2,
3486 expected_push_result);
3487
3488 // Verify the SYN_REPLY.
3489 EXPECT_TRUE(response.headers.get() != NULL);
3490 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3491
3492 // Verify the pushed stream.
3493 EXPECT_TRUE(response2.headers.get() != NULL);
3494 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3495 }
3496
3497 TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) {
3498 if (GetParam().protocol > kProtoSPDY3)
3499 return;
3500
3501 scoped_ptr<SpdyFrame> stream1_syn(
3502 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3503 scoped_ptr<SpdyFrame> stream1_body(
3504 spdy_util_.ConstructSpdyBodyFrame(1, true));
3505 MockWrite writes[] = {
3506 CreateMockWrite(*stream1_syn, 1),
3507 };
3508
3509 scoped_ptr<SpdyFrame>
3510 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3511 scoped_ptr<SpdyFrame>
3512 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3513 0,
3514 2,
3515 1,
3516 "http://www.google.com/foo.dat"));
3517 scoped_ptr<SpdyFrame> stream2_rst(
3518 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
3519 MockRead reads[] = {
3520 CreateMockRead(*stream1_reply, 2),
3521 CreateMockRead(*stream2_syn, 3),
3522 CreateMockRead(*stream2_rst, 4),
3523 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
3524 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
3525 }; 3016 };
3526 3017
3527 OrderedSocketData data(reads, arraysize(reads), 3018 OrderedSocketData data(reads, arraysize(reads),
3528 writes, arraysize(writes)); 3019 writes, arraysize(writes));
3529 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3020 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3530 BoundNetLog(), GetParam(), NULL); 3021 BoundNetLog(), GetParam(), NULL);
3531 3022
3532 helper.RunPreTestSetup(); 3023 helper.RunPreTestSetup();
3533 helper.AddData(&data); 3024 helper.AddData(&data);
3534 3025
(...skipping 16 matching lines...) Expand all
3551 << data.write_count() 3042 << data.write_count()
3552 << " Write index: " 3043 << " Write index: "
3553 << data.write_index(); 3044 << data.write_index();
3554 3045
3555 // Verify the SYN_REPLY. 3046 // Verify the SYN_REPLY.
3556 HttpResponseInfo response = *trans->GetResponseInfo(); 3047 HttpResponseInfo response = *trans->GetResponseInfo();
3557 EXPECT_TRUE(response.headers.get() != NULL); 3048 EXPECT_TRUE(response.headers.get() != NULL);
3558 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3049 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3559 } 3050 }
3560 3051
3561 TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { 3052 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
3562 if (GetParam().protocol > kProtoSPDY3)
3563 return;
3564
3565 // Verify that we don't leak streams and that we properly send a reset
3566 // if the server pushes the same stream twice.
3567 static const unsigned char kPushBodyFrame[] = {
3568 0x00, 0x00, 0x00, 0x02, // header, ID
3569 0x01, 0x00, 0x00, 0x06, // FIN, length
3570 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3571 };
3572
3573 scoped_ptr<SpdyFrame> stream1_syn(
3574 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3575 scoped_ptr<SpdyFrame> stream1_body(
3576 spdy_util_.ConstructSpdyBodyFrame(1, true));
3577 scoped_ptr<SpdyFrame> stream3_rst(
3578 spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR));
3579 MockWrite writes[] = {
3580 CreateMockWrite(*stream1_syn, 1),
3581 CreateMockWrite(*stream3_rst, 5),
3582 };
3583
3584 scoped_ptr<SpdyFrame>
3585 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3586 scoped_ptr<SpdyFrame>
3587 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3588 0,
3589 2,
3590 1,
3591 "http://www.google.com/foo.dat"));
3592 scoped_ptr<SpdyFrame>
3593 stream3_syn(spdy_util_.ConstructSpdyPush(NULL,
3594 0,
3595 4,
3596 1,
3597 "http://www.google.com/foo.dat"));
3598 MockRead reads[] = {
3599 CreateMockRead(*stream1_reply, 2),
3600 CreateMockRead(*stream2_syn, 3),
3601 CreateMockRead(*stream3_syn, 4),
3602 CreateMockRead(*stream1_body, 6, SYNCHRONOUS),
3603 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
3604 arraysize(kPushBodyFrame), 7),
3605 MockRead(ASYNC, ERR_IO_PENDING, 8), // Force a pause
3606 };
3607
3608 HttpResponseInfo response;
3609 HttpResponseInfo response2;
3610 std::string expected_push_result("pushed");
3611 OrderedSocketData data(reads, arraysize(reads),
3612 writes, arraysize(writes));
3613 RunServerPushTest(&data,
3614 &response,
3615 &response2,
3616 expected_push_result);
3617
3618 // Verify the SYN_REPLY.
3619 EXPECT_TRUE(response.headers.get() != NULL);
3620 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3621
3622 // Verify the pushed stream.
3623 EXPECT_TRUE(response2.headers.get() != NULL);
3624 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3625 }
3626
3627 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) {
3628 if (GetParam().protocol > kProtoSPDY3)
3629 return;
3630
3631 static const unsigned char kPushBodyFrame1[] = {
3632 0x00, 0x00, 0x00, 0x02, // header, ID
3633 0x01, 0x00, 0x00, 0x1F, // FIN, length
3634 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3635 };
3636 static const char kPushBodyFrame2[] = " my darling";
3637 static const char kPushBodyFrame3[] = " hello";
3638 static const char kPushBodyFrame4[] = " my baby";
3639
3640 scoped_ptr<SpdyFrame> stream1_syn(
3641 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3642 scoped_ptr<SpdyFrame> stream1_body(
3643 spdy_util_.ConstructSpdyBodyFrame(1, true));
3644 MockWrite writes[] = {
3645 CreateMockWrite(*stream1_syn, 1),
3646 };
3647
3648 scoped_ptr<SpdyFrame>
3649 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3650 scoped_ptr<SpdyFrame>
3651 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3652 0,
3653 2,
3654 1,
3655 "http://www.google.com/foo.dat"));
3656 MockRead reads[] = {
3657 CreateMockRead(*stream1_reply, 2),
3658 CreateMockRead(*stream2_syn, 3),
3659 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
3660 arraysize(kPushBodyFrame1), 4),
3661 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
3662 arraysize(kPushBodyFrame2) - 1, 5),
3663 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
3664 arraysize(kPushBodyFrame3) - 1, 6),
3665 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
3666 arraysize(kPushBodyFrame4) - 1, 7),
3667 CreateMockRead(*stream1_body, 8, SYNCHRONOUS),
3668 MockRead(ASYNC, ERR_IO_PENDING, 9), // Force a pause
3669 };
3670
3671 HttpResponseInfo response;
3672 HttpResponseInfo response2;
3673 std::string expected_push_result("pushed my darling hello my baby");
3674 OrderedSocketData data(reads, arraysize(reads),
3675 writes, arraysize(writes));
3676 RunServerPushTest(&data,
3677 &response,
3678 &response2,
3679 expected_push_result);
3680
3681 // Verify the SYN_REPLY.
3682 EXPECT_TRUE(response.headers.get() != NULL);
3683 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3684
3685 // Verify the pushed stream.
3686 EXPECT_TRUE(response2.headers.get() != NULL);
3687 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3688 }
3689
3690 TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) {
3691 if (GetParam().protocol > kProtoSPDY3)
3692 return;
3693
3694 static const unsigned char kPushBodyFrame1[] = {
3695 0x00, 0x00, 0x00, 0x02, // header, ID
3696 0x01, 0x00, 0x00, 0x1F, // FIN, length
3697 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
3698 };
3699 static const char kPushBodyFrame2[] = " my darling";
3700 static const char kPushBodyFrame3[] = " hello";
3701 static const char kPushBodyFrame4[] = " my baby";
3702
3703 scoped_ptr<SpdyFrame> stream1_syn(
3704 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3705 scoped_ptr<SpdyFrame> stream1_body(
3706 spdy_util_.ConstructSpdyBodyFrame(1, true));
3707 MockWrite writes[] = {
3708 CreateMockWrite(*stream1_syn, 1),
3709 };
3710
3711 scoped_ptr<SpdyFrame>
3712 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3713 scoped_ptr<SpdyFrame>
3714 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3715 0,
3716 2,
3717 1,
3718 "http://www.google.com/foo.dat"));
3719 MockRead reads[] = {
3720 CreateMockRead(*stream1_reply, 2),
3721 CreateMockRead(*stream2_syn, 3),
3722 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame1),
3723 arraysize(kPushBodyFrame1), 4),
3724 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame2),
3725 arraysize(kPushBodyFrame2) - 1, 5),
3726 MockRead(ASYNC, ERR_IO_PENDING, 6), // Force a pause
3727 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame3),
3728 arraysize(kPushBodyFrame3) - 1, 7),
3729 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame4),
3730 arraysize(kPushBodyFrame4) - 1, 8),
3731 CreateMockRead(*stream1_body.get(), 9, SYNCHRONOUS),
3732 MockRead(ASYNC, ERR_IO_PENDING, 10) // Force a pause.
3733 };
3734
3735 HttpResponseInfo response;
3736 HttpResponseInfo response2;
3737 std::string expected_push_result("pushed my darling hello my baby");
3738 OrderedSocketData data(reads, arraysize(reads),
3739 writes, arraysize(writes));
3740 RunServerPushTest(&data,
3741 &response,
3742 &response2,
3743 expected_push_result);
3744
3745 // Verify the SYN_REPLY.
3746 EXPECT_TRUE(response.headers.get() != NULL);
3747 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3748
3749 // Verify the pushed stream.
3750 EXPECT_TRUE(response2.headers.get() != NULL);
3751 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
3752 }
3753
3754 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) {
3755 if (GetParam().protocol > kProtoSPDY3)
3756 return;
3757
3758 scoped_ptr<SpdyFrame> stream1_syn( 3053 scoped_ptr<SpdyFrame> stream1_syn(
3759 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3054 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3760 scoped_ptr<SpdyFrame> stream1_body( 3055 scoped_ptr<SpdyFrame> stream1_body(
3761 spdy_util_.ConstructSpdyBodyFrame(1, true)); 3056 spdy_util_.ConstructSpdyBodyFrame(1, true));
3762 scoped_ptr<SpdyFrame> stream2_rst( 3057 scoped_ptr<SpdyFrame> stream2_rst(
3763 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); 3058 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
3764 MockWrite writes[] = { 3059 MockWrite writes[] = {
3765 CreateMockWrite(*stream1_syn, 1), 3060 CreateMockWrite(*stream1_syn, 1),
3766 CreateMockWrite(*stream2_rst, 4), 3061 CreateMockWrite(*stream2_rst, 4),
3767 }; 3062 };
3768 3063
3769 scoped_ptr<SpdyFrame> 3064 scoped_ptr<SpdyFrame>
3770 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3065 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3771 scoped_ptr<SpdyFrame> 3066 scoped_ptr<SpdyFrame>
3772 stream2_syn(spdy_util_.ConstructSpdyPush(NULL, 3067 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3773 0, 3068 0,
3774 2, 3069 2,
3775 0, 3070 9,
3776 "http://www.google.com/foo.dat")); 3071 "http://www.google.com/foo.dat"));
3777 MockRead reads[] = { 3072 MockRead reads[] = {
3778 CreateMockRead(*stream1_reply, 2), 3073 CreateMockRead(*stream1_reply, 2),
3779 CreateMockRead(*stream2_syn, 3), 3074 CreateMockRead(*stream2_syn, 3),
3780 CreateMockRead(*stream1_body, 4), 3075 CreateMockRead(*stream1_body, 4),
3781 MockRead(ASYNC, ERR_IO_PENDING, 5) // Force a pause 3076 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
3782 }; 3077 };
3783 3078
3784 OrderedSocketData data(reads, arraysize(reads), 3079 OrderedSocketData data(reads, arraysize(reads),
3785 writes, arraysize(writes)); 3080 writes, arraysize(writes));
3786 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3081 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3787 BoundNetLog(), GetParam(), NULL); 3082 BoundNetLog(), GetParam(), NULL);
3788 3083
3789 helper.RunPreTestSetup(); 3084 helper.RunPreTestSetup();
3790 helper.AddData(&data); 3085 helper.AddData(&data);
3791 3086
(...skipping 16 matching lines...) Expand all
3808 << data.write_count() 3103 << data.write_count()
3809 << " Write index: " 3104 << " Write index: "
3810 << data.write_index(); 3105 << data.write_index();
3811 3106
3812 // Verify the SYN_REPLY. 3107 // Verify the SYN_REPLY.
3813 HttpResponseInfo response = *trans->GetResponseInfo(); 3108 HttpResponseInfo response = *trans->GetResponseInfo();
3814 EXPECT_TRUE(response.headers.get() != NULL); 3109 EXPECT_TRUE(response.headers.get() != NULL);
3815 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3110 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3816 } 3111 }
3817 3112
3818 TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) {
3819 if (GetParam().protocol > kProtoSPDY3)
3820 return;
3821
3822 scoped_ptr<SpdyFrame> stream1_syn(
3823 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3824 scoped_ptr<SpdyFrame> stream1_body(
3825 spdy_util_.ConstructSpdyBodyFrame(1, true));
3826 scoped_ptr<SpdyFrame> stream2_rst(
3827 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM));
3828 MockWrite writes[] = {
3829 CreateMockWrite(*stream1_syn, 1),
3830 CreateMockWrite(*stream2_rst, 4),
3831 };
3832
3833 scoped_ptr<SpdyFrame>
3834 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
3835 scoped_ptr<SpdyFrame>
3836 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
3837 0,
3838 2,
3839 9,
3840 "http://www.google.com/foo.dat"));
3841 MockRead reads[] = {
3842 CreateMockRead(*stream1_reply, 2),
3843 CreateMockRead(*stream2_syn, 3),
3844 CreateMockRead(*stream1_body, 4),
3845 MockRead(ASYNC, ERR_IO_PENDING, 5), // Force a pause
3846 };
3847
3848 OrderedSocketData data(reads, arraysize(reads),
3849 writes, arraysize(writes));
3850 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
3851 BoundNetLog(), GetParam(), NULL);
3852
3853 helper.RunPreTestSetup();
3854 helper.AddData(&data);
3855
3856 HttpNetworkTransaction* trans = helper.trans();
3857
3858 // Start the transaction with basic parameters.
3859 TestCompletionCallback callback;
3860 int rv = trans->Start(
3861 &CreateGetRequest(), callback.callback(), BoundNetLog());
3862 EXPECT_EQ(ERR_IO_PENDING, rv);
3863 rv = callback.WaitForResult();
3864 EXPECT_EQ(OK, rv);
3865
3866 // Verify that we consumed all test data.
3867 EXPECT_TRUE(data.at_read_eof()) << "Read count: "
3868 << data.read_count()
3869 << " Read index: "
3870 << data.read_index();
3871 EXPECT_TRUE(data.at_write_eof()) << "Write count: "
3872 << data.write_count()
3873 << " Write index: "
3874 << data.write_index();
3875
3876 // Verify the SYN_REPLY.
3877 HttpResponseInfo response = *trans->GetResponseInfo();
3878 EXPECT_TRUE(response.headers.get() != NULL);
3879 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3880 }
3881
3882 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { 3113 TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) {
3883 if (GetParam().protocol > kProtoSPDY3)
3884 return;
3885
3886 scoped_ptr<SpdyFrame> stream1_syn( 3114 scoped_ptr<SpdyFrame> stream1_syn(
3887 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3115 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
3888 scoped_ptr<SpdyFrame> stream1_body( 3116 scoped_ptr<SpdyFrame> stream1_body(
3889 spdy_util_.ConstructSpdyBodyFrame(1, true)); 3117 spdy_util_.ConstructSpdyBodyFrame(1, true));
3890 scoped_ptr<SpdyFrame> stream2_rst( 3118 scoped_ptr<SpdyFrame> stream2_rst(
3891 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); 3119 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR));
3892 MockWrite writes[] = { 3120 MockWrite writes[] = {
3893 CreateMockWrite(*stream1_syn, 1), 3121 CreateMockWrite(*stream1_syn, 1),
3894 CreateMockWrite(*stream2_rst, 4), 3122 CreateMockWrite(*stream2_rst, 4),
3895 }; 3123 };
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
3945 3173
3946 // Verify the SYN_REPLY. 3174 // Verify the SYN_REPLY.
3947 HttpResponseInfo response = *trans->GetResponseInfo(); 3175 HttpResponseInfo response = *trans->GetResponseInfo();
3948 EXPECT_TRUE(response.headers.get() != NULL); 3176 EXPECT_TRUE(response.headers.get() != NULL);
3949 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 3177 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
3950 } 3178 }
3951 3179
3952 // Verify that various SynReply headers parse correctly through the 3180 // Verify that various SynReply headers parse correctly through the
3953 // HTTP layer. 3181 // HTTP layer.
3954 TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { 3182 TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) {
3955 if (GetParam().protocol > kProtoSPDY3)
3956 return;
3957
3958 struct SynReplyHeadersTests { 3183 struct SynReplyHeadersTests {
3959 int num_headers; 3184 int num_headers;
3960 const char* extra_headers[5]; 3185 const char* extra_headers[5];
3961 SpdyHeaderBlock expected_headers; 3186 SpdyHeaderBlock expected_headers;
3962 } test_cases[] = { 3187 } test_cases[] = {
3963 // This uses a multi-valued cookie header. 3188 // This uses a multi-valued cookie header.
3964 { 2, 3189 { 2,
3965 { "cookie", "val1", 3190 { "cookie", "val1",
3966 "cookie", "val2", // will get appended separated by NULL 3191 "cookie", "val2", // will get appended separated by NULL
3967 NULL 3192 NULL
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
4035 header_block[name] += value; 3260 header_block[name] += value;
4036 } 3261 }
4037 } 3262 }
4038 EXPECT_EQ(test_cases[i].expected_headers, header_block); 3263 EXPECT_EQ(test_cases[i].expected_headers, header_block);
4039 } 3264 }
4040 } 3265 }
4041 3266
4042 // Verify that various SynReply headers parse vary fields correctly 3267 // Verify that various SynReply headers parse vary fields correctly
4043 // through the HTTP layer, and the response matches the request. 3268 // through the HTTP layer, and the response matches the request.
4044 TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { 3269 TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) {
4045 if (GetParam().protocol > kProtoSPDY3)
4046 return;
4047
4048 static const SpdyHeaderInfo syn_reply_info = { 3270 static const SpdyHeaderInfo syn_reply_info = {
4049 SYN_REPLY, // Syn Reply 3271 SYN_REPLY, // Syn Reply
4050 1, // Stream ID 3272 1, // Stream ID
4051 0, // Associated Stream ID 3273 0, // Associated Stream ID
4052 ConvertRequestPriorityToSpdyPriority( 3274 ConvertRequestPriorityToSpdyPriority(
4053 LOWEST, spdy_util_.spdy_version()), 3275 LOWEST, spdy_util_.spdy_version()),
4054 kSpdyCredentialSlotUnused, 3276 kSpdyCredentialSlotUnused,
4055 CONTROL_FLAG_NONE, // Control Flags 3277 CONTROL_FLAG_NONE, // Control Flags
4056 false, // Compressed 3278 false, // Compressed
4057 RST_STREAM_INVALID, // Status 3279 RST_STREAM_INVALID, // Status
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
4207 test_cases[i].num_headers[1], 3429 test_cases[i].num_headers[1],
4208 &reply_headers); 3430 &reply_headers);
4209 std::string expected_reply = 3431 std::string expected_reply =
4210 spdy_util_.ConstructSpdyReplyString(reply_headers); 3432 spdy_util_.ConstructSpdyReplyString(reply_headers);
4211 EXPECT_EQ(expected_reply, lines) << i; 3433 EXPECT_EQ(expected_reply, lines) << i;
4212 } 3434 }
4213 } 3435 }
4214 3436
4215 // Verify that we don't crash on invalid SynReply responses. 3437 // Verify that we don't crash on invalid SynReply responses.
4216 TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { 3438 TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) {
4217 if (GetParam().protocol > kProtoSPDY3)
4218 return;
4219
4220 const SpdyHeaderInfo kSynStartHeader = { 3439 const SpdyHeaderInfo kSynStartHeader = {
4221 SYN_REPLY, // Kind = SynReply 3440 SYN_REPLY, // Kind = SynReply
4222 1, // Stream ID 3441 1, // Stream ID
4223 0, // Associated stream ID 3442 0, // Associated stream ID
4224 ConvertRequestPriorityToSpdyPriority( 3443 ConvertRequestPriorityToSpdyPriority(
4225 LOWEST, spdy_util_.spdy_version()), 3444 LOWEST, spdy_util_.spdy_version()),
4226 kSpdyCredentialSlotUnused, 3445 kSpdyCredentialSlotUnused,
4227 CONTROL_FLAG_NONE, // Control Flags 3446 CONTROL_FLAG_NONE, // Control Flags
4228 false, // Compressed 3447 false, // Compressed
4229 RST_STREAM_INVALID, // Status 3448 RST_STREAM_INVALID, // Status
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4282 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3501 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4283 BoundNetLog(), GetParam(), NULL); 3502 BoundNetLog(), GetParam(), NULL);
4284 helper.RunToCompletion(&data); 3503 helper.RunToCompletion(&data);
4285 TransactionHelperResult out = helper.output(); 3504 TransactionHelperResult out = helper.output();
4286 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3505 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
4287 } 3506 }
4288 } 3507 }
4289 3508
4290 // Verify that we don't crash on some corrupt frames. 3509 // Verify that we don't crash on some corrupt frames.
4291 TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { 3510 TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) {
4292 if (GetParam().protocol > kProtoSPDY3)
4293 return;
4294
4295 // This is the length field that's too short. 3511 // This is the length field that's too short.
4296 scoped_ptr<SpdyFrame> syn_reply_wrong_length( 3512 scoped_ptr<SpdyFrame> syn_reply_wrong_length(
4297 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3513 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4298 size_t wrong_size = syn_reply_wrong_length->size() - 4;
4299 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 3514 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
3515 size_t right_size =
3516 (spdy_util_.spdy_version() < SPDY4) ?
3517 syn_reply_wrong_length->size() - framer.GetControlFrameHeaderSize() :
3518 syn_reply_wrong_length->size();
3519 size_t wrong_size = right_size - 4;
4300 test::SetFrameLength(syn_reply_wrong_length.get(), 3520 test::SetFrameLength(syn_reply_wrong_length.get(),
4301 wrong_size - framer.GetControlFrameHeaderSize(), 3521 wrong_size,
4302 spdy_util_.spdy_version()); 3522 spdy_util_.spdy_version());
4303 3523
4304 struct SynReplyTests { 3524 struct SynReplyTests {
4305 const SpdyFrame* syn_reply; 3525 const SpdyFrame* syn_reply;
4306 } test_cases[] = { 3526 } test_cases[] = {
4307 { syn_reply_wrong_length.get(), }, 3527 { syn_reply_wrong_length.get(), },
4308 }; 3528 };
4309 3529
4310 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) { 3530 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_cases); ++i) {
4311 scoped_ptr<SpdyFrame> req( 3531 scoped_ptr<SpdyFrame> req(
(...skipping 13 matching lines...) Expand all
4325 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3545 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4326 BoundNetLog(), GetParam(), NULL); 3546 BoundNetLog(), GetParam(), NULL);
4327 helper.RunToCompletion(&data); 3547 helper.RunToCompletion(&data);
4328 TransactionHelperResult out = helper.output(); 3548 TransactionHelperResult out = helper.output();
4329 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3549 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
4330 } 3550 }
4331 } 3551 }
4332 3552
4333 // Test that we shutdown correctly on write errors. 3553 // Test that we shutdown correctly on write errors.
4334 TEST_P(SpdyNetworkTransactionTest, WriteError) { 3554 TEST_P(SpdyNetworkTransactionTest, WriteError) {
4335 if (GetParam().protocol > kProtoSPDY3)
4336 return;
4337
4338 scoped_ptr<SpdyFrame> req( 3555 scoped_ptr<SpdyFrame> req(
4339 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3556 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4340 MockWrite writes[] = { 3557 MockWrite writes[] = {
4341 // We'll write 10 bytes successfully 3558 // We'll write 10 bytes successfully
4342 MockWrite(ASYNC, req->data(), 10), 3559 MockWrite(ASYNC, req->data(), 10),
4343 // Followed by ERROR! 3560 // Followed by ERROR!
4344 MockWrite(ASYNC, ERR_FAILED), 3561 MockWrite(ASYNC, ERR_FAILED),
4345 }; 3562 };
4346 3563
4347 DelayedSocketData data(2, NULL, 0, 3564 DelayedSocketData data(2, NULL, 0,
4348 writes, arraysize(writes)); 3565 writes, arraysize(writes));
4349 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3566 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4350 BoundNetLog(), GetParam(), NULL); 3567 BoundNetLog(), GetParam(), NULL);
4351 helper.RunToCompletion(&data); 3568 helper.RunToCompletion(&data);
4352 TransactionHelperResult out = helper.output(); 3569 TransactionHelperResult out = helper.output();
4353 EXPECT_EQ(ERR_FAILED, out.rv); 3570 EXPECT_EQ(ERR_FAILED, out.rv);
4354 data.Reset(); 3571 data.Reset();
4355 } 3572 }
4356 3573
4357 // Test that partial writes work. 3574 // Test that partial writes work.
4358 TEST_P(SpdyNetworkTransactionTest, PartialWrite) { 3575 TEST_P(SpdyNetworkTransactionTest, PartialWrite) {
4359 if (GetParam().protocol > kProtoSPDY3)
4360 return;
4361
4362 // Chop the SYN_STREAM frame into 5 chunks. 3576 // Chop the SYN_STREAM frame into 5 chunks.
4363 scoped_ptr<SpdyFrame> req( 3577 scoped_ptr<SpdyFrame> req(
4364 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3578 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4365 const int kChunks = 5; 3579 const int kChunks = 5;
4366 scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks)); 3580 scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks));
4367 3581
4368 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3582 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4369 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3583 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4370 MockRead reads[] = { 3584 MockRead reads[] = {
4371 CreateMockRead(*resp), 3585 CreateMockRead(*resp),
4372 CreateMockRead(*body), 3586 CreateMockRead(*body),
4373 MockRead(ASYNC, 0, 0) // EOF 3587 MockRead(ASYNC, 0, 0) // EOF
4374 }; 3588 };
4375 3589
4376 DelayedSocketData data(kChunks, reads, arraysize(reads), 3590 DelayedSocketData data(kChunks, reads, arraysize(reads),
4377 writes.get(), kChunks); 3591 writes.get(), kChunks);
4378 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3592 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4379 BoundNetLog(), GetParam(), NULL); 3593 BoundNetLog(), GetParam(), NULL);
4380 helper.RunToCompletion(&data); 3594 helper.RunToCompletion(&data);
4381 TransactionHelperResult out = helper.output(); 3595 TransactionHelperResult out = helper.output();
4382 EXPECT_EQ(OK, out.rv); 3596 EXPECT_EQ(OK, out.rv);
4383 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3597 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4384 EXPECT_EQ("hello!", out.response_data); 3598 EXPECT_EQ("hello!", out.response_data);
4385 } 3599 }
4386 3600
4387 // In this test, we enable compression, but get a uncompressed SynReply from 3601 // In this test, we enable compression, but get a uncompressed SynReply from
4388 // the server. Verify that teardown is all clean. 3602 // the server. Verify that teardown is all clean.
4389 TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) { 3603 TEST_P(SpdyNetworkTransactionTest, DecompressFailureOnSynReply) {
4390 if (GetParam().protocol > kProtoSPDY3)
4391 return;
4392
4393 scoped_ptr<SpdyFrame> compressed( 3604 scoped_ptr<SpdyFrame> compressed(
4394 spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, LOWEST, true)); 3605 spdy_util_.ConstructSpdyGet(NULL, 0, true, 1, LOWEST, true));
4395 scoped_ptr<SpdyFrame> rst( 3606 scoped_ptr<SpdyFrame> rst(
4396 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); 3607 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
4397 MockWrite writes[] = { 3608 MockWrite writes[] = {
4398 CreateMockWrite(*compressed), 3609 CreateMockWrite(*compressed),
4399 }; 3610 };
4400 3611
4401 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3612 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4402 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3613 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4403 MockRead reads[] = { 3614 MockRead reads[] = {
4404 CreateMockRead(*resp), 3615 CreateMockRead(*resp),
4405 }; 3616 };
4406 3617
4407 DelayedSocketData data(1, reads, arraysize(reads), 3618 DelayedSocketData data(1, reads, arraysize(reads),
4408 writes, arraysize(writes)); 3619 writes, arraysize(writes));
4409 SpdySessionDependencies* session_deps = 3620 SpdySessionDependencies* session_deps =
4410 CreateSpdySessionDependencies(GetParam()); 3621 CreateSpdySessionDependencies(GetParam());
4411 session_deps->enable_compression = true; 3622 session_deps->enable_compression = true;
4412 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 3623 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
4413 BoundNetLog(), GetParam(), session_deps); 3624 BoundNetLog(), GetParam(), session_deps);
4414 helper.RunToCompletion(&data); 3625 helper.RunToCompletion(&data);
4415 TransactionHelperResult out = helper.output(); 3626 TransactionHelperResult out = helper.output();
4416 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv); 3627 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
4417 data.Reset(); 3628 data.Reset();
4418 } 3629 }
4419 3630
4420 // Test that the NetLog contains good data for a simple GET request. 3631 // Test that the NetLog contains good data for a simple GET request.
4421 TEST_P(SpdyNetworkTransactionTest, NetLog) { 3632 TEST_P(SpdyNetworkTransactionTest, NetLog) {
4422 if (GetParam().protocol > kProtoSPDY3)
4423 return;
4424
4425 static const char* const kExtraHeaders[] = { 3633 static const char* const kExtraHeaders[] = {
4426 "user-agent", "Chrome", 3634 "user-agent", "Chrome",
4427 }; 3635 };
4428 scoped_ptr<SpdyFrame> req( 3636 scoped_ptr<SpdyFrame> req(
4429 spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, false, 1, LOWEST, true)); 3637 spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, false, 1, LOWEST, true));
4430 MockWrite writes[] = { CreateMockWrite(*req) }; 3638 MockWrite writes[] = { CreateMockWrite(*req) };
4431 3639
4432 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3640 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4433 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 3641 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
4434 MockRead reads[] = { 3642 MockRead reads[] = {
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
4503 EXPECT_NE(header_list->end(), header_list->Find(header)) << 3711 EXPECT_NE(header_list->end(), header_list->Find(header)) <<
4504 "Header not found: " << *it; 3712 "Header not found: " << *it;
4505 } 3713 }
4506 } 3714 }
4507 3715
4508 // Since we buffer the IO from the stream to the renderer, this test verifies 3716 // Since we buffer the IO from the stream to the renderer, this test verifies
4509 // that when we read out the maximum amount of data (e.g. we received 50 bytes 3717 // that when we read out the maximum amount of data (e.g. we received 50 bytes
4510 // on the network, but issued a Read for only 5 of those bytes) that the data 3718 // on the network, but issued a Read for only 5 of those bytes) that the data
4511 // flow still works correctly. 3719 // flow still works correctly.
4512 TEST_P(SpdyNetworkTransactionTest, BufferFull) { 3720 TEST_P(SpdyNetworkTransactionTest, BufferFull) {
4513 if (GetParam().protocol > kProtoSPDY3)
4514 return;
4515
4516 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 3721 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4517 3722
4518 scoped_ptr<SpdyFrame> req( 3723 scoped_ptr<SpdyFrame> req(
4519 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3724 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4520 MockWrite writes[] = { CreateMockWrite(*req) }; 3725 MockWrite writes[] = { CreateMockWrite(*req) };
4521 3726
4522 // 2 data frames in a single read. 3727 // 2 data frames in a single read.
4523 scoped_ptr<SpdyFrame> data_frame_1( 3728 scoped_ptr<SpdyFrame> data_frame_1(
4524 framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE)); 3729 framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE));
4525 scoped_ptr<SpdyFrame> data_frame_2( 3730 scoped_ptr<SpdyFrame> data_frame_2(
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4600 3805
4601 EXPECT_EQ(OK, out.rv); 3806 EXPECT_EQ(OK, out.rv);
4602 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3807 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4603 EXPECT_EQ("goodbye world", out.response_data); 3808 EXPECT_EQ("goodbye world", out.response_data);
4604 } 3809 }
4605 3810
4606 // Verify that basic buffering works; when multiple data frames arrive 3811 // Verify that basic buffering works; when multiple data frames arrive
4607 // at the same time, ensure that we don't notify a read completion for 3812 // at the same time, ensure that we don't notify a read completion for
4608 // each data frame individually. 3813 // each data frame individually.
4609 TEST_P(SpdyNetworkTransactionTest, Buffering) { 3814 TEST_P(SpdyNetworkTransactionTest, Buffering) {
4610 if (GetParam().protocol > kProtoSPDY3)
4611 return;
4612
4613 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 3815 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4614 3816
4615 scoped_ptr<SpdyFrame> req( 3817 scoped_ptr<SpdyFrame> req(
4616 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3818 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4617 MockWrite writes[] = { CreateMockWrite(*req) }; 3819 MockWrite writes[] = { CreateMockWrite(*req) };
4618 3820
4619 // 4 data frames in a single read. 3821 // 4 data frames in a single read.
4620 scoped_ptr<SpdyFrame> data_frame( 3822 scoped_ptr<SpdyFrame> data_frame(
4621 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 3823 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4622 scoped_ptr<SpdyFrame> data_frame_fin( 3824 scoped_ptr<SpdyFrame> data_frame_fin(
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
4698 // Verify that we consumed all test data. 3900 // Verify that we consumed all test data.
4699 helper.VerifyDataConsumed(); 3901 helper.VerifyDataConsumed();
4700 3902
4701 EXPECT_EQ(OK, out.rv); 3903 EXPECT_EQ(OK, out.rv);
4702 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3904 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4703 EXPECT_EQ("messagemessagemessagemessage", out.response_data); 3905 EXPECT_EQ("messagemessagemessagemessage", out.response_data);
4704 } 3906 }
4705 3907
4706 // Verify the case where we buffer data but read it after it has been buffered. 3908 // Verify the case where we buffer data but read it after it has been buffered.
4707 TEST_P(SpdyNetworkTransactionTest, BufferedAll) { 3909 TEST_P(SpdyNetworkTransactionTest, BufferedAll) {
4708 if (GetParam().protocol > kProtoSPDY3)
4709 return;
4710
4711 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 3910 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4712 3911
4713 scoped_ptr<SpdyFrame> req( 3912 scoped_ptr<SpdyFrame> req(
4714 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 3913 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4715 MockWrite writes[] = { CreateMockWrite(*req) }; 3914 MockWrite writes[] = { CreateMockWrite(*req) };
4716 3915
4717 // 5 data frames in a single read. 3916 // 5 data frames in a single read.
4718 scoped_ptr<SpdyFrame> syn_reply( 3917 scoped_ptr<SpdyFrame> syn_reply(
4719 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 3918 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4720 // turn off FIN bit 3919 // turn off FIN bit
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
4795 // Verify that we consumed all test data. 3994 // Verify that we consumed all test data.
4796 helper.VerifyDataConsumed(); 3995 helper.VerifyDataConsumed();
4797 3996
4798 EXPECT_EQ(OK, out.rv); 3997 EXPECT_EQ(OK, out.rv);
4799 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line); 3998 EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
4800 EXPECT_EQ("messagemessagemessagemessage", out.response_data); 3999 EXPECT_EQ("messagemessagemessagemessage", out.response_data);
4801 } 4000 }
4802 4001
4803 // Verify the case where we buffer data and close the connection. 4002 // Verify the case where we buffer data and close the connection.
4804 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { 4003 TEST_P(SpdyNetworkTransactionTest, BufferedClosed) {
4805 if (GetParam().protocol > kProtoSPDY3)
4806 return;
4807
4808 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 4004 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4809 4005
4810 scoped_ptr<SpdyFrame> req( 4006 scoped_ptr<SpdyFrame> req(
4811 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4007 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4812 MockWrite writes[] = { CreateMockWrite(*req) }; 4008 MockWrite writes[] = { CreateMockWrite(*req) };
4813 4009
4814 // All data frames in a single read. 4010 // All data frames in a single read.
4815 // NOTE: We don't FIN the stream. 4011 // NOTE: We don't FIN the stream.
4816 scoped_ptr<SpdyFrame> data_frame( 4012 scoped_ptr<SpdyFrame> data_frame(
4817 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 4013 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
4889 // Flush the MessageLoop while the SpdySessionDependencies (in particular, the 4085 // Flush the MessageLoop while the SpdySessionDependencies (in particular, the
4890 // MockClientSocketFactory) are still alive. 4086 // MockClientSocketFactory) are still alive.
4891 base::MessageLoop::current()->RunUntilIdle(); 4087 base::MessageLoop::current()->RunUntilIdle();
4892 4088
4893 // Verify that we consumed all test data. 4089 // Verify that we consumed all test data.
4894 helper.VerifyDataConsumed(); 4090 helper.VerifyDataConsumed();
4895 } 4091 }
4896 4092
4897 // Verify the case where we buffer data and cancel the transaction. 4093 // Verify the case where we buffer data and cancel the transaction.
4898 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { 4094 TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) {
4899 if (GetParam().protocol > kProtoSPDY3)
4900 return;
4901
4902 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); 4095 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false);
4903 4096
4904 scoped_ptr<SpdyFrame> req( 4097 scoped_ptr<SpdyFrame> req(
4905 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4098 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
4906 MockWrite writes[] = { CreateMockWrite(*req) }; 4099 MockWrite writes[] = { CreateMockWrite(*req) };
4907 4100
4908 // NOTE: We don't FIN the stream. 4101 // NOTE: We don't FIN the stream.
4909 scoped_ptr<SpdyFrame> data_frame( 4102 scoped_ptr<SpdyFrame> data_frame(
4910 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); 4103 framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE));
4911 4104
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
4964 // to run for the final time. 4157 // to run for the final time.
4965 base::MessageLoop::current()->RunUntilIdle(); 4158 base::MessageLoop::current()->RunUntilIdle();
4966 4159
4967 // Verify that we consumed all test data. 4160 // Verify that we consumed all test data.
4968 helper.VerifyDataConsumed(); 4161 helper.VerifyDataConsumed();
4969 } 4162 }
4970 4163
4971 // Test that if the server requests persistence of settings, that we save 4164 // Test that if the server requests persistence of settings, that we save
4972 // the settings in the HttpServerProperties. 4165 // the settings in the HttpServerProperties.
4973 TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { 4166 TEST_P(SpdyNetworkTransactionTest, SettingsSaved) {
4974 if (GetParam().protocol > kProtoSPDY3)
4975 return;
4976
4977 static const SpdyHeaderInfo kSynReplyInfo = { 4167 static const SpdyHeaderInfo kSynReplyInfo = {
4978 SYN_REPLY, // Syn Reply 4168 SYN_REPLY, // Syn Reply
4979 1, // Stream ID 4169 1, // Stream ID
4980 0, // Associated Stream ID 4170 0, // Associated Stream ID
4981 ConvertRequestPriorityToSpdyPriority( 4171 ConvertRequestPriorityToSpdyPriority(
4982 LOWEST, spdy_util_.spdy_version()), 4172 LOWEST, spdy_util_.spdy_version()),
4983 kSpdyCredentialSlotUnused, 4173 kSpdyCredentialSlotUnused,
4984 CONTROL_FLAG_NONE, // Control Flags 4174 CONTROL_FLAG_NONE, // Control Flags
4985 false, // Compressed 4175 false, // Compressed
4986 RST_STREAM_INVALID, // Status 4176 RST_STREAM_INVALID, // Status
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
5071 EXPECT_TRUE(it3 != settings_map.end()); 4261 EXPECT_TRUE(it3 != settings_map.end());
5072 SettingsFlagsAndValue flags_and_value3 = it3->second; 4262 SettingsFlagsAndValue flags_and_value3 = it3->second;
5073 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first); 4263 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value3.first);
5074 EXPECT_EQ(kSampleValue3, flags_and_value3.second); 4264 EXPECT_EQ(kSampleValue3, flags_and_value3.second);
5075 } 4265 }
5076 } 4266 }
5077 4267
5078 // Test that when there are settings saved that they are sent back to the 4268 // Test that when there are settings saved that they are sent back to the
5079 // server upon session establishment. 4269 // server upon session establishment.
5080 TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { 4270 TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) {
5081 if (GetParam().protocol > kProtoSPDY3)
5082 return;
5083
5084 static const SpdyHeaderInfo kSynReplyInfo = { 4271 static const SpdyHeaderInfo kSynReplyInfo = {
5085 SYN_REPLY, // Syn Reply 4272 SYN_REPLY, // Syn Reply
5086 1, // Stream ID 4273 1, // Stream ID
5087 0, // Associated Stream ID 4274 0, // Associated Stream ID
5088 ConvertRequestPriorityToSpdyPriority( 4275 ConvertRequestPriorityToSpdyPriority(
5089 LOWEST, spdy_util_.spdy_version()), 4276 LOWEST, spdy_util_.spdy_version()),
5090 kSpdyCredentialSlotUnused, 4277 kSpdyCredentialSlotUnused,
5091 CONTROL_FLAG_NONE, // Control Flags 4278 CONTROL_FLAG_NONE, // Control Flags
5092 false, // Compressed 4279 false, // Compressed
5093 RST_STREAM_INVALID, // Status 4280 RST_STREAM_INVALID, // Status
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
5186 // Verify the second persisted setting. 4373 // Verify the second persisted setting.
5187 SettingsMap::const_iterator it2 = settings_map.find(kSampleId2); 4374 SettingsMap::const_iterator it2 = settings_map.find(kSampleId2);
5188 EXPECT_TRUE(it2 != settings_map.end()); 4375 EXPECT_TRUE(it2 != settings_map.end());
5189 SettingsFlagsAndValue flags_and_value2 = it2->second; 4376 SettingsFlagsAndValue flags_and_value2 = it2->second;
5190 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first); 4377 EXPECT_EQ(SETTINGS_FLAG_PERSISTED, flags_and_value2.first);
5191 EXPECT_EQ(kSampleValue2, flags_and_value2.second); 4378 EXPECT_EQ(kSampleValue2, flags_and_value2.second);
5192 } 4379 }
5193 } 4380 }
5194 4381
5195 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { 4382 TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) {
5196 if (GetParam().protocol > kProtoSPDY3)
5197 return;
5198
5199 scoped_ptr<SpdyFrame> req( 4383 scoped_ptr<SpdyFrame> req(
5200 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4384 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5201 MockWrite writes[] = { CreateMockWrite(*req) }; 4385 MockWrite writes[] = { CreateMockWrite(*req) };
5202 4386
5203 scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway()); 4387 scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway());
5204 MockRead reads[] = { 4388 MockRead reads[] = {
5205 CreateMockRead(*go_away), 4389 CreateMockRead(*go_away),
5206 MockRead(ASYNC, 0, 0), // EOF 4390 MockRead(ASYNC, 0, 0), // EOF
5207 }; 4391 };
5208 4392
5209 DelayedSocketData data(1, reads, arraysize(reads), 4393 DelayedSocketData data(1, reads, arraysize(reads),
5210 writes, arraysize(writes)); 4394 writes, arraysize(writes));
5211 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4395 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5212 BoundNetLog(), GetParam(), NULL); 4396 BoundNetLog(), GetParam(), NULL);
5213 helper.AddData(&data); 4397 helper.AddData(&data);
5214 helper.RunToCompletion(&data); 4398 helper.RunToCompletion(&data);
5215 TransactionHelperResult out = helper.output(); 4399 TransactionHelperResult out = helper.output();
5216 EXPECT_EQ(ERR_ABORTED, out.rv); 4400 EXPECT_EQ(ERR_ABORTED, out.rv);
5217 } 4401 }
5218 4402
5219 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { 4403 TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
5220 if (GetParam().protocol > kProtoSPDY3)
5221 return;
5222
5223 scoped_ptr<SpdyFrame> req( 4404 scoped_ptr<SpdyFrame> req(
5224 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4405 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5225 MockWrite writes[] = { CreateMockWrite(*req) }; 4406 MockWrite writes[] = { CreateMockWrite(*req) };
5226 4407
5227 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4408 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5228 MockRead reads[] = { 4409 MockRead reads[] = {
5229 CreateMockRead(*resp), 4410 CreateMockRead(*resp),
5230 MockRead(SYNCHRONOUS, 0, 0) // EOF 4411 MockRead(SYNCHRONOUS, 0, 0) // EOF
5231 }; 4412 };
5232 4413
(...skipping 19 matching lines...) Expand all
5252 EXPECT_TRUE(response->was_fetched_via_spdy); 4433 EXPECT_TRUE(response->was_fetched_via_spdy);
5253 out.rv = ReadTransaction(trans, &out.response_data); 4434 out.rv = ReadTransaction(trans, &out.response_data);
5254 EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv); 4435 EXPECT_EQ(ERR_CONNECTION_CLOSED, out.rv);
5255 4436
5256 // Verify that we consumed all test data. 4437 // Verify that we consumed all test data.
5257 helper.VerifyDataConsumed(); 4438 helper.VerifyDataConsumed();
5258 } 4439 }
5259 4440
5260 // Test to make sure we can correctly connect through a proxy. 4441 // Test to make sure we can correctly connect through a proxy.
5261 TEST_P(SpdyNetworkTransactionTest, ProxyConnect) { 4442 TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
5262 if (GetParam().protocol > kProtoSPDY3)
5263 return;
5264
5265 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4443 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5266 BoundNetLog(), GetParam(), NULL); 4444 BoundNetLog(), GetParam(), NULL);
5267 helper.session_deps().reset(CreateSpdySessionDependencies( 4445 helper.session_deps().reset(CreateSpdySessionDependencies(
5268 GetParam(), 4446 GetParam(),
5269 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"))); 4447 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")));
5270 helper.SetSession(make_scoped_refptr( 4448 helper.SetSession(make_scoped_refptr(
5271 SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get()))); 4449 SpdySessionDependencies::SpdyCreateSession(helper.session_deps().get())));
5272 helper.RunPreTestSetup(); 4450 helper.RunPreTestSetup();
5273 HttpNetworkTransaction* trans = helper.trans(); 4451 HttpNetworkTransaction* trans = helper.trans();
5274 4452
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
5358 std::string response_data; 4536 std::string response_data;
5359 ASSERT_EQ(OK, ReadTransaction(trans, &response_data)); 4537 ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
5360 EXPECT_EQ("hello!", response_data); 4538 EXPECT_EQ("hello!", response_data);
5361 helper.VerifyDataConsumed(); 4539 helper.VerifyDataConsumed();
5362 } 4540 }
5363 4541
5364 // Test to make sure we can correctly connect through a proxy to www.google.com, 4542 // Test to make sure we can correctly connect through a proxy to www.google.com,
5365 // if there already exists a direct spdy connection to www.google.com. See 4543 // if there already exists a direct spdy connection to www.google.com. See
5366 // http://crbug.com/49874 4544 // http://crbug.com/49874
5367 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { 4545 TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) {
5368 if (GetParam().protocol > kProtoSPDY3)
5369 return;
5370
5371 // When setting up the first transaction, we store the SpdySessionPool so that 4546 // When setting up the first transaction, we store the SpdySessionPool so that
5372 // we can use the same pool in the second transaction. 4547 // we can use the same pool in the second transaction.
5373 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 4548 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5374 BoundNetLog(), GetParam(), NULL); 4549 BoundNetLog(), GetParam(), NULL);
5375 4550
5376 // Use a proxy service which returns a proxy fallback list from DIRECT to 4551 // Use a proxy service which returns a proxy fallback list from DIRECT to
5377 // myproxy:70. For this test there will be no fallback, so it is equivalent 4552 // myproxy:70. For this test there will be no fallback, so it is equivalent
5378 // to simply DIRECT. The reason for appending the second proxy is to verify 4553 // to simply DIRECT. The reason for appending the second proxy is to verify
5379 // that the session pool key used does is just "DIRECT". 4554 // that the session pool key used does is just "DIRECT".
5380 helper.session_deps().reset(CreateSpdySessionDependencies( 4555 helper.session_deps().reset(CreateSpdySessionDependencies(
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after
5542 4717
5543 data.CompleteRead(); 4718 data.CompleteRead();
5544 helper_proxy.VerifyDataConsumed(); 4719 helper_proxy.VerifyDataConsumed();
5545 } 4720 }
5546 4721
5547 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction 4722 // When we get a TCP-level RST, we need to retry a HttpNetworkTransaction
5548 // on a new connection, if the connection was previously known to be good. 4723 // on a new connection, if the connection was previously known to be good.
5549 // This can happen when a server reboots without saying goodbye, or when 4724 // This can happen when a server reboots without saying goodbye, or when
5550 // we're behind a NAT that masked the RST. 4725 // we're behind a NAT that masked the RST.
5551 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { 4726 TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) {
5552 if (GetParam().protocol > kProtoSPDY3)
5553 return;
5554
5555 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4727 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5556 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4728 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
5557 MockRead reads[] = { 4729 MockRead reads[] = {
5558 CreateMockRead(*resp), 4730 CreateMockRead(*resp),
5559 CreateMockRead(*body), 4731 CreateMockRead(*body),
5560 MockRead(ASYNC, ERR_IO_PENDING), 4732 MockRead(ASYNC, ERR_IO_PENDING),
5561 MockRead(ASYNC, ERR_CONNECTION_RESET), 4733 MockRead(ASYNC, ERR_CONNECTION_RESET),
5562 }; 4734 };
5563 4735
5564 MockRead reads2[] = { 4736 MockRead reads2[] = {
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
5623 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine()); 4795 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
5624 EXPECT_EQ("hello!", response_data); 4796 EXPECT_EQ("hello!", response_data);
5625 } 4797 }
5626 4798
5627 helper.VerifyDataConsumed(); 4799 helper.VerifyDataConsumed();
5628 } 4800 }
5629 } 4801 }
5630 4802
5631 // Test that turning SPDY on and off works properly. 4803 // Test that turning SPDY on and off works properly.
5632 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { 4804 TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) {
5633 if (GetParam().protocol > kProtoSPDY3)
5634 return;
5635
5636 net::HttpStreamFactory::set_spdy_enabled(true); 4805 net::HttpStreamFactory::set_spdy_enabled(true);
5637 scoped_ptr<SpdyFrame> req( 4806 scoped_ptr<SpdyFrame> req(
5638 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4807 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5639 MockWrite spdy_writes[] = { CreateMockWrite(*req) }; 4808 MockWrite spdy_writes[] = { CreateMockWrite(*req) };
5640 4809
5641 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4810 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5642 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true)); 4811 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
5643 MockRead spdy_reads[] = { 4812 MockRead spdy_reads[] = {
5644 CreateMockRead(*resp), 4813 CreateMockRead(*resp),
5645 CreateMockRead(*body), 4814 CreateMockRead(*body),
(...skipping 24 matching lines...) Expand all
5670 TransactionHelperResult out2 = helper2.output(); 4839 TransactionHelperResult out2 = helper2.output();
5671 EXPECT_EQ(OK, out2.rv); 4840 EXPECT_EQ(OK, out2.rv);
5672 EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line); 4841 EXPECT_EQ("HTTP/1.1 200 OK", out2.status_line);
5673 EXPECT_EQ("hello from http", out2.response_data); 4842 EXPECT_EQ("hello from http", out2.response_data);
5674 4843
5675 net::HttpStreamFactory::set_spdy_enabled(true); 4844 net::HttpStreamFactory::set_spdy_enabled(true);
5676 } 4845 }
5677 4846
5678 // Tests that Basic authentication works over SPDY 4847 // Tests that Basic authentication works over SPDY
5679 TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { 4848 TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) {
5680 if (GetParam().protocol > kProtoSPDY3)
5681 return;
5682
5683 net::HttpStreamFactory::set_spdy_enabled(true); 4849 net::HttpStreamFactory::set_spdy_enabled(true);
5684 4850
5685 // The first request will be a bare GET, the second request will be a 4851 // The first request will be a bare GET, the second request will be a
5686 // GET with an Authorization header. 4852 // GET with an Authorization header.
5687 scoped_ptr<SpdyFrame> req_get( 4853 scoped_ptr<SpdyFrame> req_get(
5688 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4854 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5689 const char* const kExtraAuthorizationHeaders[] = { 4855 const char* const kExtraAuthorizationHeaders[] = {
5690 "authorization", "Basic Zm9vOmJhcg==" 4856 "authorization", "Basic Zm9vOmJhcg=="
5691 }; 4857 };
5692 scoped_ptr<SpdyFrame> req_get_authorization( 4858 scoped_ptr<SpdyFrame> req_get_authorization(
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
5763 // TODO(cbentzel): This is actually the same response object as before, but 4929 // TODO(cbentzel): This is actually the same response object as before, but
5764 // data has changed. 4930 // data has changed.
5765 const HttpResponseInfo* const response_restart = trans->GetResponseInfo(); 4931 const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
5766 ASSERT_TRUE(response_restart != NULL); 4932 ASSERT_TRUE(response_restart != NULL);
5767 ASSERT_TRUE(response_restart->headers.get() != NULL); 4933 ASSERT_TRUE(response_restart->headers.get() != NULL);
5768 EXPECT_EQ(200, response_restart->headers->response_code()); 4934 EXPECT_EQ(200, response_restart->headers->response_code());
5769 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL); 4935 EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
5770 } 4936 }
5771 4937
5772 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { 4938 TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) {
5773 if (GetParam().protocol > kProtoSPDY3)
5774 return;
5775
5776 static const unsigned char kPushBodyFrame[] = {
5777 0x00, 0x00, 0x00, 0x02, // header, ID
5778 0x01, 0x00, 0x00, 0x06, // FIN, length
5779 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
5780 };
5781 scoped_ptr<SpdyFrame> stream1_syn( 4939 scoped_ptr<SpdyFrame> stream1_syn(
5782 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 4940 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5783 scoped_ptr<SpdyFrame> stream1_body( 4941 scoped_ptr<SpdyFrame> stream1_body(
5784 spdy_util_.ConstructSpdyBodyFrame(1, true)); 4942 spdy_util_.ConstructSpdyBodyFrame(1, true));
5785 MockWrite writes[] = { 4943 MockWrite writes[] = {
5786 CreateMockWrite(*stream1_syn, 1), 4944 CreateMockWrite(*stream1_syn, 1),
5787 }; 4945 };
5788 4946
5789 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 4947 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5790 spdy_util_.AddUrlToHeaderBlock( 4948 spdy_util_.AddUrlToHeaderBlock(
(...skipping 15 matching lines...) Expand all
5806 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 4964 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5807 false, 4965 false,
5808 2, 4966 2,
5809 LOWEST, 4967 LOWEST,
5810 HEADERS, 4968 HEADERS,
5811 CONTROL_FLAG_NONE, 4969 CONTROL_FLAG_NONE,
5812 0)); 4970 0));
5813 4971
5814 scoped_ptr<SpdyFrame> 4972 scoped_ptr<SpdyFrame>
5815 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 4973 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
4974 const char kPushedData[] = "pushed";
4975 scoped_ptr<SpdyFrame> stream2_body(
4976 spdy_util_.ConstructSpdyBodyFrame(
4977 2, kPushedData, strlen(kPushedData), true));
5816 MockRead reads[] = { 4978 MockRead reads[] = {
5817 CreateMockRead(*stream1_reply, 2), 4979 CreateMockRead(*stream1_reply, 2),
5818 CreateMockRead(*stream2_syn, 3), 4980 CreateMockRead(*stream2_syn, 3),
5819 CreateMockRead(*stream2_headers, 4), 4981 CreateMockRead(*stream2_headers, 4),
5820 CreateMockRead(*stream1_body, 5, SYNCHRONOUS), 4982 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5821 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame), 4983 CreateMockRead(*stream2_body, 5),
5822 arraysize(kPushBodyFrame), 6),
5823 MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause 4984 MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause
5824 }; 4985 };
5825 4986
5826 HttpResponseInfo response; 4987 HttpResponseInfo response;
5827 HttpResponseInfo response2; 4988 HttpResponseInfo response2;
5828 std::string expected_push_result("pushed"); 4989 std::string expected_push_result("pushed");
5829 OrderedSocketData data(reads, arraysize(reads), 4990 OrderedSocketData data(reads, arraysize(reads),
5830 writes, arraysize(writes)); 4991 writes, arraysize(writes));
5831 RunServerPushTest(&data, 4992 RunServerPushTest(&data,
5832 &response, 4993 &response,
5833 &response2, 4994 &response2,
5834 expected_push_result); 4995 expected_push_result);
5835 4996
5836 // Verify the SYN_REPLY. 4997 // Verify the SYN_REPLY.
5837 EXPECT_TRUE(response.headers.get() != NULL); 4998 EXPECT_TRUE(response.headers.get() != NULL);
5838 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 4999 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5839 5000
5840 // Verify the pushed stream. 5001 // Verify the pushed stream.
5841 EXPECT_TRUE(response2.headers.get() != NULL); 5002 EXPECT_TRUE(response2.headers.get() != NULL);
5842 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine()); 5003 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5843 } 5004 }
5844 5005
5845 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { 5006 TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) {
5846 if (GetParam().protocol > kProtoSPDY3)
5847 return;
5848
5849 // We push a stream and attempt to claim it before the headers come down. 5007 // We push a stream and attempt to claim it before the headers come down.
5850 static const unsigned char kPushBodyFrame[] = {
5851 0x00, 0x00, 0x00, 0x02, // header, ID
5852 0x01, 0x00, 0x00, 0x06, // FIN, length
5853 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
5854 };
5855 scoped_ptr<SpdyFrame> stream1_syn( 5008 scoped_ptr<SpdyFrame> stream1_syn(
5856 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5009 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5857 scoped_ptr<SpdyFrame> stream1_body( 5010 scoped_ptr<SpdyFrame> stream1_body(
5858 spdy_util_.ConstructSpdyBodyFrame(1, true)); 5011 spdy_util_.ConstructSpdyBodyFrame(1, true));
5859 MockWrite writes[] = { 5012 MockWrite writes[] = {
5860 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), 5013 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5861 }; 5014 };
5862 5015
5863 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); 5016 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5864 spdy_util_.AddUrlToHeaderBlock( 5017 spdy_util_.AddUrlToHeaderBlock(
(...skipping 15 matching lines...) Expand all
5880 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(), 5033 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5881 false, 5034 false,
5882 2, 5035 2,
5883 LOWEST, 5036 LOWEST,
5884 HEADERS, 5037 HEADERS,
5885 CONTROL_FLAG_NONE, 5038 CONTROL_FLAG_NONE,
5886 0)); 5039 0));
5887 5040
5888 scoped_ptr<SpdyFrame> 5041 scoped_ptr<SpdyFrame>
5889 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5042 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5043 const char kPushedData[] = "pushed";
5044 scoped_ptr<SpdyFrame> stream2_body(
5045 spdy_util_.ConstructSpdyBodyFrame(
5046 2, kPushedData, strlen(kPushedData), true));
5890 MockRead reads[] = { 5047 MockRead reads[] = {
5891 CreateMockRead(*stream1_reply, 1), 5048 CreateMockRead(*stream1_reply, 1),
5892 CreateMockRead(*stream2_syn, 2), 5049 CreateMockRead(*stream2_syn, 2),
5893 CreateMockRead(*stream1_body, 3), 5050 CreateMockRead(*stream1_body, 3),
5894 CreateMockRead(*stream2_headers, 4), 5051 CreateMockRead(*stream2_headers, 4),
5895 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame), 5052 CreateMockRead(*stream2_body, 5),
5896 arraysize(kPushBodyFrame), 5),
5897 MockRead(ASYNC, 0, 6), // EOF 5053 MockRead(ASYNC, 0, 6), // EOF
5898 }; 5054 };
5899 5055
5900 HttpResponseInfo response; 5056 HttpResponseInfo response;
5901 HttpResponseInfo response2; 5057 HttpResponseInfo response2;
5902 std::string expected_push_result("pushed"); 5058 std::string expected_push_result("pushed");
5903 DeterministicSocketData data(reads, arraysize(reads), 5059 DeterministicSocketData data(reads, arraysize(reads),
5904 writes, arraysize(writes)); 5060 writes, arraysize(writes));
5905 5061
5906 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5062 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5907 BoundNetLog(), GetParam(), NULL); 5063 BoundNetLog(), GetParam(), NULL);
5908 helper.SetDeterministic(); 5064 helper.SetDeterministic();
5909 helper.AddDeterministicData(&data); 5065 helper.AddDeterministicData(&data);
5066 helper.RunPreTestSetup();
5067
5068 HttpNetworkTransaction* trans = helper.trans();
5069
5070 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5071 // and the body of the primary stream, but before we've received the HEADERS
5072 // for the pushed stream.
5073 data.SetStop(3);
5074
5075 // Start the transaction.
5076 TestCompletionCallback callback;
5077 int rv = trans->Start(
5078 &CreateGetRequest(), callback.callback(), BoundNetLog());
5079 EXPECT_EQ(ERR_IO_PENDING, rv);
5080 data.Run();
5081 rv = callback.WaitForResult();
5082 EXPECT_EQ(0, rv);
5083
5084 // Request the pushed path. At this point, we've received the push, but the
5085 // headers are not yet complete.
5086 scoped_ptr<HttpNetworkTransaction> trans2(
5087 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5088 rv = trans2->Start(
5089 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5090 EXPECT_EQ(ERR_IO_PENDING, rv);
5091 data.RunFor(3);
5092 base::MessageLoop::current()->RunUntilIdle();
5093
5094 // Read the server push body.
5095 std::string result2;
5096 ReadResult(trans2.get(), &data, &result2);
5097 // Read the response body.
5098 std::string result;
5099 ReadResult(trans, &data, &result);
5100
5101 // Verify that the received push data is same as the expected push data.
5102 EXPECT_EQ(result2.compare(expected_push_result), 0)
5103 << "Received data: "
5104 << result2
5105 << "||||| Expected data: "
5106 << expected_push_result;
5107
5108 // Verify the SYN_REPLY.
5109 // Copy the response info, because trans goes away.
5110 response = *trans->GetResponseInfo();
5111 response2 = *trans2->GetResponseInfo();
5112
5113 VerifyStreamsClosed(helper);
5114
5115 // Verify the SYN_REPLY.
5116 EXPECT_TRUE(response.headers.get() != NULL);
5117 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5118
5119 // Verify the pushed stream.
5120 EXPECT_TRUE(response2.headers.get() != NULL);
5121 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5122
5123 // Read the final EOF (which will close the session)
5124 data.RunFor(1);
5125
5126 // Verify that we consumed all test data.
5127 EXPECT_TRUE(data.at_read_eof());
5128 EXPECT_TRUE(data.at_write_eof());
5129 }
5130
5131 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) {
5132 // We push a stream and attempt to claim it before the headers come down.
5133 scoped_ptr<SpdyFrame> stream1_syn(
5134 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5135 scoped_ptr<SpdyFrame> stream1_body(
5136 spdy_util_.ConstructSpdyBodyFrame(1, true));
5137 MockWrite writes[] = {
5138 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5139 };
5140
5141 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5142 spdy_util_.AddUrlToHeaderBlock(
5143 "http://www.google.com/foo.dat", initial_headers.get());
5144 scoped_ptr<SpdyFrame> stream2_syn(
5145 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5146 false,
5147 2,
5148 LOWEST,
5149 SYN_STREAM,
5150 CONTROL_FLAG_NONE,
5151 1));
5152
5153 scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5154 (*middle_headers)["hello"] = "bye";
5155 scoped_ptr<SpdyFrame> stream2_headers1(
5156 spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5157 false,
5158 2,
5159 LOWEST,
5160 HEADERS,
5161 CONTROL_FLAG_NONE,
5162 0));
5163
5164 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5165 (*late_headers)[spdy_util_.GetStatusKey()] = "200";
5166 (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5167 scoped_ptr<SpdyFrame> stream2_headers2(
5168 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5169 false,
5170 2,
5171 LOWEST,
5172 HEADERS,
5173 CONTROL_FLAG_NONE,
5174 0));
5175
5176 scoped_ptr<SpdyFrame>
5177 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5178 const char kPushedData[] = "pushed";
5179 scoped_ptr<SpdyFrame> stream2_body(
5180 spdy_util_.ConstructSpdyBodyFrame(
5181 2, kPushedData, strlen(kPushedData), true));
5182 MockRead reads[] = {
5183 CreateMockRead(*stream1_reply, 1),
5184 CreateMockRead(*stream2_syn, 2),
5185 CreateMockRead(*stream1_body, 3),
5186 CreateMockRead(*stream2_headers1, 4),
5187 CreateMockRead(*stream2_headers2, 5),
5188 CreateMockRead(*stream2_body, 6),
5189 MockRead(ASYNC, 0, 7), // EOF
5190 };
5191
5192 HttpResponseInfo response;
5193 HttpResponseInfo response2;
5194 std::string expected_push_result("pushed");
5195 DeterministicSocketData data(reads, arraysize(reads),
5196 writes, arraysize(writes));
5197
5198 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5199 BoundNetLog(), GetParam(), NULL);
5200 helper.SetDeterministic();
5201 helper.AddDeterministicData(&data);
5202 helper.RunPreTestSetup();
5203
5204 HttpNetworkTransaction* trans = helper.trans();
5205
5206 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5207 // the first HEADERS frame, and the body of the primary stream, but before
5208 // we've received the final HEADERS for the pushed stream.
5209 data.SetStop(4);
5210
5211 // Start the transaction.
5212 TestCompletionCallback callback;
5213 int rv = trans->Start(
5214 &CreateGetRequest(), callback.callback(), BoundNetLog());
5215 EXPECT_EQ(ERR_IO_PENDING, rv);
5216 data.Run();
5217 rv = callback.WaitForResult();
5218 EXPECT_EQ(0, rv);
5219
5220 // Request the pushed path. At this point, we've received the push, but the
5221 // headers are not yet complete.
5222 scoped_ptr<HttpNetworkTransaction> trans2(
5223 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5224 rv = trans2->Start(
5225 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5226 EXPECT_EQ(ERR_IO_PENDING, rv);
5227 data.RunFor(3);
5228 base::MessageLoop::current()->RunUntilIdle();
5229
5230 // Read the server push body.
5231 std::string result2;
5232 ReadResult(trans2.get(), &data, &result2);
5233 // Read the response body.
5234 std::string result;
5235 ReadResult(trans, &data, &result);
5236
5237 // Verify that the received push data is same as the expected push data.
5238 EXPECT_EQ(expected_push_result, result2);
5239
5240 // Verify the SYN_REPLY.
5241 // Copy the response info, because trans goes away.
5242 response = *trans->GetResponseInfo();
5243 response2 = *trans2->GetResponseInfo();
5244
5245 VerifyStreamsClosed(helper);
5246
5247 // Verify the SYN_REPLY.
5248 EXPECT_TRUE(response.headers.get() != NULL);
5249 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5250
5251 // Verify the pushed stream.
5252 EXPECT_TRUE(response2.headers.get() != NULL);
5253 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5254
5255 // Verify we got all the headers
5256 if (spdy_util_.spdy_version() < SPDY3) {
5257 EXPECT_TRUE(response2.headers->HasHeaderValue(
5258 "url",
5259 "http://www.google.com/foo.dat"));
5260 } else {
5261 EXPECT_TRUE(response2.headers->HasHeaderValue(
5262 "scheme", "http"));
5263 EXPECT_TRUE(response2.headers->HasHeaderValue(
5264 "host", "www.google.com"));
5265 EXPECT_TRUE(response2.headers->HasHeaderValue(
5266 "path", "/foo.dat"));
5267 }
5268 EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
5269 EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
5270 EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
5271
5272 // Read the final EOF (which will close the session)
5273 data.RunFor(1);
5274
5275 // Verify that we consumed all test data.
5276 EXPECT_TRUE(data.at_read_eof());
5277 EXPECT_TRUE(data.at_write_eof());
5278 }
5279
5280 TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
5281 // We push a stream and attempt to claim it before the headers come down.
5282 scoped_ptr<SpdyFrame> stream1_syn(
5283 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5284 scoped_ptr<SpdyFrame> stream1_body(
5285 spdy_util_.ConstructSpdyBodyFrame(1, true));
5286 MockWrite writes[] = {
5287 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5288 };
5289
5290 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5291 spdy_util_.AddUrlToHeaderBlock(
5292 "http://www.google.com/foo.dat", initial_headers.get());
5293 scoped_ptr<SpdyFrame> stream2_syn(
5294 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5295 false,
5296 2,
5297 LOWEST,
5298 SYN_STREAM,
5299 CONTROL_FLAG_NONE,
5300 1));
5301
5302 scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
5303 (*middle_headers)["hello"] = "bye";
5304 scoped_ptr<SpdyFrame> stream2_headers1(
5305 spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
5306 false,
5307 2,
5308 LOWEST,
5309 HEADERS,
5310 CONTROL_FLAG_NONE,
5311 0));
5312
5313 scoped_ptr<SpdyFrame>
5314 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5315 const char kPushedData[] = "pushed";
5316 scoped_ptr<SpdyFrame> stream2_body(
5317 spdy_util_.ConstructSpdyBodyFrame(
5318 2, kPushedData, strlen(kPushedData), true));
5319 MockRead reads[] = {
5320 CreateMockRead(*stream1_reply, 1),
5321 CreateMockRead(*stream2_syn, 2),
5322 CreateMockRead(*stream1_body, 3),
5323 CreateMockRead(*stream2_headers1, 4),
5324 CreateMockRead(*stream2_body, 5),
5325 MockRead(ASYNC, 0, 6), // EOF
5326 };
5327
5328 DeterministicSocketData data(reads, arraysize(reads),
5329 writes, arraysize(writes));
5330
5331 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5332 BoundNetLog(), GetParam(), NULL);
5333 helper.SetDeterministic();
5334 helper.AddDeterministicData(&data);
5335 helper.RunPreTestSetup();
5336
5337 HttpNetworkTransaction* trans = helper.trans();
5338
5339 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5340 // the first HEADERS frame, and the body of the primary stream, but before
5341 // we've received the final HEADERS for the pushed stream.
5342 data.SetStop(4);
5343
5344 // Start the transaction.
5345 TestCompletionCallback callback;
5346 int rv = trans->Start(
5347 &CreateGetRequest(), callback.callback(), BoundNetLog());
5348 EXPECT_EQ(ERR_IO_PENDING, rv);
5349 data.Run();
5350 rv = callback.WaitForResult();
5351 EXPECT_EQ(0, rv);
5352
5353 // Request the pushed path. At this point, we've received the push, but the
5354 // headers are not yet complete.
5355 scoped_ptr<HttpNetworkTransaction> trans2(
5356 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5357 rv = trans2->Start(
5358 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5359 EXPECT_EQ(ERR_IO_PENDING, rv);
5360 data.RunFor(2);
5361 base::MessageLoop::current()->RunUntilIdle();
5362
5363 // Read the server push body.
5364 std::string result2;
5365 ReadResult(trans2.get(), &data, &result2);
5366 // Read the response body.
5367 std::string result;
5368 ReadResult(trans, &data, &result);
5369 EXPECT_EQ("hello!", result);
5370
5371 // Verify that we haven't received any push data.
5372 EXPECT_EQ("", result2);
5373
5374 // Verify the SYN_REPLY.
5375 // Copy the response info, because trans goes away.
5376 HttpResponseInfo response = *trans->GetResponseInfo();
5377 ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
5378
5379 VerifyStreamsClosed(helper);
5380
5381 // Verify the SYN_REPLY.
5382 EXPECT_TRUE(response.headers.get() != NULL);
5383 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5384
5385 // Read the final EOF (which will close the session).
5386 data.RunFor(1);
5387
5388 // Verify that we consumed all test data.
5389 EXPECT_TRUE(data.at_read_eof());
5390 EXPECT_TRUE(data.at_write_eof());
5391 }
5392
5393 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
5394 scoped_ptr<SpdyFrame> req(
5395 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5396 scoped_ptr<SpdyFrame> rst(
5397 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5398 MockWrite writes[] = {
5399 CreateMockWrite(*req),
5400 CreateMockWrite(*rst),
5401 };
5402
5403 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5404 (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5405 (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5406 scoped_ptr<SpdyFrame> stream1_reply(
5407 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5408 false,
5409 1,
5410 LOWEST,
5411 SYN_REPLY,
5412 CONTROL_FLAG_NONE,
5413 0));
5414
5415 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5416 (*late_headers)["hello"] = "bye";
5417 scoped_ptr<SpdyFrame> stream1_headers(
5418 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5419 false,
5420 1,
5421 LOWEST,
5422 HEADERS,
5423 CONTROL_FLAG_NONE,
5424 0));
5425 scoped_ptr<SpdyFrame> stream1_body(
5426 spdy_util_.ConstructSpdyBodyFrame(1, true));
5427 MockRead reads[] = {
5428 CreateMockRead(*stream1_reply),
5429 CreateMockRead(*stream1_headers),
5430 CreateMockRead(*stream1_body),
5431 MockRead(ASYNC, 0, 0) // EOF
5432 };
5433
5434 DelayedSocketData data(1, reads, arraysize(reads),
5435 writes, arraysize(writes));
5436 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5437 BoundNetLog(), GetParam(), NULL);
5438 helper.RunToCompletion(&data);
5439 TransactionHelperResult out = helper.output();
5440 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5441 }
5442
5443 TEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) {
5444 scoped_ptr<SpdyFrame> req(
5445 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5446 scoped_ptr<SpdyFrame> rst(
5447 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
5448 MockWrite writes[] = {
5449 CreateMockWrite(*req),
5450 CreateMockWrite(*rst),
5451 };
5452
5453 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5454 (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
5455 (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
5456 scoped_ptr<SpdyFrame> stream1_reply(
5457 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5458 false,
5459 1,
5460 LOWEST,
5461 SYN_REPLY,
5462 CONTROL_FLAG_NONE,
5463 0));
5464
5465 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
5466 (*late_headers)["hello"] = "bye";
5467 scoped_ptr<SpdyFrame> stream1_headers(
5468 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
5469 false,
5470 1,
5471 LOWEST,
5472 HEADERS,
5473 CONTROL_FLAG_NONE,
5474 0));
5475 scoped_ptr<SpdyFrame> stream1_body(
5476 spdy_util_.ConstructSpdyBodyFrame(1, false));
5477 scoped_ptr<SpdyFrame> stream1_body2(
5478 spdy_util_.ConstructSpdyBodyFrame(1, true));
5479 MockRead reads[] = {
5480 CreateMockRead(*stream1_reply),
5481 CreateMockRead(*stream1_body),
5482 CreateMockRead(*stream1_headers),
5483 CreateMockRead(*stream1_body2),
5484 MockRead(ASYNC, 0, 0) // EOF
5485 };
5486
5487 DelayedSocketData data(1, reads, arraysize(reads),
5488 writes, arraysize(writes));
5489 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5490 BoundNetLog(), GetParam(), NULL);
5491 helper.RunToCompletion(&data);
5492 TransactionHelperResult out = helper.output();
5493 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
5494 }
5495
5496 TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
5497 // In this test we want to verify that we can't accidentally push content
5498 // which can't be pushed by this content server.
5499 // This test assumes that:
5500 // - if we're requesting http://www.foo.com/barbaz
5501 // - the browser has made a connection to "www.foo.com".
5502
5503 // A list of the URL to fetch, followed by the URL being pushed.
5504 static const char* const kTestCases[] = {
5505 "http://www.google.com/foo.html",
5506 "http://www.google.com:81/foo.js", // Bad port
5507
5508 "http://www.google.com/foo.html",
5509 "https://www.google.com/foo.js", // Bad protocol
5510
5511 "http://www.google.com/foo.html",
5512 "ftp://www.google.com/foo.js", // Invalid Protocol
5513
5514 "http://www.google.com/foo.html",
5515 "http://blat.www.google.com/foo.js", // Cross subdomain
5516
5517 "http://www.google.com/foo.html",
5518 "http://www.foo.com/foo.js", // Cross domain
5519 };
5520
5521 for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
5522 const char* url_to_fetch = kTestCases[index];
5523 const char* url_to_push = kTestCases[index + 1];
5524
5525 scoped_ptr<SpdyFrame> stream1_syn(
5526 spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
5527 scoped_ptr<SpdyFrame> stream1_body(
5528 spdy_util_.ConstructSpdyBodyFrame(1, true));
5529 scoped_ptr<SpdyFrame> push_rst(
5530 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
5531 MockWrite writes[] = {
5532 CreateMockWrite(*stream1_syn, 1),
5533 CreateMockWrite(*push_rst, 4),
5534 };
5535
5536 scoped_ptr<SpdyFrame>
5537 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5538 scoped_ptr<SpdyFrame>
5539 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
5540 0,
5541 2,
5542 1,
5543 url_to_push));
5544 const char kPushedData[] = "pushed";
5545 scoped_ptr<SpdyFrame> stream2_body(
5546 spdy_util_.ConstructSpdyBodyFrame(
5547 2, kPushedData, strlen(kPushedData), true));
5548 scoped_ptr<SpdyFrame> rst(
5549 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
5550
5551 MockRead reads[] = {
5552 CreateMockRead(*stream1_reply, 2),
5553 CreateMockRead(*stream2_syn, 3),
5554 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
5555 CreateMockRead(*stream2_body, 6),
5556 MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause
5557 };
5558
5559 HttpResponseInfo response;
5560 OrderedSocketData data(reads, arraysize(reads),
5561 writes, arraysize(writes));
5562
5563 HttpRequestInfo request;
5564 request.method = "GET";
5565 request.url = GURL(url_to_fetch);
5566 request.load_flags = 0;
5567
5568 // Enable cross-origin push. Since we are not using a proxy, this should
5569 // not actually enable cross-origin SPDY push.
5570 scoped_ptr<SpdySessionDependencies> session_deps(
5571 CreateSpdySessionDependencies(GetParam()));
5572 session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
5573 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5574 BoundNetLog(), GetParam(),
5575 session_deps.release());
5576 helper.RunPreTestSetup();
5577 helper.AddData(&data);
5578
5579 HttpNetworkTransaction* trans = helper.trans();
5580
5581 // Start the transaction with basic parameters.
5582 TestCompletionCallback callback;
5583
5584 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
5585 EXPECT_EQ(ERR_IO_PENDING, rv);
5586 rv = callback.WaitForResult();
5587
5588 // Read the response body.
5589 std::string result;
5590 ReadResult(trans, &data, &result);
5591
5592 // Verify that we consumed all test data.
5593 EXPECT_TRUE(data.at_read_eof());
5594 EXPECT_TRUE(data.at_write_eof());
5595
5596 // Verify the SYN_REPLY.
5597 // Copy the response info, because trans goes away.
5598 response = *trans->GetResponseInfo();
5599
5600 VerifyStreamsClosed(helper);
5601
5602 // Verify the SYN_REPLY.
5603 EXPECT_TRUE(response.headers.get() != NULL);
5604 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5605 }
5606 }
5607
5608 TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
5609 // Construct the request.
5610 scoped_ptr<SpdyFrame> req(
5611 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5612 scoped_ptr<SpdyFrame> req2(
5613 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
5614 MockWrite writes[] = {
5615 CreateMockWrite(*req, 1),
5616 CreateMockWrite(*req2, 3),
5617 };
5618
5619 scoped_ptr<SpdyFrame> refused(
5620 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
5621 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5622 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true));
5623 MockRead reads[] = {
5624 CreateMockRead(*refused, 2),
5625 CreateMockRead(*resp, 4),
5626 CreateMockRead(*body, 5),
5627 MockRead(ASYNC, 0, 6) // EOF
5628 };
5629
5630 OrderedSocketData data(reads, arraysize(reads),
5631 writes, arraysize(writes));
5632 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
5633 BoundNetLog(), GetParam(), NULL);
5634
5635 helper.RunPreTestSetup();
5636 helper.AddData(&data);
5637
5638 HttpNetworkTransaction* trans = helper.trans();
5639
5640 // Start the transaction with basic parameters.
5641 TestCompletionCallback callback;
5642 int rv = trans->Start(
5643 &CreateGetRequest(), callback.callback(), BoundNetLog());
5644 EXPECT_EQ(ERR_IO_PENDING, rv);
5645 rv = callback.WaitForResult();
5646 EXPECT_EQ(OK, rv);
5647
5648 // Verify that we consumed all test data.
5649 EXPECT_TRUE(data.at_read_eof()) << "Read count: "
5650 << data.read_count()
5651 << " Read index: "
5652 << data.read_index();
5653 EXPECT_TRUE(data.at_write_eof()) << "Write count: "
5654 << data.write_count()
5655 << " Write index: "
5656 << data.write_index();
5657
5658 // Verify the SYN_REPLY.
5659 HttpResponseInfo response = *trans->GetResponseInfo();
5660 EXPECT_TRUE(response.headers.get() != NULL);
5661 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5662 }
5663
5664 TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) {
5665 // This first request will start to establish the SpdySession.
5666 // Then we will start the second (MEDIUM priority) and then third
5667 // (HIGHEST priority) request in such a way that the third will actually
5668 // start before the second, causing the second to be numbered differently
5669 // than the order they were created.
5670 scoped_ptr<SpdyFrame> req1(
5671 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5672 scoped_ptr<SpdyFrame> req2(
5673 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true));
5674 scoped_ptr<SpdyFrame> req3(
5675 spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true));
5676 MockWrite writes[] = {
5677 CreateMockWrite(*req1, 0),
5678 CreateMockWrite(*req2, 3),
5679 CreateMockWrite(*req3, 4),
5680 };
5681
5682 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5683 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
5684 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
5685 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
5686 scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
5687 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
5688 MockRead reads[] = {
5689 CreateMockRead(*resp1, 1),
5690 CreateMockRead(*body1, 2),
5691 CreateMockRead(*resp2, 5),
5692 CreateMockRead(*body2, 6),
5693 CreateMockRead(*resp3, 7),
5694 CreateMockRead(*body3, 8),
5695 MockRead(ASYNC, 0, 9) // EOF
5696 };
5697
5698 DeterministicSocketData data(reads, arraysize(reads),
5699 writes, arraysize(writes));
5700 NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST,
5701 BoundNetLog(), GetParam(), NULL);
5702 helper.SetDeterministic();
5703 helper.RunPreTestSetup();
5704 helper.AddDeterministicData(&data);
5705
5706 // Start the first transaction to set up the SpdySession
5707 HttpNetworkTransaction* trans = helper.trans();
5708 TestCompletionCallback callback;
5709 HttpRequestInfo info1 = CreateGetRequest();
5710 int rv = trans->Start(&info1, callback.callback(), BoundNetLog());
5711 EXPECT_EQ(ERR_IO_PENDING, rv);
5712
5713 // Run the message loop, but do not allow the write to complete.
5714 // This leaves the SpdySession with a write pending, which prevents
5715 // SpdySession from attempting subsequent writes until this write completes.
5716 base::MessageLoop::current()->RunUntilIdle();
5717
5718 // Now, start both new transactions
5719 HttpRequestInfo info2 = CreateGetRequest();
5720 TestCompletionCallback callback2;
5721 scoped_ptr<HttpNetworkTransaction> trans2(
5722 new HttpNetworkTransaction(MEDIUM, helper.session().get()));
5723 rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
5724 EXPECT_EQ(ERR_IO_PENDING, rv);
5725 base::MessageLoop::current()->RunUntilIdle();
5726
5727 HttpRequestInfo info3 = CreateGetRequest();
5728 TestCompletionCallback callback3;
5729 scoped_ptr<HttpNetworkTransaction> trans3(
5730 new HttpNetworkTransaction(HIGHEST, helper.session().get()));
5731 rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
5732 EXPECT_EQ(ERR_IO_PENDING, rv);
5733 base::MessageLoop::current()->RunUntilIdle();
5734
5735 // We now have two SYN_STREAM frames queued up which will be
5736 // dequeued only once the first write completes, which we
5737 // now allow to happen.
5738 data.RunFor(2);
5739 EXPECT_EQ(OK, callback.WaitForResult());
5740
5741 // And now we can allow everything else to run to completion.
5742 data.SetStop(10);
5743 data.Run();
5744 EXPECT_EQ(OK, callback2.WaitForResult());
5745 EXPECT_EQ(OK, callback3.WaitForResult());
5746
5747 helper.VerifyDataConsumed();
5748 }
5749
5750 // The tests below are only for SPDY/3 and above.
5751
5752 // Test that sent data frames and received WINDOW_UPDATE frames change
5753 // the send_window_size_ correctly.
5754
5755 // WINDOW_UPDATE is different than most other frames in that it can arrive
5756 // while the client is still sending the request body. In order to enforce
5757 // this scenario, we feed a couple of dummy frames and give a delay of 0 to
5758 // socket data provider, so that initial read that is done as soon as the
5759 // stream is created, succeeds and schedules another read. This way reads
5760 // and writes are interleaved; after doing a full frame write, SpdyStream
5761 // will break out of DoLoop and will read and process a WINDOW_UPDATE.
5762 // Once our WINDOW_UPDATE is read, we cannot send SYN_REPLY right away
5763 // since request has not been completely written, therefore we feed
5764 // enough number of WINDOW_UPDATEs to finish the first read and cause a
5765 // write, leading to a complete write of request body; after that we send
5766 // a reply with a body, to cause a graceful shutdown.
5767
5768 // TODO(agayev): develop a socket data provider where both, reads and
5769 // writes are ordered so that writing tests like these are easy and rewrite
5770 // all these tests using it. Right now we are working around the
5771 // limitations as described above and it's not deterministic, tests may
5772 // fail under specific circumstances.
5773 TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) {
5774 if (GetParam().protocol < kProtoSPDY3)
5775 return;
5776
5777 static int kFrameCount = 2;
5778 scoped_ptr<std::string> content(
5779 new std::string(kMaxSpdyFrameChunkSize, 'a'));
5780 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
5781 kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
5782 scoped_ptr<SpdyFrame> body(
5783 spdy_util_.ConstructSpdyBodyFrame(
5784 1, content->c_str(), content->size(), false));
5785 scoped_ptr<SpdyFrame> body_end(
5786 spdy_util_.ConstructSpdyBodyFrame(
5787 1, content->c_str(), content->size(), true));
5788
5789 MockWrite writes[] = {
5790 CreateMockWrite(*req, 0),
5791 CreateMockWrite(*body, 1),
5792 CreateMockWrite(*body_end, 2),
5793 };
5794
5795 static const int32 kDeltaWindowSize = 0xff;
5796 static const int kDeltaCount = 4;
5797 scoped_ptr<SpdyFrame> window_update(
5798 spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
5799 scoped_ptr<SpdyFrame> window_update_dummy(
5800 spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize));
5801 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
5802 MockRead reads[] = {
5803 CreateMockRead(*window_update_dummy, 3),
5804 CreateMockRead(*window_update_dummy, 4),
5805 CreateMockRead(*window_update_dummy, 5),
5806 CreateMockRead(*window_update, 6), // Four updates, therefore window
5807 CreateMockRead(*window_update, 7), // size should increase by
5808 CreateMockRead(*window_update, 8), // kDeltaWindowSize * 4
5809 CreateMockRead(*window_update, 9),
5810 CreateMockRead(*resp, 10),
5811 CreateMockRead(*body_end, 11),
5812 MockRead(ASYNC, 0, 0, 12) // EOF
5813 };
5814
5815 DeterministicSocketData data(reads, arraysize(reads),
5816 writes, arraysize(writes));
5817
5818 ScopedVector<UploadElementReader> element_readers;
5819 for (int i = 0; i < kFrameCount; ++i) {
5820 element_readers.push_back(
5821 new UploadBytesElementReader(content->c_str(), content->size()));
5822 }
5823 UploadDataStream upload_data_stream(&element_readers, 0);
5824
5825 // Setup the request
5826 HttpRequestInfo request;
5827 request.method = "POST";
5828 request.url = GURL(kDefaultURL);
5829 request.upload_data_stream = &upload_data_stream;
5830
5831 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
5832 BoundNetLog(), GetParam(), NULL);
5833 helper.SetDeterministic();
5834 helper.AddDeterministicData(&data);
5910 helper.RunPreTestSetup(); 5835 helper.RunPreTestSetup();
5911 5836
5912 HttpNetworkTransaction* trans = helper.trans(); 5837 HttpNetworkTransaction* trans = helper.trans();
5913 5838
5914 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
5915 // and the body of the primary stream, but before we've received the HEADERS
5916 // for the pushed stream.
5917 data.SetStop(3);
5918
5919 // Start the transaction.
5920 TestCompletionCallback callback; 5839 TestCompletionCallback callback;
5921 int rv = trans->Start( 5840 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
5922 &CreateGetRequest(), callback.callback(), BoundNetLog()); 5841
5923 EXPECT_EQ(ERR_IO_PENDING, rv); 5842 EXPECT_EQ(ERR_IO_PENDING, rv);
5924 data.Run(); 5843
5844 data.RunFor(11);
5845
5846 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
5847 ASSERT_TRUE(stream != NULL);
5848 ASSERT_TRUE(stream->stream() != NULL);
5849 EXPECT_EQ(static_cast<int>(kSpdyStreamInitialWindowSize) +
5850 kDeltaWindowSize * kDeltaCount -
5851 kMaxSpdyFrameChunkSize * kFrameCount,
5852 stream->stream()->send_window_size());
5853
5854 data.RunFor(1);
5855
5925 rv = callback.WaitForResult(); 5856 rv = callback.WaitForResult();
5926 EXPECT_EQ(0, rv); 5857 EXPECT_EQ(OK, rv);
5927 5858
5928 // Request the pushed path. At this point, we've received the push, but the 5859 helper.VerifyDataConsumed();
5929 // headers are not yet complete.
5930 scoped_ptr<HttpNetworkTransaction> trans2(
5931 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
5932 rv = trans2->Start(
5933 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
5934 EXPECT_EQ(ERR_IO_PENDING, rv);
5935 data.RunFor(3);
5936 base::MessageLoop::current()->RunUntilIdle();
5937
5938 // Read the server push body.
5939 std::string result2;
5940 ReadResult(trans2.get(), &data, &result2);
5941 // Read the response body.
5942 std::string result;
5943 ReadResult(trans, &data, &result);
5944
5945 // Verify that the received push data is same as the expected push data.
5946 EXPECT_EQ(result2.compare(expected_push_result), 0)
5947 << "Received data: "
5948 << result2
5949 << "||||| Expected data: "
5950 << expected_push_result;
5951
5952 // Verify the SYN_REPLY.
5953 // Copy the response info, because trans goes away.
5954 response = *trans->GetResponseInfo();
5955 response2 = *trans2->GetResponseInfo();
5956
5957 VerifyStreamsClosed(helper);
5958
5959 // Verify the SYN_REPLY.
5960 EXPECT_TRUE(response.headers.get() != NULL);
5961 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
5962
5963 // Verify the pushed stream.
5964 EXPECT_TRUE(response2.headers.get() != NULL);
5965 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
5966
5967 // Read the final EOF (which will close the session)
5968 data.RunFor(1);
5969
5970 // Verify that we consumed all test data.
5971 EXPECT_TRUE(data.at_read_eof());
5972 EXPECT_TRUE(data.at_write_eof());
5973 } 5860 }
5974 5861
5975 TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { 5862 // Test that received data frames and sent WINDOW_UPDATE frames change
5976 if (GetParam().protocol > kProtoSPDY3) 5863 // the recv_window_size_ correctly.
5864 TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) {
5865 if (GetParam().protocol < kProtoSPDY3)
5977 return; 5866 return;
5978 5867
5979 // We push a stream and attempt to claim it before the headers come down. 5868 // Set the data in the body frame large enough to trigger sending a
5980 static const unsigned char kPushBodyFrame[] = { 5869 // WINDOW_UPDATE by the stream.
5981 0x00, 0x00, 0x00, 0x02, // header, ID 5870 const std::string body_data(kSpdyStreamInitialWindowSize / 2 + 1, 'x');
5982 0x01, 0x00, 0x00, 0x06, // FIN, length 5871
5983 'p', 'u', 's', 'h', 'e', 'd' // "pushed" 5872 scoped_ptr<SpdyFrame> req(
5873 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
5874 scoped_ptr<SpdyFrame> session_window_update(
5875 spdy_util_.ConstructSpdyWindowUpdate(0, body_data.size()));
5876 scoped_ptr<SpdyFrame> window_update(
5877 spdy_util_.ConstructSpdyWindowUpdate(1, body_data.size()));
5878
5879 std::vector<MockWrite> writes;
5880 writes.push_back(CreateMockWrite(*req));
5881 if (GetParam().protocol >= kProtoSPDY31)
5882 writes.push_back(CreateMockWrite(*session_window_update));
5883 writes.push_back(CreateMockWrite(*window_update));
5884
5885 scoped_ptr<SpdyFrame> resp(
5886 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
5887 scoped_ptr<SpdyFrame> body_no_fin(
5888 spdy_util_.ConstructSpdyBodyFrame(
5889 1, body_data.data(), body_data.size(), false));
5890 scoped_ptr<SpdyFrame> body_fin(
5891 spdy_util_.ConstructSpdyBodyFrame(1, NULL, 0, true));
5892 MockRead reads[] = {
5893 CreateMockRead(*resp),
5894 CreateMockRead(*body_no_fin),
5895 MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause
5896 CreateMockRead(*body_fin),
5897 MockRead(ASYNC, ERR_IO_PENDING, 0), // Force a pause
5898 MockRead(ASYNC, 0, 0) // EOF
5984 }; 5899 };
5985 scoped_ptr<SpdyFrame> stream1_syn( 5900
5986 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5901 DelayedSocketData data(1, reads, arraysize(reads),
5987 scoped_ptr<SpdyFrame> stream1_body( 5902 vector_as_array(&writes), writes.size());
5988 spdy_util_.ConstructSpdyBodyFrame(1, true));
5989 MockWrite writes[] = {
5990 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
5991 };
5992
5993 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
5994 spdy_util_.AddUrlToHeaderBlock(
5995 "http://www.google.com/foo.dat", initial_headers.get());
5996 scoped_ptr<SpdyFrame> stream2_syn(
5997 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
5998 false,
5999 2,
6000 LOWEST,
6001 SYN_STREAM,
6002 CONTROL_FLAG_NONE,
6003 1));
6004
6005 scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
6006 (*middle_headers)["hello"] = "bye";
6007 scoped_ptr<SpdyFrame> stream2_headers1(
6008 spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
6009 false,
6010 2,
6011 LOWEST,
6012 HEADERS,
6013 CONTROL_FLAG_NONE,
6014 0));
6015
6016 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
6017 (*late_headers)[spdy_util_.GetStatusKey()] = "200";
6018 (*late_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
6019 scoped_ptr<SpdyFrame> stream2_headers2(
6020 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
6021 false,
6022 2,
6023 LOWEST,
6024 HEADERS,
6025 CONTROL_FLAG_NONE,
6026 0));
6027
6028 scoped_ptr<SpdyFrame>
6029 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6030 MockRead reads[] = {
6031 CreateMockRead(*stream1_reply, 1),
6032 CreateMockRead(*stream2_syn, 2),
6033 CreateMockRead(*stream1_body, 3),
6034 CreateMockRead(*stream2_headers1, 4),
6035 CreateMockRead(*stream2_headers2, 5),
6036 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
6037 arraysize(kPushBodyFrame), 6),
6038 MockRead(ASYNC, 0, 7), // EOF
6039 };
6040
6041 HttpResponseInfo response;
6042 HttpResponseInfo response2;
6043 std::string expected_push_result("pushed");
6044 DeterministicSocketData data(reads, arraysize(reads),
6045 writes, arraysize(writes));
6046 5903
6047 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, 5904 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6048 BoundNetLog(), GetParam(), NULL); 5905 BoundNetLog(), GetParam(), NULL);
6049 helper.SetDeterministic(); 5906 helper.AddData(&data);
6050 helper.AddDeterministicData(&data);
6051 helper.RunPreTestSetup(); 5907 helper.RunPreTestSetup();
6052
6053 HttpNetworkTransaction* trans = helper.trans(); 5908 HttpNetworkTransaction* trans = helper.trans();
6054 5909
6055 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
6056 // the first HEADERS frame, and the body of the primary stream, but before
6057 // we've received the final HEADERS for the pushed stream.
6058 data.SetStop(4);
6059
6060 // Start the transaction.
6061 TestCompletionCallback callback; 5910 TestCompletionCallback callback;
6062 int rv = trans->Start( 5911 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6063 &CreateGetRequest(), callback.callback(), BoundNetLog()); 5912
6064 EXPECT_EQ(ERR_IO_PENDING, rv);
6065 data.Run();
6066 rv = callback.WaitForResult();
6067 EXPECT_EQ(0, rv);
6068
6069 // Request the pushed path. At this point, we've received the push, but the
6070 // headers are not yet complete.
6071 scoped_ptr<HttpNetworkTransaction> trans2(
6072 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
6073 rv = trans2->Start(
6074 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
6075 EXPECT_EQ(ERR_IO_PENDING, rv);
6076 data.RunFor(3);
6077 base::MessageLoop::current()->RunUntilIdle();
6078
6079 // Read the server push body.
6080 std::string result2;
6081 ReadResult(trans2.get(), &data, &result2);
6082 // Read the response body.
6083 std::string result;
6084 ReadResult(trans, &data, &result);
6085
6086 // Verify that the received push data is same as the expected push data.
6087 EXPECT_EQ(expected_push_result, result2);
6088
6089 // Verify the SYN_REPLY.
6090 // Copy the response info, because trans goes away.
6091 response = *trans->GetResponseInfo();
6092 response2 = *trans2->GetResponseInfo();
6093
6094 VerifyStreamsClosed(helper);
6095
6096 // Verify the SYN_REPLY.
6097 EXPECT_TRUE(response.headers.get() != NULL);
6098 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
6099
6100 // Verify the pushed stream.
6101 EXPECT_TRUE(response2.headers.get() != NULL);
6102 EXPECT_EQ("HTTP/1.1 200 OK", response2.headers->GetStatusLine());
6103
6104 // Verify we got all the headers
6105 if (spdy_util_.spdy_version() < SPDY3) {
6106 EXPECT_TRUE(response2.headers->HasHeaderValue(
6107 "url",
6108 "http://www.google.com/foo.dat"));
6109 } else {
6110 EXPECT_TRUE(response2.headers->HasHeaderValue(
6111 "scheme", "http"));
6112 EXPECT_TRUE(response2.headers->HasHeaderValue(
6113 "host", "www.google.com"));
6114 EXPECT_TRUE(response2.headers->HasHeaderValue(
6115 "path", "/foo.dat"));
6116 }
6117 EXPECT_TRUE(response2.headers->HasHeaderValue("hello", "bye"));
6118 EXPECT_TRUE(response2.headers->HasHeaderValue("status", "200"));
6119 EXPECT_TRUE(response2.headers->HasHeaderValue("version", "HTTP/1.1"));
6120
6121 // Read the final EOF (which will close the session)
6122 data.RunFor(1);
6123
6124 // Verify that we consumed all test data.
6125 EXPECT_TRUE(data.at_read_eof());
6126 EXPECT_TRUE(data.at_write_eof());
6127 }
6128
6129 TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) {
6130 if (GetParam().protocol > kProtoSPDY3)
6131 return;
6132
6133 // We push a stream and attempt to claim it before the headers come down.
6134 static const unsigned char kPushBodyFrame[] = {
6135 0x00, 0x00, 0x00, 0x02, // header, ID
6136 0x01, 0x00, 0x00, 0x06, // FIN, length
6137 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
6138 };
6139 scoped_ptr<SpdyFrame> stream1_syn(
6140 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
6141 scoped_ptr<SpdyFrame> stream1_body(
6142 spdy_util_.ConstructSpdyBodyFrame(1, true));
6143 MockWrite writes[] = {
6144 CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS),
6145 };
6146
6147 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
6148 spdy_util_.AddUrlToHeaderBlock(
6149 "http://www.google.com/foo.dat", initial_headers.get());
6150 scoped_ptr<SpdyFrame> stream2_syn(
6151 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
6152 false,
6153 2,
6154 LOWEST,
6155 SYN_STREAM,
6156 CONTROL_FLAG_NONE,
6157 1));
6158
6159 scoped_ptr<SpdyHeaderBlock> middle_headers(new SpdyHeaderBlock());
6160 (*middle_headers)["hello"] = "bye";
6161 scoped_ptr<SpdyFrame> stream2_headers1(
6162 spdy_util_.ConstructSpdyControlFrame(middle_headers.Pass(),
6163 false,
6164 2,
6165 LOWEST,
6166 HEADERS,
6167 CONTROL_FLAG_NONE,
6168 0));
6169
6170 scoped_ptr<SpdyFrame>
6171 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6172 MockRead reads[] = {
6173 CreateMockRead(*stream1_reply, 1),
6174 CreateMockRead(*stream2_syn, 2),
6175 CreateMockRead(*stream1_body, 3),
6176 CreateMockRead(*stream2_headers1, 4),
6177 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
6178 arraysize(kPushBodyFrame), 5),
6179 MockRead(ASYNC, 0, 6), // EOF
6180 };
6181
6182 DeterministicSocketData data(reads, arraysize(reads),
6183 writes, arraysize(writes));
6184
6185 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6186 BoundNetLog(), GetParam(), NULL);
6187 helper.SetDeterministic();
6188 helper.AddDeterministicData(&data);
6189 helper.RunPreTestSetup();
6190
6191 HttpNetworkTransaction* trans = helper.trans();
6192
6193 // Run until we've received the primary SYN_STREAM, the pushed SYN_STREAM,
6194 // the first HEADERS frame, and the body of the primary stream, but before
6195 // we've received the final HEADERS for the pushed stream.
6196 data.SetStop(4);
6197
6198 // Start the transaction.
6199 TestCompletionCallback callback;
6200 int rv = trans->Start(
6201 &CreateGetRequest(), callback.callback(), BoundNetLog());
6202 EXPECT_EQ(ERR_IO_PENDING, rv);
6203 data.Run();
6204 rv = callback.WaitForResult();
6205 EXPECT_EQ(0, rv);
6206
6207 // Request the pushed path. At this point, we've received the push, but the
6208 // headers are not yet complete.
6209 scoped_ptr<HttpNetworkTransaction> trans2(
6210 new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session().get()));
6211 rv = trans2->Start(
6212 &CreateGetPushRequest(), callback.callback(), BoundNetLog());
6213 EXPECT_EQ(ERR_IO_PENDING, rv);
6214 data.RunFor(2);
6215 base::MessageLoop::current()->RunUntilIdle();
6216
6217 // Read the server push body.
6218 std::string result2;
6219 ReadResult(trans2.get(), &data, &result2);
6220 // Read the response body.
6221 std::string result;
6222 ReadResult(trans, &data, &result);
6223 EXPECT_EQ("hello!", result);
6224
6225 // Verify that we haven't received any push data.
6226 EXPECT_EQ("", result2);
6227
6228 // Verify the SYN_REPLY.
6229 // Copy the response info, because trans goes away.
6230 HttpResponseInfo response = *trans->GetResponseInfo();
6231 ASSERT_TRUE(trans2->GetResponseInfo() == NULL);
6232
6233 VerifyStreamsClosed(helper);
6234
6235 // Verify the SYN_REPLY.
6236 EXPECT_TRUE(response.headers.get() != NULL);
6237 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
6238
6239 // Read the final EOF (which will close the session).
6240 data.RunFor(1);
6241
6242 // Verify that we consumed all test data.
6243 EXPECT_TRUE(data.at_read_eof());
6244 EXPECT_TRUE(data.at_write_eof());
6245 }
6246
6247 TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) {
6248 if (GetParam().protocol > kProtoSPDY3)
6249 return;
6250
6251 scoped_ptr<SpdyFrame> req(
6252 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
6253 scoped_ptr<SpdyFrame> rst(
6254 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
6255 MockWrite writes[] = {
6256 CreateMockWrite(*req),
6257 CreateMockWrite(*rst),
6258 };
6259
6260 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
6261 (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
6262 (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
6263 scoped_ptr<SpdyFrame> stream1_reply(
6264 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
6265 false,
6266 1,
6267 LOWEST,
6268 SYN_REPLY,
6269 CONTROL_FLAG_NONE,
6270 0));
6271
6272 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
6273 (*late_headers)["hello"] = "bye";
6274 scoped_ptr<SpdyFrame> stream1_headers(
6275 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
6276 false,
6277 1,
6278 LOWEST,
6279 HEADERS,
6280 CONTROL_FLAG_NONE,
6281 0));
6282 scoped_ptr<SpdyFrame> stream1_body(
6283 spdy_util_.ConstructSpdyBodyFrame(1, true));
6284 MockRead reads[] = {
6285 CreateMockRead(*stream1_reply),
6286 CreateMockRead(*stream1_headers),
6287 CreateMockRead(*stream1_body),
6288 MockRead(ASYNC, 0, 0) // EOF
6289 };
6290
6291 DelayedSocketData data(1, reads, arraysize(reads),
6292 writes, arraysize(writes));
6293 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6294 BoundNetLog(), GetParam(), NULL);
6295 helper.RunToCompletion(&data);
6296 TransactionHelperResult out = helper.output();
6297 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
6298 }
6299
6300 TEST_P(SpdyNetworkTransactionTest, SynReplyWithLateHeaders) {
6301 if (GetParam().protocol > kProtoSPDY3)
6302 return;
6303
6304 scoped_ptr<SpdyFrame> req(
6305 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
6306 scoped_ptr<SpdyFrame> rst(
6307 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR));
6308 MockWrite writes[] = {
6309 CreateMockWrite(*req),
6310 CreateMockWrite(*rst),
6311 };
6312
6313 scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock());
6314 (*initial_headers)[spdy_util_.GetStatusKey()] = "200 OK";
6315 (*initial_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1";
6316 scoped_ptr<SpdyFrame> stream1_reply(
6317 spdy_util_.ConstructSpdyControlFrame(initial_headers.Pass(),
6318 false,
6319 1,
6320 LOWEST,
6321 SYN_REPLY,
6322 CONTROL_FLAG_NONE,
6323 0));
6324
6325 scoped_ptr<SpdyHeaderBlock> late_headers(new SpdyHeaderBlock());
6326 (*late_headers)["hello"] = "bye";
6327 scoped_ptr<SpdyFrame> stream1_headers(
6328 spdy_util_.ConstructSpdyControlFrame(late_headers.Pass(),
6329 false,
6330 1,
6331 LOWEST,
6332 HEADERS,
6333 CONTROL_FLAG_NONE,
6334 0));
6335 scoped_ptr<SpdyFrame> stream1_body(
6336 spdy_util_.ConstructSpdyBodyFrame(1, false));
6337 scoped_ptr<SpdyFrame> stream1_body2(
6338 spdy_util_.ConstructSpdyBodyFrame(1, true));
6339 MockRead reads[] = {
6340 CreateMockRead(*stream1_reply),
6341 CreateMockRead(*stream1_body),
6342 CreateMockRead(*stream1_headers),
6343 CreateMockRead(*stream1_body2),
6344 MockRead(ASYNC, 0, 0) // EOF
6345 };
6346
6347 DelayedSocketData data(1, reads, arraysize(reads),
6348 writes, arraysize(writes));
6349 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6350 BoundNetLog(), GetParam(), NULL);
6351 helper.RunToCompletion(&data);
6352 TransactionHelperResult out = helper.output();
6353 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, out.rv);
6354 }
6355
6356 TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) {
6357 if (GetParam().protocol > kProtoSPDY3)
6358 return;
6359
6360 // In this test we want to verify that we can't accidentally push content
6361 // which can't be pushed by this content server.
6362 // This test assumes that:
6363 // - if we're requesting http://www.foo.com/barbaz
6364 // - the browser has made a connection to "www.foo.com".
6365
6366 // A list of the URL to fetch, followed by the URL being pushed.
6367 static const char* const kTestCases[] = {
6368 "http://www.google.com/foo.html",
6369 "http://www.google.com:81/foo.js", // Bad port
6370
6371 "http://www.google.com/foo.html",
6372 "https://www.google.com/foo.js", // Bad protocol
6373
6374 "http://www.google.com/foo.html",
6375 "ftp://www.google.com/foo.js", // Invalid Protocol
6376
6377 "http://www.google.com/foo.html",
6378 "http://blat.www.google.com/foo.js", // Cross subdomain
6379
6380 "http://www.google.com/foo.html",
6381 "http://www.foo.com/foo.js", // Cross domain
6382 };
6383
6384
6385 static const unsigned char kPushBodyFrame[] = {
6386 0x00, 0x00, 0x00, 0x02, // header, ID
6387 0x01, 0x00, 0x00, 0x06, // FIN, length
6388 'p', 'u', 's', 'h', 'e', 'd' // "pushed"
6389 };
6390
6391 for (size_t index = 0; index < arraysize(kTestCases); index += 2) {
6392 const char* url_to_fetch = kTestCases[index];
6393 const char* url_to_push = kTestCases[index + 1];
6394
6395 scoped_ptr<SpdyFrame> stream1_syn(
6396 spdy_util_.ConstructSpdyGet(url_to_fetch, false, 1, LOWEST));
6397 scoped_ptr<SpdyFrame> stream1_body(
6398 spdy_util_.ConstructSpdyBodyFrame(1, true));
6399 scoped_ptr<SpdyFrame> push_rst(
6400 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
6401 MockWrite writes[] = {
6402 CreateMockWrite(*stream1_syn, 1),
6403 CreateMockWrite(*push_rst, 4),
6404 };
6405
6406 scoped_ptr<SpdyFrame>
6407 stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
6408 scoped_ptr<SpdyFrame>
6409 stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
6410 0,
6411 2,
6412 1,
6413 url_to_push));
6414 scoped_ptr<SpdyFrame> rst(
6415 spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL));
6416
6417 MockRead reads[] = {
6418 CreateMockRead(*stream1_reply, 2),
6419 CreateMockRead(*stream2_syn, 3),
6420 CreateMockRead(*stream1_body, 5, SYNCHRONOUS),
6421 MockRead(ASYNC, reinterpret_cast<const char*>(kPushBodyFrame),
6422 arraysize(kPushBodyFrame), 6),
6423 MockRead(ASYNC, ERR_IO_PENDING, 7), // Force a pause
6424 };
6425
6426 HttpResponseInfo response;
6427 OrderedSocketData data(reads, arraysize(reads),
6428 writes, arraysize(writes));
6429
6430 HttpRequestInfo request;
6431 request.method = "GET";
6432 request.url = GURL(url_to_fetch);
6433 request.load_flags = 0;
6434
6435 // Enable cross-origin push. Since we are not using a proxy, this should
6436 // not actually enable cross-origin SPDY push.
6437 scoped_ptr<SpdySessionDependencies> session_deps(
6438 CreateSpdySessionDependencies(GetParam()));
6439 session_deps->trusted_spdy_proxy = "123.45.67.89:8080";
6440 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6441 BoundNetLog(), GetParam(),
6442 session_deps.release());
6443 helper.RunPreTestSetup();
6444 helper.AddData(&data);
6445
6446 HttpNetworkTransaction* trans = helper.trans();
6447
6448 // Start the transaction with basic parameters.
6449 TestCompletionCallback callback;
6450
6451 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
6452 EXPECT_EQ(ERR_IO_PENDING, rv);
6453 rv = callback.WaitForResult();
6454
6455 // Read the response body.
6456 std::string result;
6457 ReadResult(trans, &data, &result);
6458
6459 // Verify that we consumed all test data.
6460 EXPECT_TRUE(data.at_read_eof());
6461 EXPECT_TRUE(data.at_write_eof());
6462
6463 // Verify the SYN_REPLY.
6464 // Copy the response info, because trans goes away.
6465 response = *trans->GetResponseInfo();
6466
6467 VerifyStreamsClosed(helper);
6468
6469 // Verify the SYN_REPLY.
6470 EXPECT_TRUE(response.headers.get() != NULL);
6471 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine());
6472 }
6473 }
6474
6475 TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) {
6476 if (GetParam().protocol > kProtoSPDY3)
6477 return;
6478
6479 // Construct the request.
6480 scoped_ptr<SpdyFrame> req(
6481 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
6482 scoped_ptr<SpdyFrame> req2(
6483 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
6484 MockWrite writes[] = {
6485 CreateMockWrite(*req, 1),
6486 CreateMockWrite(*req2, 3),
6487 };
6488
6489 scoped_ptr<SpdyFrame> refused(
6490 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM));
6491 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
6492 scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(3, true));
6493 MockRead reads[] = {
6494 CreateMockRead(*refused, 2),
6495 CreateMockRead(*resp, 4),
6496 CreateMockRead(*body, 5),
6497 MockRead(ASYNC, 0, 6) // EOF
6498 };
6499
6500 OrderedSocketData data(reads, arraysize(reads),
6501 writes, arraysize(writes));
6502 NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
6503 BoundNetLog(), GetParam(), NULL);
6504
6505 helper.RunPreTestSetup();
6506 helper.AddData(&data);
6507
6508 HttpNetworkTransaction* trans = helper.trans();
6509
6510 // Start the transaction with basic parameters.
6511 TestCompletionCallback callback;
6512 int rv = trans->Start(
6513 &CreateGetRequest(), callback.callback(), BoundNetLog());
6514 EXPECT_EQ(ERR_IO_PENDING, rv); 5913 EXPECT_EQ(ERR_IO_PENDING, rv);
6515 rv = callback.WaitForResult(); 5914 rv = callback.WaitForResult();
6516 EXPECT_EQ(OK, rv); 5915 EXPECT_EQ(OK, rv);
6517 5916
6518 // Verify that we consumed all test data. 5917 SpdyHttpStream* stream =
6519 EXPECT_TRUE(data.at_read_eof()) << "Read count: " 5918 static_cast<SpdyHttpStream*>(trans->stream_.get());
6520 << data.read_count() 5919 ASSERT_TRUE(stream != NULL);
6521 << " Read index: " 5920 ASSERT_TRUE(stream->stream() != NULL);
6522 << data.read_index(); 5921
6523 EXPECT_TRUE(data.at_write_eof()) << "Write count: " 5922 EXPECT_EQ(
6524 << data.write_count() 5923 static_cast<int>(kSpdyStreamInitialWindowSize - body_data.size()),
6525 << " Write index: " 5924 stream->stream()->recv_window_size());
6526 << data.write_index(); 5925
6527 5926 const HttpResponseInfo* response = trans->GetResponseInfo();
6528 // Verify the SYN_REPLY. 5927 ASSERT_TRUE(response != NULL);
6529 HttpResponseInfo response = *trans->GetResponseInfo(); 5928 ASSERT_TRUE(response->headers.get() != NULL);
6530 EXPECT_TRUE(response.headers.get() != NULL); 5929 EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
6531 EXPECT_EQ("HTTP/1.1 200 OK", response.headers->GetStatusLine()); 5930 EXPECT_TRUE(response->was_fetched_via_spdy);
5931
5932 // Issue a read which will cause a WINDOW_UPDATE to be sent and window
5933 // size increased to default.
5934 scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(body_data.size()));
5935 rv = trans->Read(buf.get(), body_data.size(), CompletionCallback());
5936 EXPECT_EQ(static_cast<int>(body_data.size()), rv);
5937 std::string content(buf->data(), buf->data() + body_data.size());
5938 EXPECT_EQ(body_data, content);
5939
5940 // Schedule the reading of empty data frame with FIN
5941 data.CompleteRead();
5942
5943 // Force write of WINDOW_UPDATE which was scheduled during the above
5944 // read.
5945 base::MessageLoop::current()->RunUntilIdle();
5946
5947 // Read EOF.
5948 data.CompleteRead();
5949
5950 helper.VerifyDataConsumed();
6532 } 5951 }
6533 5952
6534 TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { 5953 // Test that WINDOW_UPDATE frame causing overflow is handled correctly.
6535 if (GetParam().protocol > kProtoSPDY3) 5954 TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) {
5955 if (GetParam().protocol < kProtoSPDY3)
6536 return; 5956 return;
6537 5957
6538 // This first request will start to establish the SpdySession. 5958 // Number of full frames we hope to write (but will not, used to
6539 // Then we will start the second (MEDIUM priority) and then third 5959 // set content-length header correctly)
6540 // (HIGHEST priority) request in such a way that the third will actually 5960 static int kFrameCount = 3;
6541 // start before the second, causing the second to be numbered differently 5961
6542 // than the order they were created. 5962 scoped_ptr<std::string> content(
6543 scoped_ptr<SpdyFrame> req1( 5963 new std::string(kMaxSpdyFrameChunkSize, 'a'));
6544 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); 5964 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6545 scoped_ptr<SpdyFrame> req2( 5965 kRequestUrl, 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0));
6546 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, HIGHEST, true)); 5966 scoped_ptr<SpdyFrame> body(
6547 scoped_ptr<SpdyFrame> req3( 5967 spdy_util_.ConstructSpdyBodyFrame(
6548 spdy_util_.ConstructSpdyGet(NULL, 0, false, 5, MEDIUM, true)); 5968 1, content->c_str(), content->size(), false));
5969 scoped_ptr<SpdyFrame> rst(
5970 spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR));
5971
5972 // We're not going to write a data frame with FIN, we'll receive a bad
5973 // WINDOW_UPDATE while sending a request and will send a RST_STREAM frame.
6549 MockWrite writes[] = { 5974 MockWrite writes[] = {
6550 CreateMockWrite(*req1, 0), 5975 CreateMockWrite(*req, 0),
6551 CreateMockWrite(*req2, 3), 5976 CreateMockWrite(*body, 2),
6552 CreateMockWrite(*req3, 4), 5977 CreateMockWrite(*rst, 3),
6553 }; 5978 };
6554 5979
6555 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); 5980 static const int32 kDeltaWindowSize = 0x7fffffff; // cause an overflow
6556 scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true)); 5981 scoped_ptr<SpdyFrame> window_update(
6557 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); 5982 spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize));
6558 scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
6559 scoped_ptr<SpdyFrame> resp3(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5));
6560 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(5, true));
6561 MockRead reads[] = { 5983 MockRead reads[] = {
6562 CreateMockRead(*resp1, 1), 5984 CreateMockRead(*window_update, 1),
6563 CreateMockRead(*body1, 2), 5985 MockRead(ASYNC, 0, 4) // EOF
6564 CreateMockRead(*resp2, 5),
6565 CreateMockRead(*body2, 6),
6566 CreateMockRead(*resp3, 7),
6567 CreateMockRead(*body3, 8),
6568 MockRead(ASYNC, 0, 9) // EOF
6569 }; 5986 };
6570 5987
6571 DeterministicSocketData data(reads, arraysize(reads), 5988 DeterministicSocketData data(reads, arraysize(reads),
6572 writes, arraysize(writes)); 5989 writes, arraysize(writes));
6573 NormalSpdyTransactionHelper helper(CreateGetRequest(), LOWEST, 5990
5991 ScopedVector<UploadElementReader> element_readers;
5992 for (int i = 0; i < kFrameCount; ++i) {
5993 element_readers.push_back(
5994 new UploadBytesElementReader(content->c_str(), content->size()));
5995 }
5996 UploadDataStream upload_data_stream(&element_readers, 0);
5997
5998 // Setup the request
5999 HttpRequestInfo request;
6000 request.method = "POST";
6001 request.url = GURL("http://www.google.com/");
6002 request.upload_data_stream = &upload_data_stream;
6003
6004 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6574 BoundNetLog(), GetParam(), NULL); 6005 BoundNetLog(), GetParam(), NULL);
6575 helper.SetDeterministic(); 6006 helper.SetDeterministic();
6576 helper.RunPreTestSetup(); 6007 helper.RunPreTestSetup();
6577 helper.AddDeterministicData(&data); 6008 helper.AddDeterministicData(&data);
6578
6579 // Start the first transaction to set up the SpdySession
6580 HttpNetworkTransaction* trans = helper.trans(); 6009 HttpNetworkTransaction* trans = helper.trans();
6010
6581 TestCompletionCallback callback; 6011 TestCompletionCallback callback;
6582 HttpRequestInfo info1 = CreateGetRequest(); 6012 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6583 int rv = trans->Start(&info1, callback.callback(), BoundNetLog()); 6013 ASSERT_EQ(ERR_IO_PENDING, rv);
6584 EXPECT_EQ(ERR_IO_PENDING, rv); 6014
6585 6015 data.RunFor(5);
6586 // Run the message loop, but do not allow the write to complete. 6016 ASSERT_TRUE(callback.have_result());
6587 // This leaves the SpdySession with a write pending, which prevents 6017 EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, callback.WaitForResult());
6588 // SpdySession from attempting subsequent writes until this write completes.
6589 base::MessageLoop::current()->RunUntilIdle();
6590
6591 // Now, start both new transactions
6592 HttpRequestInfo info2 = CreateGetRequest();
6593 TestCompletionCallback callback2;
6594 scoped_ptr<HttpNetworkTransaction> trans2(
6595 new HttpNetworkTransaction(MEDIUM, helper.session().get()));
6596 rv = trans2->Start(&info2, callback2.callback(), BoundNetLog());
6597 EXPECT_EQ(ERR_IO_PENDING, rv);
6598 base::MessageLoop::current()->RunUntilIdle();
6599
6600 HttpRequestInfo info3 = CreateGetRequest();
6601 TestCompletionCallback callback3;
6602 scoped_ptr<HttpNetworkTransaction> trans3(
6603 new HttpNetworkTransaction(HIGHEST, helper.session().get()));
6604 rv = trans3->Start(&info3, callback3.callback(), BoundNetLog());
6605 EXPECT_EQ(ERR_IO_PENDING, rv);
6606 base::MessageLoop::current()->RunUntilIdle();
6607
6608 // We now have two SYN_STREAM frames queued up which will be
6609 // dequeued only once the first write completes, which we
6610 // now allow to happen.
6611 data.RunFor(2);
6612 EXPECT_EQ(OK, callback.WaitForResult());
6613
6614 // And now we can allow everything else to run to completion.
6615 data.SetStop(10);
6616 data.Run();
6617 EXPECT_EQ(OK, callback2.WaitForResult());
6618 EXPECT_EQ(OK, callback3.WaitForResult());
6619
6620 helper.VerifyDataConsumed(); 6018 helper.VerifyDataConsumed();
6621 } 6019 }
6622 6020
6021 // Test that after hitting a send window size of 0, the write process
6022 // stalls and upon receiving WINDOW_UPDATE frame write resumes.
6023
6024 // This test constructs a POST request followed by enough data frames
6025 // containing 'a' that would make the window size 0, followed by another
6026 // data frame containing default content (which is "hello!") and this frame
6027 // also contains a FIN flag. DelayedSocketData is used to enforce all
6028 // writes go through before a read could happen. However, the last frame
6029 // ("hello!") is not supposed to go through since by the time its turn
6030 // arrives, window size is 0. At this point MessageLoop::Run() called via
6031 // callback would block. Therefore we call MessageLoop::RunUntilIdle()
6032 // which returns after performing all possible writes. We use DCHECKS to
6033 // ensure that last data frame is still there and stream has stalled.
6034 // After that, next read is artifically enforced, which causes a
6035 // WINDOW_UPDATE to be read and I/O process resumes.
6036 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) {
6037 if (GetParam().protocol < kProtoSPDY3)
6038 return;
6039
6040 // Number of frames we need to send to zero out the window size: data
6041 // frames plus SYN_STREAM plus the last data frame; also we need another
6042 // data frame that we will send once the WINDOW_UPDATE is received,
6043 // therefore +3.
6044 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6045
6046 // Calculate last frame's size; 0 size data frame is legal.
6047 size_t last_frame_size =
6048 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6049
6050 // Construct content for a data frame of maximum size.
6051 std::string content(kMaxSpdyFrameChunkSize, 'a');
6052
6053 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6054 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6055 LOWEST, NULL, 0));
6056
6057 // Full frames.
6058 scoped_ptr<SpdyFrame> body1(
6059 spdy_util_.ConstructSpdyBodyFrame(
6060 1, content.c_str(), content.size(), false));
6061
6062 // Last frame to zero out the window size.
6063 scoped_ptr<SpdyFrame> body2(
6064 spdy_util_.ConstructSpdyBodyFrame(
6065 1, content.c_str(), last_frame_size, false));
6066
6067 // Data frame to be sent once WINDOW_UPDATE frame is received.
6068 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6069
6070 // Fill in mock writes.
6071 scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]);
6072 size_t i = 0;
6073 writes[i] = CreateMockWrite(*req);
6074 for (i = 1; i < num_writes - 2; i++)
6075 writes[i] = CreateMockWrite(*body1);
6076 writes[i++] = CreateMockWrite(*body2);
6077 writes[i] = CreateMockWrite(*body3);
6078
6079 // Construct read frame, give enough space to upload the rest of the
6080 // data.
6081 scoped_ptr<SpdyFrame> session_window_update(
6082 spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6083 scoped_ptr<SpdyFrame> window_update(
6084 spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize));
6085 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6086 MockRead reads[] = {
6087 CreateMockRead(*session_window_update),
6088 CreateMockRead(*session_window_update),
6089 CreateMockRead(*window_update),
6090 CreateMockRead(*window_update),
6091 CreateMockRead(*reply),
6092 CreateMockRead(*body2),
6093 CreateMockRead(*body3),
6094 MockRead(ASYNC, 0, 0) // EOF
6095 };
6096
6097 // Skip the session window updates unless we're using SPDY/3.1 and
6098 // above.
6099 size_t read_offset = (GetParam().protocol >= kProtoSPDY31) ? 0 : 2;
6100 size_t num_reads = arraysize(reads) - read_offset;
6101
6102 // Force all writes to happen before any read, last write will not
6103 // actually queue a frame, due to window size being 0.
6104 DelayedSocketData data(num_writes, reads + read_offset, num_reads,
6105 writes.get(), num_writes);
6106
6107 ScopedVector<UploadElementReader> element_readers;
6108 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6109 upload_data_string.append(kUploadData, kUploadDataSize);
6110 element_readers.push_back(new UploadBytesElementReader(
6111 upload_data_string.c_str(), upload_data_string.size()));
6112 UploadDataStream upload_data_stream(&element_readers, 0);
6113
6114 HttpRequestInfo request;
6115 request.method = "POST";
6116 request.url = GURL("http://www.google.com/");
6117 request.upload_data_stream = &upload_data_stream;
6118 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6119 BoundNetLog(), GetParam(), NULL);
6120 helper.AddData(&data);
6121 helper.RunPreTestSetup();
6122
6123 HttpNetworkTransaction* trans = helper.trans();
6124
6125 TestCompletionCallback callback;
6126 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6127 EXPECT_EQ(ERR_IO_PENDING, rv);
6128
6129 base::MessageLoop::current()->RunUntilIdle(); // Write as much as we can.
6130
6131 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6132 ASSERT_TRUE(stream != NULL);
6133 ASSERT_TRUE(stream->stream() != NULL);
6134 EXPECT_EQ(0, stream->stream()->send_window_size());
6135 // All the body data should have been read.
6136 // TODO(satorux): This is because of the weirdness in reading the request
6137 // body in OnSendBodyComplete(). See crbug.com/113107.
6138 EXPECT_TRUE(upload_data_stream.IsEOF());
6139 // But the body is not yet fully sent (kUploadData is not yet sent)
6140 // since we're send-stalled.
6141 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6142
6143 data.ForceNextRead(); // Read in WINDOW_UPDATE frame.
6144 rv = callback.WaitForResult();
6145 helper.VerifyDataConsumed();
6146 }
6147
6148 // Test we correctly handle the case where the SETTINGS frame results in
6149 // unstalling the send window.
6150 TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) {
6151 if (GetParam().protocol < kProtoSPDY3)
6152 return;
6153
6154 // Number of frames we need to send to zero out the window size: data
6155 // frames plus SYN_STREAM plus the last data frame; also we need another
6156 // data frame that we will send once the SETTING is received, therefore +3.
6157 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6158
6159 // Calculate last frame's size; 0 size data frame is legal.
6160 size_t last_frame_size =
6161 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6162
6163 // Construct content for a data frame of maximum size.
6164 std::string content(kMaxSpdyFrameChunkSize, 'a');
6165
6166 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6167 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6168 LOWEST, NULL, 0));
6169
6170 // Full frames.
6171 scoped_ptr<SpdyFrame> body1(
6172 spdy_util_.ConstructSpdyBodyFrame(
6173 1, content.c_str(), content.size(), false));
6174
6175 // Last frame to zero out the window size.
6176 scoped_ptr<SpdyFrame> body2(
6177 spdy_util_.ConstructSpdyBodyFrame(
6178 1, content.c_str(), last_frame_size, false));
6179
6180 // Data frame to be sent once SETTINGS frame is received.
6181 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6182
6183 // Fill in mock reads/writes.
6184 std::vector<MockRead> reads;
6185 std::vector<MockWrite> writes;
6186 size_t i = 0;
6187 writes.push_back(CreateMockWrite(*req, i++));
6188 while (i < num_writes - 2)
6189 writes.push_back(CreateMockWrite(*body1, i++));
6190 writes.push_back(CreateMockWrite(*body2, i++));
6191
6192 // Construct read frame for SETTINGS that gives enough space to upload the
6193 // rest of the data.
6194 SettingsMap settings;
6195 settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6196 SettingsFlagsAndValue(
6197 SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize * 2);
6198 scoped_ptr<SpdyFrame> settings_frame_large(
6199 spdy_util_.ConstructSpdySettings(settings));
6200
6201 reads.push_back(CreateMockRead(*settings_frame_large, i++));
6202
6203 scoped_ptr<SpdyFrame> session_window_update(
6204 spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize));
6205 if (GetParam().protocol >= kProtoSPDY31)
6206 reads.push_back(CreateMockRead(*session_window_update, i++));
6207
6208 writes.push_back(CreateMockWrite(*body3, i++));
6209
6210 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6211 reads.push_back(CreateMockRead(*reply, i++));
6212 reads.push_back(CreateMockRead(*body2, i++));
6213 reads.push_back(CreateMockRead(*body3, i++));
6214 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
6215
6216 // Force all writes to happen before any read, last write will not
6217 // actually queue a frame, due to window size being 0.
6218 DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6219 vector_as_array(&writes), writes.size());
6220
6221 ScopedVector<UploadElementReader> element_readers;
6222 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6223 upload_data_string.append(kUploadData, kUploadDataSize);
6224 element_readers.push_back(new UploadBytesElementReader(
6225 upload_data_string.c_str(), upload_data_string.size()));
6226 UploadDataStream upload_data_stream(&element_readers, 0);
6227
6228 HttpRequestInfo request;
6229 request.method = "POST";
6230 request.url = GURL("http://www.google.com/");
6231 request.upload_data_stream = &upload_data_stream;
6232 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6233 BoundNetLog(), GetParam(), NULL);
6234 helper.SetDeterministic();
6235 helper.RunPreTestSetup();
6236 helper.AddDeterministicData(&data);
6237
6238 HttpNetworkTransaction* trans = helper.trans();
6239
6240 TestCompletionCallback callback;
6241 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6242 EXPECT_EQ(ERR_IO_PENDING, rv);
6243
6244 data.RunFor(num_writes - 1); // Write as much as we can.
6245
6246 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6247 ASSERT_TRUE(stream != NULL);
6248 ASSERT_TRUE(stream->stream() != NULL);
6249 EXPECT_EQ(0, stream->stream()->send_window_size());
6250
6251 // All the body data should have been read.
6252 // TODO(satorux): This is because of the weirdness in reading the request
6253 // body in OnSendBodyComplete(). See crbug.com/113107.
6254 EXPECT_TRUE(upload_data_stream.IsEOF());
6255 // But the body is not yet fully sent (kUploadData is not yet sent)
6256 // since we're send-stalled.
6257 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6258
6259 data.RunFor(6); // Read in SETTINGS frame to unstall.
6260 rv = callback.WaitForResult();
6261 helper.VerifyDataConsumed();
6262 // If stream is NULL, that means it was unstalled and closed.
6263 EXPECT_TRUE(stream->stream() == NULL);
6264 }
6265
6266 // Test we correctly handle the case where the SETTINGS frame results in a
6267 // negative send window size.
6268 TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) {
6269 if (GetParam().protocol < kProtoSPDY3)
6270 return;
6271
6272 // Number of frames we need to send to zero out the window size: data
6273 // frames plus SYN_STREAM plus the last data frame; also we need another
6274 // data frame that we will send once the SETTING is received, therefore +3.
6275 size_t num_writes = kSpdyStreamInitialWindowSize / kMaxSpdyFrameChunkSize + 3;
6276
6277 // Calculate last frame's size; 0 size data frame is legal.
6278 size_t last_frame_size =
6279 kSpdyStreamInitialWindowSize % kMaxSpdyFrameChunkSize;
6280
6281 // Construct content for a data frame of maximum size.
6282 std::string content(kMaxSpdyFrameChunkSize, 'a');
6283
6284 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyPost(
6285 kRequestUrl, 1, kSpdyStreamInitialWindowSize + kUploadDataSize,
6286 LOWEST, NULL, 0));
6287
6288 // Full frames.
6289 scoped_ptr<SpdyFrame> body1(
6290 spdy_util_.ConstructSpdyBodyFrame(
6291 1, content.c_str(), content.size(), false));
6292
6293 // Last frame to zero out the window size.
6294 scoped_ptr<SpdyFrame> body2(
6295 spdy_util_.ConstructSpdyBodyFrame(
6296 1, content.c_str(), last_frame_size, false));
6297
6298 // Data frame to be sent once SETTINGS frame is received.
6299 scoped_ptr<SpdyFrame> body3(spdy_util_.ConstructSpdyBodyFrame(1, true));
6300
6301 // Fill in mock reads/writes.
6302 std::vector<MockRead> reads;
6303 std::vector<MockWrite> writes;
6304 size_t i = 0;
6305 writes.push_back(CreateMockWrite(*req, i++));
6306 while (i < num_writes - 2)
6307 writes.push_back(CreateMockWrite(*body1, i++));
6308 writes.push_back(CreateMockWrite(*body2, i++));
6309
6310 // Construct read frame for SETTINGS that makes the send_window_size
6311 // negative.
6312 SettingsMap new_settings;
6313 new_settings[SETTINGS_INITIAL_WINDOW_SIZE] =
6314 SettingsFlagsAndValue(
6315 SETTINGS_FLAG_NONE, kSpdyStreamInitialWindowSize / 2);
6316 scoped_ptr<SpdyFrame> settings_frame_small(
6317 spdy_util_.ConstructSpdySettings(new_settings));
6318 // Construct read frames for WINDOW_UPDATE that makes the send_window_size
6319 // positive.
6320 scoped_ptr<SpdyFrame> session_window_update_init_size(
6321 spdy_util_.ConstructSpdyWindowUpdate(0, kSpdyStreamInitialWindowSize));
6322 scoped_ptr<SpdyFrame> window_update_init_size(
6323 spdy_util_.ConstructSpdyWindowUpdate(1, kSpdyStreamInitialWindowSize));
6324
6325 reads.push_back(CreateMockRead(*settings_frame_small, i++));
6326
6327 if (GetParam().protocol >= kProtoSPDY3)
6328 reads.push_back(CreateMockRead(*session_window_update_init_size, i++));
6329
6330 reads.push_back(CreateMockRead(*window_update_init_size, i++));
6331
6332 writes.push_back(CreateMockWrite(*body3, i++));
6333
6334 scoped_ptr<SpdyFrame> reply(spdy_util_.ConstructSpdyPostSynReply(NULL, 0));
6335 reads.push_back(CreateMockRead(*reply, i++));
6336 reads.push_back(CreateMockRead(*body2, i++));
6337 reads.push_back(CreateMockRead(*body3, i++));
6338 reads.push_back(MockRead(ASYNC, 0, i++)); // EOF
6339
6340 // Force all writes to happen before any read, last write will not
6341 // actually queue a frame, due to window size being 0.
6342 DeterministicSocketData data(vector_as_array(&reads), reads.size(),
6343 vector_as_array(&writes), writes.size());
6344
6345 ScopedVector<UploadElementReader> element_readers;
6346 std::string upload_data_string(kSpdyStreamInitialWindowSize, 'a');
6347 upload_data_string.append(kUploadData, kUploadDataSize);
6348 element_readers.push_back(new UploadBytesElementReader(
6349 upload_data_string.c_str(), upload_data_string.size()));
6350 UploadDataStream upload_data_stream(&element_readers, 0);
6351
6352 HttpRequestInfo request;
6353 request.method = "POST";
6354 request.url = GURL("http://www.google.com/");
6355 request.upload_data_stream = &upload_data_stream;
6356 NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY,
6357 BoundNetLog(), GetParam(), NULL);
6358 helper.SetDeterministic();
6359 helper.RunPreTestSetup();
6360 helper.AddDeterministicData(&data);
6361
6362 HttpNetworkTransaction* trans = helper.trans();
6363
6364 TestCompletionCallback callback;
6365 int rv = trans->Start(&helper.request(), callback.callback(), BoundNetLog());
6366 EXPECT_EQ(ERR_IO_PENDING, rv);
6367
6368 data.RunFor(num_writes - 1); // Write as much as we can.
6369
6370 SpdyHttpStream* stream = static_cast<SpdyHttpStream*>(trans->stream_.get());
6371 ASSERT_TRUE(stream != NULL);
6372 ASSERT_TRUE(stream->stream() != NULL);
6373 EXPECT_EQ(0, stream->stream()->send_window_size());
6374
6375 // All the body data should have been read.
6376 // TODO(satorux): This is because of the weirdness in reading the request
6377 // body in OnSendBodyComplete(). See crbug.com/113107.
6378 EXPECT_TRUE(upload_data_stream.IsEOF());
6379 // But the body is not yet fully sent (kUploadData is not yet sent)
6380 // since we're send-stalled.
6381 EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control());
6382
6383 // Read in WINDOW_UPDATE or SETTINGS frame.
6384 data.RunFor((GetParam().protocol >= kProtoSPDY31) ? 8 : 7);
6385 rv = callback.WaitForResult();
6386 helper.VerifyDataConsumed();
6387 }
6388
6623 } // namespace net 6389 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698