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 3 // found in the LICENSE file. 4 5 #include "net/http/http_pipelined_connection_impl.h" 6 7 #include <string> 8 9 #include "base/memory/ref_counted.h" 10 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_vector.h" 12 #include "net/base/capturing_net_log.h" 13 #include "net/base/io_buffer.h" 14 #include "net/base/load_timing_info.h" 15 #include "net/base/load_timing_info_test_util.h" 16 #include "net/base/net_errors.h" 17 #include "net/base/request_priority.h" 18 #include "net/http/http_pipelined_stream.h" 19 #include "net/socket/client_socket_handle.h" 20 #include "net/socket/client_socket_pool_histograms.h" 21 #include "net/socket/socket_test_util.h" 22 #include "testing/gmock/include/gmock/gmock.h" 23 #include "testing/gtest/include/gtest/gtest.h" 24 25 using testing::_; 26 using testing::NiceMock; 27 using testing::StrEq; 28 29 namespace net { 30 31 namespace { 32 33 // Tests the load timing of a stream that's connected and is not the first 34 // request sent on a connection. 35 void TestLoadTimingReused(const HttpStream& stream) { 36 LoadTimingInfo load_timing_info; 37 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info)); 38 39 EXPECT_TRUE(load_timing_info.socket_reused); 40 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 41 42 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing); 43 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); 44 } 45 46 // Tests the load timing of a stream that's connected and using a fresh 47 // connection. 48 void TestLoadTimingNotReused(const HttpStream& stream) { 49 LoadTimingInfo load_timing_info; 50 EXPECT_TRUE(stream.GetLoadTimingInfo(&load_timing_info)); 51 52 EXPECT_FALSE(load_timing_info.socket_reused); 53 EXPECT_NE(NetLog::Source::kInvalidId, load_timing_info.socket_log_id); 54 55 ExpectConnectTimingHasTimes(load_timing_info.connect_timing, 56 CONNECT_TIMING_HAS_DNS_TIMES); 57 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info); 58 } 59 60 class MockPipelineDelegate : public HttpPipelinedConnection::Delegate { 61 public: 62 MOCK_METHOD1(OnPipelineHasCapacity, void(HttpPipelinedConnection* pipeline)); 63 MOCK_METHOD2(OnPipelineFeedback, void( 64 HttpPipelinedConnection* pipeline, 65 HttpPipelinedConnection::Feedback feedback)); 66 }; 67 68 class SuddenCloseObserver : public base::MessageLoop::TaskObserver { 69 public: 70 SuddenCloseObserver(HttpStream* stream, int close_before_task) 71 : stream_(stream), 72 close_before_task_(close_before_task), 73 current_task_(0) { } 74 75 virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE { 76 ++current_task_; 77 if (current_task_ == close_before_task_) { 78 stream_->Close(false); 79 base::MessageLoop::current()->RemoveTaskObserver(this); 80 } 81 } 82 83 virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {} 84 85 private: 86 HttpStream* stream_; 87 int close_before_task_; 88 int current_task_; 89 }; 90 91 class HttpPipelinedConnectionImplTest : public testing::Test { 92 public: 93 HttpPipelinedConnectionImplTest() 94 : histograms_("a"), 95 pool_(1, 1, &histograms_, &factory_), 96 origin_("host", 123) { 97 } 98 99 void TearDown() { 100 base::MessageLoop::current()->RunUntilIdle(); 101 } 102 103 void Initialize(MockRead* reads, size_t reads_count, 104 MockWrite* writes, size_t writes_count) { 105 data_.reset(new DeterministicSocketData(reads, reads_count, 106 writes, writes_count)); 107 data_->set_connect_data(MockConnect(SYNCHRONOUS, OK)); 108 if (reads_count || writes_count) { 109 data_->StopAfter(reads_count + writes_count); 110 } 111 factory_.AddSocketDataProvider(data_.get()); 112 scoped_refptr<MockTransportSocketParams> params; 113 ClientSocketHandle* connection = new ClientSocketHandle; 114 // Only give the connection a real NetLog to make sure that LoadTiming uses 115 // the connection's ID, rather than the pipeline's. Since pipelines are 116 // destroyed when they've responded to all requests, but the connection 117 // lives on, this is an important behavior. 118 connection->Init("a", params, MEDIUM, CompletionCallback(), &pool_, 119 net_log_.bound()); 120 pipeline_.reset(new HttpPipelinedConnectionImpl( 121 connection, &delegate_, origin_, ssl_config_, proxy_info_, 122 BoundNetLog(), false, kProtoUnknown)); 123 } 124 125 HttpRequestInfo* GetRequestInfo(const std::string& filename) { 126 HttpRequestInfo* request_info = new HttpRequestInfo; 127 request_info->url = GURL("http://localhost/" + filename); 128 request_info->method = "GET"; 129 request_info_vector_.push_back(request_info); 130 return request_info; 131 } 132 133 HttpStream* NewTestStream(const std::string& filename) { 134 HttpStream* stream = pipeline_->CreateNewStream(); 135 HttpRequestInfo* request_info = GetRequestInfo(filename); 136 int rv = stream->InitializeStream( 137 request_info, DEFAULT_PRIORITY, BoundNetLog(), CompletionCallback()); 138 DCHECK_EQ(OK, rv); 139 return stream; 140 } 141 142 void ExpectResponse(const std::string& expected, 143 scoped_ptr<HttpStream>& stream, bool async) { 144 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); 145 146 if (async) { 147 EXPECT_EQ(ERR_IO_PENDING, 148 stream->ReadResponseBody(buffer.get(), expected.size(), 149 callback_.callback())); 150 data_->RunFor(1); 151 EXPECT_EQ(static_cast<int>(expected.size()), callback_.WaitForResult()); 152 } else { 153 EXPECT_EQ(static_cast<int>(expected.size()), 154 stream->ReadResponseBody(buffer.get(), expected.size(), 155 callback_.callback())); 156 } 157 std::string actual(buffer->data(), expected.size()); 158 EXPECT_THAT(actual, StrEq(expected)); 159 } 160 161 void TestSyncRequest(scoped_ptr<HttpStream>& stream, 162 const std::string& filename) { 163 HttpRequestHeaders headers; 164 HttpResponseInfo response; 165 EXPECT_EQ(OK, stream->SendRequest(headers, &response, 166 callback_.callback())); 167 EXPECT_EQ(OK, stream->ReadResponseHeaders(callback_.callback())); 168 ExpectResponse(filename, stream, false); 169 170 stream->Close(false); 171 } 172 173 CapturingBoundNetLog net_log_; 174 DeterministicMockClientSocketFactory factory_; 175 ClientSocketPoolHistograms histograms_; 176 MockTransportClientSocketPool pool_; 177 scoped_ptr<DeterministicSocketData> data_; 178 179 HostPortPair origin_; 180 SSLConfig ssl_config_; 181 ProxyInfo proxy_info_; 182 NiceMock<MockPipelineDelegate> delegate_; 183 TestCompletionCallback callback_; 184 scoped_ptr<HttpPipelinedConnectionImpl> pipeline_; 185 ScopedVector<HttpRequestInfo> request_info_vector_; 186 }; 187 188 TEST_F(HttpPipelinedConnectionImplTest, PipelineNotUsed) { 189 Initialize(NULL, 0, NULL, 0); 190 } 191 192 TEST_F(HttpPipelinedConnectionImplTest, StreamNotUsed) { 193 Initialize(NULL, 0, NULL, 0); 194 195 scoped_ptr<HttpStream> stream(pipeline_->CreateNewStream()); 196 197 stream->Close(false); 198 } 199 200 TEST_F(HttpPipelinedConnectionImplTest, StreamBoundButNotUsed) { 201 Initialize(NULL, 0, NULL, 0); 202 203 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 204 205 TestLoadTimingNotReused(*stream); 206 stream->Close(false); 207 TestLoadTimingNotReused(*stream); 208 } 209 210 TEST_F(HttpPipelinedConnectionImplTest, SyncSingleRequest) { 211 MockWrite writes[] = { 212 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 213 }; 214 MockRead reads[] = { 215 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 216 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"), 217 MockRead(SYNCHRONOUS, 3, "ok.html"), 218 }; 219 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 220 221 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 222 TestLoadTimingNotReused(*stream); 223 TestSyncRequest(stream, "ok.html"); 224 TestLoadTimingNotReused(*stream); 225 } 226 227 TEST_F(HttpPipelinedConnectionImplTest, AsyncSingleRequest) { 228 MockWrite writes[] = { 229 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 230 }; 231 MockRead reads[] = { 232 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), 233 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"), 234 MockRead(ASYNC, 3, "ok.html"), 235 }; 236 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 237 238 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 239 240 HttpRequestHeaders headers; 241 HttpResponseInfo response; 242 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response, 243 callback_.callback())); 244 data_->RunFor(1); 245 EXPECT_LE(OK, callback_.WaitForResult()); 246 TestLoadTimingNotReused(*stream); 247 248 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback())); 249 data_->RunFor(2); 250 EXPECT_LE(OK, callback_.WaitForResult()); 251 TestLoadTimingNotReused(*stream); 252 253 ExpectResponse("ok.html", stream, true); 254 TestLoadTimingNotReused(*stream); 255 256 stream->Close(false); 257 } 258 259 TEST_F(HttpPipelinedConnectionImplTest, LockStepAsyncRequests) { 260 MockWrite writes[] = { 261 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 262 MockWrite(ASYNC, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), 263 }; 264 MockRead reads[] = { 265 MockRead(ASYNC, 2, "HTTP/1.1 200 OK\r\n"), 266 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"), 267 MockRead(ASYNC, 4, "ok.html"), 268 MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\n"), 269 MockRead(ASYNC, 6, "Content-Length: 7\r\n\r\n"), 270 MockRead(ASYNC, 7, "ko.html"), 271 }; 272 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 273 274 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 275 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 276 277 HttpRequestHeaders headers1; 278 HttpResponseInfo response1; 279 EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequest(headers1, &response1, 280 callback_.callback())); 281 TestLoadTimingNotReused(*stream1); 282 283 HttpRequestHeaders headers2; 284 HttpResponseInfo response2; 285 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2, 286 callback_.callback())); 287 TestLoadTimingReused(*stream2); 288 289 data_->RunFor(1); 290 EXPECT_LE(OK, callback_.WaitForResult()); 291 data_->RunFor(1); 292 EXPECT_LE(OK, callback_.WaitForResult()); 293 294 EXPECT_EQ(ERR_IO_PENDING, stream1->ReadResponseHeaders(callback_.callback())); 295 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback_.callback())); 296 297 data_->RunFor(2); 298 EXPECT_LE(OK, callback_.WaitForResult()); 299 300 ExpectResponse("ok.html", stream1, true); 301 302 TestLoadTimingNotReused(*stream1); 303 LoadTimingInfo load_timing_info1; 304 EXPECT_TRUE(stream1->GetLoadTimingInfo(&load_timing_info1)); 305 stream1->Close(false); 306 307 data_->RunFor(2); 308 EXPECT_LE(OK, callback_.WaitForResult()); 309 310 ExpectResponse("ko.html", stream2, true); 311 312 TestLoadTimingReused(*stream2); 313 LoadTimingInfo load_timing_info2; 314 EXPECT_TRUE(stream2->GetLoadTimingInfo(&load_timing_info2)); 315 EXPECT_EQ(load_timing_info1.socket_log_id, 316 load_timing_info2.socket_log_id); 317 stream2->Close(false); 318 } 319 320 TEST_F(HttpPipelinedConnectionImplTest, TwoResponsesInOnePacket) { 321 MockWrite writes[] = { 322 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 323 MockWrite(SYNCHRONOUS, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), 324 }; 325 MockRead reads[] = { 326 MockRead(SYNCHRONOUS, 2, 327 "HTTP/1.1 200 OK\r\n" 328 "Content-Length: 7\r\n\r\n" 329 "ok.html" 330 "HTTP/1.1 200 OK\r\n" 331 "Content-Length: 7\r\n\r\n" 332 "ko.html"), 333 }; 334 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 335 336 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 337 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 338 339 HttpRequestHeaders headers1; 340 HttpResponseInfo response1; 341 EXPECT_EQ(OK, stream1->SendRequest(headers1, 342 &response1, callback_.callback())); 343 HttpRequestHeaders headers2; 344 HttpResponseInfo response2; 345 EXPECT_EQ(OK, stream2->SendRequest(headers2, 346 &response2, callback_.callback())); 347 348 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 349 ExpectResponse("ok.html", stream1, false); 350 stream1->Close(false); 351 352 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback())); 353 ExpectResponse("ko.html", stream2, false); 354 stream2->Close(false); 355 } 356 357 TEST_F(HttpPipelinedConnectionImplTest, SendOrderSwapped) { 358 MockWrite writes[] = { 359 MockWrite(SYNCHRONOUS, 0, "GET /ko.html HTTP/1.1\r\n\r\n"), 360 MockWrite(SYNCHRONOUS, 4, "GET /ok.html HTTP/1.1\r\n\r\n"), 361 }; 362 MockRead reads[] = { 363 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 364 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"), 365 MockRead(SYNCHRONOUS, 3, "ko.html"), 366 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 367 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"), 368 MockRead(SYNCHRONOUS, 7, "ok.html"), 369 }; 370 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 371 372 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 373 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 374 375 TestSyncRequest(stream2, "ko.html"); 376 TestSyncRequest(stream1, "ok.html"); 377 TestLoadTimingNotReused(*stream1); 378 TestLoadTimingReused(*stream2); 379 } 380 381 TEST_F(HttpPipelinedConnectionImplTest, ReadOrderSwapped) { 382 MockWrite writes[] = { 383 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 384 MockWrite(SYNCHRONOUS, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), 385 }; 386 MockRead reads[] = { 387 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 388 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 389 MockRead(SYNCHRONOUS, 4, "ok.html"), 390 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 391 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"), 392 MockRead(SYNCHRONOUS, 7, "ko.html"), 393 }; 394 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 395 396 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 397 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 398 399 HttpRequestHeaders headers1; 400 HttpResponseInfo response1; 401 EXPECT_EQ(OK, stream1->SendRequest(headers1, 402 &response1, callback_.callback())); 403 404 HttpRequestHeaders headers2; 405 HttpResponseInfo response2; 406 EXPECT_EQ(OK, stream2->SendRequest(headers2, 407 &response2, callback_.callback())); 408 409 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback_.callback())); 410 411 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 412 ExpectResponse("ok.html", stream1, false); 413 414 stream1->Close(false); 415 416 EXPECT_LE(OK, callback_.WaitForResult()); 417 ExpectResponse("ko.html", stream2, false); 418 419 stream2->Close(false); 420 } 421 422 TEST_F(HttpPipelinedConnectionImplTest, SendWhileReading) { 423 MockWrite writes[] = { 424 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 425 MockWrite(SYNCHRONOUS, 3, "GET /ko.html HTTP/1.1\r\n\r\n"), 426 }; 427 MockRead reads[] = { 428 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 429 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"), 430 MockRead(SYNCHRONOUS, 4, "ok.html"), 431 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 432 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"), 433 MockRead(SYNCHRONOUS, 7, "ko.html"), 434 }; 435 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 436 437 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 438 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 439 440 HttpRequestHeaders headers1; 441 HttpResponseInfo response1; 442 EXPECT_EQ(OK, stream1->SendRequest(headers1, 443 &response1, callback_.callback())); 444 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 445 446 HttpRequestHeaders headers2; 447 HttpResponseInfo response2; 448 EXPECT_EQ(OK, stream2->SendRequest(headers2, 449 &response2, callback_.callback())); 450 451 ExpectResponse("ok.html", stream1, false); 452 stream1->Close(false); 453 454 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback())); 455 ExpectResponse("ko.html", stream2, false); 456 stream2->Close(false); 457 } 458 459 TEST_F(HttpPipelinedConnectionImplTest, AsyncSendWhileAsyncReadBlocked) { 460 MockWrite writes[] = { 461 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 462 MockWrite(ASYNC, 3, "GET /ko.html HTTP/1.1\r\n\r\n"), 463 }; 464 MockRead reads[] = { 465 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 466 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"), 467 MockRead(ASYNC, 4, "ok.html"), 468 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 469 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"), 470 MockRead(SYNCHRONOUS, 7, "ko.html"), 471 }; 472 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 473 474 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 475 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 476 477 HttpRequestHeaders headers1; 478 HttpResponseInfo response1; 479 EXPECT_EQ(OK, stream1->SendRequest(headers1, 480 &response1, callback_.callback())); 481 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 482 TestCompletionCallback callback1; 483 std::string expected = "ok.html"; 484 scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size())); 485 EXPECT_EQ(ERR_IO_PENDING, 486 stream1->ReadResponseBody(buffer.get(), expected.size(), 487 callback1.callback())); 488 489 HttpRequestHeaders headers2; 490 HttpResponseInfo response2; 491 TestCompletionCallback callback2; 492 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2, 493 callback2.callback())); 494 495 data_->RunFor(1); 496 EXPECT_LE(OK, callback2.WaitForResult()); 497 EXPECT_EQ(ERR_IO_PENDING, stream2->ReadResponseHeaders(callback2.callback())); 498 499 data_->RunFor(1); 500 EXPECT_EQ(static_cast<int>(expected.size()), callback1.WaitForResult()); 501 std::string actual(buffer->data(), expected.size()); 502 EXPECT_THAT(actual, StrEq(expected)); 503 stream1->Close(false); 504 505 data_->StopAfter(8); 506 EXPECT_LE(OK, callback2.WaitForResult()); 507 ExpectResponse("ko.html", stream2, false); 508 stream2->Close(false); 509 } 510 511 TEST_F(HttpPipelinedConnectionImplTest, UnusedStreamAllowsLaterUse) { 512 MockWrite writes[] = { 513 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 514 }; 515 MockRead reads[] = { 516 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 517 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n\r\n"), 518 MockRead(SYNCHRONOUS, 3, "ok.html"), 519 }; 520 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 521 522 scoped_ptr<HttpStream> unused_stream(NewTestStream("unused.html")); 523 unused_stream->Close(false); 524 525 scoped_ptr<HttpStream> later_stream(NewTestStream("ok.html")); 526 TestSyncRequest(later_stream, "ok.html"); 527 } 528 529 TEST_F(HttpPipelinedConnectionImplTest, UnsentStreamAllowsLaterUse) { 530 MockWrite writes[] = { 531 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 532 MockWrite(SYNCHRONOUS, 4, "GET /ko.html HTTP/1.1\r\n\r\n"), 533 }; 534 MockRead reads[] = { 535 MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"), 536 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"), 537 MockRead(ASYNC, 3, "ok.html"), 538 MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"), 539 MockRead(SYNCHRONOUS, 6, "Content-Length: 7\r\n\r\n"), 540 MockRead(SYNCHRONOUS, 7, "ko.html"), 541 }; 542 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 543 544 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 545 546 HttpRequestHeaders headers; 547 HttpResponseInfo response; 548 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response, 549 callback_.callback())); 550 551 scoped_ptr<HttpStream> unsent_stream(NewTestStream("unsent.html")); 552 HttpRequestHeaders unsent_headers; 553 HttpResponseInfo unsent_response; 554 EXPECT_EQ(ERR_IO_PENDING, unsent_stream->SendRequest(unsent_headers, 555 &unsent_response, 556 callback_.callback())); 557 unsent_stream->Close(false); 558 559 data_->RunFor(1); 560 EXPECT_LE(OK, callback_.WaitForResult()); 561 562 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(callback_.callback())); 563 data_->RunFor(2); 564 EXPECT_LE(OK, callback_.WaitForResult()); 565 566 ExpectResponse("ok.html", stream, true); 567 568 stream->Close(false); 569 570 data_->StopAfter(8); 571 scoped_ptr<HttpStream> later_stream(NewTestStream("ko.html")); 572 TestSyncRequest(later_stream, "ko.html"); 573 } 574 575 TEST_F(HttpPipelinedConnectionImplTest, FailedSend) { 576 MockWrite writes[] = { 577 MockWrite(ASYNC, ERR_FAILED), 578 }; 579 Initialize(NULL, 0, writes, arraysize(writes)); 580 581 scoped_ptr<HttpStream> failed_stream(NewTestStream("ok.html")); 582 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 583 scoped_ptr<HttpStream> closed_stream(NewTestStream("closed.html")); 584 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html")); 585 586 HttpRequestHeaders headers; 587 HttpResponseInfo response; 588 TestCompletionCallback failed_callback; 589 EXPECT_EQ(ERR_IO_PENDING, 590 failed_stream->SendRequest(headers, &response, 591 failed_callback.callback())); 592 TestCompletionCallback evicted_callback; 593 EXPECT_EQ(ERR_IO_PENDING, 594 evicted_stream->SendRequest(headers, &response, 595 evicted_callback.callback())); 596 EXPECT_EQ(ERR_IO_PENDING, closed_stream->SendRequest(headers, &response, 597 callback_.callback())); 598 closed_stream->Close(false); 599 600 data_->RunFor(1); 601 EXPECT_EQ(ERR_FAILED, failed_callback.WaitForResult()); 602 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 603 EXPECT_EQ(ERR_PIPELINE_EVICTION, 604 rejected_stream->SendRequest(headers, &response, 605 callback_.callback())); 606 607 failed_stream->Close(true); 608 evicted_stream->Close(true); 609 rejected_stream->Close(true); 610 } 611 612 TEST_F(HttpPipelinedConnectionImplTest, ConnectionSuddenlyClosedAfterResponse) { 613 MockWrite writes[] = { 614 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 615 MockWrite(SYNCHRONOUS, 1, "GET /read_evicted.html HTTP/1.1\r\n\r\n"), 616 MockWrite(SYNCHRONOUS, 2, "GET /read_rejected.html HTTP/1.1\r\n\r\n"), 617 MockWrite(ASYNC, ERR_SOCKET_NOT_CONNECTED, 5), 618 }; 619 MockRead reads[] = { 620 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n\r\n"), 621 MockRead(SYNCHRONOUS, 4, "ok.html"), 622 MockRead(ASYNC, OK, 6), // Connection closed message. Not read before the 623 // ERR_SOCKET_NOT_CONNECTED. 624 }; 625 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 626 627 scoped_ptr<HttpStream> closed_stream(NewTestStream("ok.html")); 628 scoped_ptr<HttpStream> read_evicted_stream( 629 NewTestStream("read_evicted.html")); 630 scoped_ptr<HttpStream> read_rejected_stream( 631 NewTestStream("read_rejected.html")); 632 scoped_ptr<HttpStream> send_closed_stream( 633 NewTestStream("send_closed.html")); 634 scoped_ptr<HttpStream> send_evicted_stream( 635 NewTestStream("send_evicted.html")); 636 scoped_ptr<HttpStream> send_rejected_stream( 637 NewTestStream("send_rejected.html")); 638 639 HttpRequestHeaders headers; 640 HttpResponseInfo response; 641 EXPECT_EQ(OK, closed_stream->SendRequest(headers, 642 &response, callback_.callback())); 643 EXPECT_EQ(OK, read_evicted_stream->SendRequest(headers, &response, 644 callback_.callback())); 645 EXPECT_EQ(OK, read_rejected_stream->SendRequest(headers, &response, 646 callback_.callback())); 647 TestCompletionCallback send_closed_callback; 648 EXPECT_EQ(ERR_IO_PENDING, 649 send_closed_stream->SendRequest(headers, &response, 650 send_closed_callback.callback())); 651 TestCompletionCallback send_evicted_callback; 652 EXPECT_EQ(ERR_IO_PENDING, 653 send_evicted_stream->SendRequest(headers, &response, 654 send_evicted_callback.callback())); 655 656 TestCompletionCallback read_evicted_callback; 657 EXPECT_EQ(ERR_IO_PENDING, 658 read_evicted_stream->ReadResponseHeaders( 659 read_evicted_callback.callback())); 660 661 EXPECT_EQ(OK, closed_stream->ReadResponseHeaders(callback_.callback())); 662 ExpectResponse("ok.html", closed_stream, false); 663 closed_stream->Close(true); 664 665 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_evicted_callback.WaitForResult()); 666 read_evicted_stream->Close(true); 667 668 EXPECT_EQ(ERR_PIPELINE_EVICTION, 669 read_rejected_stream->ReadResponseHeaders(callback_.callback())); 670 read_rejected_stream->Close(true); 671 672 data_->RunFor(1); 673 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, send_closed_callback.WaitForResult()); 674 send_closed_stream->Close(true); 675 676 EXPECT_EQ(ERR_PIPELINE_EVICTION, send_evicted_callback.WaitForResult()); 677 send_evicted_stream->Close(true); 678 679 EXPECT_EQ(ERR_PIPELINE_EVICTION, 680 send_rejected_stream->SendRequest(headers, &response, 681 callback_.callback())); 682 send_rejected_stream->Close(true); 683 } 684 685 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSending) { 686 MockWrite writes[] = { 687 MockWrite(ASYNC, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"), 688 }; 689 Initialize(NULL, 0, writes, arraysize(writes)); 690 691 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); 692 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 693 694 HttpRequestHeaders headers; 695 HttpResponseInfo response; 696 TestCompletionCallback aborted_callback; 697 EXPECT_EQ(ERR_IO_PENDING, 698 aborted_stream->SendRequest(headers, &response, 699 aborted_callback.callback())); 700 TestCompletionCallback evicted_callback; 701 EXPECT_EQ(ERR_IO_PENDING, 702 evicted_stream->SendRequest(headers, &response, 703 evicted_callback.callback())); 704 705 aborted_stream->Close(true); 706 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 707 evicted_stream->Close(true); 708 EXPECT_FALSE(aborted_callback.have_result()); 709 } 710 711 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSendingSecondRequest) { 712 MockWrite writes[] = { 713 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 714 MockWrite(ASYNC, 1, "GET /aborts.html HTTP/1.1\r\n\r\n"), 715 }; 716 Initialize(NULL, 0, writes, arraysize(writes)); 717 718 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 719 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); 720 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 721 722 HttpRequestHeaders headers; 723 HttpResponseInfo response; 724 TestCompletionCallback ok_callback; 725 EXPECT_EQ(ERR_IO_PENDING, ok_stream->SendRequest(headers, &response, 726 ok_callback.callback())); 727 TestCompletionCallback aborted_callback; 728 EXPECT_EQ(ERR_IO_PENDING, 729 aborted_stream->SendRequest(headers, &response, 730 aborted_callback.callback())); 731 TestCompletionCallback evicted_callback; 732 EXPECT_EQ(ERR_IO_PENDING, 733 evicted_stream->SendRequest(headers, &response, 734 evicted_callback.callback())); 735 736 data_->RunFor(1); 737 EXPECT_LE(OK, ok_callback.WaitForResult()); 738 base::MessageLoop::current()->RunUntilIdle(); 739 aborted_stream->Close(true); 740 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 741 evicted_stream->Close(true); 742 EXPECT_FALSE(aborted_callback.have_result()); 743 ok_stream->Close(true); 744 } 745 746 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileReadingHeaders) { 747 MockWrite writes[] = { 748 MockWrite(SYNCHRONOUS, 0, "GET /aborts.html HTTP/1.1\r\n\r\n"), 749 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 750 }; 751 MockRead reads[] = { 752 MockRead(ASYNC, ERR_FAILED, 2), 753 }; 754 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 755 756 scoped_ptr<HttpStream> aborted_stream(NewTestStream("aborts.html")); 757 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 758 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html")); 759 760 HttpRequestHeaders headers; 761 HttpResponseInfo response; 762 EXPECT_EQ(OK, 763 aborted_stream->SendRequest(headers, &response, 764 callback_.callback())); 765 EXPECT_EQ(OK, 766 evicted_stream->SendRequest(headers, &response, 767 callback_.callback())); 768 769 EXPECT_EQ(ERR_IO_PENDING, 770 aborted_stream->ReadResponseHeaders(callback_.callback())); 771 TestCompletionCallback evicted_callback; 772 EXPECT_EQ(ERR_IO_PENDING, 773 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 774 775 aborted_stream->Close(true); 776 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 777 evicted_stream->Close(true); 778 779 EXPECT_EQ(ERR_PIPELINE_EVICTION, 780 rejected_stream->SendRequest(headers, &response, 781 callback_.callback())); 782 rejected_stream->Close(true); 783 } 784 785 TEST_F(HttpPipelinedConnectionImplTest, PendingResponseAbandoned) { 786 MockWrite writes[] = { 787 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 788 MockWrite(SYNCHRONOUS, 1, "GET /abandoned.html HTTP/1.1\r\n\r\n"), 789 MockWrite(SYNCHRONOUS, 2, "GET /evicted.html HTTP/1.1\r\n\r\n"), 790 }; 791 MockRead reads[] = { 792 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), 793 MockRead(SYNCHRONOUS, 4, "Content-Length: 7\r\n\r\n"), 794 MockRead(SYNCHRONOUS, 5, "ok.html"), 795 }; 796 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 797 798 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 799 scoped_ptr<HttpStream> abandoned_stream(NewTestStream("abandoned.html")); 800 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 801 802 HttpRequestHeaders headers; 803 HttpResponseInfo response; 804 EXPECT_EQ(OK, ok_stream->SendRequest(headers, &response, 805 callback_.callback())); 806 EXPECT_EQ(OK, abandoned_stream->SendRequest(headers, &response, 807 callback_.callback())); 808 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response, 809 callback_.callback())); 810 811 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback())); 812 TestCompletionCallback abandoned_callback; 813 EXPECT_EQ(ERR_IO_PENDING, abandoned_stream->ReadResponseHeaders( 814 abandoned_callback.callback())); 815 TestCompletionCallback evicted_callback; 816 EXPECT_EQ(ERR_IO_PENDING, 817 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 818 819 abandoned_stream->Close(false); 820 821 ExpectResponse("ok.html", ok_stream, false); 822 ok_stream->Close(false); 823 824 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 825 evicted_stream->Close(true); 826 EXPECT_FALSE(evicted_stream->IsConnectionReusable()); 827 } 828 829 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedAfterOneRequestRecovery) { 830 MockWrite writes[] = { 831 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 832 MockWrite(SYNCHRONOUS, 1, "GET /rejected.html HTTP/1.1\r\n\r\n"), 833 MockWrite(ASYNC, ERR_SOCKET_NOT_CONNECTED, 5), 834 MockWrite(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 7), 835 }; 836 MockRead reads[] = { 837 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 838 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 839 MockRead(SYNCHRONOUS, 4, "ok.html"), 840 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 6), 841 }; 842 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 843 844 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 845 scoped_ptr<HttpStream> rejected_read_stream(NewTestStream("rejected.html")); 846 scoped_ptr<HttpStream> evicted_send_stream(NewTestStream("evicted.html")); 847 scoped_ptr<HttpStream> rejected_send_stream(NewTestStream("rejected.html")); 848 849 HttpRequestHeaders headers; 850 HttpResponseInfo response; 851 EXPECT_EQ(OK, ok_stream->SendRequest(headers, 852 &response, callback_.callback())); 853 EXPECT_EQ(OK, rejected_read_stream->SendRequest(headers, &response, 854 callback_.callback())); 855 856 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback())); 857 ExpectResponse("ok.html", ok_stream, false); 858 ok_stream->Close(false); 859 860 TestCompletionCallback read_callback; 861 EXPECT_EQ(ERR_IO_PENDING, 862 evicted_send_stream->SendRequest(headers, &response, 863 read_callback.callback())); 864 data_->RunFor(1); 865 EXPECT_EQ(ERR_PIPELINE_EVICTION, read_callback.WaitForResult()); 866 867 EXPECT_EQ(ERR_PIPELINE_EVICTION, 868 rejected_read_stream->ReadResponseHeaders(callback_.callback())); 869 EXPECT_EQ(ERR_PIPELINE_EVICTION, 870 rejected_send_stream->SendRequest(headers, &response, 871 callback_.callback())); 872 873 rejected_read_stream->Close(true); 874 rejected_send_stream->Close(true); 875 } 876 877 TEST_F(HttpPipelinedConnectionImplTest, DisconnectedPendingReadRecovery) { 878 MockWrite writes[] = { 879 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 880 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 881 }; 882 MockRead reads[] = { 883 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 884 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 885 MockRead(SYNCHRONOUS, 4, "ok.html"), 886 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5), 887 }; 888 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 889 890 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 891 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 892 893 HttpRequestHeaders headers; 894 HttpResponseInfo response; 895 EXPECT_EQ(OK, ok_stream->SendRequest(headers, 896 &response, callback_.callback())); 897 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response, 898 callback_.callback())); 899 900 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback())); 901 ExpectResponse("ok.html", ok_stream, false); 902 903 TestCompletionCallback evicted_callback; 904 EXPECT_EQ(ERR_IO_PENDING, 905 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 906 907 ok_stream->Close(false); 908 909 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 910 evicted_stream->Close(false); 911 } 912 913 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeNextReadLoop) { 914 MockWrite writes[] = { 915 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 916 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 917 }; 918 MockRead reads[] = { 919 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 920 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 921 MockRead(SYNCHRONOUS, 4, "ok.html"), 922 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5), 923 }; 924 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 925 926 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 927 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 928 929 HttpRequestHeaders headers; 930 HttpResponseInfo response; 931 EXPECT_EQ(OK, ok_stream->SendRequest(headers, 932 &response, callback_.callback())); 933 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response, 934 callback_.callback())); 935 936 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback())); 937 ExpectResponse("ok.html", ok_stream, false); 938 939 TestCompletionCallback evicted_callback; 940 EXPECT_EQ(ERR_IO_PENDING, 941 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 942 943 ok_stream->Close(false); 944 evicted_stream->Close(false); 945 } 946 947 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledBeforeReadCallback) { 948 MockWrite writes[] = { 949 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 950 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 951 }; 952 MockRead reads[] = { 953 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 954 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 955 MockRead(SYNCHRONOUS, 4, "ok.html"), 956 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5), 957 }; 958 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 959 960 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 961 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 962 963 HttpRequestHeaders headers; 964 HttpResponseInfo response; 965 EXPECT_EQ(OK, ok_stream->SendRequest(headers, 966 &response, callback_.callback())); 967 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response, 968 callback_.callback())); 969 970 EXPECT_EQ(OK, ok_stream->ReadResponseHeaders(callback_.callback())); 971 ExpectResponse("ok.html", ok_stream, false); 972 973 TestCompletionCallback evicted_callback; 974 EXPECT_EQ(ERR_IO_PENDING, 975 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 976 977 ok_stream->Close(false); 978 979 // The posted tasks should be: 980 // 1. DoReadHeadersLoop, which will post: 981 // 2. InvokeUserCallback 982 SuddenCloseObserver observer(evicted_stream.get(), 2); 983 base::MessageLoop::current()->AddTaskObserver(&observer); 984 base::MessageLoop::current()->RunUntilIdle(); 985 EXPECT_FALSE(evicted_callback.have_result()); 986 } 987 988 class StreamDeleter { 989 public: 990 StreamDeleter(HttpStream* stream) 991 : stream_(stream), 992 callback_(base::Bind(&StreamDeleter::OnIOComplete, 993 base::Unretained(this))) { 994 } 995 996 ~StreamDeleter() { 997 EXPECT_FALSE(stream_); 998 } 999 1000 const CompletionCallback& callback() { return callback_; } 1001 1002 private: 1003 void OnIOComplete(int result) { 1004 stream_->Close(true); 1005 stream_.reset(); 1006 } 1007 1008 scoped_ptr<HttpStream> stream_; 1009 CompletionCallback callback_; 1010 }; 1011 1012 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringSendCallback) { 1013 MockWrite writes[] = { 1014 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1015 }; 1016 Initialize(NULL, 0, writes, arraysize(writes)); 1017 1018 HttpStream* stream(NewTestStream("ok.html")); 1019 1020 StreamDeleter deleter(stream); 1021 HttpRequestHeaders headers; 1022 HttpResponseInfo response; 1023 EXPECT_EQ(ERR_IO_PENDING, stream->SendRequest(headers, &response, 1024 deleter.callback())); 1025 data_->RunFor(1); 1026 } 1027 1028 TEST_F(HttpPipelinedConnectionImplTest, CloseCalledDuringReadCallback) { 1029 MockWrite writes[] = { 1030 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1031 }; 1032 MockRead reads[] = { 1033 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 1034 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"), 1035 }; 1036 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1037 1038 HttpStream* stream(NewTestStream("ok.html")); 1039 1040 HttpRequestHeaders headers; 1041 HttpResponseInfo response; 1042 EXPECT_EQ(OK, stream->SendRequest(headers, 1043 &response, callback_.callback())); 1044 1045 StreamDeleter deleter(stream); 1046 EXPECT_EQ(ERR_IO_PENDING, stream->ReadResponseHeaders(deleter.callback())); 1047 data_->RunFor(1); 1048 } 1049 1050 TEST_F(HttpPipelinedConnectionImplTest, 1051 CloseCalledDuringReadCallbackWithPendingRead) { 1052 MockWrite writes[] = { 1053 MockWrite(SYNCHRONOUS, 0, "GET /failed.html HTTP/1.1\r\n\r\n"), 1054 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 1055 }; 1056 MockRead reads[] = { 1057 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 1058 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"), 1059 }; 1060 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1061 1062 HttpStream* failed_stream(NewTestStream("failed.html")); 1063 HttpStream* evicted_stream(NewTestStream("evicted.html")); 1064 1065 HttpRequestHeaders headers; 1066 HttpResponseInfo response; 1067 EXPECT_EQ(OK, failed_stream->SendRequest(headers, &response, 1068 callback_.callback())); 1069 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, &response, 1070 callback_.callback())); 1071 1072 StreamDeleter failed_deleter(failed_stream); 1073 EXPECT_EQ(ERR_IO_PENDING, 1074 failed_stream->ReadResponseHeaders(failed_deleter.callback())); 1075 StreamDeleter evicted_deleter(evicted_stream); 1076 EXPECT_EQ(ERR_IO_PENDING, 1077 evicted_stream->ReadResponseHeaders(evicted_deleter.callback())); 1078 data_->RunFor(1); 1079 } 1080 1081 TEST_F(HttpPipelinedConnectionImplTest, CloseOtherDuringReadCallback) { 1082 MockWrite writes[] = { 1083 MockWrite(SYNCHRONOUS, 0, "GET /deleter.html HTTP/1.1\r\n\r\n"), 1084 MockWrite(SYNCHRONOUS, 1, "GET /deleted.html HTTP/1.1\r\n\r\n"), 1085 }; 1086 MockRead reads[] = { 1087 MockRead(SYNCHRONOUS, 2, "HTTP/1.1 200 OK\r\n"), 1088 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"), 1089 }; 1090 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1091 1092 scoped_ptr<HttpStream> deleter_stream(NewTestStream("deleter.html")); 1093 HttpStream* deleted_stream(NewTestStream("deleted.html")); 1094 1095 HttpRequestHeaders headers; 1096 HttpResponseInfo response; 1097 EXPECT_EQ(OK, deleter_stream->SendRequest(headers, 1098 &response, callback_.callback())); 1099 EXPECT_EQ(OK, deleted_stream->SendRequest(headers, 1100 &response, callback_.callback())); 1101 1102 StreamDeleter deleter(deleted_stream); 1103 EXPECT_EQ(ERR_IO_PENDING, 1104 deleter_stream->ReadResponseHeaders(deleter.callback())); 1105 EXPECT_EQ(ERR_IO_PENDING, 1106 deleted_stream->ReadResponseHeaders(callback_.callback())); 1107 data_->RunFor(1); 1108 } 1109 1110 TEST_F(HttpPipelinedConnectionImplTest, CloseBeforeSendCallbackRuns) { 1111 MockWrite writes[] = { 1112 MockWrite(ASYNC, 0, "GET /close.html HTTP/1.1\r\n\r\n"), 1113 MockWrite(ASYNC, 1, "GET /dummy.html HTTP/1.1\r\n\r\n"), 1114 }; 1115 Initialize(NULL, 0, writes, arraysize(writes)); 1116 1117 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html")); 1118 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html")); 1119 1120 scoped_ptr<TestCompletionCallback> close_callback( 1121 new TestCompletionCallback); 1122 HttpRequestHeaders headers; 1123 HttpResponseInfo response; 1124 EXPECT_EQ(ERR_IO_PENDING, 1125 close_stream->SendRequest(headers, 1126 &response, close_callback->callback())); 1127 1128 data_->RunFor(1); 1129 EXPECT_FALSE(close_callback->have_result()); 1130 1131 close_stream->Close(false); 1132 close_stream.reset(); 1133 close_callback.reset(); 1134 1135 base::MessageLoop::current()->RunUntilIdle(); 1136 } 1137 1138 TEST_F(HttpPipelinedConnectionImplTest, CloseBeforeReadCallbackRuns) { 1139 MockWrite writes[] = { 1140 MockWrite(SYNCHRONOUS, 0, "GET /close.html HTTP/1.1\r\n\r\n"), 1141 MockWrite(SYNCHRONOUS, 3, "GET /dummy.html HTTP/1.1\r\n\r\n"), 1142 }; 1143 MockRead reads[] = { 1144 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 1145 MockRead(ASYNC, 2, "Content-Length: 7\r\n\r\n"), 1146 }; 1147 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1148 1149 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html")); 1150 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html")); 1151 1152 HttpRequestHeaders headers; 1153 HttpResponseInfo response; 1154 EXPECT_EQ(OK, close_stream->SendRequest(headers, 1155 &response, callback_.callback())); 1156 1157 scoped_ptr<TestCompletionCallback> close_callback( 1158 new TestCompletionCallback); 1159 EXPECT_EQ(ERR_IO_PENDING, 1160 close_stream->ReadResponseHeaders(close_callback->callback())); 1161 1162 data_->RunFor(1); 1163 EXPECT_FALSE(close_callback->have_result()); 1164 1165 close_stream->Close(false); 1166 close_stream.reset(); 1167 close_callback.reset(); 1168 1169 base::MessageLoop::current()->RunUntilIdle(); 1170 } 1171 1172 TEST_F(HttpPipelinedConnectionImplTest, AbortWhileSendQueued) { 1173 MockWrite writes[] = { 1174 MockWrite(ASYNC, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1175 MockWrite(ASYNC, 1, "GET /ko.html HTTP/1.1\r\n\r\n"), 1176 }; 1177 Initialize(NULL, 0, writes, arraysize(writes)); 1178 1179 scoped_ptr<HttpStream> stream1(NewTestStream("ok.html")); 1180 scoped_ptr<HttpStream> stream2(NewTestStream("ko.html")); 1181 1182 HttpRequestHeaders headers1; 1183 HttpResponseInfo response1; 1184 TestCompletionCallback callback1; 1185 EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequest(headers1, &response1, 1186 callback1.callback())); 1187 1188 HttpRequestHeaders headers2; 1189 HttpResponseInfo response2; 1190 TestCompletionCallback callback2; 1191 EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequest(headers2, &response2, 1192 callback2.callback())); 1193 1194 stream2.reset(); 1195 stream1->Close(true); 1196 1197 EXPECT_FALSE(callback2.have_result()); 1198 } 1199 1200 TEST_F(HttpPipelinedConnectionImplTest, NoGapBetweenCloseAndEviction) { 1201 MockWrite writes[] = { 1202 MockWrite(SYNCHRONOUS, 0, "GET /close.html HTTP/1.1\r\n\r\n"), 1203 MockWrite(SYNCHRONOUS, 2, "GET /dummy.html HTTP/1.1\r\n\r\n"), 1204 }; 1205 MockRead reads[] = { 1206 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 1207 MockRead(ASYNC, 3, "Content-Length: 7\r\n\r\n"), 1208 }; 1209 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1210 1211 scoped_ptr<HttpStream> close_stream(NewTestStream("close.html")); 1212 scoped_ptr<HttpStream> dummy_stream(NewTestStream("dummy.html")); 1213 1214 HttpRequestHeaders headers; 1215 HttpResponseInfo response; 1216 EXPECT_EQ(OK, close_stream->SendRequest(headers, &response, 1217 callback_.callback())); 1218 1219 TestCompletionCallback close_callback; 1220 EXPECT_EQ(ERR_IO_PENDING, 1221 close_stream->ReadResponseHeaders(close_callback.callback())); 1222 1223 EXPECT_EQ(OK, dummy_stream->SendRequest(headers, &response, 1224 callback_.callback())); 1225 1226 TestCompletionCallback dummy_callback; 1227 EXPECT_EQ(ERR_IO_PENDING, 1228 dummy_stream->ReadResponseHeaders(dummy_callback.callback())); 1229 1230 close_stream->Close(true); 1231 close_stream.reset(); 1232 1233 EXPECT_TRUE(dummy_callback.have_result()); 1234 EXPECT_EQ(ERR_PIPELINE_EVICTION, dummy_callback.WaitForResult()); 1235 dummy_stream->Close(true); 1236 dummy_stream.reset(); 1237 pipeline_.reset(); 1238 } 1239 1240 TEST_F(HttpPipelinedConnectionImplTest, RecoverFromDrainOnRedirect) { 1241 MockWrite writes[] = { 1242 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"), 1243 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"), 1244 }; 1245 MockRead reads[] = { 1246 MockRead(SYNCHRONOUS, 2, 1247 "HTTP/1.1 302 OK\r\n" 1248 "Content-Length: 8\r\n\r\n" 1249 "redirect"), 1250 MockRead(SYNCHRONOUS, 3, 1251 "HTTP/1.1 200 OK\r\n" 1252 "Content-Length: 7\r\n\r\n" 1253 "ok.html"), 1254 }; 1255 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1256 1257 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html")); 1258 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html")); 1259 1260 HttpRequestHeaders headers1; 1261 HttpResponseInfo response1; 1262 EXPECT_EQ(OK, stream1->SendRequest(headers1, 1263 &response1, callback_.callback())); 1264 HttpRequestHeaders headers2; 1265 HttpResponseInfo response2; 1266 EXPECT_EQ(OK, stream2->SendRequest(headers2, 1267 &response2, callback_.callback())); 1268 1269 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 1270 stream1.release()->Drain(NULL); 1271 1272 EXPECT_EQ(OK, stream2->ReadResponseHeaders(callback_.callback())); 1273 ExpectResponse("ok.html", stream2, false); 1274 stream2->Close(false); 1275 } 1276 1277 TEST_F(HttpPipelinedConnectionImplTest, EvictAfterDrainOfUnknownSize) { 1278 MockWrite writes[] = { 1279 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"), 1280 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"), 1281 }; 1282 MockRead reads[] = { 1283 MockRead(SYNCHRONOUS, 2, 1284 "HTTP/1.1 302 OK\r\n\r\n" 1285 "redirect"), 1286 }; 1287 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1288 1289 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html")); 1290 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html")); 1291 1292 HttpRequestHeaders headers1; 1293 HttpResponseInfo response1; 1294 EXPECT_EQ(OK, stream1->SendRequest(headers1, 1295 &response1, callback_.callback())); 1296 HttpRequestHeaders headers2; 1297 HttpResponseInfo response2; 1298 EXPECT_EQ(OK, stream2->SendRequest(headers2, 1299 &response2, callback_.callback())); 1300 1301 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 1302 stream1.release()->Drain(NULL); 1303 1304 EXPECT_EQ(ERR_PIPELINE_EVICTION, 1305 stream2->ReadResponseHeaders(callback_.callback())); 1306 stream2->Close(false); 1307 } 1308 1309 TEST_F(HttpPipelinedConnectionImplTest, EvictAfterFailedDrain) { 1310 MockWrite writes[] = { 1311 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"), 1312 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"), 1313 }; 1314 MockRead reads[] = { 1315 MockRead(SYNCHRONOUS, 2, 1316 "HTTP/1.1 302 OK\r\n" 1317 "Content-Length: 8\r\n\r\n"), 1318 MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 3), 1319 }; 1320 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1321 1322 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html")); 1323 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html")); 1324 1325 HttpRequestHeaders headers1; 1326 HttpResponseInfo response1; 1327 EXPECT_EQ(OK, stream1->SendRequest(headers1, 1328 &response1, callback_.callback())); 1329 HttpRequestHeaders headers2; 1330 HttpResponseInfo response2; 1331 EXPECT_EQ(OK, stream2->SendRequest(headers2, 1332 &response2, callback_.callback())); 1333 1334 1335 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 1336 stream1.release()->Drain(NULL); 1337 1338 EXPECT_EQ(ERR_PIPELINE_EVICTION, 1339 stream2->ReadResponseHeaders(callback_.callback())); 1340 stream2->Close(false); 1341 } 1342 1343 TEST_F(HttpPipelinedConnectionImplTest, EvictIfDrainingChunkedEncoding) { 1344 MockWrite writes[] = { 1345 MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n\r\n"), 1346 MockWrite(SYNCHRONOUS, 1, "GET /ok.html HTTP/1.1\r\n\r\n"), 1347 }; 1348 MockRead reads[] = { 1349 MockRead(SYNCHRONOUS, 2, 1350 "HTTP/1.1 302 OK\r\n" 1351 "Transfer-Encoding: chunked\r\n\r\n"), 1352 MockRead(SYNCHRONOUS, 3, 1353 "jibberish"), 1354 }; 1355 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1356 1357 scoped_ptr<HttpStream> stream1(NewTestStream("redirect.html")); 1358 scoped_ptr<HttpStream> stream2(NewTestStream("ok.html")); 1359 1360 HttpRequestHeaders headers1; 1361 HttpResponseInfo response1; 1362 EXPECT_EQ(OK, stream1->SendRequest(headers1, 1363 &response1, callback_.callback())); 1364 HttpRequestHeaders headers2; 1365 HttpResponseInfo response2; 1366 EXPECT_EQ(OK, stream2->SendRequest(headers2, 1367 &response2, callback_.callback())); 1368 1369 1370 EXPECT_EQ(OK, stream1->ReadResponseHeaders(callback_.callback())); 1371 stream1.release()->Drain(NULL); 1372 1373 EXPECT_EQ(ERR_PIPELINE_EVICTION, 1374 stream2->ReadResponseHeaders(callback_.callback())); 1375 stream2->Close(false); 1376 } 1377 1378 TEST_F(HttpPipelinedConnectionImplTest, EvictionDueToMissingContentLength) { 1379 MockWrite writes[] = { 1380 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1381 MockWrite(SYNCHRONOUS, 1, "GET /evicted.html HTTP/1.1\r\n\r\n"), 1382 MockWrite(SYNCHRONOUS, 2, "GET /rejected.html HTTP/1.1\r\n\r\n"), 1383 }; 1384 MockRead reads[] = { 1385 MockRead(ASYNC, 3, "HTTP/1.1 200 OK\r\n\r\n"), 1386 MockRead(SYNCHRONOUS, 4, "ok.html"), 1387 MockRead(SYNCHRONOUS, OK, 5), 1388 }; 1389 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1390 1391 scoped_ptr<HttpStream> ok_stream(NewTestStream("ok.html")); 1392 scoped_ptr<HttpStream> evicted_stream(NewTestStream("evicted.html")); 1393 scoped_ptr<HttpStream> rejected_stream(NewTestStream("rejected.html")); 1394 1395 HttpRequestHeaders headers; 1396 HttpResponseInfo response; 1397 EXPECT_EQ(OK, ok_stream->SendRequest(headers, 1398 &response, callback_.callback())); 1399 EXPECT_EQ(OK, evicted_stream->SendRequest(headers, 1400 &response, callback_.callback())); 1401 EXPECT_EQ(OK, rejected_stream->SendRequest(headers, 1402 &response, callback_.callback())); 1403 1404 TestCompletionCallback ok_callback; 1405 EXPECT_EQ(ERR_IO_PENDING, 1406 ok_stream->ReadResponseHeaders(ok_callback.callback())); 1407 1408 TestCompletionCallback evicted_callback; 1409 EXPECT_EQ(ERR_IO_PENDING, 1410 evicted_stream->ReadResponseHeaders(evicted_callback.callback())); 1411 1412 data_->RunFor(1); 1413 EXPECT_LE(OK, ok_callback.WaitForResult()); 1414 data_->StopAfter(10); 1415 1416 ExpectResponse("ok.html", ok_stream, false); 1417 ok_stream->Close(false); 1418 1419 EXPECT_EQ(ERR_PIPELINE_EVICTION, 1420 rejected_stream->ReadResponseHeaders(callback_.callback())); 1421 rejected_stream->Close(true); 1422 EXPECT_EQ(ERR_PIPELINE_EVICTION, evicted_callback.WaitForResult()); 1423 evicted_stream->Close(true); 1424 } 1425 1426 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnSocketError) { 1427 MockWrite writes[] = { 1428 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1429 }; 1430 MockRead reads[] = { 1431 MockRead(SYNCHRONOUS, ERR_FAILED, 1), 1432 }; 1433 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1434 1435 EXPECT_CALL(delegate_, 1436 OnPipelineFeedback( 1437 pipeline_.get(), 1438 HttpPipelinedConnection::PIPELINE_SOCKET_ERROR)) 1439 .Times(1); 1440 1441 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1442 HttpRequestHeaders headers; 1443 HttpResponseInfo response; 1444 EXPECT_EQ(OK, stream->SendRequest(headers, 1445 &response, callback_.callback())); 1446 EXPECT_EQ(ERR_FAILED, stream->ReadResponseHeaders(callback_.callback())); 1447 } 1448 1449 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnNoInternetConnection) { 1450 MockWrite writes[] = { 1451 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1452 }; 1453 MockRead reads[] = { 1454 MockRead(SYNCHRONOUS, ERR_INTERNET_DISCONNECTED, 1), 1455 }; 1456 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1457 1458 EXPECT_CALL(delegate_, OnPipelineFeedback(_, _)) 1459 .Times(0); 1460 1461 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1462 HttpRequestHeaders headers; 1463 HttpResponseInfo response; 1464 EXPECT_EQ(OK, stream->SendRequest(headers, 1465 &response, callback_.callback())); 1466 EXPECT_EQ(ERR_INTERNET_DISCONNECTED, 1467 stream->ReadResponseHeaders(callback_.callback())); 1468 } 1469 1470 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnHttp10) { 1471 MockWrite writes[] = { 1472 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1473 }; 1474 MockRead reads[] = { 1475 MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"), 1476 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n"), 1477 MockRead(SYNCHRONOUS, 3, "Connection: keep-alive\r\n\r\n"), 1478 MockRead(SYNCHRONOUS, 4, "ok.html"), 1479 }; 1480 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1481 1482 EXPECT_CALL(delegate_, 1483 OnPipelineFeedback(pipeline_.get(), 1484 HttpPipelinedConnection::OLD_HTTP_VERSION)) 1485 .Times(1); 1486 1487 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1488 TestSyncRequest(stream, "ok.html"); 1489 } 1490 1491 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnMustClose) { 1492 MockWrite writes[] = { 1493 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1494 }; 1495 MockRead reads[] = { 1496 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"), 1497 MockRead(SYNCHRONOUS, 2, "Content-Length: 7\r\n"), 1498 MockRead(SYNCHRONOUS, 3, "Connection: close\r\n\r\n"), 1499 MockRead(SYNCHRONOUS, 4, "ok.html"), 1500 }; 1501 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1502 1503 EXPECT_CALL(delegate_, 1504 OnPipelineFeedback( 1505 pipeline_.get(), 1506 HttpPipelinedConnection::MUST_CLOSE_CONNECTION)) 1507 .Times(1); 1508 1509 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1510 TestSyncRequest(stream, "ok.html"); 1511 } 1512 1513 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnNoContentLength) { 1514 MockWrite writes[] = { 1515 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1516 }; 1517 MockRead reads[] = { 1518 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"), 1519 MockRead(SYNCHRONOUS, 2, "ok.html"), 1520 }; 1521 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1522 1523 EXPECT_CALL(delegate_, 1524 OnPipelineFeedback( 1525 pipeline_.get(), 1526 HttpPipelinedConnection::MUST_CLOSE_CONNECTION)) 1527 .Times(1); 1528 1529 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1530 TestSyncRequest(stream, "ok.html"); 1531 } 1532 1533 TEST_F(HttpPipelinedConnectionImplTest, FeedbackOnAuthenticationRequired) { 1534 MockWrite writes[] = { 1535 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1536 }; 1537 MockRead reads[] = { 1538 MockRead(SYNCHRONOUS, 1, "HTTP/1.1 401 Unauthorized\r\n"), 1539 MockRead(SYNCHRONOUS, 2, "WWW-Authenticate: NTLM\r\n"), 1540 MockRead(SYNCHRONOUS, 3, "Content-Length: 7\r\n\r\n"), 1541 MockRead(SYNCHRONOUS, 4, "ok.html"), 1542 }; 1543 Initialize(reads, arraysize(reads), writes, arraysize(writes)); 1544 1545 EXPECT_CALL(delegate_, 1546 OnPipelineFeedback( 1547 pipeline_.get(), 1548 HttpPipelinedConnection::AUTHENTICATION_REQUIRED)) 1549 .Times(1); 1550 1551 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1552 TestSyncRequest(stream, "ok.html"); 1553 } 1554 1555 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacity) { 1556 MockWrite writes[] = { 1557 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1558 }; 1559 Initialize(NULL, 0, writes, arraysize(writes)); 1560 1561 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); 1562 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1563 1564 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); 1565 HttpRequestHeaders headers; 1566 HttpResponseInfo response; 1567 EXPECT_EQ(OK, stream->SendRequest(headers, 1568 &response, callback_.callback())); 1569 1570 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); 1571 base::MessageLoop::current()->RunUntilIdle(); 1572 1573 stream->Close(false); 1574 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); 1575 stream.reset(NULL); 1576 } 1577 1578 TEST_F(HttpPipelinedConnectionImplTest, OnPipelineHasCapacityWithoutSend) { 1579 MockWrite writes[] = { 1580 MockWrite(SYNCHRONOUS, 0, "GET /ok.html HTTP/1.1\r\n\r\n"), 1581 }; 1582 Initialize(NULL, 0, writes, arraysize(writes)); 1583 1584 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(0); 1585 scoped_ptr<HttpStream> stream(NewTestStream("ok.html")); 1586 1587 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); 1588 base::MessageLoop::current()->RunUntilIdle(); 1589 1590 stream->Close(false); 1591 EXPECT_CALL(delegate_, OnPipelineHasCapacity(pipeline_.get())).Times(1); 1592 stream.reset(NULL); 1593 } 1594 1595 } // anonymous namespace 1596 1597 } // namespace net 1598