| 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 |