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 <string>
      6 
      7 #include "base/memory/ref_counted.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/memory/scoped_vector.h"
     10 #include "base/strings/stringprintf.h"
     11 #include "base/strings/utf_string_conversions.h"
     12 #include "net/base/address_list.h"
     13 #include "net/base/io_buffer.h"
     14 #include "net/base/net_errors.h"
     15 #include "net/base/net_util.h"
     16 #include "net/base/request_priority.h"
     17 #include "net/dns/host_cache.h"
     18 #include "net/dns/mock_host_resolver.h"
     19 #include "net/http/http_auth_handler_mock.h"
     20 #include "net/http/http_network_session.h"
     21 #include "net/http/http_network_transaction.h"
     22 #include "net/http/http_request_info.h"
     23 #include "net/http/http_server_properties_impl.h"
     24 #include "net/proxy/proxy_config_service.h"
     25 #include "net/proxy/proxy_service.h"
     26 #include "net/socket/client_socket_handle.h"
     27 #include "net/socket/client_socket_pool_histograms.h"
     28 #include "net/socket/client_socket_pool_manager.h"
     29 #include "net/socket/socket_test_util.h"
     30 #include "net/ssl/ssl_config_service_defaults.h"
     31 #include "testing/gmock/include/gmock/gmock.h"
     32 #include "testing/gtest/include/gtest/gtest.h"
     33 
     34 using testing::StrEq;
     35 
     36 namespace net {
     37 
     38 namespace {
     39 
     40 class SimpleProxyConfigService : public ProxyConfigService {
     41  public:
     42   virtual void AddObserver(Observer* observer) OVERRIDE {
     43     observer_ = observer;
     44   }
     45 
     46   virtual void RemoveObserver(Observer* observer) OVERRIDE {
     47     if (observer_ == observer) {
     48       observer_ = NULL;
     49     }
     50   }
     51 
     52   virtual ConfigAvailability GetLatestProxyConfig(
     53       ProxyConfig* config) OVERRIDE {
     54     *config = config_;
     55     return CONFIG_VALID;
     56   }
     57 
     58   void IncrementConfigId() {
     59     config_.set_id(config_.id() + 1);
     60     observer_->OnProxyConfigChanged(config_, ProxyConfigService::CONFIG_VALID);
     61   }
     62 
     63  private:
     64   ProxyConfig config_;
     65   Observer* observer_;
     66 };
     67 
     68 class HttpPipelinedNetworkTransactionTest : public testing::Test {
     69  public:
     70   HttpPipelinedNetworkTransactionTest()
     71       : histograms_("a"),
     72         pool_(1, 1, &histograms_, &factory_) {
     73   }
     74 
     75   void Initialize(bool force_http_pipelining) {
     76     // Normally, this code could just go in SetUp(). For a few of these tests,
     77     // we change the default number of sockets per group. That needs to be done
     78     // before we construct the HttpNetworkSession.
     79     proxy_config_service_ = new SimpleProxyConfigService();
     80     proxy_service_.reset(new ProxyService(proxy_config_service_, NULL, NULL));
     81     ssl_config_ = new SSLConfigServiceDefaults;
     82     auth_handler_factory_.reset(new HttpAuthHandlerMock::Factory());
     83 
     84     HttpNetworkSession::Params session_params;
     85     session_params.client_socket_factory = &factory_;
     86     session_params.proxy_service = proxy_service_.get();
     87     session_params.host_resolver = &mock_resolver_;
     88     session_params.ssl_config_service = ssl_config_.get();
     89     session_params.http_auth_handler_factory = auth_handler_factory_.get();
     90     session_params.http_server_properties =
     91         http_server_properties_.GetWeakPtr();
     92     session_params.force_http_pipelining = force_http_pipelining;
     93     session_params.http_pipelining_enabled = true;
     94     session_ = new HttpNetworkSession(session_params);
     95   }
     96 
     97   void AddExpectedConnection(MockRead* reads, size_t reads_count,
     98                              MockWrite* writes, size_t writes_count) {
     99     DeterministicSocketData* data = new DeterministicSocketData(
    100         reads, reads_count, writes, writes_count);
    101     data->set_connect_data(MockConnect(SYNCHRONOUS, OK));
    102     if (reads_count || writes_count) {
    103       data->StopAfter(reads_count + writes_count);
    104     }
    105     factory_.AddSocketDataProvider(data);
    106     data_vector_.push_back(data);
    107   }
    108 
    109   enum RequestInfoOptions {
    110     REQUEST_DEFAULT,
    111     REQUEST_MAIN_RESOURCE,
    112   };
    113 
    114   HttpRequestInfo* GetRequestInfo(
    115       const char* filename, RequestInfoOptions options = REQUEST_DEFAULT) {
    116     std::string url = base::StringPrintf("http://localhost/%s", filename);
    117     HttpRequestInfo* request_info = new HttpRequestInfo;
    118     request_info->url = GURL(url);
    119     request_info->method = "GET";
    120     if (options == REQUEST_MAIN_RESOURCE) {
    121       request_info->load_flags = LOAD_MAIN_FRAME;
    122     }
    123     request_info_vector_.push_back(request_info);
    124     return request_info;
    125   }
    126 
    127   void ExpectResponse(const std::string& expected,
    128                       HttpNetworkTransaction& transaction,
    129                       IoMode io_mode) {
    130     scoped_refptr<IOBuffer> buffer(new IOBuffer(expected.size()));
    131     if (io_mode == ASYNC) {
    132       EXPECT_EQ(ERR_IO_PENDING, transaction.Read(buffer.get(), expected.size(),
    133                                                  callback_.callback()));
    134       data_vector_[0]->RunFor(1);
    135       EXPECT_EQ(static_cast<int>(expected.length()), callback_.WaitForResult());
    136     } else {
    137       EXPECT_EQ(static_cast<int>(expected.size()),
    138                 transaction.Read(buffer.get(), expected.size(),
    139                                  callback_.callback()));
    140     }
    141     std::string actual(buffer->data(), expected.size());
    142     EXPECT_THAT(actual, StrEq(expected));
    143     EXPECT_EQ(OK, transaction.Read(buffer.get(), expected.size(),
    144                                    callback_.callback()));
    145   }
    146 
    147   void CompleteTwoRequests(int data_index, int stop_at_step) {
    148     scoped_ptr<HttpNetworkTransaction> one_transaction(
    149         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    150     TestCompletionCallback one_callback;
    151     EXPECT_EQ(ERR_IO_PENDING,
    152               one_transaction->Start(GetRequestInfo("one.html"),
    153                                      one_callback.callback(), BoundNetLog()));
    154     EXPECT_EQ(OK, one_callback.WaitForResult());
    155 
    156     HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    157     TestCompletionCallback two_callback;
    158     EXPECT_EQ(ERR_IO_PENDING,
    159               two_transaction.Start(GetRequestInfo("two.html"),
    160                                     two_callback.callback(), BoundNetLog()));
    161 
    162     TestCompletionCallback one_read_callback;
    163     scoped_refptr<IOBuffer> buffer(new IOBuffer(8));
    164     EXPECT_EQ(ERR_IO_PENDING,
    165               one_transaction->Read(buffer.get(), 8,
    166                                     one_read_callback.callback()));
    167 
    168     data_vector_[data_index]->SetStop(stop_at_step);
    169     data_vector_[data_index]->Run();
    170     EXPECT_EQ(8, one_read_callback.WaitForResult());
    171     data_vector_[data_index]->SetStop(10);
    172     std::string actual(buffer->data(), 8);
    173     EXPECT_THAT(actual, StrEq("one.html"));
    174     EXPECT_EQ(OK, one_transaction->Read(buffer.get(), 8,
    175                                         one_read_callback.callback()));
    176 
    177     EXPECT_EQ(OK, two_callback.WaitForResult());
    178     ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    179   }
    180 
    181   void CompleteFourRequests(RequestInfoOptions options) {
    182     scoped_ptr<HttpNetworkTransaction> one_transaction(
    183         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    184     TestCompletionCallback one_callback;
    185     EXPECT_EQ(ERR_IO_PENDING,
    186               one_transaction->Start(GetRequestInfo("one.html", options),
    187                                      one_callback.callback(), BoundNetLog()));
    188     EXPECT_EQ(OK, one_callback.WaitForResult());
    189 
    190     HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    191     TestCompletionCallback two_callback;
    192     EXPECT_EQ(ERR_IO_PENDING,
    193               two_transaction.Start(GetRequestInfo("two.html", options),
    194                                     two_callback.callback(), BoundNetLog()));
    195 
    196     HttpNetworkTransaction three_transaction(DEFAULT_PRIORITY, session_.get());
    197     TestCompletionCallback three_callback;
    198     EXPECT_EQ(ERR_IO_PENDING,
    199               three_transaction.Start(GetRequestInfo("three.html", options),
    200                                       three_callback.callback(),
    201                                       BoundNetLog()));
    202 
    203     HttpNetworkTransaction four_transaction(DEFAULT_PRIORITY, session_.get());
    204     TestCompletionCallback four_callback;
    205     EXPECT_EQ(ERR_IO_PENDING,
    206               four_transaction.Start(GetRequestInfo("four.html", options),
    207                                      four_callback.callback(), BoundNetLog()));
    208 
    209     ExpectResponse("one.html", *one_transaction.get(), SYNCHRONOUS);
    210     EXPECT_EQ(OK, two_callback.WaitForResult());
    211     ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    212     EXPECT_EQ(OK, three_callback.WaitForResult());
    213     ExpectResponse("three.html", three_transaction, SYNCHRONOUS);
    214 
    215     one_transaction.reset();
    216     EXPECT_EQ(OK, four_callback.WaitForResult());
    217     ExpectResponse("four.html", four_transaction, SYNCHRONOUS);
    218   }
    219 
    220   DeterministicMockClientSocketFactory factory_;
    221   ClientSocketPoolHistograms histograms_;
    222   MockTransportClientSocketPool pool_;
    223   ScopedVector<DeterministicSocketData> data_vector_;
    224   TestCompletionCallback callback_;
    225   ScopedVector<HttpRequestInfo> request_info_vector_;
    226 
    227   SimpleProxyConfigService* proxy_config_service_;
    228   scoped_ptr<ProxyService> proxy_service_;
    229   MockHostResolver mock_resolver_;
    230   scoped_refptr<SSLConfigService> ssl_config_;
    231   scoped_ptr<HttpAuthHandlerMock::Factory> auth_handler_factory_;
    232   HttpServerPropertiesImpl http_server_properties_;
    233   scoped_refptr<HttpNetworkSession> session_;
    234 };
    235 
    236 TEST_F(HttpPipelinedNetworkTransactionTest, OneRequest) {
    237   Initialize(false);
    238 
    239   MockWrite writes[] = {
    240     MockWrite(SYNCHRONOUS, 0, "GET /test.html HTTP/1.1\r\n"
    241               "Host: localhost\r\n"
    242               "Connection: keep-alive\r\n\r\n"),
    243   };
    244   MockRead reads[] = {
    245     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    246     MockRead(SYNCHRONOUS, 2, "Content-Length: 9\r\n\r\n"),
    247     MockRead(SYNCHRONOUS, 3, "test.html"),
    248   };
    249   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    250 
    251   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
    252   EXPECT_EQ(ERR_IO_PENDING,
    253             transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
    254                               BoundNetLog()));
    255   EXPECT_EQ(OK, callback_.WaitForResult());
    256   ExpectResponse("test.html", transaction, SYNCHRONOUS);
    257 }
    258 
    259 TEST_F(HttpPipelinedNetworkTransactionTest, ReusePipeline) {
    260   Initialize(false);
    261 
    262   MockWrite writes[] = {
    263     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    264               "Host: localhost\r\n"
    265               "Connection: keep-alive\r\n\r\n"),
    266     MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
    267               "Host: localhost\r\n"
    268               "Connection: keep-alive\r\n\r\n"),
    269   };
    270   MockRead reads[] = {
    271     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    272     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    273     MockRead(ASYNC, 4, "one.html"),
    274     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    275     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    276     MockRead(SYNCHRONOUS, 7, "two.html"),
    277   };
    278   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    279 
    280   CompleteTwoRequests(0, 5);
    281 }
    282 
    283 TEST_F(HttpPipelinedNetworkTransactionTest, ReusesOnSpaceAvailable) {
    284   int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
    285       HttpNetworkSession::NORMAL_SOCKET_POOL);
    286   ClientSocketPoolManager::set_max_sockets_per_group(
    287       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
    288   Initialize(false);
    289 
    290   MockWrite writes[] = {
    291     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    292               "Host: localhost\r\n"
    293               "Connection: keep-alive\r\n\r\n"),
    294     MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
    295               "Host: localhost\r\n"
    296               "Connection: keep-alive\r\n\r\n"),
    297     MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
    298               "Host: localhost\r\n"
    299               "Connection: keep-alive\r\n\r\n"),
    300     MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
    301               "Host: localhost\r\n"
    302               "Connection: keep-alive\r\n\r\n"),
    303   };
    304   MockRead reads[] = {
    305     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    306     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    307     MockRead(SYNCHRONOUS, 3, "one.html"),
    308     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    309     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    310     MockRead(SYNCHRONOUS, 8, "two.html"),
    311     MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    312     MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    313     MockRead(SYNCHRONOUS, 11, "three.html"),
    314     MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    315     MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    316     MockRead(SYNCHRONOUS, 15, "four.html"),
    317   };
    318   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    319 
    320   CompleteFourRequests(REQUEST_DEFAULT);
    321 
    322   ClientSocketPoolManager::set_max_sockets_per_group(
    323       HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
    324 }
    325 
    326 TEST_F(HttpPipelinedNetworkTransactionTest, WontPipelineMainResource) {
    327   int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
    328       HttpNetworkSession::NORMAL_SOCKET_POOL);
    329   ClientSocketPoolManager::set_max_sockets_per_group(
    330       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
    331   Initialize(false);
    332 
    333   MockWrite writes[] = {
    334     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    335               "Host: localhost\r\n"
    336               "Connection: keep-alive\r\n\r\n"),
    337     MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
    338               "Host: localhost\r\n"
    339               "Connection: keep-alive\r\n\r\n"),
    340     MockWrite(SYNCHRONOUS, 8, "GET /three.html HTTP/1.1\r\n"
    341               "Host: localhost\r\n"
    342               "Connection: keep-alive\r\n\r\n"),
    343     MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
    344               "Host: localhost\r\n"
    345               "Connection: keep-alive\r\n\r\n"),
    346   };
    347   MockRead reads[] = {
    348     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    349     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    350     MockRead(SYNCHRONOUS, 3, "one.html"),
    351     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    352     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    353     MockRead(SYNCHRONOUS, 7, "two.html"),
    354     MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    355     MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    356     MockRead(SYNCHRONOUS, 11, "three.html"),
    357     MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    358     MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    359     MockRead(SYNCHRONOUS, 15, "four.html"),
    360   };
    361   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    362 
    363   CompleteFourRequests(REQUEST_MAIN_RESOURCE);
    364 
    365   ClientSocketPoolManager::set_max_sockets_per_group(
    366       HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
    367 }
    368 
    369 TEST_F(HttpPipelinedNetworkTransactionTest, UnknownSizeEvictsToNewPipeline) {
    370   Initialize(false);
    371 
    372   MockWrite writes[] = {
    373     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    374               "Host: localhost\r\n"
    375               "Connection: keep-alive\r\n\r\n"),
    376   };
    377   MockRead reads[] = {
    378     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
    379     MockRead(ASYNC, 2, "one.html"),
    380     MockRead(SYNCHRONOUS, OK, 3),
    381   };
    382   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    383 
    384   MockWrite writes2[] = {
    385     MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
    386               "Host: localhost\r\n"
    387               "Connection: keep-alive\r\n\r\n"),
    388   };
    389   MockRead reads2[] = {
    390     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    391     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    392     MockRead(SYNCHRONOUS, 3, "two.html"),
    393   };
    394   AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
    395 
    396   CompleteTwoRequests(0, 3);
    397 }
    398 
    399 TEST_F(HttpPipelinedNetworkTransactionTest, ConnectionCloseEvictToNewPipeline) {
    400   Initialize(false);
    401 
    402   MockWrite writes[] = {
    403     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    404               "Host: localhost\r\n"
    405               "Connection: keep-alive\r\n\r\n"),
    406     MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
    407               "Host: localhost\r\n"
    408               "Connection: keep-alive\r\n\r\n"),
    409   };
    410   MockRead reads[] = {
    411     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    412     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    413     MockRead(ASYNC, 4, "one.html"),
    414     MockRead(SYNCHRONOUS, ERR_SOCKET_NOT_CONNECTED, 5),
    415   };
    416   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    417 
    418   MockWrite writes2[] = {
    419     MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
    420               "Host: localhost\r\n"
    421               "Connection: keep-alive\r\n\r\n"),
    422   };
    423   MockRead reads2[] = {
    424     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    425     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    426     MockRead(SYNCHRONOUS, 3, "two.html"),
    427   };
    428   AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
    429 
    430   CompleteTwoRequests(0, 5);
    431 }
    432 
    433 TEST_F(HttpPipelinedNetworkTransactionTest, ErrorEvictsToNewPipeline) {
    434   Initialize(false);
    435 
    436   MockWrite writes[] = {
    437     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    438               "Host: localhost\r\n"
    439               "Connection: keep-alive\r\n\r\n"),
    440     MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
    441               "Host: localhost\r\n"
    442               "Connection: keep-alive\r\n\r\n"),
    443   };
    444   MockRead reads[] = {
    445     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n\r\n"),
    446     MockRead(SYNCHRONOUS, ERR_FAILED, 2),
    447   };
    448   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    449 
    450   MockWrite writes2[] = {
    451     MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
    452               "Host: localhost\r\n"
    453               "Connection: keep-alive\r\n\r\n"),
    454   };
    455   MockRead reads2[] = {
    456     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    457     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    458     MockRead(SYNCHRONOUS, 3, "two.html"),
    459   };
    460   AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
    461 
    462   HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
    463   TestCompletionCallback one_callback;
    464   EXPECT_EQ(ERR_IO_PENDING,
    465             one_transaction.Start(GetRequestInfo("one.html"),
    466                                   one_callback.callback(), BoundNetLog()));
    467   EXPECT_EQ(OK, one_callback.WaitForResult());
    468 
    469   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    470   TestCompletionCallback two_callback;
    471   EXPECT_EQ(ERR_IO_PENDING,
    472             two_transaction.Start(GetRequestInfo("two.html"),
    473                                   two_callback.callback(), BoundNetLog()));
    474 
    475   scoped_refptr<IOBuffer> buffer(new IOBuffer(1));
    476   EXPECT_EQ(ERR_FAILED,
    477             one_transaction.Read(buffer.get(), 1, callback_.callback()));
    478   EXPECT_EQ(OK, two_callback.WaitForResult());
    479   ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    480 }
    481 
    482 TEST_F(HttpPipelinedNetworkTransactionTest, SendErrorEvictsToNewPipeline) {
    483   Initialize(false);
    484 
    485   MockWrite writes[] = {
    486     MockWrite(ASYNC, ERR_FAILED, 0),
    487   };
    488   AddExpectedConnection(NULL, 0, writes, arraysize(writes));
    489 
    490   MockWrite writes2[] = {
    491     MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
    492               "Host: localhost\r\n"
    493               "Connection: keep-alive\r\n\r\n"),
    494   };
    495   MockRead reads2[] = {
    496     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    497     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    498     MockRead(SYNCHRONOUS, 3, "two.html"),
    499   };
    500   AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
    501 
    502   HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
    503   TestCompletionCallback one_callback;
    504   EXPECT_EQ(ERR_IO_PENDING,
    505             one_transaction.Start(GetRequestInfo("one.html"),
    506                                   one_callback.callback(), BoundNetLog()));
    507 
    508   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    509   TestCompletionCallback two_callback;
    510   EXPECT_EQ(ERR_IO_PENDING,
    511             two_transaction.Start(GetRequestInfo("two.html"),
    512                                   two_callback.callback(), BoundNetLog()));
    513 
    514   data_vector_[0]->RunFor(1);
    515   EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
    516 
    517   EXPECT_EQ(OK, two_callback.WaitForResult());
    518   ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    519 }
    520 
    521 TEST_F(HttpPipelinedNetworkTransactionTest, RedirectDrained) {
    522   Initialize(false);
    523 
    524   MockWrite writes[] = {
    525     MockWrite(SYNCHRONOUS, 0, "GET /redirect.html HTTP/1.1\r\n"
    526               "Host: localhost\r\n"
    527               "Connection: keep-alive\r\n\r\n"),
    528     MockWrite(SYNCHRONOUS, 3, "GET /two.html HTTP/1.1\r\n"
    529               "Host: localhost\r\n"
    530               "Connection: keep-alive\r\n\r\n"),
    531   };
    532   MockRead reads[] = {
    533     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 302 OK\r\n"),
    534     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    535     MockRead(ASYNC, 4, "redirect"),
    536     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    537     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    538     MockRead(SYNCHRONOUS, 7, "two.html"),
    539   };
    540   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    541 
    542   scoped_ptr<HttpNetworkTransaction> one_transaction(
    543       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    544   TestCompletionCallback one_callback;
    545   EXPECT_EQ(ERR_IO_PENDING,
    546             one_transaction->Start(GetRequestInfo("redirect.html"),
    547                                    one_callback.callback(), BoundNetLog()));
    548   EXPECT_EQ(OK, one_callback.WaitForResult());
    549 
    550   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    551   TestCompletionCallback two_callback;
    552   EXPECT_EQ(ERR_IO_PENDING,
    553             two_transaction.Start(GetRequestInfo("two.html"),
    554                                   two_callback.callback(), BoundNetLog()));
    555 
    556   one_transaction.reset();
    557   data_vector_[0]->RunFor(2);
    558   data_vector_[0]->SetStop(10);
    559 
    560   EXPECT_EQ(OK, two_callback.WaitForResult());
    561   ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    562 }
    563 
    564 TEST_F(HttpPipelinedNetworkTransactionTest, BasicHttpAuthentication) {
    565   Initialize(false);
    566 
    567   MockWrite writes[] = {
    568     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    569               "Host: localhost\r\n"
    570               "Connection: keep-alive\r\n\r\n"),
    571     MockWrite(SYNCHRONOUS, 5, "GET /one.html HTTP/1.1\r\n"
    572               "Host: localhost\r\n"
    573               "Connection: keep-alive\r\n"
    574               "Authorization: auth_token\r\n\r\n"),
    575   };
    576   MockRead reads[] = {
    577     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 401 Authentication Required\r\n"),
    578     MockRead(SYNCHRONOUS, 2,
    579              "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"),
    580     MockRead(SYNCHRONOUS, 3, "Content-Length: 20\r\n\r\n"),
    581     MockRead(SYNCHRONOUS, 4, "needs authentication"),
    582     MockRead(SYNCHRONOUS, 6, "HTTP/1.1 200 OK\r\n"),
    583     MockRead(SYNCHRONOUS, 7, "Content-Length: 8\r\n\r\n"),
    584     MockRead(SYNCHRONOUS, 8, "one.html"),
    585   };
    586   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    587 
    588   HttpAuthHandlerMock* mock_auth = new HttpAuthHandlerMock;
    589   std::string challenge_text = "Basic";
    590   HttpAuth::ChallengeTokenizer challenge(challenge_text.begin(),
    591                                          challenge_text.end());
    592   GURL origin("localhost");
    593   EXPECT_TRUE(mock_auth->InitFromChallenge(&challenge,
    594                                            HttpAuth::AUTH_SERVER,
    595                                            origin,
    596                                            BoundNetLog()));
    597   auth_handler_factory_->AddMockHandler(mock_auth, HttpAuth::AUTH_SERVER);
    598 
    599   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
    600   EXPECT_EQ(ERR_IO_PENDING,
    601             transaction.Start(GetRequestInfo("one.html"),
    602                               callback_.callback(),
    603                               BoundNetLog()));
    604   EXPECT_EQ(OK, callback_.WaitForResult());
    605 
    606   AuthCredentials credentials(ASCIIToUTF16("user"), ASCIIToUTF16("pass"));
    607   EXPECT_EQ(OK, transaction.RestartWithAuth(credentials, callback_.callback()));
    608 
    609   ExpectResponse("one.html", transaction, SYNCHRONOUS);
    610 }
    611 
    612 TEST_F(HttpPipelinedNetworkTransactionTest, OldVersionDisablesPipelining) {
    613   Initialize(false);
    614 
    615   MockWrite writes[] = {
    616     MockWrite(SYNCHRONOUS, 0, "GET /pipelined.html HTTP/1.1\r\n"
    617               "Host: localhost\r\n"
    618               "Connection: keep-alive\r\n\r\n"),
    619   };
    620   MockRead reads[] = {
    621     MockRead(SYNCHRONOUS, 1, "HTTP/1.0 200 OK\r\n"),
    622     MockRead(SYNCHRONOUS, 2, "Content-Length: 14\r\n\r\n"),
    623     MockRead(SYNCHRONOUS, 3, "pipelined.html"),
    624   };
    625   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    626 
    627   MockWrite writes2[] = {
    628     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    629               "Host: localhost\r\n"
    630               "Connection: keep-alive\r\n\r\n"),
    631   };
    632   MockRead reads2[] = {
    633     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    634     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    635     MockRead(ASYNC, 3, "one.html"),
    636     MockRead(SYNCHRONOUS, OK, 4),
    637   };
    638   AddExpectedConnection(reads2, arraysize(reads2), writes2, arraysize(writes2));
    639 
    640   MockWrite writes3[] = {
    641     MockWrite(SYNCHRONOUS, 0, "GET /two.html HTTP/1.1\r\n"
    642               "Host: localhost\r\n"
    643               "Connection: keep-alive\r\n\r\n"),
    644   };
    645   MockRead reads3[] = {
    646     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    647     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    648     MockRead(SYNCHRONOUS, 3, "two.html"),
    649     MockRead(SYNCHRONOUS, OK, 4),
    650   };
    651   AddExpectedConnection(reads3, arraysize(reads3), writes3, arraysize(writes3));
    652 
    653   HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
    654   TestCompletionCallback one_callback;
    655   EXPECT_EQ(ERR_IO_PENDING,
    656             one_transaction.Start(GetRequestInfo("pipelined.html"),
    657                                   one_callback.callback(), BoundNetLog()));
    658   EXPECT_EQ(OK, one_callback.WaitForResult());
    659   ExpectResponse("pipelined.html", one_transaction, SYNCHRONOUS);
    660 
    661   CompleteTwoRequests(1, 4);
    662 }
    663 
    664 TEST_F(HttpPipelinedNetworkTransactionTest, PipelinesImmediatelyIfKnownGood) {
    665   // The first request gets us an HTTP/1.1. The next 3 test pipelining. When the
    666   // 3rd request completes, we know pipelining is safe. After the first 4
    667   // complete, the 5th and 6th should then be immediately sent pipelined on a
    668   // new HttpPipelinedConnection.
    669   int old_max_sockets = ClientSocketPoolManager::max_sockets_per_group(
    670       HttpNetworkSession::NORMAL_SOCKET_POOL);
    671   ClientSocketPoolManager::set_max_sockets_per_group(
    672       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
    673   Initialize(false);
    674 
    675   MockWrite writes[] = {
    676     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    677               "Host: localhost\r\n"
    678               "Connection: keep-alive\r\n\r\n"),
    679     MockWrite(SYNCHRONOUS, 4, "GET /two.html HTTP/1.1\r\n"
    680               "Host: localhost\r\n"
    681               "Connection: keep-alive\r\n\r\n"),
    682     MockWrite(SYNCHRONOUS, 7, "GET /three.html HTTP/1.1\r\n"
    683               "Host: localhost\r\n"
    684               "Connection: keep-alive\r\n\r\n"),
    685     MockWrite(SYNCHRONOUS, 12, "GET /four.html HTTP/1.1\r\n"
    686               "Host: localhost\r\n"
    687               "Connection: keep-alive\r\n\r\n"),
    688     MockWrite(SYNCHRONOUS, 16, "GET /second-pipeline-one.html HTTP/1.1\r\n"
    689               "Host: localhost\r\n"
    690               "Connection: keep-alive\r\n\r\n"),
    691     MockWrite(SYNCHRONOUS, 17, "GET /second-pipeline-two.html HTTP/1.1\r\n"
    692               "Host: localhost\r\n"
    693               "Connection: keep-alive\r\n\r\n"),
    694   };
    695   MockRead reads[] = {
    696     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    697     MockRead(SYNCHRONOUS, 2, "Content-Length: 8\r\n\r\n"),
    698     MockRead(SYNCHRONOUS, 3, "one.html"),
    699     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    700     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    701     MockRead(SYNCHRONOUS, 8, "two.html"),
    702     MockRead(SYNCHRONOUS, 9, "HTTP/1.1 200 OK\r\n"),
    703     MockRead(SYNCHRONOUS, 10, "Content-Length: 10\r\n\r\n"),
    704     MockRead(SYNCHRONOUS, 11, "three.html"),
    705     MockRead(SYNCHRONOUS, 13, "HTTP/1.1 200 OK\r\n"),
    706     MockRead(SYNCHRONOUS, 14, "Content-Length: 9\r\n\r\n"),
    707     MockRead(SYNCHRONOUS, 15, "four.html"),
    708     MockRead(ASYNC, 18, "HTTP/1.1 200 OK\r\n"),
    709     MockRead(ASYNC, 19, "Content-Length: 24\r\n\r\n"),
    710     MockRead(SYNCHRONOUS, 20, "second-pipeline-one.html"),
    711     MockRead(SYNCHRONOUS, 21, "HTTP/1.1 200 OK\r\n"),
    712     MockRead(SYNCHRONOUS, 22, "Content-Length: 24\r\n\r\n"),
    713     MockRead(SYNCHRONOUS, 23, "second-pipeline-two.html"),
    714   };
    715   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    716 
    717   CompleteFourRequests(REQUEST_DEFAULT);
    718 
    719   HttpNetworkTransaction second_one_transaction(
    720       DEFAULT_PRIORITY, session_.get());
    721   TestCompletionCallback second_one_callback;
    722   EXPECT_EQ(ERR_IO_PENDING,
    723             second_one_transaction.Start(
    724                 GetRequestInfo("second-pipeline-one.html"),
    725                 second_one_callback.callback(), BoundNetLog()));
    726   base::MessageLoop::current()->RunUntilIdle();
    727 
    728   HttpNetworkTransaction second_two_transaction(
    729       DEFAULT_PRIORITY, session_.get());
    730   TestCompletionCallback second_two_callback;
    731   EXPECT_EQ(ERR_IO_PENDING,
    732             second_two_transaction.Start(
    733                 GetRequestInfo("second-pipeline-two.html"),
    734                 second_two_callback.callback(), BoundNetLog()));
    735 
    736   data_vector_[0]->RunFor(3);
    737   EXPECT_EQ(OK, second_one_callback.WaitForResult());
    738   data_vector_[0]->StopAfter(100);
    739   ExpectResponse("second-pipeline-one.html", second_one_transaction,
    740                  SYNCHRONOUS);
    741   EXPECT_EQ(OK, second_two_callback.WaitForResult());
    742   ExpectResponse("second-pipeline-two.html", second_two_transaction,
    743                  SYNCHRONOUS);
    744 
    745   ClientSocketPoolManager::set_max_sockets_per_group(
    746       HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_sockets);
    747 }
    748 
    749 class DataRunnerObserver : public base::MessageLoop::TaskObserver {
    750  public:
    751   DataRunnerObserver(DeterministicSocketData* data, int run_before_task)
    752       : data_(data),
    753         run_before_task_(run_before_task),
    754         current_task_(0) { }
    755 
    756   virtual void WillProcessTask(const base::PendingTask& pending_task) OVERRIDE {
    757     ++current_task_;
    758     if (current_task_ == run_before_task_) {
    759       data_->Run();
    760       base::MessageLoop::current()->RemoveTaskObserver(this);
    761     }
    762   }
    763 
    764   virtual void DidProcessTask(const base::PendingTask& pending_task) OVERRIDE {}
    765 
    766  private:
    767   DeterministicSocketData* data_;
    768   int run_before_task_;
    769   int current_task_;
    770 };
    771 
    772 TEST_F(HttpPipelinedNetworkTransactionTest, OpenPipelinesWhileBinding) {
    773   // There was a racy crash in the pipelining code. This test recreates that
    774   // race. The steps are:
    775   // 1. The first request starts a pipeline and requests headers.
    776   // 2. HttpStreamFactoryImpl::Job tries to bind a pending request to a new
    777   // pipeline and queues a task to do so.
    778   // 3. Before that task runs, the first request receives its headers and
    779   // determines this host is probably capable of pipelining.
    780   // 4. All of the hosts' pipelines are notified they have capacity in a loop.
    781   // 5. On the first iteration, the first pipeline is opened up to accept new
    782   // requests and steals the request from step #2.
    783   // 6. The pipeline from #2 is deleted because it has no streams.
    784   // 7. On the second iteration, the host tries to notify the pipeline from step
    785   // #2 that it has capacity. This is a use-after-free.
    786   Initialize(false);
    787 
    788   MockWrite writes[] = {
    789     MockWrite(SYNCHRONOUS, 0, "GET /one.html HTTP/1.1\r\n"
    790               "Host: localhost\r\n"
    791               "Connection: keep-alive\r\n\r\n"),
    792     MockWrite(ASYNC, 3, "GET /two.html HTTP/1.1\r\n"
    793               "Host: localhost\r\n"
    794               "Connection: keep-alive\r\n\r\n"),
    795   };
    796   MockRead reads[] = {
    797     MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 OK\r\n"),
    798     MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
    799     MockRead(SYNCHRONOUS, 4, "one.html"),
    800     MockRead(SYNCHRONOUS, 5, "HTTP/1.1 200 OK\r\n"),
    801     MockRead(SYNCHRONOUS, 6, "Content-Length: 8\r\n\r\n"),
    802     MockRead(SYNCHRONOUS, 7, "two.html"),
    803   };
    804   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    805 
    806   AddExpectedConnection(NULL, 0, NULL, 0);
    807 
    808   HttpNetworkTransaction one_transaction(DEFAULT_PRIORITY, session_.get());
    809   TestCompletionCallback one_callback;
    810   EXPECT_EQ(ERR_IO_PENDING,
    811             one_transaction.Start(GetRequestInfo("one.html"),
    812                                   one_callback.callback(), BoundNetLog()));
    813 
    814   data_vector_[0]->SetStop(2);
    815   data_vector_[0]->Run();
    816 
    817   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    818   TestCompletionCallback two_callback;
    819   EXPECT_EQ(ERR_IO_PENDING,
    820             two_transaction.Start(GetRequestInfo("two.html"),
    821                                   two_callback.callback(), BoundNetLog()));
    822   // Posted tasks should be:
    823   // 1. MockHostResolverBase::ResolveNow
    824   // 2. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 1
    825   // 3. HttpStreamFactoryImpl::Job::OnStreamReadyCallback for job 2
    826   //
    827   // We need to make sure that the response that triggers OnPipelineFeedback(OK)
    828   // is called in between when task #3 is scheduled and when it runs. The
    829   // DataRunnerObserver does that.
    830   DataRunnerObserver observer(data_vector_[0], 3);
    831   base::MessageLoop::current()->AddTaskObserver(&observer);
    832   data_vector_[0]->SetStop(4);
    833   base::MessageLoop::current()->RunUntilIdle();
    834   data_vector_[0]->SetStop(10);
    835 
    836   EXPECT_EQ(OK, one_callback.WaitForResult());
    837   ExpectResponse("one.html", one_transaction, SYNCHRONOUS);
    838   EXPECT_EQ(OK, two_callback.WaitForResult());
    839   ExpectResponse("two.html", two_transaction, SYNCHRONOUS);
    840 }
    841 
    842 TEST_F(HttpPipelinedNetworkTransactionTest, ProxyChangesWhileConnecting) {
    843   Initialize(false);
    844 
    845   DeterministicSocketData data(NULL, 0, NULL, 0);
    846   data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
    847   factory_.AddSocketDataProvider(&data);
    848 
    849   DeterministicSocketData data2(NULL, 0, NULL, 0);
    850   data2.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
    851   factory_.AddSocketDataProvider(&data2);
    852 
    853   HttpNetworkTransaction transaction(DEFAULT_PRIORITY, session_.get());
    854   EXPECT_EQ(ERR_IO_PENDING,
    855             transaction.Start(GetRequestInfo("test.html"), callback_.callback(),
    856                               BoundNetLog()));
    857 
    858   proxy_config_service_->IncrementConfigId();
    859 
    860   EXPECT_EQ(ERR_FAILED, callback_.WaitForResult());
    861 }
    862 
    863 TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineSharesConnection) {
    864   Initialize(true);
    865 
    866   MockWrite writes[] = {
    867     MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n"
    868               "Host: localhost\r\n"
    869               "Connection: keep-alive\r\n\r\n"
    870               "GET /two.html HTTP/1.1\r\n"
    871               "Host: localhost\r\n"
    872               "Connection: keep-alive\r\n\r\n"),
    873   };
    874   MockRead reads[] = {
    875     MockRead(ASYNC, 1, "HTTP/1.1 200 OK\r\n"),
    876     MockRead(ASYNC, 2, "Content-Length: 8\r\n\r\n"),
    877     MockRead(ASYNC, 3, "one.html"),
    878     MockRead(ASYNC, 4, "HTTP/1.1 200 OK\r\n"),
    879     MockRead(ASYNC, 5, "Content-Length: 8\r\n\r\n"),
    880     MockRead(ASYNC, 6, "two.html"),
    881   };
    882   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    883 
    884   scoped_ptr<HttpNetworkTransaction> one_transaction(
    885       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    886   TestCompletionCallback one_callback;
    887   EXPECT_EQ(ERR_IO_PENDING,
    888             one_transaction->Start(GetRequestInfo("one.html"),
    889                                    one_callback.callback(), BoundNetLog()));
    890 
    891   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    892   TestCompletionCallback two_callback;
    893   EXPECT_EQ(ERR_IO_PENDING,
    894             two_transaction.Start(GetRequestInfo("two.html"),
    895                                   two_callback.callback(), BoundNetLog()));
    896 
    897   data_vector_[0]->RunFor(3);  // Send + 2 lines of headers.
    898   EXPECT_EQ(OK, one_callback.WaitForResult());
    899   ExpectResponse("one.html", *one_transaction.get(), ASYNC);
    900   one_transaction.reset();
    901 
    902   data_vector_[0]->RunFor(2);  // 2 lines of headers.
    903   EXPECT_EQ(OK, two_callback.WaitForResult());
    904   ExpectResponse("two.html", two_transaction, ASYNC);
    905 }
    906 
    907 TEST_F(HttpPipelinedNetworkTransactionTest,
    908        ForcedPipelineConnectionErrorFailsBoth) {
    909   Initialize(true);
    910 
    911   DeterministicSocketData data(NULL, 0, NULL, 0);
    912   data.set_connect_data(MockConnect(ASYNC, ERR_FAILED));
    913   factory_.AddSocketDataProvider(&data);
    914 
    915   scoped_ptr<HttpNetworkTransaction> one_transaction(
    916       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    917   TestCompletionCallback one_callback;
    918   EXPECT_EQ(ERR_IO_PENDING,
    919             one_transaction->Start(GetRequestInfo("one.html"),
    920                                    one_callback.callback(), BoundNetLog()));
    921 
    922   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    923   TestCompletionCallback two_callback;
    924   EXPECT_EQ(ERR_IO_PENDING,
    925             two_transaction.Start(GetRequestInfo("two.html"),
    926                                   two_callback.callback(), BoundNetLog()));
    927 
    928   data.Run();
    929   EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
    930   EXPECT_EQ(ERR_FAILED, two_callback.WaitForResult());
    931 }
    932 
    933 TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineEvictionIsFatal) {
    934   Initialize(true);
    935 
    936   MockWrite writes[] = {
    937     MockWrite(ASYNC, 0, "GET /one.html HTTP/1.1\r\n"
    938               "Host: localhost\r\n"
    939               "Connection: keep-alive\r\n\r\n"
    940               "GET /two.html HTTP/1.1\r\n"
    941               "Host: localhost\r\n"
    942               "Connection: keep-alive\r\n\r\n"),
    943   };
    944   MockRead reads[] = {
    945     MockRead(ASYNC, ERR_FAILED, 1),
    946   };
    947   AddExpectedConnection(reads, arraysize(reads), writes, arraysize(writes));
    948 
    949   scoped_ptr<HttpNetworkTransaction> one_transaction(
    950       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    951   TestCompletionCallback one_callback;
    952   EXPECT_EQ(ERR_IO_PENDING,
    953             one_transaction->Start(GetRequestInfo("one.html"),
    954                                    one_callback.callback(), BoundNetLog()));
    955 
    956   HttpNetworkTransaction two_transaction(DEFAULT_PRIORITY, session_.get());
    957   TestCompletionCallback two_callback;
    958   EXPECT_EQ(ERR_IO_PENDING,
    959             two_transaction.Start(GetRequestInfo("two.html"),
    960                                   two_callback.callback(), BoundNetLog()));
    961 
    962   data_vector_[0]->RunFor(2);
    963   EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
    964   one_transaction.reset();
    965   EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
    966 }
    967 
    968 TEST_F(HttpPipelinedNetworkTransactionTest, ForcedPipelineOrder) {
    969   Initialize(true);
    970 
    971   MockWrite writes[] = {
    972     MockWrite(ASYNC, 0,
    973               "GET /one.html HTTP/1.1\r\n"
    974               "Host: localhost\r\n"
    975               "Connection: keep-alive\r\n\r\n"
    976               "GET /two.html HTTP/1.1\r\n"
    977               "Host: localhost\r\n"
    978               "Connection: keep-alive\r\n\r\n"
    979               "GET /three.html HTTP/1.1\r\n"
    980               "Host: localhost\r\n"
    981               "Connection: keep-alive\r\n\r\n"
    982               "GET /four.html HTTP/1.1\r\n"
    983               "Host: localhost\r\n"
    984               "Connection: keep-alive\r\n\r\n"
    985               ),
    986   };
    987   MockRead reads[] = {
    988     MockRead(ASYNC, ERR_FAILED, 1),
    989   };
    990   DeterministicSocketData data(
    991       reads, arraysize(reads), writes, arraysize(writes));
    992   data.set_connect_data(MockConnect(ASYNC, OK));
    993   factory_.AddSocketDataProvider(&data);
    994 
    995   scoped_ptr<HttpNetworkTransaction> one_transaction(
    996       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    997   TestCompletionCallback one_callback;
    998   EXPECT_EQ(ERR_IO_PENDING,
    999             one_transaction->Start(GetRequestInfo("one.html"),
   1000                                    one_callback.callback(), BoundNetLog()));
   1001 
   1002   scoped_ptr<HttpNetworkTransaction> two_transaction(
   1003       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
   1004   TestCompletionCallback two_callback;
   1005   EXPECT_EQ(ERR_IO_PENDING,
   1006             two_transaction->Start(GetRequestInfo("two.html"),
   1007                                    two_callback.callback(), BoundNetLog()));
   1008 
   1009   scoped_ptr<HttpNetworkTransaction> three_transaction(
   1010       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
   1011   TestCompletionCallback three_callback;
   1012   EXPECT_EQ(ERR_IO_PENDING,
   1013             three_transaction->Start(GetRequestInfo("three.html"),
   1014                                      three_callback.callback(), BoundNetLog()));
   1015 
   1016   scoped_ptr<HttpNetworkTransaction> four_transaction(
   1017       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
   1018   TestCompletionCallback four_callback;
   1019   EXPECT_EQ(ERR_IO_PENDING,
   1020             four_transaction->Start(GetRequestInfo("four.html"),
   1021                                     four_callback.callback(), BoundNetLog()));
   1022 
   1023   data.RunFor(3);
   1024   EXPECT_EQ(ERR_FAILED, one_callback.WaitForResult());
   1025   one_transaction.reset();
   1026   EXPECT_EQ(ERR_PIPELINE_EVICTION, two_callback.WaitForResult());
   1027   two_transaction.reset();
   1028   EXPECT_EQ(ERR_PIPELINE_EVICTION, three_callback.WaitForResult());
   1029   three_transaction.reset();
   1030   EXPECT_EQ(ERR_PIPELINE_EVICTION, four_callback.WaitForResult());
   1031 }
   1032 
   1033 }  // anonymous namespace
   1034 
   1035 }  // namespace net
   1036