Home | History | Annotate | Download | only in http
      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