OLD | NEW |
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 "net/spdy/spdy_http_stream.h" | 5 #include "net/spdy/spdy_http_stream.h" |
6 | 6 |
7 #include <vector> | 7 #include <vector> |
8 | 8 |
9 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
10 #include "base/message_loop/message_loop_proxy.h" | 10 #include "base/message_loop/message_loop_proxy.h" |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
59 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, | 59 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, |
60 CONNECT_TIMING_HAS_DNS_TIMES); | 60 CONNECT_TIMING_HAS_DNS_TIMES); |
61 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); | 61 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); |
62 } | 62 } |
63 | 63 |
64 } // namespace | 64 } // namespace |
65 | 65 |
66 class SpdyHttpStreamTest : public testing::Test, | 66 class SpdyHttpStreamTest : public testing::Test, |
67 public testing::WithParamInterface<NextProto> { | 67 public testing::WithParamInterface<NextProto> { |
68 public: | 68 public: |
69 SpdyHttpStreamTest() | 69 SpdyHttpStreamTest() : spdy_util_(GetParam()), session_deps_(GetParam()) { |
70 : spdy_util_(GetParam()), | |
71 session_deps_(GetParam()) { | |
72 session_deps_.net_log = &net_log_; | 70 session_deps_.net_log = &net_log_; |
73 } | 71 } |
74 | 72 |
75 DeterministicSocketData* deterministic_data() { | 73 DeterministicSocketData* deterministic_data() { |
76 return deterministic_data_.get(); | 74 return deterministic_data_.get(); |
77 } | 75 } |
78 | 76 |
79 OrderedSocketData* data() { return data_.get(); } | 77 OrderedSocketData* data() { return data_.get(); } |
80 | 78 |
81 protected: | 79 protected: |
82 virtual void TearDown() OVERRIDE { | 80 virtual void TearDown() OVERRIDE { |
83 crypto::ECSignatureCreator::SetFactoryForTesting(NULL); | 81 crypto::ECSignatureCreator::SetFactoryForTesting(NULL); |
84 base::MessageLoop::current()->RunUntilIdle(); | 82 base::MessageLoop::current()->RunUntilIdle(); |
85 } | 83 } |
86 | 84 |
87 // Initializes the session using DeterministicSocketData. It's advisable | 85 // Initializes the session using DeterministicSocketData. It's advisable |
88 // to use this function rather than the OrderedSocketData, since the | 86 // to use this function rather than the OrderedSocketData, since the |
89 // DeterministicSocketData behaves in a reasonable manner. | 87 // DeterministicSocketData behaves in a reasonable manner. |
90 void InitSessionDeterministic(MockRead* reads, size_t reads_count, | 88 void InitSessionDeterministic(MockRead* reads, |
91 MockWrite* writes, size_t writes_count, | 89 size_t reads_count, |
| 90 MockWrite* writes, |
| 91 size_t writes_count, |
92 const SpdySessionKey& key) { | 92 const SpdySessionKey& key) { |
93 deterministic_data_.reset( | 93 deterministic_data_.reset( |
94 new DeterministicSocketData(reads, reads_count, writes, writes_count)); | 94 new DeterministicSocketData(reads, reads_count, writes, writes_count)); |
95 session_deps_.deterministic_socket_factory->AddSocketDataProvider( | 95 session_deps_.deterministic_socket_factory->AddSocketDataProvider( |
96 deterministic_data_.get()); | 96 deterministic_data_.get()); |
97 http_session_ = | 97 http_session_ = |
98 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); | 98 SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_); |
99 session_ = CreateInsecureSpdySession(http_session_, key, BoundNetLog()); | 99 session_ = CreateInsecureSpdySession(http_session_, key, BoundNetLog()); |
100 } | 100 } |
101 | 101 |
102 // Initializes the session using the finicky OrderedSocketData class. | 102 // Initializes the session using the finicky OrderedSocketData class. |
103 void InitSession(MockRead* reads, size_t reads_count, | 103 void InitSession(MockRead* reads, |
104 MockWrite* writes, size_t writes_count, | 104 size_t reads_count, |
| 105 MockWrite* writes, |
| 106 size_t writes_count, |
105 const SpdySessionKey& key) { | 107 const SpdySessionKey& key) { |
106 data_.reset(new OrderedSocketData(reads, reads_count, | 108 data_.reset( |
107 writes, writes_count)); | 109 new OrderedSocketData(reads, reads_count, writes, writes_count)); |
108 session_deps_.socket_factory->AddSocketDataProvider(data_.get()); | 110 session_deps_.socket_factory->AddSocketDataProvider(data_.get()); |
109 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); | 111 http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); |
110 session_ = CreateInsecureSpdySession(http_session_, key, BoundNetLog()); | 112 session_ = CreateInsecureSpdySession(http_session_, key, BoundNetLog()); |
111 } | 113 } |
112 | 114 |
113 void TestSendCredentials( | 115 void TestSendCredentials(ServerBoundCertService* server_bound_cert_service, |
114 ServerBoundCertService* server_bound_cert_service, | 116 const std::string& cert, |
115 const std::string& cert, | 117 const std::string& proof); |
116 const std::string& proof); | |
117 | 118 |
118 SpdyTestUtil spdy_util_; | 119 SpdyTestUtil spdy_util_; |
119 CapturingNetLog net_log_; | 120 CapturingNetLog net_log_; |
120 SpdySessionDependencies session_deps_; | 121 SpdySessionDependencies session_deps_; |
121 scoped_ptr<OrderedSocketData> data_; | 122 scoped_ptr<OrderedSocketData> data_; |
122 scoped_ptr<DeterministicSocketData> deterministic_data_; | 123 scoped_ptr<DeterministicSocketData> deterministic_data_; |
123 scoped_refptr<HttpNetworkSession> http_session_; | 124 scoped_refptr<HttpNetworkSession> http_session_; |
124 base::WeakPtr<SpdySession> session_; | 125 base::WeakPtr<SpdySession> session_; |
125 | 126 |
126 private: | 127 private: |
127 MockECSignatureCreatorFactory ec_signature_creator_factory_; | 128 MockECSignatureCreatorFactory ec_signature_creator_factory_; |
128 }; | 129 }; |
129 | 130 |
130 INSTANTIATE_TEST_CASE_P( | 131 INSTANTIATE_TEST_CASE_P(NextProto, |
131 NextProto, | 132 SpdyHttpStreamTest, |
132 SpdyHttpStreamTest, | 133 testing::Values(kProtoDeprecatedSPDY2, |
133 testing::Values(kProtoDeprecatedSPDY2, | 134 kProtoSPDY3, |
134 kProtoSPDY3, kProtoSPDY31, kProtoSPDY4)); | 135 kProtoSPDY31, |
| 136 kProtoSPDY4)); |
135 | 137 |
136 // SpdyHttpStream::GetUploadProgress() should still work even before the | 138 // SpdyHttpStream::GetUploadProgress() should still work even before the |
137 // stream is initialized. | 139 // stream is initialized. |
138 TEST_P(SpdyHttpStreamTest, GetUploadProgressBeforeInitialization) { | 140 TEST_P(SpdyHttpStreamTest, GetUploadProgressBeforeInitialization) { |
139 MockRead reads[] = { | 141 MockRead reads[] = { |
140 MockRead(ASYNC, 0, 0) // EOF | 142 MockRead(ASYNC, 0, 0) // EOF |
141 }; | 143 }; |
142 | 144 |
143 HostPortPair host_port_pair("www.google.com", 80); | 145 HostPortPair host_port_pair("www.google.com", 80); |
144 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 146 SpdySessionKey key( |
145 PRIVACY_MODE_DISABLED); | 147 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
146 InitSession(reads, arraysize(reads), NULL, 0, key); | 148 InitSession(reads, arraysize(reads), NULL, 0, key); |
147 | 149 |
148 SpdyHttpStream stream(session_, false); | 150 SpdyHttpStream stream(session_, false); |
149 UploadProgress progress = stream.GetUploadProgress(); | 151 UploadProgress progress = stream.GetUploadProgress(); |
150 EXPECT_EQ(0u, progress.size()); | 152 EXPECT_EQ(0u, progress.size()); |
151 EXPECT_EQ(0u, progress.position()); | 153 EXPECT_EQ(0u, progress.position()); |
152 | 154 |
153 // Pump the event loop so |reads| is consumed before the function returns. | 155 // Pump the event loop so |reads| is consumed before the function returns. |
154 base::RunLoop().RunUntilIdle(); | 156 base::RunLoop().RunUntilIdle(); |
155 } | 157 } |
156 | 158 |
157 TEST_P(SpdyHttpStreamTest, SendRequest) { | 159 TEST_P(SpdyHttpStreamTest, SendRequest) { |
158 scoped_ptr<SpdyFrame> req( | 160 scoped_ptr<SpdyFrame> req( |
159 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 161 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); |
160 MockWrite writes[] = { | 162 MockWrite writes[] = { |
161 CreateMockWrite(*req.get(), 1), | 163 CreateMockWrite(*req.get(), 1), |
162 }; | 164 }; |
163 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 165 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
164 MockRead reads[] = { | 166 MockRead reads[] = { |
165 CreateMockRead(*resp, 2), | 167 CreateMockRead(*resp, 2), MockRead(SYNCHRONOUS, 0, 3) // EOF |
166 MockRead(SYNCHRONOUS, 0, 3) // EOF | |
167 }; | 168 }; |
168 | 169 |
169 HostPortPair host_port_pair("www.google.com", 80); | 170 HostPortPair host_port_pair("www.google.com", 80); |
170 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 171 SpdySessionKey key( |
171 PRIVACY_MODE_DISABLED); | 172 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
172 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); | 173 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); |
173 | 174 |
174 HttpRequestInfo request; | 175 HttpRequestInfo request; |
175 request.method = "GET"; | 176 request.method = "GET"; |
176 request.url = GURL("http://www.google.com/"); | 177 request.url = GURL("http://www.google.com/"); |
177 TestCompletionCallback callback; | 178 TestCompletionCallback callback; |
178 HttpResponseInfo response; | 179 HttpResponseInfo response; |
179 HttpRequestHeaders headers; | 180 HttpRequestHeaders headers; |
180 BoundNetLog net_log; | 181 BoundNetLog net_log; |
181 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | 182 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); |
182 // Make sure getting load timing information the stream early does not crash. | 183 // Make sure getting load timing information the stream early does not crash. |
183 LoadTimingInfo load_timing_info; | 184 LoadTimingInfo load_timing_info; |
184 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); | 185 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); |
185 | 186 |
186 ASSERT_EQ( | 187 ASSERT_EQ(OK, |
187 OK, | 188 http_stream->InitializeStream( |
188 http_stream->InitializeStream(&request, DEFAULT_PRIORITY, | 189 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); |
189 net_log, CompletionCallback())); | |
190 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); | 190 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); |
191 | 191 |
192 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | 192 EXPECT_EQ(ERR_IO_PENDING, |
193 callback.callback())); | 193 http_stream->SendRequest(headers, &response, callback.callback())); |
194 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 194 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
195 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); | 195 EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); |
196 | 196 |
197 // This triggers the MockWrite and read 2 | 197 // This triggers the MockWrite and read 2 |
198 callback.WaitForResult(); | 198 callback.WaitForResult(); |
199 | 199 |
200 // Can get timing information once the stream connects. | 200 // Can get timing information once the stream connects. |
201 TestLoadTimingNotReused(*http_stream); | 201 TestLoadTimingNotReused(*http_stream); |
202 | 202 |
203 // This triggers read 3. The empty read causes the session to shut down. | 203 // This triggers read 3. The empty read causes the session to shut down. |
(...skipping 11 matching lines...) Expand all Loading... |
215 // stream has been closed. | 215 // stream has been closed. |
216 TestLoadTimingNotReused(*http_stream); | 216 TestLoadTimingNotReused(*http_stream); |
217 } | 217 } |
218 | 218 |
219 TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { | 219 TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { |
220 scoped_ptr<SpdyFrame> req1( | 220 scoped_ptr<SpdyFrame> req1( |
221 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); | 221 spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true)); |
222 scoped_ptr<SpdyFrame> req2( | 222 scoped_ptr<SpdyFrame> req2( |
223 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); | 223 spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true)); |
224 MockWrite writes[] = { | 224 MockWrite writes[] = { |
225 CreateMockWrite(*req1, 0), | 225 CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), |
226 CreateMockWrite(*req2, 1), | |
227 }; | 226 }; |
228 scoped_ptr<SpdyFrame> resp1( | 227 scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
229 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | |
230 scoped_ptr<SpdyFrame> body1( | 228 scoped_ptr<SpdyFrame> body1( |
231 spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); | 229 spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); |
232 scoped_ptr<SpdyFrame> resp2( | 230 scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); |
233 spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); | |
234 scoped_ptr<SpdyFrame> body2( | 231 scoped_ptr<SpdyFrame> body2( |
235 spdy_util_.ConstructSpdyBodyFrame(3, "", 0, true)); | 232 spdy_util_.ConstructSpdyBodyFrame(3, "", 0, true)); |
236 MockRead reads[] = { | 233 MockRead reads[] = { |
237 CreateMockRead(*resp1, 2), | 234 CreateMockRead(*resp1, 2), CreateMockRead(*body1, 3), |
238 CreateMockRead(*body1, 3), | 235 CreateMockRead(*resp2, 4), CreateMockRead(*body2, 5), |
239 CreateMockRead(*resp2, 4), | 236 MockRead(ASYNC, 0, 6) // EOF |
240 CreateMockRead(*body2, 5), | |
241 MockRead(ASYNC, 0, 6) // EOF | |
242 }; | 237 }; |
243 | 238 |
244 HostPortPair host_port_pair("www.google.com", 80); | 239 HostPortPair host_port_pair("www.google.com", 80); |
245 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 240 SpdySessionKey key( |
246 PRIVACY_MODE_DISABLED); | 241 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
247 InitSessionDeterministic(reads, arraysize(reads), | 242 InitSessionDeterministic( |
248 writes, arraysize(writes), | 243 reads, arraysize(reads), writes, arraysize(writes), key); |
249 key); | |
250 | 244 |
251 HttpRequestInfo request1; | 245 HttpRequestInfo request1; |
252 request1.method = "GET"; | 246 request1.method = "GET"; |
253 request1.url = GURL("http://www.google.com/"); | 247 request1.url = GURL("http://www.google.com/"); |
254 TestCompletionCallback callback1; | 248 TestCompletionCallback callback1; |
255 HttpResponseInfo response1; | 249 HttpResponseInfo response1; |
256 HttpRequestHeaders headers1; | 250 HttpRequestHeaders headers1; |
257 scoped_ptr<SpdyHttpStream> http_stream1(new SpdyHttpStream(session_, true)); | 251 scoped_ptr<SpdyHttpStream> http_stream1(new SpdyHttpStream(session_, true)); |
258 | 252 |
259 HttpRequestInfo request2; | 253 HttpRequestInfo request2; |
260 request2.method = "GET"; | 254 request2.method = "GET"; |
261 request2.url = GURL("http://www.google.com/"); | 255 request2.url = GURL("http://www.google.com/"); |
262 TestCompletionCallback callback2; | 256 TestCompletionCallback callback2; |
263 HttpResponseInfo response2; | 257 HttpResponseInfo response2; |
264 HttpRequestHeaders headers2; | 258 HttpRequestHeaders headers2; |
265 scoped_ptr<SpdyHttpStream> http_stream2(new SpdyHttpStream(session_, true)); | 259 scoped_ptr<SpdyHttpStream> http_stream2(new SpdyHttpStream(session_, true)); |
266 | 260 |
267 // First write. | 261 // First write. |
268 ASSERT_EQ(OK, | 262 ASSERT_EQ( |
269 http_stream1->InitializeStream(&request1, DEFAULT_PRIORITY, | 263 OK, |
270 BoundNetLog(), | 264 http_stream1->InitializeStream( |
271 CompletionCallback())); | 265 &request1, DEFAULT_PRIORITY, BoundNetLog(), CompletionCallback())); |
272 EXPECT_EQ(ERR_IO_PENDING, http_stream1->SendRequest(headers1, &response1, | 266 EXPECT_EQ( |
273 callback1.callback())); | 267 ERR_IO_PENDING, |
| 268 http_stream1->SendRequest(headers1, &response1, callback1.callback())); |
274 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 269 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
275 | 270 |
276 deterministic_data()->RunFor(1); | 271 deterministic_data()->RunFor(1); |
277 EXPECT_LE(0, callback1.WaitForResult()); | 272 EXPECT_LE(0, callback1.WaitForResult()); |
278 | 273 |
279 TestLoadTimingNotReused(*http_stream1); | 274 TestLoadTimingNotReused(*http_stream1); |
280 LoadTimingInfo load_timing_info1; | 275 LoadTimingInfo load_timing_info1; |
281 LoadTimingInfo load_timing_info2; | 276 LoadTimingInfo load_timing_info2; |
282 EXPECT_TRUE(http_stream1->GetLoadTimingInfo(&load_timing_info1)); | 277 EXPECT_TRUE(http_stream1->GetLoadTimingInfo(&load_timing_info1)); |
283 EXPECT_FALSE(http_stream2->GetLoadTimingInfo(&load_timing_info2)); | 278 EXPECT_FALSE(http_stream2->GetLoadTimingInfo(&load_timing_info2)); |
284 | 279 |
285 // Second write. | 280 // Second write. |
286 ASSERT_EQ(OK, | 281 ASSERT_EQ( |
287 http_stream2->InitializeStream(&request2, DEFAULT_PRIORITY, | 282 OK, |
288 BoundNetLog(), | 283 http_stream2->InitializeStream( |
289 CompletionCallback())); | 284 &request2, DEFAULT_PRIORITY, BoundNetLog(), CompletionCallback())); |
290 EXPECT_EQ(ERR_IO_PENDING, http_stream2->SendRequest(headers2, &response2, | 285 EXPECT_EQ( |
291 callback2.callback())); | 286 ERR_IO_PENDING, |
| 287 http_stream2->SendRequest(headers2, &response2, callback2.callback())); |
292 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 288 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
293 | 289 |
294 deterministic_data()->RunFor(1); | 290 deterministic_data()->RunFor(1); |
295 EXPECT_LE(0, callback2.WaitForResult()); | 291 EXPECT_LE(0, callback2.WaitForResult()); |
296 TestLoadTimingReused(*http_stream2); | 292 TestLoadTimingReused(*http_stream2); |
297 EXPECT_TRUE(http_stream2->GetLoadTimingInfo(&load_timing_info2)); | 293 EXPECT_TRUE(http_stream2->GetLoadTimingInfo(&load_timing_info2)); |
298 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); | 294 EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id); |
299 | 295 |
300 // All the reads. | 296 // All the reads. |
301 deterministic_data()->RunFor(6); | 297 deterministic_data()->RunFor(6); |
302 | 298 |
303 // Read stream 1 to completion, before making sure we can still read load | 299 // Read stream 1 to completion, before making sure we can still read load |
304 // timing from both streams. | 300 // timing from both streams. |
305 scoped_refptr<IOBuffer> buf1(new IOBuffer(1)); | 301 scoped_refptr<IOBuffer> buf1(new IOBuffer(1)); |
306 ASSERT_EQ( | 302 ASSERT_EQ( |
307 0, http_stream1->ReadResponseBody(buf1.get(), 1, callback1.callback())); | 303 0, http_stream1->ReadResponseBody(buf1.get(), 1, callback1.callback())); |
308 | 304 |
309 // Stream 1 has been read to completion. | 305 // Stream 1 has been read to completion. |
310 TestLoadTimingNotReused(*http_stream1); | 306 TestLoadTimingNotReused(*http_stream1); |
311 // Stream 2 still has queued body data. | 307 // Stream 2 still has queued body data. |
312 TestLoadTimingReused(*http_stream2); | 308 TestLoadTimingReused(*http_stream2); |
313 } | 309 } |
314 | 310 |
315 TEST_P(SpdyHttpStreamTest, SendChunkedPost) { | 311 TEST_P(SpdyHttpStreamTest, SendChunkedPost) { |
316 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); | 312 BufferedSpdyFramer framer(spdy_util_.spdy_version(), false); |
317 | 313 |
318 scoped_ptr<SpdyFrame> req( | 314 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); |
319 spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | |
320 scoped_ptr<SpdyFrame> body( | 315 scoped_ptr<SpdyFrame> body( |
321 framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_FIN)); | 316 framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_FIN)); |
322 std::vector<MockWrite> writes; | 317 std::vector<MockWrite> writes; |
323 int seq = 0; | 318 int seq = 0; |
324 writes.push_back(CreateMockWrite(*req, seq++)); | 319 writes.push_back(CreateMockWrite(*req, seq++)); |
325 writes.push_back(CreateMockWrite(*body, seq++)); // POST upload frame | 320 writes.push_back(CreateMockWrite(*body, seq++)); // POST upload frame |
326 | 321 |
327 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | 322 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); |
328 std::vector<MockRead> reads; | 323 std::vector<MockRead> reads; |
329 reads.push_back(CreateMockRead(*resp, seq++)); | 324 reads.push_back(CreateMockRead(*resp, seq++)); |
330 reads.push_back(CreateMockRead(*body, seq++)); | 325 reads.push_back(CreateMockRead(*body, seq++)); |
331 reads.push_back(MockRead(SYNCHRONOUS, 0, seq++)); // EOF | 326 reads.push_back(MockRead(SYNCHRONOUS, 0, seq++)); // EOF |
332 | 327 |
333 HostPortPair host_port_pair("www.google.com", 80); | 328 HostPortPair host_port_pair("www.google.com", 80); |
334 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 329 SpdySessionKey key( |
335 PRIVACY_MODE_DISABLED); | 330 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
336 InitSession(vector_as_array(&reads), reads.size(), | 331 InitSession(vector_as_array(&reads), |
337 vector_as_array(&writes), writes.size(), | 332 reads.size(), |
| 333 vector_as_array(&writes), |
| 334 writes.size(), |
338 key); | 335 key); |
339 EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion()); | 336 EXPECT_EQ(spdy_util_.spdy_version(), session_->GetProtocolVersion()); |
340 | 337 |
341 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | 338 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); |
342 const int kFirstChunkSize = kUploadDataSize/2; | 339 const int kFirstChunkSize = kUploadDataSize / 2; |
343 upload_stream.AppendChunk(kUploadData, kFirstChunkSize, false); | 340 upload_stream.AppendChunk(kUploadData, kFirstChunkSize, false); |
344 upload_stream.AppendChunk(kUploadData + kFirstChunkSize, | 341 upload_stream.AppendChunk( |
345 kUploadDataSize - kFirstChunkSize, true); | 342 kUploadData + kFirstChunkSize, kUploadDataSize - kFirstChunkSize, true); |
346 | 343 |
347 HttpRequestInfo request; | 344 HttpRequestInfo request; |
348 request.method = "POST"; | 345 request.method = "POST"; |
349 request.url = GURL("http://www.google.com/"); | 346 request.url = GURL("http://www.google.com/"); |
350 request.upload_data_stream = &upload_stream; | 347 request.upload_data_stream = &upload_stream; |
351 | 348 |
352 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | 349 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); |
353 | 350 |
354 TestCompletionCallback callback; | 351 TestCompletionCallback callback; |
355 HttpResponseInfo response; | 352 HttpResponseInfo response; |
356 HttpRequestHeaders headers; | 353 HttpRequestHeaders headers; |
357 BoundNetLog net_log; | 354 BoundNetLog net_log; |
358 SpdyHttpStream http_stream(session_, true); | 355 SpdyHttpStream http_stream(session_, true); |
359 ASSERT_EQ( | 356 ASSERT_EQ(OK, |
360 OK, | 357 http_stream.InitializeStream( |
361 http_stream.InitializeStream(&request, DEFAULT_PRIORITY, | 358 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); |
362 net_log, CompletionCallback())); | |
363 | 359 |
364 EXPECT_EQ(ERR_IO_PENDING, http_stream.SendRequest( | 360 EXPECT_EQ(ERR_IO_PENDING, |
365 headers, &response, callback.callback())); | 361 http_stream.SendRequest(headers, &response, callback.callback())); |
366 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 362 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
367 | 363 |
368 // This results in writing the post body and reading the response headers. | 364 // This results in writing the post body and reading the response headers. |
369 callback.WaitForResult(); | 365 callback.WaitForResult(); |
370 | 366 |
371 // This triggers reading the body and the EOF, causing the session to shut | 367 // This triggers reading the body and the EOF, causing the session to shut |
372 // down. | 368 // down. |
373 data()->CompleteRead(); | 369 data()->CompleteRead(); |
374 base::MessageLoop::current()->RunUntilIdle(); | 370 base::MessageLoop::current()->RunUntilIdle(); |
375 | 371 |
376 // Because we abandoned the stream, we don't expect to find a session in the | 372 // Because we abandoned the stream, we don't expect to find a session in the |
377 // pool anymore. | 373 // pool anymore. |
378 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 374 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
379 EXPECT_TRUE(data()->at_read_eof()); | 375 EXPECT_TRUE(data()->at_read_eof()); |
380 EXPECT_TRUE(data()->at_write_eof()); | 376 EXPECT_TRUE(data()->at_write_eof()); |
381 } | 377 } |
382 | 378 |
383 // Test to ensure the SpdyStream state machine does not get confused when a | 379 // Test to ensure the SpdyStream state machine does not get confused when a |
384 // chunk becomes available while a write is pending. | 380 // chunk becomes available while a write is pending. |
385 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { | 381 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { |
386 const char kUploadData1[] = "12345678"; | 382 const char kUploadData1[] = "12345678"; |
387 const int kUploadData1Size = arraysize(kUploadData1)-1; | 383 const int kUploadData1Size = arraysize(kUploadData1) - 1; |
388 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | 384 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); |
389 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false)); | 385 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, false)); |
390 scoped_ptr<SpdyFrame> chunk2( | 386 scoped_ptr<SpdyFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame( |
391 spdy_util_.ConstructSpdyBodyFrame( | 387 1, kUploadData1, kUploadData1Size, false)); |
392 1, kUploadData1, kUploadData1Size, false)); | |
393 scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 388 scoped_ptr<SpdyFrame> chunk3(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
394 MockWrite writes[] = { | 389 MockWrite writes[] = { |
395 CreateMockWrite(*req.get(), 0), | 390 CreateMockWrite(*req.get(), 0), |
396 CreateMockWrite(*chunk1, 1), // POST upload frames | 391 CreateMockWrite(*chunk1, 1), // POST upload frames |
397 CreateMockWrite(*chunk2, 2), | 392 CreateMockWrite(*chunk2, 2), CreateMockWrite(*chunk3, 3), |
398 CreateMockWrite(*chunk3, 3), | |
399 }; | 393 }; |
400 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | 394 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); |
401 MockRead reads[] = { | 395 MockRead reads[] = { |
402 CreateMockRead(*resp, 4), | 396 CreateMockRead(*resp, 4), CreateMockRead(*chunk1, 5), |
403 CreateMockRead(*chunk1, 5), | 397 CreateMockRead(*chunk2, 6), CreateMockRead(*chunk3, 7), |
404 CreateMockRead(*chunk2, 6), | 398 MockRead(ASYNC, 0, 8) // EOF |
405 CreateMockRead(*chunk3, 7), | |
406 MockRead(ASYNC, 0, 8) // EOF | |
407 }; | 399 }; |
408 | 400 |
409 HostPortPair host_port_pair("www.google.com", 80); | 401 HostPortPair host_port_pair("www.google.com", 80); |
410 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 402 SpdySessionKey key( |
411 PRIVACY_MODE_DISABLED); | 403 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
412 InitSessionDeterministic(reads, arraysize(reads), | 404 InitSessionDeterministic( |
413 writes, arraysize(writes), | 405 reads, arraysize(reads), writes, arraysize(writes), key); |
414 key); | |
415 | 406 |
416 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | 407 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); |
417 | 408 |
418 HttpRequestInfo request; | 409 HttpRequestInfo request; |
419 request.method = "POST"; | 410 request.method = "POST"; |
420 request.url = GURL("http://www.google.com/"); | 411 request.url = GURL("http://www.google.com/"); |
421 request.upload_data_stream = &upload_stream; | 412 request.upload_data_stream = &upload_stream; |
422 | 413 |
423 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | 414 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); |
424 upload_stream.AppendChunk(kUploadData, kUploadDataSize, false); | 415 upload_stream.AppendChunk(kUploadData, kUploadDataSize, false); |
425 | 416 |
426 BoundNetLog net_log; | 417 BoundNetLog net_log; |
427 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | 418 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); |
428 ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, | 419 ASSERT_EQ(OK, |
429 net_log, CompletionCallback())); | 420 http_stream->InitializeStream( |
| 421 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); |
430 | 422 |
431 TestCompletionCallback callback; | 423 TestCompletionCallback callback; |
432 HttpRequestHeaders headers; | 424 HttpRequestHeaders headers; |
433 HttpResponseInfo response; | 425 HttpResponseInfo response; |
434 // This will attempt to Write() the initial request and headers, which will | 426 // This will attempt to Write() the initial request and headers, which will |
435 // complete asynchronously. | 427 // complete asynchronously. |
436 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | 428 EXPECT_EQ(ERR_IO_PENDING, |
437 callback.callback())); | 429 http_stream->SendRequest(headers, &response, callback.callback())); |
438 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 430 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
439 | 431 |
440 // Complete the initial request write and the first chunk. | 432 // Complete the initial request write and the first chunk. |
441 deterministic_data()->RunFor(2); | 433 deterministic_data()->RunFor(2); |
442 ASSERT_TRUE(callback.have_result()); | 434 ASSERT_TRUE(callback.have_result()); |
443 EXPECT_EQ(OK, callback.WaitForResult()); | 435 EXPECT_EQ(OK, callback.WaitForResult()); |
444 | 436 |
445 // Now append the final two chunks which will enqueue two more writes. | 437 // Now append the final two chunks which will enqueue two more writes. |
446 upload_stream.AppendChunk(kUploadData1, kUploadData1Size, false); | 438 upload_stream.AppendChunk(kUploadData1, kUploadData1Size, false); |
447 upload_stream.AppendChunk(kUploadData, kUploadDataSize, true); | 439 upload_stream.AppendChunk(kUploadData, kUploadDataSize, true); |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 // Finish reading the |EOF|. | 472 // Finish reading the |EOF|. |
481 deterministic_data()->RunFor(1); | 473 deterministic_data()->RunFor(1); |
482 ASSERT_TRUE(response.headers.get()); | 474 ASSERT_TRUE(response.headers.get()); |
483 ASSERT_EQ(200, response.headers->response_code()); | 475 ASSERT_EQ(200, response.headers->response_code()); |
484 EXPECT_TRUE(deterministic_data()->at_read_eof()); | 476 EXPECT_TRUE(deterministic_data()->at_read_eof()); |
485 EXPECT_TRUE(deterministic_data()->at_write_eof()); | 477 EXPECT_TRUE(deterministic_data()->at_write_eof()); |
486 } | 478 } |
487 | 479 |
488 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 | 480 // Test case for bug: http://code.google.com/p/chromium/issues/detail?id=50058 |
489 TEST_P(SpdyHttpStreamTest, SpdyURLTest) { | 481 TEST_P(SpdyHttpStreamTest, SpdyURLTest) { |
490 const char * const full_url = "http://www.google.com/foo?query=what#anchor"; | 482 const char* const full_url = "http://www.google.com/foo?query=what#anchor"; |
491 const char * const base_url = "http://www.google.com/foo?query=what"; | 483 const char* const base_url = "http://www.google.com/foo?query=what"; |
492 scoped_ptr<SpdyFrame> req( | 484 scoped_ptr<SpdyFrame> req( |
493 spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST)); | 485 spdy_util_.ConstructSpdyGet(base_url, false, 1, LOWEST)); |
494 MockWrite writes[] = { | 486 MockWrite writes[] = { |
495 CreateMockWrite(*req.get(), 1), | 487 CreateMockWrite(*req.get(), 1), |
496 }; | 488 }; |
497 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); | 489 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); |
498 MockRead reads[] = { | 490 MockRead reads[] = { |
499 CreateMockRead(*resp, 2), | 491 CreateMockRead(*resp, 2), MockRead(SYNCHRONOUS, 0, 3) // EOF |
500 MockRead(SYNCHRONOUS, 0, 3) // EOF | |
501 }; | 492 }; |
502 | 493 |
503 HostPortPair host_port_pair("www.google.com", 80); | 494 HostPortPair host_port_pair("www.google.com", 80); |
504 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 495 SpdySessionKey key( |
505 PRIVACY_MODE_DISABLED); | 496 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
506 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); | 497 InitSession(reads, arraysize(reads), writes, arraysize(writes), key); |
507 | 498 |
508 HttpRequestInfo request; | 499 HttpRequestInfo request; |
509 request.method = "GET"; | 500 request.method = "GET"; |
510 request.url = GURL(full_url); | 501 request.url = GURL(full_url); |
511 TestCompletionCallback callback; | 502 TestCompletionCallback callback; |
512 HttpResponseInfo response; | 503 HttpResponseInfo response; |
513 HttpRequestHeaders headers; | 504 HttpRequestHeaders headers; |
514 BoundNetLog net_log; | 505 BoundNetLog net_log; |
515 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | 506 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); |
516 ASSERT_EQ(OK, | 507 ASSERT_EQ(OK, |
517 http_stream->InitializeStream( | 508 http_stream->InitializeStream( |
518 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); | 509 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); |
519 | 510 |
520 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | 511 EXPECT_EQ(ERR_IO_PENDING, |
521 callback.callback())); | 512 http_stream->SendRequest(headers, &response, callback.callback())); |
522 | 513 |
523 EXPECT_EQ(base_url, http_stream->stream()->GetUrlFromHeaders().spec()); | 514 EXPECT_EQ(base_url, http_stream->stream()->GetUrlFromHeaders().spec()); |
524 | 515 |
525 // This triggers the MockWrite and read 2 | 516 // This triggers the MockWrite and read 2 |
526 callback.WaitForResult(); | 517 callback.WaitForResult(); |
527 | 518 |
528 // This triggers read 3. The empty read causes the session to shut down. | 519 // This triggers read 3. The empty read causes the session to shut down. |
529 data()->CompleteRead(); | 520 data()->CompleteRead(); |
530 | 521 |
531 // Because we abandoned the stream, we don't expect to find a session in the | 522 // Because we abandoned the stream, we don't expect to find a session in the |
532 // pool anymore. | 523 // pool anymore. |
533 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 524 EXPECT_FALSE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
534 EXPECT_TRUE(data()->at_read_eof()); | 525 EXPECT_TRUE(data()->at_read_eof()); |
535 EXPECT_TRUE(data()->at_write_eof()); | 526 EXPECT_TRUE(data()->at_write_eof()); |
536 } | 527 } |
537 | 528 |
538 // The tests below are only for SPDY/3 and above. | 529 // The tests below are only for SPDY/3 and above. |
539 | 530 |
540 // Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be | 531 // Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be |
541 // made available is handled correctly. | 532 // made available is handled correctly. |
542 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) { | 533 TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) { |
543 if (GetParam() < kProtoSPDY3) | 534 if (GetParam() < kProtoSPDY3) |
544 return; | 535 return; |
545 | 536 |
546 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); | 537 scoped_ptr<SpdyFrame> req(spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); |
547 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, true)); | 538 scoped_ptr<SpdyFrame> chunk1(spdy_util_.ConstructSpdyBodyFrame(1, true)); |
548 MockWrite writes[] = { | 539 MockWrite writes[] = { |
549 CreateMockWrite(*req.get(), 0), | 540 CreateMockWrite(*req.get(), 0), CreateMockWrite(*chunk1, 1), |
550 CreateMockWrite(*chunk1, 1), | |
551 }; | 541 }; |
552 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); | 542 scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); |
553 scoped_ptr<SpdyFrame> window_update( | 543 scoped_ptr<SpdyFrame> window_update( |
554 spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); | 544 spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); |
555 MockRead reads[] = { | 545 MockRead reads[] = { |
556 CreateMockRead(*window_update, 2), | 546 CreateMockRead(*window_update, 2), CreateMockRead(*resp, 3), |
557 CreateMockRead(*resp, 3), | 547 CreateMockRead(*chunk1, 4), MockRead(ASYNC, 0, 5) // EOF |
558 CreateMockRead(*chunk1, 4), | |
559 MockRead(ASYNC, 0, 5) // EOF | |
560 }; | 548 }; |
561 | 549 |
562 HostPortPair host_port_pair("www.google.com", 80); | 550 HostPortPair host_port_pair("www.google.com", 80); |
563 SpdySessionKey key(host_port_pair, ProxyServer::Direct(), | 551 SpdySessionKey key( |
564 PRIVACY_MODE_DISABLED); | 552 host_port_pair, ProxyServer::Direct(), PRIVACY_MODE_DISABLED); |
565 | 553 |
566 InitSessionDeterministic(reads, arraysize(reads), | 554 InitSessionDeterministic( |
567 writes, arraysize(writes), | 555 reads, arraysize(reads), writes, arraysize(writes), key); |
568 key); | |
569 | 556 |
570 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); | 557 UploadDataStream upload_stream(UploadDataStream::CHUNKED, 0); |
571 | 558 |
572 HttpRequestInfo request; | 559 HttpRequestInfo request; |
573 request.method = "POST"; | 560 request.method = "POST"; |
574 request.url = GURL("http://www.google.com/"); | 561 request.url = GURL("http://www.google.com/"); |
575 request.upload_data_stream = &upload_stream; | 562 request.upload_data_stream = &upload_stream; |
576 | 563 |
577 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); | 564 ASSERT_EQ(OK, upload_stream.Init(CompletionCallback())); |
578 upload_stream.AppendChunk(kUploadData, kUploadDataSize, true); | 565 upload_stream.AppendChunk(kUploadData, kUploadDataSize, true); |
579 | 566 |
580 BoundNetLog net_log; | 567 BoundNetLog net_log; |
581 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); | 568 scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); |
582 ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, | 569 ASSERT_EQ(OK, |
583 net_log, CompletionCallback())); | 570 http_stream->InitializeStream( |
| 571 &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); |
584 | 572 |
585 HttpRequestHeaders headers; | 573 HttpRequestHeaders headers; |
586 HttpResponseInfo response; | 574 HttpResponseInfo response; |
587 // This will attempt to Write() the initial request and headers, which will | 575 // This will attempt to Write() the initial request and headers, which will |
588 // complete asynchronously. | 576 // complete asynchronously. |
589 TestCompletionCallback callback; | 577 TestCompletionCallback callback; |
590 EXPECT_EQ(ERR_IO_PENDING, http_stream->SendRequest(headers, &response, | 578 EXPECT_EQ(ERR_IO_PENDING, |
591 callback.callback())); | 579 http_stream->SendRequest(headers, &response, callback.callback())); |
592 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); | 580 EXPECT_TRUE(HasSpdySession(http_session_->spdy_session_pool(), key)); |
593 | 581 |
594 // Complete the initial request write and first chunk. | 582 // Complete the initial request write and first chunk. |
595 deterministic_data_->RunFor(2); | 583 deterministic_data_->RunFor(2); |
596 ASSERT_TRUE(callback.have_result()); | 584 ASSERT_TRUE(callback.have_result()); |
597 EXPECT_EQ(OK, callback.WaitForResult()); | 585 EXPECT_EQ(OK, callback.WaitForResult()); |
598 | 586 |
599 // Verify that the window size has decreased. | 587 // Verify that the window size has decreased. |
600 ASSERT_TRUE(http_stream->stream() != NULL); | 588 ASSERT_TRUE(http_stream->stream() != NULL); |
601 EXPECT_NE(static_cast<int>(kSpdyStreamInitialWindowSize), | 589 EXPECT_NE(static_cast<int>(kSpdyStreamInitialWindowSize), |
(...skipping 24 matching lines...) Expand all Loading... |
626 ASSERT_TRUE(response.headers.get()); | 614 ASSERT_TRUE(response.headers.get()); |
627 ASSERT_EQ(200, response.headers->response_code()); | 615 ASSERT_EQ(200, response.headers->response_code()); |
628 EXPECT_TRUE(deterministic_data_->at_read_eof()); | 616 EXPECT_TRUE(deterministic_data_->at_read_eof()); |
629 EXPECT_TRUE(deterministic_data_->at_write_eof()); | 617 EXPECT_TRUE(deterministic_data_->at_write_eof()); |
630 } | 618 } |
631 | 619 |
632 // TODO(willchan): Write a longer test for SpdyStream that exercises all | 620 // TODO(willchan): Write a longer test for SpdyStream that exercises all |
633 // methods. | 621 // methods. |
634 | 622 |
635 } // namespace net | 623 } // namespace net |
OLD | NEW |