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