Home | History | Annotate | Download | only in http
      1 // Copyright 2013 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_network_transaction.h"
      6 
      7 #include <math.h>  // ceil
      8 #include <stdarg.h>
      9 #include <string>
     10 #include <vector>
     11 
     12 #include "base/basictypes.h"
     13 #include "base/compiler_specific.h"
     14 #include "base/files/file_path.h"
     15 #include "base/files/file_util.h"
     16 #include "base/json/json_writer.h"
     17 #include "base/memory/scoped_ptr.h"
     18 #include "base/memory/weak_ptr.h"
     19 #include "base/run_loop.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/strings/utf_string_conversions.h"
     22 #include "base/test/test_file_util.h"
     23 #include "net/base/auth.h"
     24 #include "net/base/capturing_net_log.h"
     25 #include "net/base/completion_callback.h"
     26 #include "net/base/load_timing_info.h"
     27 #include "net/base/load_timing_info_test_util.h"
     28 #include "net/base/net_log.h"
     29 #include "net/base/net_log_unittest.h"
     30 #include "net/base/request_priority.h"
     31 #include "net/base/test_completion_callback.h"
     32 #include "net/base/test_data_directory.h"
     33 #include "net/base/upload_bytes_element_reader.h"
     34 #include "net/base/upload_data_stream.h"
     35 #include "net/base/upload_file_element_reader.h"
     36 #include "net/cert/mock_cert_verifier.h"
     37 #include "net/dns/host_cache.h"
     38 #include "net/dns/mock_host_resolver.h"
     39 #include "net/http/http_auth_challenge_tokenizer.h"
     40 #include "net/http/http_auth_handler_digest.h"
     41 #include "net/http/http_auth_handler_mock.h"
     42 #include "net/http/http_auth_handler_ntlm.h"
     43 #include "net/http/http_basic_stream.h"
     44 #include "net/http/http_network_session.h"
     45 #include "net/http/http_network_session_peer.h"
     46 #include "net/http/http_server_properties_impl.h"
     47 #include "net/http/http_stream.h"
     48 #include "net/http/http_stream_factory.h"
     49 #include "net/http/http_transaction_test_util.h"
     50 #include "net/proxy/proxy_config_service_fixed.h"
     51 #include "net/proxy/proxy_info.h"
     52 #include "net/proxy/proxy_resolver.h"
     53 #include "net/proxy/proxy_service.h"
     54 #include "net/socket/client_socket_factory.h"
     55 #include "net/socket/client_socket_pool_manager.h"
     56 #include "net/socket/mock_client_socket_pool_manager.h"
     57 #include "net/socket/next_proto.h"
     58 #include "net/socket/socket_test_util.h"
     59 #include "net/socket/ssl_client_socket.h"
     60 #include "net/spdy/spdy_framer.h"
     61 #include "net/spdy/spdy_session.h"
     62 #include "net/spdy/spdy_session_pool.h"
     63 #include "net/spdy/spdy_test_util_common.h"
     64 #include "net/ssl/ssl_cert_request_info.h"
     65 #include "net/ssl/ssl_config_service.h"
     66 #include "net/ssl/ssl_config_service_defaults.h"
     67 #include "net/ssl/ssl_info.h"
     68 #include "net/test/cert_test_util.h"
     69 #include "net/websockets/websocket_handshake_stream_base.h"
     70 #include "testing/gtest/include/gtest/gtest.h"
     71 #include "testing/platform_test.h"
     72 #include "url/gurl.h"
     73 
     74 using base::ASCIIToUTF16;
     75 
     76 //-----------------------------------------------------------------------------
     77 
     78 namespace {
     79 
     80 const base::string16 kBar(ASCIIToUTF16("bar"));
     81 const base::string16 kBar2(ASCIIToUTF16("bar2"));
     82 const base::string16 kBar3(ASCIIToUTF16("bar3"));
     83 const base::string16 kBaz(ASCIIToUTF16("baz"));
     84 const base::string16 kFirst(ASCIIToUTF16("first"));
     85 const base::string16 kFoo(ASCIIToUTF16("foo"));
     86 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
     87 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
     88 const base::string16 kFou(ASCIIToUTF16("fou"));
     89 const base::string16 kSecond(ASCIIToUTF16("second"));
     90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
     91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
     92 
     93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
     94   return session->GetTransportSocketPool(
     95       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     96 }
     97 
     98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
     99   return session->GetSSLSocketPool(
    100       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
    101 }
    102 
    103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
    104   return session->GetTransportSocketPool(
    105       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
    106 }
    107 
    108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
    109 // a JSONified list of headers as a single string.  Uses single quotes instead
    110 // of double quotes for easier comparison.  Returns false on failure.
    111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
    112   if (!params)
    113     return false;
    114   base::ListValue* header_list;
    115   if (!params->GetList("headers", &header_list))
    116     return false;
    117   std::string double_quote_headers;
    118   base::JSONWriter::Write(header_list, &double_quote_headers);
    119   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
    120   return true;
    121 }
    122 
    123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
    124 // used.
    125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
    126   EXPECT_TRUE(load_timing_info.socket_reused);
    127   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    128 
    129   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    130   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    131 
    132   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    133   EXPECT_FALSE(load_timing_info.send_start.is_null());
    134 
    135   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    136 
    137   // Set at a higher level.
    138   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    139   EXPECT_TRUE(load_timing_info.request_start.is_null());
    140   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    141 }
    142 
    143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
    144 // used.
    145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
    146                              int connect_timing_flags) {
    147   EXPECT_FALSE(load_timing_info.socket_reused);
    148   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    149 
    150   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    151   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    152 
    153   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    154                                    connect_timing_flags);
    155   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    156             load_timing_info.send_start);
    157 
    158   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    159 
    160   // Set at a higher level.
    161   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    162   EXPECT_TRUE(load_timing_info.request_start.is_null());
    163   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    164 }
    165 
    166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
    167 // used.
    168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
    169   EXPECT_TRUE(load_timing_info.socket_reused);
    170   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    171 
    172   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    173 
    174   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    175   EXPECT_LE(load_timing_info.proxy_resolve_start,
    176             load_timing_info.proxy_resolve_end);
    177   EXPECT_LE(load_timing_info.proxy_resolve_end,
    178             load_timing_info.send_start);
    179   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    180 
    181   // Set at a higher level.
    182   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    183   EXPECT_TRUE(load_timing_info.request_start.is_null());
    184   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    185 }
    186 
    187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
    188 // used.
    189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
    190                                     int connect_timing_flags) {
    191   EXPECT_FALSE(load_timing_info.socket_reused);
    192   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    193 
    194   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    195   EXPECT_LE(load_timing_info.proxy_resolve_start,
    196             load_timing_info.proxy_resolve_end);
    197   EXPECT_LE(load_timing_info.proxy_resolve_end,
    198             load_timing_info.connect_timing.connect_start);
    199   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    200                                    connect_timing_flags);
    201   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    202             load_timing_info.send_start);
    203 
    204   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    205 
    206   // Set at a higher level.
    207   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    208   EXPECT_TRUE(load_timing_info.request_start.is_null());
    209   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    210 }
    211 
    212 }  // namespace
    213 
    214 namespace net {
    215 
    216 namespace {
    217 
    218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
    219   return SpdySessionDependencies::SpdyCreateSession(session_deps);
    220 }
    221 
    222 }  // namespace
    223 
    224 class HttpNetworkTransactionTest
    225     : public PlatformTest,
    226       public ::testing::WithParamInterface<NextProto> {
    227  public:
    228   virtual ~HttpNetworkTransactionTest() {
    229     // Important to restore the per-pool limit first, since the pool limit must
    230     // always be greater than group limit, and the tests reduce both limits.
    231     ClientSocketPoolManager::set_max_sockets_per_pool(
    232         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    233     ClientSocketPoolManager::set_max_sockets_per_group(
    234         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    235   }
    236 
    237  protected:
    238   HttpNetworkTransactionTest()
    239       : spdy_util_(GetParam()),
    240         session_deps_(GetParam()),
    241         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    242             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    243         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    244             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
    245   }
    246 
    247   struct SimpleGetHelperResult {
    248     int rv;
    249     std::string status_line;
    250     std::string response_data;
    251     int64 totalReceivedBytes;
    252     LoadTimingInfo load_timing_info;
    253   };
    254 
    255   virtual void SetUp() {
    256     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    257     base::MessageLoop::current()->RunUntilIdle();
    258   }
    259 
    260   virtual void TearDown() {
    261     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    262     base::MessageLoop::current()->RunUntilIdle();
    263     // Empty the current queue.
    264     base::MessageLoop::current()->RunUntilIdle();
    265     PlatformTest::TearDown();
    266     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    267     base::MessageLoop::current()->RunUntilIdle();
    268   }
    269 
    270   // This is the expected return from a current server advertising SPDY.
    271   std::string GetAlternateProtocolHttpHeader() {
    272     return
    273         std::string("Alternate-Protocol: 443:") +
    274         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
    275         "\r\n\r\n";
    276   }
    277 
    278   // Either |write_failure| specifies a write failure or |read_failure|
    279   // specifies a read failure when using a reused socket.  In either case, the
    280   // failure should cause the network transaction to resend the request, and the
    281   // other argument should be NULL.
    282   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
    283                                             const MockRead* read_failure);
    284 
    285   // Either |write_failure| specifies a write failure or |read_failure|
    286   // specifies a read failure when using a reused socket.  In either case, the
    287   // failure should cause the network transaction to resend the request, and the
    288   // other argument should be NULL.
    289   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
    290                                         const MockRead* read_failure,
    291                                         bool use_spdy);
    292 
    293   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
    294                                                size_t data_count) {
    295     SimpleGetHelperResult out;
    296 
    297     HttpRequestInfo request;
    298     request.method = "GET";
    299     request.url = GURL("http://www.google.com/");
    300     request.load_flags = 0;
    301 
    302     CapturingBoundNetLog log;
    303     session_deps_.net_log = log.bound().net_log();
    304     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    305     scoped_ptr<HttpTransaction> trans(
    306         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
    307 
    308     for (size_t i = 0; i < data_count; ++i) {
    309       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
    310     }
    311 
    312     TestCompletionCallback callback;
    313 
    314     EXPECT_TRUE(log.bound().IsLogging());
    315     int rv = trans->Start(&request, callback.callback(), log.bound());
    316     EXPECT_EQ(ERR_IO_PENDING, rv);
    317 
    318     out.rv = callback.WaitForResult();
    319 
    320     // Even in the failure cases that use this function, connections are always
    321     // successfully established before the error.
    322     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
    323     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
    324 
    325     if (out.rv != OK)
    326       return out;
    327 
    328     const HttpResponseInfo* response = trans->GetResponseInfo();
    329     // Can't use ASSERT_* inside helper functions like this, so
    330     // return an error.
    331     if (response == NULL || response->headers.get() == NULL) {
    332       out.rv = ERR_UNEXPECTED;
    333       return out;
    334     }
    335     out.status_line = response->headers->GetStatusLine();
    336 
    337     EXPECT_EQ("127.0.0.1", response->socket_address.host());
    338     EXPECT_EQ(80, response->socket_address.port());
    339 
    340     rv = ReadTransaction(trans.get(), &out.response_data);
    341     EXPECT_EQ(OK, rv);
    342 
    343     net::CapturingNetLog::CapturedEntryList entries;
    344     log.GetEntries(&entries);
    345     size_t pos = ExpectLogContainsSomewhere(
    346         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
    347         NetLog::PHASE_NONE);
    348     ExpectLogContainsSomewhere(
    349         entries, pos,
    350         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
    351         NetLog::PHASE_NONE);
    352 
    353     std::string line;
    354     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
    355     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
    356 
    357     HttpRequestHeaders request_headers;
    358     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
    359     std::string value;
    360     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
    361     EXPECT_EQ("www.google.com", value);
    362     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
    363     EXPECT_EQ("keep-alive", value);
    364 
    365     std::string response_headers;
    366     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
    367     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
    368               response_headers);
    369 
    370     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
    371     return out;
    372   }
    373 
    374   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
    375                                         size_t reads_count) {
    376     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
    377     StaticSocketDataProvider* data[] = { &reads };
    378     return SimpleGetHelperForData(data, 1);
    379   }
    380 
    381   int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
    382     int64 size = 0;
    383     for (size_t i = 0; i < reads_count; ++i)
    384       size += data_reads[i].data_len;
    385     return size;
    386   }
    387 
    388   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    389                                              int expected_status);
    390 
    391   void ConnectStatusHelper(const MockRead& status);
    392 
    393   void BypassHostCacheOnRefreshHelper(int load_flags);
    394 
    395   void CheckErrorIsPassedBack(int error, IoMode mode);
    396 
    397   SpdyTestUtil spdy_util_;
    398   SpdySessionDependencies session_deps_;
    399 
    400   // Original socket limits.  Some tests set these.  Safest to always restore
    401   // them once each test has been run.
    402   int old_max_group_sockets_;
    403   int old_max_pool_sockets_;
    404 };
    405 
    406 INSTANTIATE_TEST_CASE_P(
    407     NextProto,
    408     HttpNetworkTransactionTest,
    409     testing::Values(kProtoDeprecatedSPDY2,
    410                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    411 
    412 namespace {
    413 
    414 class BeforeNetworkStartHandler {
    415  public:
    416   explicit BeforeNetworkStartHandler(bool defer)
    417       : defer_on_before_network_start_(defer),
    418         observed_before_network_start_(false) {}
    419 
    420   void OnBeforeNetworkStart(bool* defer) {
    421     *defer = defer_on_before_network_start_;
    422     observed_before_network_start_ = true;
    423   }
    424 
    425   bool observed_before_network_start() const {
    426     return observed_before_network_start_;
    427   }
    428 
    429  private:
    430   const bool defer_on_before_network_start_;
    431   bool observed_before_network_start_;
    432 
    433   DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
    434 };
    435 
    436 class BeforeProxyHeadersSentHandler {
    437  public:
    438   BeforeProxyHeadersSentHandler()
    439       : observed_before_proxy_headers_sent_(false) {}
    440 
    441   void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
    442                                 HttpRequestHeaders* request_headers) {
    443     observed_before_proxy_headers_sent_ = true;
    444     observed_proxy_server_uri_ = proxy_info.proxy_server().ToURI();
    445   }
    446 
    447   bool observed_before_proxy_headers_sent() const {
    448     return observed_before_proxy_headers_sent_;
    449   }
    450 
    451   std::string observed_proxy_server_uri() const {
    452     return observed_proxy_server_uri_;
    453   }
    454 
    455  private:
    456   bool observed_before_proxy_headers_sent_;
    457   std::string observed_proxy_server_uri_;
    458 
    459   DISALLOW_COPY_AND_ASSIGN(BeforeProxyHeadersSentHandler);
    460 };
    461 
    462 // Fill |str| with a long header list that consumes >= |size| bytes.
    463 void FillLargeHeadersString(std::string* str, int size) {
    464   const char* row =
    465       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    466   const int sizeof_row = strlen(row);
    467   const int num_rows = static_cast<int>(
    468       ceil(static_cast<float>(size) / sizeof_row));
    469   const int sizeof_data = num_rows * sizeof_row;
    470   DCHECK(sizeof_data >= size);
    471   str->reserve(sizeof_data);
    472 
    473   for (int i = 0; i < num_rows; ++i)
    474     str->append(row, sizeof_row);
    475 }
    476 
    477 // Alternative functions that eliminate randomness and dependency on the local
    478 // host name so that the generated NTLM messages are reproducible.
    479 void MockGenerateRandom1(uint8* output, size_t n) {
    480   static const uint8 bytes[] = {
    481     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    482   };
    483   static size_t current_byte = 0;
    484   for (size_t i = 0; i < n; ++i) {
    485     output[i] = bytes[current_byte++];
    486     current_byte %= arraysize(bytes);
    487   }
    488 }
    489 
    490 void MockGenerateRandom2(uint8* output, size_t n) {
    491   static const uint8 bytes[] = {
    492     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    493     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    494   };
    495   static size_t current_byte = 0;
    496   for (size_t i = 0; i < n; ++i) {
    497     output[i] = bytes[current_byte++];
    498     current_byte %= arraysize(bytes);
    499   }
    500 }
    501 
    502 std::string MockGetHostName() {
    503   return "WTC-WIN7";
    504 }
    505 
    506 template<typename ParentPool>
    507 class CaptureGroupNameSocketPool : public ParentPool {
    508  public:
    509   CaptureGroupNameSocketPool(HostResolver* host_resolver,
    510                              CertVerifier* cert_verifier);
    511 
    512   const std::string last_group_name_received() const {
    513     return last_group_name_;
    514   }
    515 
    516   virtual int RequestSocket(const std::string& group_name,
    517                             const void* socket_params,
    518                             RequestPriority priority,
    519                             ClientSocketHandle* handle,
    520                             const CompletionCallback& callback,
    521                             const BoundNetLog& net_log) {
    522     last_group_name_ = group_name;
    523     return ERR_IO_PENDING;
    524   }
    525   virtual void CancelRequest(const std::string& group_name,
    526                              ClientSocketHandle* handle) {}
    527   virtual void ReleaseSocket(const std::string& group_name,
    528                              scoped_ptr<StreamSocket> socket,
    529                              int id) {}
    530   virtual void CloseIdleSockets() {}
    531   virtual int IdleSocketCount() const {
    532     return 0;
    533   }
    534   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    535     return 0;
    536   }
    537   virtual LoadState GetLoadState(const std::string& group_name,
    538                                  const ClientSocketHandle* handle) const {
    539     return LOAD_STATE_IDLE;
    540   }
    541   virtual base::TimeDelta ConnectionTimeout() const {
    542     return base::TimeDelta();
    543   }
    544 
    545  private:
    546   std::string last_group_name_;
    547 };
    548 
    549 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
    550 CaptureGroupNameTransportSocketPool;
    551 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
    552 CaptureGroupNameHttpProxySocketPool;
    553 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
    554 CaptureGroupNameSOCKSSocketPool;
    555 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
    556 CaptureGroupNameSSLSocketPool;
    557 
    558 template<typename ParentPool>
    559 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
    560     HostResolver* host_resolver,
    561     CertVerifier* /* cert_verifier */)
    562     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
    563 
    564 template<>
    565 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
    566     HostResolver* host_resolver,
    567     CertVerifier* /* cert_verifier */)
    568     : HttpProxyClientSocketPool(
    569           0, 0, NULL, host_resolver, NULL, NULL, NULL, NULL) {}
    570 
    571 template <>
    572 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
    573     HostResolver* host_resolver,
    574     CertVerifier* cert_verifier)
    575     : SSLClientSocketPool(0,
    576                           0,
    577                           NULL,
    578                           host_resolver,
    579                           cert_verifier,
    580                           NULL,
    581                           NULL,
    582                           NULL,
    583                           std::string(),
    584                           NULL,
    585                           NULL,
    586                           NULL,
    587                           NULL,
    588                           NULL,
    589                           false,
    590                           NULL) {
    591 }
    592 
    593 //-----------------------------------------------------------------------------
    594 
    595 // Helper functions for validating that AuthChallengeInfo's are correctly
    596 // configured for common cases.
    597 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
    598   if (!auth_challenge)
    599     return false;
    600   EXPECT_FALSE(auth_challenge->is_proxy);
    601   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    602   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    603   EXPECT_EQ("basic", auth_challenge->scheme);
    604   return true;
    605 }
    606 
    607 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
    608   if (!auth_challenge)
    609     return false;
    610   EXPECT_TRUE(auth_challenge->is_proxy);
    611   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
    612   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    613   EXPECT_EQ("basic", auth_challenge->scheme);
    614   return true;
    615 }
    616 
    617 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
    618   if (!auth_challenge)
    619     return false;
    620   EXPECT_FALSE(auth_challenge->is_proxy);
    621   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    622   EXPECT_EQ("digestive", auth_challenge->realm);
    623   EXPECT_EQ("digest", auth_challenge->scheme);
    624   return true;
    625 }
    626 
    627 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
    628   if (!auth_challenge)
    629     return false;
    630   EXPECT_FALSE(auth_challenge->is_proxy);
    631   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
    632   EXPECT_EQ(std::string(), auth_challenge->realm);
    633   EXPECT_EQ("ntlm", auth_challenge->scheme);
    634   return true;
    635 }
    636 
    637 }  // namespace
    638 
    639 TEST_P(HttpNetworkTransactionTest, Basic) {
    640   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    641   scoped_ptr<HttpTransaction> trans(
    642       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
    643 }
    644 
    645 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
    646   MockRead data_reads[] = {
    647     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    648     MockRead("hello world"),
    649     MockRead(SYNCHRONOUS, OK),
    650   };
    651   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    652                                               arraysize(data_reads));
    653   EXPECT_EQ(OK, out.rv);
    654   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    655   EXPECT_EQ("hello world", out.response_data);
    656   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    657   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    658 }
    659 
    660 // Response with no status line.
    661 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    662   MockRead data_reads[] = {
    663     MockRead("hello world"),
    664     MockRead(SYNCHRONOUS, OK),
    665   };
    666   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    667                                               arraysize(data_reads));
    668   EXPECT_EQ(OK, out.rv);
    669   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    670   EXPECT_EQ("hello world", out.response_data);
    671   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    672   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    673 }
    674 
    675 // Allow up to 4 bytes of junk to precede status line.
    676 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
    677   MockRead data_reads[] = {
    678     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    679     MockRead(SYNCHRONOUS, OK),
    680   };
    681   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    682                                               arraysize(data_reads));
    683   EXPECT_EQ(OK, out.rv);
    684   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    685   EXPECT_EQ("DATA", out.response_data);
    686   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    687   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    688 }
    689 
    690 // Allow up to 4 bytes of junk to precede status line.
    691 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    692   MockRead data_reads[] = {
    693     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    694     MockRead(SYNCHRONOUS, OK),
    695   };
    696   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    697                                               arraysize(data_reads));
    698   EXPECT_EQ(OK, out.rv);
    699   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    700   EXPECT_EQ("DATA", out.response_data);
    701   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    702   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    703 }
    704 
    705 // Beyond 4 bytes of slop and it should fail to find a status line.
    706 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    707   MockRead data_reads[] = {
    708     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    709     MockRead(SYNCHRONOUS, OK),
    710   };
    711   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    712                                               arraysize(data_reads));
    713   EXPECT_EQ(OK, out.rv);
    714   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    715   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    716   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    717   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    718 }
    719 
    720 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    721 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    722   MockRead data_reads[] = {
    723     MockRead("\n"),
    724     MockRead("\n"),
    725     MockRead("Q"),
    726     MockRead("J"),
    727     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    728     MockRead(SYNCHRONOUS, OK),
    729   };
    730   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    731                                               arraysize(data_reads));
    732   EXPECT_EQ(OK, out.rv);
    733   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    734   EXPECT_EQ("DATA", out.response_data);
    735   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    736   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    737 }
    738 
    739 // Close the connection before enough bytes to have a status line.
    740 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
    741   MockRead data_reads[] = {
    742     MockRead("HTT"),
    743     MockRead(SYNCHRONOUS, OK),
    744   };
    745   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    746                                               arraysize(data_reads));
    747   EXPECT_EQ(OK, out.rv);
    748   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    749   EXPECT_EQ("HTT", out.response_data);
    750   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    751   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    752 }
    753 
    754 // Simulate a 204 response, lacking a Content-Length header, sent over a
    755 // persistent connection.  The response should still terminate since a 204
    756 // cannot have a response body.
    757 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
    758   char junk[] = "junk";
    759   MockRead data_reads[] = {
    760     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    761     MockRead(junk),  // Should not be read!!
    762     MockRead(SYNCHRONOUS, OK),
    763   };
    764   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    765                                               arraysize(data_reads));
    766   EXPECT_EQ(OK, out.rv);
    767   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    768   EXPECT_EQ("", out.response_data);
    769   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    770   int64 response_size = reads_size - strlen(junk);
    771   EXPECT_EQ(response_size, out.totalReceivedBytes);
    772 }
    773 
    774 // A simple request using chunked encoding with some extra data after.
    775 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
    776   std::string final_chunk = "0\r\n\r\n";
    777   std::string extra_data = "HTTP/1.1 200 OK\r\n";
    778   std::string last_read = final_chunk + extra_data;
    779   MockRead data_reads[] = {
    780     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    781     MockRead("5\r\nHello\r\n"),
    782     MockRead("1\r\n"),
    783     MockRead(" \r\n"),
    784     MockRead("5\r\nworld\r\n"),
    785     MockRead(last_read.data()),
    786     MockRead(SYNCHRONOUS, OK),
    787   };
    788   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    789                                               arraysize(data_reads));
    790   EXPECT_EQ(OK, out.rv);
    791   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    792   EXPECT_EQ("Hello world", out.response_data);
    793   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    794   int64 response_size = reads_size - extra_data.size();
    795   EXPECT_EQ(response_size, out.totalReceivedBytes);
    796 }
    797 
    798 // Next tests deal with http://crbug.com/56344.
    799 
    800 TEST_P(HttpNetworkTransactionTest,
    801        MultipleContentLengthHeadersNoTransferEncoding) {
    802   MockRead data_reads[] = {
    803     MockRead("HTTP/1.1 200 OK\r\n"),
    804     MockRead("Content-Length: 10\r\n"),
    805     MockRead("Content-Length: 5\r\n\r\n"),
    806   };
    807   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    808                                               arraysize(data_reads));
    809   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    810 }
    811 
    812 TEST_P(HttpNetworkTransactionTest,
    813        DuplicateContentLengthHeadersNoTransferEncoding) {
    814   MockRead data_reads[] = {
    815     MockRead("HTTP/1.1 200 OK\r\n"),
    816     MockRead("Content-Length: 5\r\n"),
    817     MockRead("Content-Length: 5\r\n\r\n"),
    818     MockRead("Hello"),
    819   };
    820   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    821                                               arraysize(data_reads));
    822   EXPECT_EQ(OK, out.rv);
    823   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    824   EXPECT_EQ("Hello", out.response_data);
    825 }
    826 
    827 TEST_P(HttpNetworkTransactionTest,
    828        ComplexContentLengthHeadersNoTransferEncoding) {
    829   // More than 2 dupes.
    830   {
    831     MockRead data_reads[] = {
    832       MockRead("HTTP/1.1 200 OK\r\n"),
    833       MockRead("Content-Length: 5\r\n"),
    834       MockRead("Content-Length: 5\r\n"),
    835       MockRead("Content-Length: 5\r\n\r\n"),
    836       MockRead("Hello"),
    837     };
    838     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    839                                                 arraysize(data_reads));
    840     EXPECT_EQ(OK, out.rv);
    841     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    842     EXPECT_EQ("Hello", out.response_data);
    843   }
    844   // HTTP/1.0
    845   {
    846     MockRead data_reads[] = {
    847       MockRead("HTTP/1.0 200 OK\r\n"),
    848       MockRead("Content-Length: 5\r\n"),
    849       MockRead("Content-Length: 5\r\n"),
    850       MockRead("Content-Length: 5\r\n\r\n"),
    851       MockRead("Hello"),
    852     };
    853     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    854                                                 arraysize(data_reads));
    855     EXPECT_EQ(OK, out.rv);
    856     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    857     EXPECT_EQ("Hello", out.response_data);
    858   }
    859   // 2 dupes and one mismatched.
    860   {
    861     MockRead data_reads[] = {
    862       MockRead("HTTP/1.1 200 OK\r\n"),
    863       MockRead("Content-Length: 10\r\n"),
    864       MockRead("Content-Length: 10\r\n"),
    865       MockRead("Content-Length: 5\r\n\r\n"),
    866     };
    867     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    868                                                 arraysize(data_reads));
    869     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    870   }
    871 }
    872 
    873 TEST_P(HttpNetworkTransactionTest,
    874        MultipleContentLengthHeadersTransferEncoding) {
    875   MockRead data_reads[] = {
    876     MockRead("HTTP/1.1 200 OK\r\n"),
    877     MockRead("Content-Length: 666\r\n"),
    878     MockRead("Content-Length: 1337\r\n"),
    879     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
    880     MockRead("5\r\nHello\r\n"),
    881     MockRead("1\r\n"),
    882     MockRead(" \r\n"),
    883     MockRead("5\r\nworld\r\n"),
    884     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    885     MockRead(SYNCHRONOUS, OK),
    886   };
    887   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    888                                               arraysize(data_reads));
    889   EXPECT_EQ(OK, out.rv);
    890   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    891   EXPECT_EQ("Hello world", out.response_data);
    892 }
    893 
    894 // Next tests deal with http://crbug.com/98895.
    895 
    896 // Checks that a single Content-Disposition header results in no error.
    897 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
    898   MockRead data_reads[] = {
    899     MockRead("HTTP/1.1 200 OK\r\n"),
    900     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
    901     MockRead("Content-Length: 5\r\n\r\n"),
    902     MockRead("Hello"),
    903   };
    904   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    905                                               arraysize(data_reads));
    906   EXPECT_EQ(OK, out.rv);
    907   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    908   EXPECT_EQ("Hello", out.response_data);
    909 }
    910 
    911 // Checks that two identical Content-Disposition headers result in no error.
    912 TEST_P(HttpNetworkTransactionTest,
    913        TwoIdenticalContentDispositionHeaders) {
    914   MockRead data_reads[] = {
    915     MockRead("HTTP/1.1 200 OK\r\n"),
    916     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    917     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    918     MockRead("Content-Length: 5\r\n\r\n"),
    919     MockRead("Hello"),
    920   };
    921   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    922                                               arraysize(data_reads));
    923   EXPECT_EQ(OK, out.rv);
    924   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    925   EXPECT_EQ("Hello", out.response_data);
    926 }
    927 
    928 // Checks that two distinct Content-Disposition headers result in an error.
    929 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
    930   MockRead data_reads[] = {
    931     MockRead("HTTP/1.1 200 OK\r\n"),
    932     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    933     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
    934     MockRead("Content-Length: 5\r\n\r\n"),
    935     MockRead("Hello"),
    936   };
    937   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    938                                               arraysize(data_reads));
    939   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
    940 }
    941 
    942 // Checks that two identical Location headers result in no error.
    943 // Also tests Location header behavior.
    944 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
    945   MockRead data_reads[] = {
    946     MockRead("HTTP/1.1 302 Redirect\r\n"),
    947     MockRead("Location: http://good.com/\r\n"),
    948     MockRead("Location: http://good.com/\r\n"),
    949     MockRead("Content-Length: 0\r\n\r\n"),
    950     MockRead(SYNCHRONOUS, OK),
    951   };
    952 
    953   HttpRequestInfo request;
    954   request.method = "GET";
    955   request.url = GURL("http://redirect.com/");
    956   request.load_flags = 0;
    957 
    958   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    959   scoped_ptr<HttpTransaction> trans(
    960       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
    961 
    962   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    963   session_deps_.socket_factory->AddSocketDataProvider(&data);
    964 
    965   TestCompletionCallback callback;
    966 
    967   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    968   EXPECT_EQ(ERR_IO_PENDING, rv);
    969 
    970   EXPECT_EQ(OK, callback.WaitForResult());
    971 
    972   const HttpResponseInfo* response = trans->GetResponseInfo();
    973   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
    974   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
    975   std::string url;
    976   EXPECT_TRUE(response->headers->IsRedirect(&url));
    977   EXPECT_EQ("http://good.com/", url);
    978   EXPECT_TRUE(response->proxy_server.IsEmpty());
    979 }
    980 
    981 // Checks that two distinct Location headers result in an error.
    982 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
    983   MockRead data_reads[] = {
    984     MockRead("HTTP/1.1 302 Redirect\r\n"),
    985     MockRead("Location: http://good.com/\r\n"),
    986     MockRead("Location: http://evil.com/\r\n"),
    987     MockRead("Content-Length: 0\r\n\r\n"),
    988     MockRead(SYNCHRONOUS, OK),
    989   };
    990   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    991                                               arraysize(data_reads));
    992   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
    993 }
    994 
    995 // Do a request using the HEAD method. Verify that we don't try to read the
    996 // message body (since HEAD has none).
    997 TEST_P(HttpNetworkTransactionTest, Head) {
    998   HttpRequestInfo request;
    999   request.method = "HEAD";
   1000   request.url = GURL("http://www.google.com/");
   1001   request.load_flags = 0;
   1002 
   1003   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1004   scoped_ptr<HttpTransaction> trans(
   1005       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1006   BeforeProxyHeadersSentHandler proxy_headers_handler;
   1007   trans->SetBeforeProxyHeadersSentCallback(
   1008       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
   1009                  base::Unretained(&proxy_headers_handler)));
   1010 
   1011   MockWrite data_writes1[] = {
   1012     MockWrite("HEAD / HTTP/1.1\r\n"
   1013               "Host: www.google.com\r\n"
   1014               "Connection: keep-alive\r\n"
   1015               "Content-Length: 0\r\n\r\n"),
   1016   };
   1017   MockRead data_reads1[] = {
   1018     MockRead("HTTP/1.1 404 Not Found\r\n"),
   1019     MockRead("Server: Blah\r\n"),
   1020     MockRead("Content-Length: 1234\r\n\r\n"),
   1021 
   1022     // No response body because the test stops reading here.
   1023     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   1024   };
   1025 
   1026   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1027                                  data_writes1, arraysize(data_writes1));
   1028   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1029 
   1030   TestCompletionCallback callback1;
   1031 
   1032   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1033   EXPECT_EQ(ERR_IO_PENDING, rv);
   1034 
   1035   rv = callback1.WaitForResult();
   1036   EXPECT_EQ(OK, rv);
   1037 
   1038   const HttpResponseInfo* response = trans->GetResponseInfo();
   1039   ASSERT_TRUE(response != NULL);
   1040 
   1041   // Check that the headers got parsed.
   1042   EXPECT_TRUE(response->headers.get() != NULL);
   1043   EXPECT_EQ(1234, response->headers->GetContentLength());
   1044   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
   1045   EXPECT_TRUE(response->proxy_server.IsEmpty());
   1046   EXPECT_FALSE(proxy_headers_handler.observed_before_proxy_headers_sent());
   1047 
   1048   std::string server_header;
   1049   void* iter = NULL;
   1050   bool has_server_header = response->headers->EnumerateHeader(
   1051       &iter, "Server", &server_header);
   1052   EXPECT_TRUE(has_server_header);
   1053   EXPECT_EQ("Blah", server_header);
   1054 
   1055   // Reading should give EOF right away, since there is no message body
   1056   // (despite non-zero content-length).
   1057   std::string response_data;
   1058   rv = ReadTransaction(trans.get(), &response_data);
   1059   EXPECT_EQ(OK, rv);
   1060   EXPECT_EQ("", response_data);
   1061 }
   1062 
   1063 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
   1064   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1065 
   1066   MockRead data_reads[] = {
   1067     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1068     MockRead("hello"),
   1069     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1070     MockRead("world"),
   1071     MockRead(SYNCHRONOUS, OK),
   1072   };
   1073   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1074   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1075 
   1076   const char* const kExpectedResponseData[] = {
   1077     "hello", "world"
   1078   };
   1079 
   1080   for (int i = 0; i < 2; ++i) {
   1081     HttpRequestInfo request;
   1082     request.method = "GET";
   1083     request.url = GURL("http://www.google.com/");
   1084     request.load_flags = 0;
   1085 
   1086     scoped_ptr<HttpTransaction> trans(
   1087         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1088 
   1089     TestCompletionCallback callback;
   1090 
   1091     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1092     EXPECT_EQ(ERR_IO_PENDING, rv);
   1093 
   1094     rv = callback.WaitForResult();
   1095     EXPECT_EQ(OK, rv);
   1096 
   1097     const HttpResponseInfo* response = trans->GetResponseInfo();
   1098     ASSERT_TRUE(response != NULL);
   1099 
   1100     EXPECT_TRUE(response->headers.get() != NULL);
   1101     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1102     EXPECT_TRUE(response->proxy_server.IsEmpty());
   1103 
   1104     std::string response_data;
   1105     rv = ReadTransaction(trans.get(), &response_data);
   1106     EXPECT_EQ(OK, rv);
   1107     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1108   }
   1109 }
   1110 
   1111 TEST_P(HttpNetworkTransactionTest, Ignores100) {
   1112   ScopedVector<UploadElementReader> element_readers;
   1113   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   1114   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   1115 
   1116   HttpRequestInfo request;
   1117   request.method = "POST";
   1118   request.url = GURL("http://www.foo.com/");
   1119   request.upload_data_stream = &upload_data_stream;
   1120   request.load_flags = 0;
   1121 
   1122   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1123   scoped_ptr<HttpTransaction> trans(
   1124       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1125 
   1126   MockRead data_reads[] = {
   1127     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   1128     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   1129     MockRead("hello world"),
   1130     MockRead(SYNCHRONOUS, OK),
   1131   };
   1132   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1133   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1134 
   1135   TestCompletionCallback callback;
   1136 
   1137   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1138   EXPECT_EQ(ERR_IO_PENDING, rv);
   1139 
   1140   rv = callback.WaitForResult();
   1141   EXPECT_EQ(OK, rv);
   1142 
   1143   const HttpResponseInfo* response = trans->GetResponseInfo();
   1144   ASSERT_TRUE(response != NULL);
   1145 
   1146   EXPECT_TRUE(response->headers.get() != NULL);
   1147   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   1148 
   1149   std::string response_data;
   1150   rv = ReadTransaction(trans.get(), &response_data);
   1151   EXPECT_EQ(OK, rv);
   1152   EXPECT_EQ("hello world", response_data);
   1153 }
   1154 
   1155 // This test is almost the same as Ignores100 above, but the response contains
   1156 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
   1157 // HTTP/1.1 and the two status headers are read in one read.
   1158 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
   1159   HttpRequestInfo request;
   1160   request.method = "GET";
   1161   request.url = GURL("http://www.foo.com/");
   1162   request.load_flags = 0;
   1163 
   1164   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1165   scoped_ptr<HttpTransaction> trans(
   1166       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1167 
   1168   MockRead data_reads[] = {
   1169     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
   1170              "HTTP/1.1 200 OK\r\n\r\n"),
   1171     MockRead("hello world"),
   1172     MockRead(SYNCHRONOUS, OK),
   1173   };
   1174   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1175   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1176 
   1177   TestCompletionCallback callback;
   1178 
   1179   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1180   EXPECT_EQ(ERR_IO_PENDING, rv);
   1181 
   1182   rv = callback.WaitForResult();
   1183   EXPECT_EQ(OK, rv);
   1184 
   1185   const HttpResponseInfo* response = trans->GetResponseInfo();
   1186   ASSERT_TRUE(response != NULL);
   1187 
   1188   EXPECT_TRUE(response->headers.get() != NULL);
   1189   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1190 
   1191   std::string response_data;
   1192   rv = ReadTransaction(trans.get(), &response_data);
   1193   EXPECT_EQ(OK, rv);
   1194   EXPECT_EQ("hello world", response_data);
   1195 }
   1196 
   1197 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
   1198   HttpRequestInfo request;
   1199   request.method = "POST";
   1200   request.url = GURL("http://www.foo.com/");
   1201   request.load_flags = 0;
   1202 
   1203   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1204   scoped_ptr<HttpTransaction> trans(
   1205       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1206 
   1207   MockRead data_reads[] = {
   1208     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
   1209     MockRead(ASYNC, 0),
   1210   };
   1211   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1212   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1213 
   1214   TestCompletionCallback callback;
   1215 
   1216   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1217   EXPECT_EQ(ERR_IO_PENDING, rv);
   1218 
   1219   rv = callback.WaitForResult();
   1220   EXPECT_EQ(OK, rv);
   1221 
   1222   std::string response_data;
   1223   rv = ReadTransaction(trans.get(), &response_data);
   1224   EXPECT_EQ(OK, rv);
   1225   EXPECT_EQ("", response_data);
   1226 }
   1227 
   1228 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
   1229   HttpRequestInfo request;
   1230   request.method = "POST";
   1231   request.url = GURL("http://www.foo.com/");
   1232   request.load_flags = 0;
   1233 
   1234   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1235   scoped_ptr<HttpTransaction> trans(
   1236       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1237 
   1238   MockRead data_reads[] = {
   1239     MockRead(ASYNC, 0),
   1240   };
   1241   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1242   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1243 
   1244   TestCompletionCallback callback;
   1245 
   1246   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1247   EXPECT_EQ(ERR_IO_PENDING, rv);
   1248 
   1249   rv = callback.WaitForResult();
   1250   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   1251 }
   1252 
   1253 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
   1254     const MockWrite* write_failure,
   1255     const MockRead* read_failure) {
   1256   HttpRequestInfo request;
   1257   request.method = "GET";
   1258   request.url = GURL("http://www.foo.com/");
   1259   request.load_flags = 0;
   1260 
   1261   CapturingNetLog net_log;
   1262   session_deps_.net_log = &net_log;
   1263   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1264 
   1265   // Written data for successfully sending both requests.
   1266   MockWrite data1_writes[] = {
   1267     MockWrite("GET / HTTP/1.1\r\n"
   1268               "Host: www.foo.com\r\n"
   1269               "Connection: keep-alive\r\n\r\n"),
   1270     MockWrite("GET / HTTP/1.1\r\n"
   1271               "Host: www.foo.com\r\n"
   1272               "Connection: keep-alive\r\n\r\n")
   1273   };
   1274 
   1275   // Read results for the first request.
   1276   MockRead data1_reads[] = {
   1277     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1278     MockRead("hello"),
   1279     MockRead(ASYNC, OK),
   1280   };
   1281 
   1282   if (write_failure) {
   1283     ASSERT_FALSE(read_failure);
   1284     data1_writes[1] = *write_failure;
   1285   } else {
   1286     ASSERT_TRUE(read_failure);
   1287     data1_reads[2] = *read_failure;
   1288   }
   1289 
   1290   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
   1291                                  data1_writes, arraysize(data1_writes));
   1292   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1293 
   1294   MockRead data2_reads[] = {
   1295     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1296     MockRead("world"),
   1297     MockRead(ASYNC, OK),
   1298   };
   1299   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1300   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1301 
   1302   const char* kExpectedResponseData[] = {
   1303     "hello", "world"
   1304   };
   1305 
   1306   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1307   for (int i = 0; i < 2; ++i) {
   1308     TestCompletionCallback callback;
   1309 
   1310     scoped_ptr<HttpTransaction> trans(
   1311         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1312 
   1313     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1314     EXPECT_EQ(ERR_IO_PENDING, rv);
   1315 
   1316     rv = callback.WaitForResult();
   1317     EXPECT_EQ(OK, rv);
   1318 
   1319     LoadTimingInfo load_timing_info;
   1320     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1321     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1322     if (i == 0) {
   1323       first_socket_log_id = load_timing_info.socket_log_id;
   1324     } else {
   1325       // The second request should be using a new socket.
   1326       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
   1327     }
   1328 
   1329     const HttpResponseInfo* response = trans->GetResponseInfo();
   1330     ASSERT_TRUE(response != NULL);
   1331 
   1332     EXPECT_TRUE(response->headers.get() != NULL);
   1333     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1334 
   1335     std::string response_data;
   1336     rv = ReadTransaction(trans.get(), &response_data);
   1337     EXPECT_EQ(OK, rv);
   1338     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1339   }
   1340 }
   1341 
   1342 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
   1343     const MockWrite* write_failure,
   1344     const MockRead* read_failure,
   1345     bool use_spdy) {
   1346   HttpRequestInfo request;
   1347   request.method = "GET";
   1348   request.url = GURL("https://www.foo.com/");
   1349   request.load_flags = 0;
   1350 
   1351   CapturingNetLog net_log;
   1352   session_deps_.net_log = &net_log;
   1353   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1354 
   1355   SSLSocketDataProvider ssl1(ASYNC, OK);
   1356   SSLSocketDataProvider ssl2(ASYNC, OK);
   1357   if (use_spdy) {
   1358     ssl1.SetNextProto(GetParam());
   1359     ssl2.SetNextProto(GetParam());
   1360   }
   1361   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   1362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   1363 
   1364   // SPDY versions of the request and response.
   1365   scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
   1366       request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
   1367   scoped_ptr<SpdyFrame> spdy_response(
   1368       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1369   scoped_ptr<SpdyFrame> spdy_data(
   1370       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
   1371 
   1372   // HTTP/1.1 versions of the request and response.
   1373   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
   1374       "Host: www.foo.com\r\n"
   1375       "Connection: keep-alive\r\n\r\n";
   1376   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
   1377   const char kHttpData[] = "hello";
   1378 
   1379   std::vector<MockRead> data1_reads;
   1380   std::vector<MockWrite> data1_writes;
   1381   if (write_failure) {
   1382     ASSERT_FALSE(read_failure);
   1383     data1_writes.push_back(*write_failure);
   1384     data1_reads.push_back(MockRead(ASYNC, OK));
   1385   } else {
   1386     ASSERT_TRUE(read_failure);
   1387     if (use_spdy) {
   1388       data1_writes.push_back(CreateMockWrite(*spdy_request));
   1389     } else {
   1390       data1_writes.push_back(MockWrite(kHttpRequest));
   1391     }
   1392     data1_reads.push_back(*read_failure);
   1393   }
   1394 
   1395   StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
   1396                                  &data1_writes[0], data1_writes.size());
   1397   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1398 
   1399   std::vector<MockRead> data2_reads;
   1400   std::vector<MockWrite> data2_writes;
   1401 
   1402   if (use_spdy) {
   1403     data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
   1404 
   1405     data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
   1406     data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
   1407     data2_reads.push_back(MockRead(ASYNC, OK, 3));
   1408   } else {
   1409     data2_writes.push_back(
   1410         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
   1411 
   1412     data2_reads.push_back(
   1413         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
   1414     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
   1415     data2_reads.push_back(MockRead(ASYNC, OK, 3));
   1416   }
   1417   OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
   1418                           &data2_writes[0], data2_writes.size());
   1419   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1420 
   1421   // Preconnect a socket.
   1422   net::SSLConfig ssl_config;
   1423   session->ssl_config_service()->GetSSLConfig(&ssl_config);
   1424   session->GetNextProtos(&ssl_config.next_protos);
   1425   session->http_stream_factory()->PreconnectStreams(
   1426       1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
   1427   // Wait for the preconnect to complete.
   1428   // TODO(davidben): Some way to wait for an idle socket count might be handy.
   1429   base::RunLoop().RunUntilIdle();
   1430   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   1431 
   1432   // Make the request.
   1433   TestCompletionCallback callback;
   1434 
   1435   scoped_ptr<HttpTransaction> trans(
   1436       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1437 
   1438   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1439   EXPECT_EQ(ERR_IO_PENDING, rv);
   1440 
   1441   rv = callback.WaitForResult();
   1442   EXPECT_EQ(OK, rv);
   1443 
   1444   LoadTimingInfo load_timing_info;
   1445   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1446   TestLoadTimingNotReused(
   1447       load_timing_info,
   1448       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
   1449 
   1450   const HttpResponseInfo* response = trans->GetResponseInfo();
   1451   ASSERT_TRUE(response != NULL);
   1452 
   1453   EXPECT_TRUE(response->headers.get() != NULL);
   1454   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1455 
   1456   std::string response_data;
   1457   rv = ReadTransaction(trans.get(), &response_data);
   1458   EXPECT_EQ(OK, rv);
   1459   EXPECT_EQ(kHttpData, response_data);
   1460 }
   1461 
   1462 TEST_P(HttpNetworkTransactionTest,
   1463        KeepAliveConnectionNotConnectedOnWrite) {
   1464   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1465   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
   1466 }
   1467 
   1468 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
   1469   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1470   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1471 }
   1472 
   1473 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
   1474   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1475   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1476 }
   1477 
   1478 // Make sure that on a 408 response (Request Timeout), the request is retried,
   1479 // if the socket was a reused keep alive socket.
   1480 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
   1481   MockRead read_failure(SYNCHRONOUS,
   1482                         "HTTP/1.1 408 Request Timeout\r\n"
   1483                         "Connection: Keep-Alive\r\n"
   1484                         "Content-Length: 6\r\n\r\n"
   1485                         "Pickle");
   1486   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1487 }
   1488 
   1489 TEST_P(HttpNetworkTransactionTest,
   1490        PreconnectErrorNotConnectedOnWrite) {
   1491   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1492   PreconnectErrorResendRequestTest(&write_failure, NULL, false);
   1493 }
   1494 
   1495 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
   1496   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1497   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1498 }
   1499 
   1500 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
   1501   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1502   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1503 }
   1504 
   1505 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
   1506   MockRead read_failure(ASYNC, OK);  // EOF
   1507   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1508 }
   1509 
   1510 // Make sure that on a 408 response (Request Timeout), the request is retried,
   1511 // if the socket was a preconnected (UNUSED_IDLE) socket.
   1512 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
   1513   MockRead read_failure(SYNCHRONOUS,
   1514                         "HTTP/1.1 408 Request Timeout\r\n"
   1515                         "Connection: Keep-Alive\r\n"
   1516                         "Content-Length: 6\r\n\r\n"
   1517                         "Pickle");
   1518   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1519   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1520 }
   1521 
   1522 TEST_P(HttpNetworkTransactionTest,
   1523        SpdyPreconnectErrorNotConnectedOnWrite) {
   1524   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1525   PreconnectErrorResendRequestTest(&write_failure, NULL, true);
   1526 }
   1527 
   1528 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
   1529   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1530   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1531 }
   1532 
   1533 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
   1534   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1535   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1536 }
   1537 
   1538 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
   1539   MockRead read_failure(ASYNC, OK);  // EOF
   1540   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1541 }
   1542 
   1543 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
   1544   HttpRequestInfo request;
   1545   request.method = "GET";
   1546   request.url = GURL("http://www.google.com/");
   1547   request.load_flags = 0;
   1548 
   1549   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1550   scoped_ptr<HttpTransaction> trans(
   1551       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1552 
   1553   MockRead data_reads[] = {
   1554     MockRead(ASYNC, ERR_CONNECTION_RESET),
   1555     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1556     MockRead("hello world"),
   1557     MockRead(SYNCHRONOUS, OK),
   1558   };
   1559   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1560   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1561 
   1562   TestCompletionCallback callback;
   1563 
   1564   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1565   EXPECT_EQ(ERR_IO_PENDING, rv);
   1566 
   1567   rv = callback.WaitForResult();
   1568   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   1569 
   1570   const HttpResponseInfo* response = trans->GetResponseInfo();
   1571   EXPECT_TRUE(response == NULL);
   1572 }
   1573 
   1574 // What do various browsers do when the server closes a non-keepalive
   1575 // connection without sending any response header or body?
   1576 //
   1577 // IE7: error page
   1578 // Safari 3.1.2 (Windows): error page
   1579 // Firefox 3.0.1: blank page
   1580 // Opera 9.52: after five attempts, blank page
   1581 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
   1582 // Us: error page (EMPTY_RESPONSE)
   1583 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
   1584   MockRead data_reads[] = {
   1585     MockRead(SYNCHRONOUS, OK),  // EOF
   1586     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1587     MockRead("hello world"),
   1588     MockRead(SYNCHRONOUS, OK),
   1589   };
   1590   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
   1591                                               arraysize(data_reads));
   1592   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
   1593 }
   1594 
   1595 // Test that network access can be deferred and resumed.
   1596 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
   1597   HttpRequestInfo request;
   1598   request.method = "GET";
   1599   request.url = GURL("http://www.google.com/");
   1600   request.load_flags = 0;
   1601 
   1602   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1603   scoped_ptr<HttpTransaction> trans(
   1604       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1605 
   1606   // Defer on OnBeforeNetworkStart.
   1607   BeforeNetworkStartHandler net_start_handler(true);  // defer
   1608   trans->SetBeforeNetworkStartCallback(
   1609       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
   1610                  base::Unretained(&net_start_handler)));
   1611 
   1612   MockRead data_reads[] = {
   1613     MockRead("HTTP/1.0 200 OK\r\n"),
   1614     MockRead("Content-Length: 5\r\n\r\n"),
   1615     MockRead("hello"),
   1616     MockRead(SYNCHRONOUS, 0),
   1617   };
   1618   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1619   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1620 
   1621   TestCompletionCallback callback;
   1622 
   1623   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1624   EXPECT_EQ(ERR_IO_PENDING, rv);
   1625   base::MessageLoop::current()->RunUntilIdle();
   1626 
   1627   // Should have deferred for network start.
   1628   EXPECT_TRUE(net_start_handler.observed_before_network_start());
   1629   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
   1630   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
   1631 
   1632   trans->ResumeNetworkStart();
   1633   rv = callback.WaitForResult();
   1634   EXPECT_EQ(OK, rv);
   1635   EXPECT_TRUE(trans->GetResponseInfo() != NULL);
   1636 
   1637   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1638   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1639   if (rv == ERR_IO_PENDING)
   1640     rv = callback.WaitForResult();
   1641   EXPECT_EQ(5, rv);
   1642   trans.reset();
   1643 }
   1644 
   1645 // Test that network use can be deferred and canceled.
   1646 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
   1647   HttpRequestInfo request;
   1648   request.method = "GET";
   1649   request.url = GURL("http://www.google.com/");
   1650   request.load_flags = 0;
   1651 
   1652   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1653   scoped_ptr<HttpTransaction> trans(
   1654       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1655 
   1656   // Defer on OnBeforeNetworkStart.
   1657   BeforeNetworkStartHandler net_start_handler(true);  // defer
   1658   trans->SetBeforeNetworkStartCallback(
   1659       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
   1660                  base::Unretained(&net_start_handler)));
   1661 
   1662   TestCompletionCallback callback;
   1663 
   1664   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1665   EXPECT_EQ(ERR_IO_PENDING, rv);
   1666   base::MessageLoop::current()->RunUntilIdle();
   1667 
   1668   // Should have deferred for network start.
   1669   EXPECT_TRUE(net_start_handler.observed_before_network_start());
   1670   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
   1671   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
   1672 }
   1673 
   1674 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
   1675 // tests. There was a bug causing HttpNetworkTransaction to hang in the
   1676 // destructor in such situations.
   1677 // See http://crbug.com/154712 and http://crbug.com/156609.
   1678 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
   1679   HttpRequestInfo request;
   1680   request.method = "GET";
   1681   request.url = GURL("http://www.google.com/");
   1682   request.load_flags = 0;
   1683 
   1684   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1685   scoped_ptr<HttpTransaction> trans(
   1686       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1687 
   1688   MockRead data_reads[] = {
   1689     MockRead("HTTP/1.0 200 OK\r\n"),
   1690     MockRead("Connection: keep-alive\r\n"),
   1691     MockRead("Content-Length: 100\r\n\r\n"),
   1692     MockRead("hello"),
   1693     MockRead(SYNCHRONOUS, 0),
   1694   };
   1695   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1696   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1697 
   1698   TestCompletionCallback callback;
   1699 
   1700   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1701   EXPECT_EQ(ERR_IO_PENDING, rv);
   1702 
   1703   rv = callback.WaitForResult();
   1704   EXPECT_EQ(OK, rv);
   1705 
   1706   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1707   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1708   if (rv == ERR_IO_PENDING)
   1709     rv = callback.WaitForResult();
   1710   EXPECT_EQ(5, rv);
   1711   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1712   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1713 
   1714   trans.reset();
   1715   base::MessageLoop::current()->RunUntilIdle();
   1716   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1717 }
   1718 
   1719 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
   1720   HttpRequestInfo request;
   1721   request.method = "GET";
   1722   request.url = GURL("http://www.google.com/");
   1723   request.load_flags = 0;
   1724 
   1725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1726   scoped_ptr<HttpTransaction> trans(
   1727       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1728 
   1729   MockRead data_reads[] = {
   1730     MockRead("HTTP/1.0 200 OK\r\n"),
   1731     MockRead("Connection: keep-alive\r\n"),
   1732     MockRead("Content-Length: 100\r\n\r\n"),
   1733     MockRead(SYNCHRONOUS, 0),
   1734   };
   1735   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1736   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1737 
   1738   TestCompletionCallback callback;
   1739 
   1740   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1741   EXPECT_EQ(ERR_IO_PENDING, rv);
   1742 
   1743   rv = callback.WaitForResult();
   1744   EXPECT_EQ(OK, rv);
   1745 
   1746   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1747   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1748   if (rv == ERR_IO_PENDING)
   1749     rv = callback.WaitForResult();
   1750   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1751 
   1752   trans.reset();
   1753   base::MessageLoop::current()->RunUntilIdle();
   1754   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1755 }
   1756 
   1757 // Test that we correctly reuse a keep-alive connection after not explicitly
   1758 // reading the body.
   1759 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
   1760   HttpRequestInfo request;
   1761   request.method = "GET";
   1762   request.url = GURL("http://www.foo.com/");
   1763   request.load_flags = 0;
   1764 
   1765   CapturingNetLog net_log;
   1766   session_deps_.net_log = &net_log;
   1767   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1768 
   1769   // Note that because all these reads happen in the same
   1770   // StaticSocketDataProvider, it shows that the same socket is being reused for
   1771   // all transactions.
   1772   MockRead data1_reads[] = {
   1773     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
   1774     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
   1775     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
   1776     MockRead("HTTP/1.1 302 Found\r\n"
   1777              "Content-Length: 0\r\n\r\n"),
   1778     MockRead("HTTP/1.1 302 Found\r\n"
   1779              "Content-Length: 5\r\n\r\n"
   1780              "hello"),
   1781     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1782              "Content-Length: 0\r\n\r\n"),
   1783     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1784              "Content-Length: 5\r\n\r\n"
   1785              "hello"),
   1786     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1787     MockRead("hello"),
   1788   };
   1789   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
   1790   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1791 
   1792   MockRead data2_reads[] = {
   1793     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   1794   };
   1795   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1796   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1797 
   1798   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
   1799   std::string response_lines[kNumUnreadBodies];
   1800 
   1801   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1802   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
   1803     TestCompletionCallback callback;
   1804 
   1805     scoped_ptr<HttpTransaction> trans(
   1806         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1807 
   1808     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1809     EXPECT_EQ(ERR_IO_PENDING, rv);
   1810 
   1811     rv = callback.WaitForResult();
   1812     EXPECT_EQ(OK, rv);
   1813 
   1814     LoadTimingInfo load_timing_info;
   1815     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1816     if (i == 0) {
   1817       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1818       first_socket_log_id = load_timing_info.socket_log_id;
   1819     } else {
   1820       TestLoadTimingReused(load_timing_info);
   1821       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
   1822     }
   1823 
   1824     const HttpResponseInfo* response = trans->GetResponseInfo();
   1825     ASSERT_TRUE(response != NULL);
   1826 
   1827     ASSERT_TRUE(response->headers.get() != NULL);
   1828     response_lines[i] = response->headers->GetStatusLine();
   1829 
   1830     // We intentionally don't read the response bodies.
   1831   }
   1832 
   1833   const char* const kStatusLines[] = {
   1834     "HTTP/1.1 204 No Content",
   1835     "HTTP/1.1 205 Reset Content",
   1836     "HTTP/1.1 304 Not Modified",
   1837     "HTTP/1.1 302 Found",
   1838     "HTTP/1.1 302 Found",
   1839     "HTTP/1.1 301 Moved Permanently",
   1840     "HTTP/1.1 301 Moved Permanently",
   1841   };
   1842 
   1843   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
   1844                  forgot_to_update_kStatusLines);
   1845 
   1846   for (int i = 0; i < kNumUnreadBodies; ++i)
   1847     EXPECT_EQ(kStatusLines[i], response_lines[i]);
   1848 
   1849   TestCompletionCallback callback;
   1850   scoped_ptr<HttpTransaction> trans(
   1851       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1852   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1853   EXPECT_EQ(ERR_IO_PENDING, rv);
   1854   rv = callback.WaitForResult();
   1855   EXPECT_EQ(OK, rv);
   1856   const HttpResponseInfo* response = trans->GetResponseInfo();
   1857   ASSERT_TRUE(response != NULL);
   1858   ASSERT_TRUE(response->headers.get() != NULL);
   1859   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1860   std::string response_data;
   1861   rv = ReadTransaction(trans.get(), &response_data);
   1862   EXPECT_EQ(OK, rv);
   1863   EXPECT_EQ("hello", response_data);
   1864 }
   1865 
   1866 // Test the request-challenge-retry sequence for basic auth.
   1867 // (basic auth is the easiest to mock, because it has no randomness).
   1868 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
   1869   HttpRequestInfo request;
   1870   request.method = "GET";
   1871   request.url = GURL("http://www.google.com/");
   1872   request.load_flags = 0;
   1873 
   1874   CapturingNetLog log;
   1875   session_deps_.net_log = &log;
   1876   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1877   scoped_ptr<HttpTransaction> trans(
   1878       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1879 
   1880   MockWrite data_writes1[] = {
   1881     MockWrite("GET / HTTP/1.1\r\n"
   1882               "Host: www.google.com\r\n"
   1883               "Connection: keep-alive\r\n\r\n"),
   1884   };
   1885 
   1886   MockRead data_reads1[] = {
   1887     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1888     // Give a couple authenticate options (only the middle one is actually
   1889     // supported).
   1890     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
   1891     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1892     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1893     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1894     // Large content-length -- won't matter, as connection will be reset.
   1895     MockRead("Content-Length: 10000\r\n\r\n"),
   1896     MockRead(SYNCHRONOUS, ERR_FAILED),
   1897   };
   1898 
   1899   // After calling trans->RestartWithAuth(), this is the request we should
   1900   // be issuing -- the final header line contains the credentials.
   1901   MockWrite data_writes2[] = {
   1902     MockWrite("GET / HTTP/1.1\r\n"
   1903               "Host: www.google.com\r\n"
   1904               "Connection: keep-alive\r\n"
   1905               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1906   };
   1907 
   1908   // Lastly, the server responds with the actual content.
   1909   MockRead data_reads2[] = {
   1910     MockRead("HTTP/1.0 200 OK\r\n"),
   1911     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1912     MockRead("Content-Length: 100\r\n\r\n"),
   1913     MockRead(SYNCHRONOUS, OK),
   1914   };
   1915 
   1916   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1917                                  data_writes1, arraysize(data_writes1));
   1918   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1919                                  data_writes2, arraysize(data_writes2));
   1920   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1921   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1922 
   1923   TestCompletionCallback callback1;
   1924 
   1925   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1926   EXPECT_EQ(ERR_IO_PENDING, rv);
   1927 
   1928   rv = callback1.WaitForResult();
   1929   EXPECT_EQ(OK, rv);
   1930 
   1931   LoadTimingInfo load_timing_info1;
   1932   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1933   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1934 
   1935   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
   1936   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
   1937 
   1938   const HttpResponseInfo* response = trans->GetResponseInfo();
   1939   ASSERT_TRUE(response != NULL);
   1940   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1941 
   1942   TestCompletionCallback callback2;
   1943 
   1944   rv = trans->RestartWithAuth(
   1945       AuthCredentials(kFoo, kBar), callback2.callback());
   1946   EXPECT_EQ(ERR_IO_PENDING, rv);
   1947 
   1948   rv = callback2.WaitForResult();
   1949   EXPECT_EQ(OK, rv);
   1950 
   1951   LoadTimingInfo load_timing_info2;
   1952   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1953   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
   1954   // The load timing after restart should have a new socket ID, and times after
   1955   // those of the first load timing.
   1956   EXPECT_LE(load_timing_info1.receive_headers_end,
   1957             load_timing_info2.connect_timing.connect_start);
   1958   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1959 
   1960   int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
   1961   EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
   1962 
   1963   response = trans->GetResponseInfo();
   1964   ASSERT_TRUE(response != NULL);
   1965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1966   EXPECT_EQ(100, response->headers->GetContentLength());
   1967 }
   1968 
   1969 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
   1970   HttpRequestInfo request;
   1971   request.method = "GET";
   1972   request.url = GURL("http://www.google.com/");
   1973   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1974 
   1975   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1976   scoped_ptr<HttpTransaction> trans(
   1977       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1978 
   1979   MockWrite data_writes[] = {
   1980     MockWrite("GET / HTTP/1.1\r\n"
   1981               "Host: www.google.com\r\n"
   1982               "Connection: keep-alive\r\n\r\n"),
   1983   };
   1984 
   1985   MockRead data_reads[] = {
   1986     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1987     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1988     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1989     // Large content-length -- won't matter, as connection will be reset.
   1990     MockRead("Content-Length: 10000\r\n\r\n"),
   1991     MockRead(SYNCHRONOUS, ERR_FAILED),
   1992   };
   1993 
   1994   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1995                                 data_writes, arraysize(data_writes));
   1996   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1997   TestCompletionCallback callback;
   1998 
   1999   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2000   EXPECT_EQ(ERR_IO_PENDING, rv);
   2001 
   2002   rv = callback.WaitForResult();
   2003   EXPECT_EQ(0, rv);
   2004 
   2005   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
   2006   EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
   2007 
   2008   const HttpResponseInfo* response = trans->GetResponseInfo();
   2009   ASSERT_TRUE(response != NULL);
   2010   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2011 }
   2012 
   2013 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2014 // connection.
   2015 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   2016   HttpRequestInfo request;
   2017   request.method = "GET";
   2018   request.url = GURL("http://www.google.com/");
   2019   request.load_flags = 0;
   2020 
   2021   CapturingNetLog log;
   2022   session_deps_.net_log = &log;
   2023   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2024 
   2025   MockWrite data_writes1[] = {
   2026     MockWrite("GET / HTTP/1.1\r\n"
   2027               "Host: www.google.com\r\n"
   2028               "Connection: keep-alive\r\n\r\n"),
   2029 
   2030     // After calling trans->RestartWithAuth(), this is the request we should
   2031     // be issuing -- the final header line contains the credentials.
   2032     MockWrite("GET / HTTP/1.1\r\n"
   2033               "Host: www.google.com\r\n"
   2034               "Connection: keep-alive\r\n"
   2035               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2036   };
   2037 
   2038   MockRead data_reads1[] = {
   2039     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2040     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2041     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2042     MockRead("Content-Length: 14\r\n\r\n"),
   2043     MockRead("Unauthorized\r\n"),
   2044 
   2045     // Lastly, the server responds with the actual content.
   2046     MockRead("HTTP/1.1 200 OK\r\n"),
   2047     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2048     MockRead("Content-Length: 5\r\n\r\n"),
   2049     MockRead("Hello"),
   2050   };
   2051 
   2052   // If there is a regression where we disconnect a Keep-Alive
   2053   // connection during an auth roundtrip, we'll end up reading this.
   2054   MockRead data_reads2[] = {
   2055     MockRead(SYNCHRONOUS, ERR_FAILED),
   2056   };
   2057 
   2058   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2059                                  data_writes1, arraysize(data_writes1));
   2060   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2061                                  NULL, 0);
   2062   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2063   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2064 
   2065   TestCompletionCallback callback1;
   2066 
   2067   scoped_ptr<HttpTransaction> trans(
   2068       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2069   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2070   EXPECT_EQ(ERR_IO_PENDING, rv);
   2071 
   2072   rv = callback1.WaitForResult();
   2073   EXPECT_EQ(OK, rv);
   2074 
   2075   LoadTimingInfo load_timing_info1;
   2076   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   2077   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   2078 
   2079   const HttpResponseInfo* response = trans->GetResponseInfo();
   2080   ASSERT_TRUE(response != NULL);
   2081   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2082 
   2083   TestCompletionCallback callback2;
   2084 
   2085   rv = trans->RestartWithAuth(
   2086       AuthCredentials(kFoo, kBar), callback2.callback());
   2087   EXPECT_EQ(ERR_IO_PENDING, rv);
   2088 
   2089   rv = callback2.WaitForResult();
   2090   EXPECT_EQ(OK, rv);
   2091 
   2092   LoadTimingInfo load_timing_info2;
   2093   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   2094   TestLoadTimingReused(load_timing_info2);
   2095   // The load timing after restart should have the same socket ID, and times
   2096   // those of the first load timing.
   2097   EXPECT_LE(load_timing_info1.receive_headers_end,
   2098             load_timing_info2.send_start);
   2099   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2100 
   2101   response = trans->GetResponseInfo();
   2102   ASSERT_TRUE(response != NULL);
   2103   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2104   EXPECT_EQ(5, response->headers->GetContentLength());
   2105 
   2106   std::string response_data;
   2107   rv = ReadTransaction(trans.get(), &response_data);
   2108   EXPECT_EQ(OK, rv);
   2109   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
   2110   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
   2111 }
   2112 
   2113 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2114 // connection and with no response body to drain.
   2115 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   2116   HttpRequestInfo request;
   2117   request.method = "GET";
   2118   request.url = GURL("http://www.google.com/");
   2119   request.load_flags = 0;
   2120 
   2121   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2122 
   2123   MockWrite data_writes1[] = {
   2124     MockWrite("GET / HTTP/1.1\r\n"
   2125               "Host: www.google.com\r\n"
   2126               "Connection: keep-alive\r\n\r\n"),
   2127 
   2128     // After calling trans->RestartWithAuth(), this is the request we should
   2129     // be issuing -- the final header line contains the credentials.
   2130     MockWrite("GET / HTTP/1.1\r\n"
   2131               "Host: www.google.com\r\n"
   2132               "Connection: keep-alive\r\n"
   2133               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2134   };
   2135 
   2136   MockRead data_reads1[] = {
   2137     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2138     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2139     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   2140 
   2141     // Lastly, the server responds with the actual content.
   2142     MockRead("HTTP/1.1 200 OK\r\n"),
   2143     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2144     MockRead("Content-Length: 5\r\n\r\n"),
   2145     MockRead("hello"),
   2146   };
   2147 
   2148   // An incorrect reconnect would cause this to be read.
   2149   MockRead data_reads2[] = {
   2150     MockRead(SYNCHRONOUS, ERR_FAILED),
   2151   };
   2152 
   2153   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2154                                  data_writes1, arraysize(data_writes1));
   2155   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2156                                  NULL, 0);
   2157   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2158   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2159 
   2160   TestCompletionCallback callback1;
   2161 
   2162   scoped_ptr<HttpTransaction> trans(
   2163       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2164   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2165   EXPECT_EQ(ERR_IO_PENDING, rv);
   2166 
   2167   rv = callback1.WaitForResult();
   2168   EXPECT_EQ(OK, rv);
   2169 
   2170   const HttpResponseInfo* response = trans->GetResponseInfo();
   2171   ASSERT_TRUE(response != NULL);
   2172   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2173 
   2174   TestCompletionCallback callback2;
   2175 
   2176   rv = trans->RestartWithAuth(
   2177       AuthCredentials(kFoo, kBar), callback2.callback());
   2178   EXPECT_EQ(ERR_IO_PENDING, rv);
   2179 
   2180   rv = callback2.WaitForResult();
   2181   EXPECT_EQ(OK, rv);
   2182 
   2183   response = trans->GetResponseInfo();
   2184   ASSERT_TRUE(response != NULL);
   2185   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2186   EXPECT_EQ(5, response->headers->GetContentLength());
   2187 }
   2188 
   2189 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2190 // connection and with a large response body to drain.
   2191 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   2192   HttpRequestInfo request;
   2193   request.method = "GET";
   2194   request.url = GURL("http://www.google.com/");
   2195   request.load_flags = 0;
   2196 
   2197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2198 
   2199   MockWrite data_writes1[] = {
   2200     MockWrite("GET / HTTP/1.1\r\n"
   2201               "Host: www.google.com\r\n"
   2202               "Connection: keep-alive\r\n\r\n"),
   2203 
   2204     // After calling trans->RestartWithAuth(), this is the request we should
   2205     // be issuing -- the final header line contains the credentials.
   2206     MockWrite("GET / HTTP/1.1\r\n"
   2207               "Host: www.google.com\r\n"
   2208               "Connection: keep-alive\r\n"
   2209               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2210   };
   2211 
   2212   // Respond with 5 kb of response body.
   2213   std::string large_body_string("Unauthorized");
   2214   large_body_string.append(5 * 1024, ' ');
   2215   large_body_string.append("\r\n");
   2216 
   2217   MockRead data_reads1[] = {
   2218     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2219     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2220     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2221     // 5134 = 12 + 5 * 1024 + 2
   2222     MockRead("Content-Length: 5134\r\n\r\n"),
   2223     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
   2224 
   2225     // Lastly, the server responds with the actual content.
   2226     MockRead("HTTP/1.1 200 OK\r\n"),
   2227     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2228     MockRead("Content-Length: 5\r\n\r\n"),
   2229     MockRead("hello"),
   2230   };
   2231 
   2232   // An incorrect reconnect would cause this to be read.
   2233   MockRead data_reads2[] = {
   2234     MockRead(SYNCHRONOUS, ERR_FAILED),
   2235   };
   2236 
   2237   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2238                                  data_writes1, arraysize(data_writes1));
   2239   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2240                                  NULL, 0);
   2241   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2242   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2243 
   2244   TestCompletionCallback callback1;
   2245 
   2246   scoped_ptr<HttpTransaction> trans(
   2247       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2248   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2249   EXPECT_EQ(ERR_IO_PENDING, rv);
   2250 
   2251   rv = callback1.WaitForResult();
   2252   EXPECT_EQ(OK, rv);
   2253 
   2254   const HttpResponseInfo* response = trans->GetResponseInfo();
   2255   ASSERT_TRUE(response != NULL);
   2256   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2257 
   2258   TestCompletionCallback callback2;
   2259 
   2260   rv = trans->RestartWithAuth(
   2261       AuthCredentials(kFoo, kBar), callback2.callback());
   2262   EXPECT_EQ(ERR_IO_PENDING, rv);
   2263 
   2264   rv = callback2.WaitForResult();
   2265   EXPECT_EQ(OK, rv);
   2266 
   2267   response = trans->GetResponseInfo();
   2268   ASSERT_TRUE(response != NULL);
   2269   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2270   EXPECT_EQ(5, response->headers->GetContentLength());
   2271 }
   2272 
   2273 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2274 // connection, but the server gets impatient and closes the connection.
   2275 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   2276   HttpRequestInfo request;
   2277   request.method = "GET";
   2278   request.url = GURL("http://www.google.com/");
   2279   request.load_flags = 0;
   2280 
   2281   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2282 
   2283   MockWrite data_writes1[] = {
   2284     MockWrite("GET / HTTP/1.1\r\n"
   2285               "Host: www.google.com\r\n"
   2286               "Connection: keep-alive\r\n\r\n"),
   2287     // This simulates the seemingly successful write to a closed connection
   2288     // if the bug is not fixed.
   2289     MockWrite("GET / HTTP/1.1\r\n"
   2290               "Host: www.google.com\r\n"
   2291               "Connection: keep-alive\r\n"
   2292               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2293   };
   2294 
   2295   MockRead data_reads1[] = {
   2296     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2297     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2298     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2299     MockRead("Content-Length: 14\r\n\r\n"),
   2300     // Tell MockTCPClientSocket to simulate the server closing the connection.
   2301     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   2302     MockRead("Unauthorized\r\n"),
   2303     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
   2304   };
   2305 
   2306   // After calling trans->RestartWithAuth(), this is the request we should
   2307   // be issuing -- the final header line contains the credentials.
   2308   MockWrite data_writes2[] = {
   2309     MockWrite("GET / HTTP/1.1\r\n"
   2310               "Host: www.google.com\r\n"
   2311               "Connection: keep-alive\r\n"
   2312               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2313   };
   2314 
   2315   // Lastly, the server responds with the actual content.
   2316   MockRead data_reads2[] = {
   2317     MockRead("HTTP/1.1 200 OK\r\n"),
   2318     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2319     MockRead("Content-Length: 5\r\n\r\n"),
   2320     MockRead("hello"),
   2321   };
   2322 
   2323   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2324                                  data_writes1, arraysize(data_writes1));
   2325   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2326                                  data_writes2, arraysize(data_writes2));
   2327   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2328   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2329 
   2330   TestCompletionCallback callback1;
   2331 
   2332   scoped_ptr<HttpTransaction> trans(
   2333       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2334   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2335   EXPECT_EQ(ERR_IO_PENDING, rv);
   2336 
   2337   rv = callback1.WaitForResult();
   2338   EXPECT_EQ(OK, rv);
   2339 
   2340   const HttpResponseInfo* response = trans->GetResponseInfo();
   2341   ASSERT_TRUE(response != NULL);
   2342   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2343 
   2344   TestCompletionCallback callback2;
   2345 
   2346   rv = trans->RestartWithAuth(
   2347       AuthCredentials(kFoo, kBar), callback2.callback());
   2348   EXPECT_EQ(ERR_IO_PENDING, rv);
   2349 
   2350   rv = callback2.WaitForResult();
   2351   EXPECT_EQ(OK, rv);
   2352 
   2353   response = trans->GetResponseInfo();
   2354   ASSERT_TRUE(response != NULL);
   2355   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2356   EXPECT_EQ(5, response->headers->GetContentLength());
   2357 }
   2358 
   2359 // Test the request-challenge-retry sequence for basic auth, over a connection
   2360 // that requires a restart when setting up an SSL tunnel.
   2361 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
   2362   HttpRequestInfo request;
   2363   request.method = "GET";
   2364   request.url = GURL("https://www.google.com/");
   2365   // when the no authentication data flag is set.
   2366   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2367 
   2368   // Configure against proxy server "myproxy:70".
   2369   session_deps_.proxy_service.reset(
   2370       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2371   CapturingBoundNetLog log;
   2372   session_deps_.net_log = log.bound().net_log();
   2373   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2374 
   2375   // Since we have proxy, should try to establish tunnel.
   2376   MockWrite data_writes1[] = {
   2377     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2378               "Host: www.google.com\r\n"
   2379               "Proxy-Connection: keep-alive\r\n\r\n"),
   2380 
   2381     // After calling trans->RestartWithAuth(), this is the request we should
   2382     // be issuing -- the final header line contains the credentials.
   2383     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2384               "Host: www.google.com\r\n"
   2385               "Proxy-Connection: keep-alive\r\n"
   2386               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2387 
   2388     MockWrite("GET / HTTP/1.1\r\n"
   2389               "Host: www.google.com\r\n"
   2390               "Connection: keep-alive\r\n\r\n"),
   2391   };
   2392 
   2393   // The proxy responds to the connect with a 407, using a persistent
   2394   // connection.
   2395   MockRead data_reads1[] = {
   2396     // No credentials.
   2397     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2398     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2399     MockRead("Proxy-Connection: close\r\n\r\n"),
   2400 
   2401     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2402 
   2403     MockRead("HTTP/1.1 200 OK\r\n"),
   2404     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2405     MockRead("Content-Length: 5\r\n\r\n"),
   2406     MockRead(SYNCHRONOUS, "hello"),
   2407   };
   2408 
   2409   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2410                                  data_writes1, arraysize(data_writes1));
   2411   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2412   SSLSocketDataProvider ssl(ASYNC, OK);
   2413   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2414 
   2415   TestCompletionCallback callback1;
   2416 
   2417   scoped_ptr<HttpTransaction> trans(
   2418       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2419 
   2420   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2421   EXPECT_EQ(ERR_IO_PENDING, rv);
   2422 
   2423   rv = callback1.WaitForResult();
   2424   EXPECT_EQ(OK, rv);
   2425   net::CapturingNetLog::CapturedEntryList entries;
   2426   log.GetEntries(&entries);
   2427   size_t pos = ExpectLogContainsSomewhere(
   2428       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2429       NetLog::PHASE_NONE);
   2430   ExpectLogContainsSomewhere(
   2431       entries, pos,
   2432       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2433       NetLog::PHASE_NONE);
   2434 
   2435   const HttpResponseInfo* response = trans->GetResponseInfo();
   2436   ASSERT_TRUE(response != NULL);
   2437   ASSERT_FALSE(response->headers.get() == NULL);
   2438   EXPECT_EQ(407, response->headers->response_code());
   2439   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2440   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2441 
   2442   LoadTimingInfo load_timing_info;
   2443   // CONNECT requests and responses are handled at the connect job level, so
   2444   // the transaction does not yet have a connection.
   2445   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
   2446 
   2447   TestCompletionCallback callback2;
   2448 
   2449   rv = trans->RestartWithAuth(
   2450       AuthCredentials(kFoo, kBar), callback2.callback());
   2451   EXPECT_EQ(ERR_IO_PENDING, rv);
   2452 
   2453   rv = callback2.WaitForResult();
   2454   EXPECT_EQ(OK, rv);
   2455 
   2456   response = trans->GetResponseInfo();
   2457   ASSERT_TRUE(response != NULL);
   2458 
   2459   EXPECT_TRUE(response->headers->IsKeepAlive());
   2460   EXPECT_EQ(200, response->headers->response_code());
   2461   EXPECT_EQ(5, response->headers->GetContentLength());
   2462   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2463 
   2464   // The password prompt info should not be set.
   2465   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2466 
   2467   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2468   TestLoadTimingNotReusedWithPac(load_timing_info,
   2469                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2470 
   2471   trans.reset();
   2472   session->CloseAllConnections();
   2473 }
   2474 
   2475 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2476 // proxy connection, when setting up an SSL tunnel.
   2477 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   2478   HttpRequestInfo request;
   2479   request.method = "GET";
   2480   request.url = GURL("https://www.google.com/");
   2481   // Ensure that proxy authentication is attempted even
   2482   // when the no authentication data flag is set.
   2483   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2484 
   2485   // Configure against proxy server "myproxy:70".
   2486   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2487   CapturingBoundNetLog log;
   2488   session_deps_.net_log = log.bound().net_log();
   2489   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2490 
   2491   scoped_ptr<HttpTransaction> trans(
   2492       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2493 
   2494   // Since we have proxy, should try to establish tunnel.
   2495   MockWrite data_writes1[] = {
   2496     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2497               "Host: www.google.com\r\n"
   2498               "Proxy-Connection: keep-alive\r\n\r\n"),
   2499 
   2500     // After calling trans->RestartWithAuth(), this is the request we should
   2501     // be issuing -- the final header line contains the credentials.
   2502     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2503               "Host: www.google.com\r\n"
   2504               "Proxy-Connection: keep-alive\r\n"
   2505               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   2506   };
   2507 
   2508   // The proxy responds to the connect with a 407, using a persistent
   2509   // connection.
   2510   MockRead data_reads1[] = {
   2511     // No credentials.
   2512     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2513     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2514     MockRead("Content-Length: 10\r\n\r\n"),
   2515     MockRead("0123456789"),
   2516 
   2517     // Wrong credentials (wrong password).
   2518     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2519     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2520     MockRead("Content-Length: 10\r\n\r\n"),
   2521     // No response body because the test stops reading here.
   2522     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2523   };
   2524 
   2525   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2526                                  data_writes1, arraysize(data_writes1));
   2527   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2528 
   2529   TestCompletionCallback callback1;
   2530 
   2531   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2532   EXPECT_EQ(ERR_IO_PENDING, rv);
   2533 
   2534   rv = callback1.WaitForResult();
   2535   EXPECT_EQ(OK, rv);
   2536   net::CapturingNetLog::CapturedEntryList entries;
   2537   log.GetEntries(&entries);
   2538   size_t pos = ExpectLogContainsSomewhere(
   2539       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2540       NetLog::PHASE_NONE);
   2541   ExpectLogContainsSomewhere(
   2542       entries, pos,
   2543       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2544       NetLog::PHASE_NONE);
   2545 
   2546   const HttpResponseInfo* response = trans->GetResponseInfo();
   2547   ASSERT_TRUE(response != NULL);
   2548   ASSERT_FALSE(response->headers.get() == NULL);
   2549   EXPECT_TRUE(response->headers->IsKeepAlive());
   2550   EXPECT_EQ(407, response->headers->response_code());
   2551   EXPECT_EQ(10, response->headers->GetContentLength());
   2552   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2553   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2554 
   2555   TestCompletionCallback callback2;
   2556 
   2557   // Wrong password (should be "bar").
   2558   rv = trans->RestartWithAuth(
   2559       AuthCredentials(kFoo, kBaz), callback2.callback());
   2560   EXPECT_EQ(ERR_IO_PENDING, rv);
   2561 
   2562   rv = callback2.WaitForResult();
   2563   EXPECT_EQ(OK, rv);
   2564 
   2565   response = trans->GetResponseInfo();
   2566   ASSERT_TRUE(response != NULL);
   2567   ASSERT_FALSE(response->headers.get() == NULL);
   2568   EXPECT_TRUE(response->headers->IsKeepAlive());
   2569   EXPECT_EQ(407, response->headers->response_code());
   2570   EXPECT_EQ(10, response->headers->GetContentLength());
   2571   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2572   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2573 
   2574   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
   2575   // out of scope.
   2576   session->CloseAllConnections();
   2577 }
   2578 
   2579 // Test that we don't read the response body when we fail to establish a tunnel,
   2580 // even if the user cancels the proxy's auth attempt.
   2581 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   2582   HttpRequestInfo request;
   2583   request.method = "GET";
   2584   request.url = GURL("https://www.google.com/");
   2585   request.load_flags = 0;
   2586 
   2587   // Configure against proxy server "myproxy:70".
   2588   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2589 
   2590   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2591 
   2592   scoped_ptr<HttpTransaction> trans(
   2593       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2594 
   2595   // Since we have proxy, should try to establish tunnel.
   2596   MockWrite data_writes[] = {
   2597     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2598               "Host: www.google.com\r\n"
   2599               "Proxy-Connection: keep-alive\r\n\r\n"),
   2600   };
   2601 
   2602   // The proxy responds to the connect with a 407.
   2603   MockRead data_reads[] = {
   2604     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2605     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2606     MockRead("Content-Length: 10\r\n\r\n"),
   2607     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2608   };
   2609 
   2610   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   2611                                 data_writes, arraysize(data_writes));
   2612   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2613 
   2614   TestCompletionCallback callback;
   2615 
   2616   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2617   EXPECT_EQ(ERR_IO_PENDING, rv);
   2618 
   2619   rv = callback.WaitForResult();
   2620   EXPECT_EQ(OK, rv);
   2621 
   2622   const HttpResponseInfo* response = trans->GetResponseInfo();
   2623   ASSERT_TRUE(response != NULL);
   2624 
   2625   EXPECT_TRUE(response->headers->IsKeepAlive());
   2626   EXPECT_EQ(407, response->headers->response_code());
   2627   EXPECT_EQ(10, response->headers->GetContentLength());
   2628   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2629 
   2630   std::string response_data;
   2631   rv = ReadTransaction(trans.get(), &response_data);
   2632   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   2633 
   2634   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
   2635   session->CloseAllConnections();
   2636 }
   2637 
   2638 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
   2639 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
   2640 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   2641   HttpRequestInfo request;
   2642   request.method = "GET";
   2643   request.url = GURL("http://www.google.com/");
   2644   request.load_flags = 0;
   2645 
   2646   // We are using a DIRECT connection (i.e. no proxy) for this session.
   2647   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2648   scoped_ptr<HttpTransaction> trans(
   2649       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2650 
   2651   MockWrite data_writes1[] = {
   2652     MockWrite("GET / HTTP/1.1\r\n"
   2653               "Host: www.google.com\r\n"
   2654               "Connection: keep-alive\r\n\r\n"),
   2655   };
   2656 
   2657   MockRead data_reads1[] = {
   2658     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
   2659     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2660     // Large content-length -- won't matter, as connection will be reset.
   2661     MockRead("Content-Length: 10000\r\n\r\n"),
   2662     MockRead(SYNCHRONOUS, ERR_FAILED),
   2663   };
   2664 
   2665   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2666                                  data_writes1, arraysize(data_writes1));
   2667   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2668 
   2669   TestCompletionCallback callback;
   2670 
   2671   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2672   EXPECT_EQ(ERR_IO_PENDING, rv);
   2673 
   2674   rv = callback.WaitForResult();
   2675   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2676 }
   2677 
   2678 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
   2679 // through a non-authenticating proxy. The request should fail with
   2680 // ERR_UNEXPECTED_PROXY_AUTH.
   2681 // Note that it is impossible to detect if an HTTP server returns a 407 through
   2682 // a non-authenticating proxy - there is nothing to indicate whether the
   2683 // response came from the proxy or the server, so it is treated as if the proxy
   2684 // issued the challenge.
   2685 TEST_P(HttpNetworkTransactionTest,
   2686        HttpsServerRequestsProxyAuthThroughProxy) {
   2687   HttpRequestInfo request;
   2688   request.method = "GET";
   2689   request.url = GURL("https://www.google.com/");
   2690 
   2691   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2692   CapturingBoundNetLog log;
   2693   session_deps_.net_log = log.bound().net_log();
   2694   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2695 
   2696   // Since we have proxy, should try to establish tunnel.
   2697   MockWrite data_writes1[] = {
   2698     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2699               "Host: www.google.com\r\n"
   2700               "Proxy-Connection: keep-alive\r\n\r\n"),
   2701 
   2702     MockWrite("GET / HTTP/1.1\r\n"
   2703               "Host: www.google.com\r\n"
   2704               "Connection: keep-alive\r\n\r\n"),
   2705   };
   2706 
   2707   MockRead data_reads1[] = {
   2708     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2709 
   2710     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
   2711     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2712     MockRead("\r\n"),
   2713     MockRead(SYNCHRONOUS, OK),
   2714   };
   2715 
   2716   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2717                                  data_writes1, arraysize(data_writes1));
   2718   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2719   SSLSocketDataProvider ssl(ASYNC, OK);
   2720   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2721 
   2722   TestCompletionCallback callback1;
   2723 
   2724   scoped_ptr<HttpTransaction> trans(
   2725       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2726 
   2727   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2728   EXPECT_EQ(ERR_IO_PENDING, rv);
   2729 
   2730   rv = callback1.WaitForResult();
   2731   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2732   net::CapturingNetLog::CapturedEntryList entries;
   2733   log.GetEntries(&entries);
   2734   size_t pos = ExpectLogContainsSomewhere(
   2735       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2736       NetLog::PHASE_NONE);
   2737   ExpectLogContainsSomewhere(
   2738       entries, pos,
   2739       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2740       NetLog::PHASE_NONE);
   2741 }
   2742 
   2743 // Test the load timing for HTTPS requests with an HTTP proxy.
   2744 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
   2745   HttpRequestInfo request1;
   2746   request1.method = "GET";
   2747   request1.url = GURL("https://www.google.com/1");
   2748 
   2749   HttpRequestInfo request2;
   2750   request2.method = "GET";
   2751   request2.url = GURL("https://www.google.com/2");
   2752 
   2753   // Configure against proxy server "myproxy:70".
   2754   session_deps_.proxy_service.reset(
   2755       ProxyService::CreateFixed("PROXY myproxy:70"));
   2756   CapturingBoundNetLog log;
   2757   session_deps_.net_log = log.bound().net_log();
   2758   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2759 
   2760   // Since we have proxy, should try to establish tunnel.
   2761   MockWrite data_writes1[] = {
   2762     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2763               "Host: www.google.com\r\n"
   2764               "Proxy-Connection: keep-alive\r\n\r\n"),
   2765 
   2766     MockWrite("GET /1 HTTP/1.1\r\n"
   2767               "Host: www.google.com\r\n"
   2768               "Connection: keep-alive\r\n\r\n"),
   2769 
   2770     MockWrite("GET /2 HTTP/1.1\r\n"
   2771               "Host: www.google.com\r\n"
   2772               "Connection: keep-alive\r\n\r\n"),
   2773   };
   2774 
   2775   // The proxy responds to the connect with a 407, using a persistent
   2776   // connection.
   2777   MockRead data_reads1[] = {
   2778     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2779 
   2780     MockRead("HTTP/1.1 200 OK\r\n"),
   2781     MockRead("Content-Length: 1\r\n\r\n"),
   2782     MockRead(SYNCHRONOUS, "1"),
   2783 
   2784     MockRead("HTTP/1.1 200 OK\r\n"),
   2785     MockRead("Content-Length: 2\r\n\r\n"),
   2786     MockRead(SYNCHRONOUS, "22"),
   2787   };
   2788 
   2789   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2790                                  data_writes1, arraysize(data_writes1));
   2791   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2792   SSLSocketDataProvider ssl(ASYNC, OK);
   2793   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2794 
   2795   TestCompletionCallback callback1;
   2796   scoped_ptr<HttpTransaction> trans1(
   2797       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2798 
   2799   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2800   EXPECT_EQ(ERR_IO_PENDING, rv);
   2801 
   2802   rv = callback1.WaitForResult();
   2803   EXPECT_EQ(OK, rv);
   2804 
   2805   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2806   ASSERT_TRUE(response1 != NULL);
   2807   ASSERT_TRUE(response1->headers.get() != NULL);
   2808   EXPECT_EQ(1, response1->headers->GetContentLength());
   2809 
   2810   LoadTimingInfo load_timing_info1;
   2811   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2812   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
   2813 
   2814   trans1.reset();
   2815 
   2816   TestCompletionCallback callback2;
   2817   scoped_ptr<HttpTransaction> trans2(
   2818       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2819 
   2820   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2821   EXPECT_EQ(ERR_IO_PENDING, rv);
   2822 
   2823   rv = callback2.WaitForResult();
   2824   EXPECT_EQ(OK, rv);
   2825 
   2826   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2827   ASSERT_TRUE(response2 != NULL);
   2828   ASSERT_TRUE(response2->headers.get() != NULL);
   2829   EXPECT_EQ(2, response2->headers->GetContentLength());
   2830 
   2831   LoadTimingInfo load_timing_info2;
   2832   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2833   TestLoadTimingReused(load_timing_info2);
   2834 
   2835   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2836 
   2837   trans2.reset();
   2838   session->CloseAllConnections();
   2839 }
   2840 
   2841 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
   2842 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
   2843   HttpRequestInfo request1;
   2844   request1.method = "GET";
   2845   request1.url = GURL("https://www.google.com/1");
   2846 
   2847   HttpRequestInfo request2;
   2848   request2.method = "GET";
   2849   request2.url = GURL("https://www.google.com/2");
   2850 
   2851   // Configure against proxy server "myproxy:70".
   2852   session_deps_.proxy_service.reset(
   2853       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2854   CapturingBoundNetLog log;
   2855   session_deps_.net_log = log.bound().net_log();
   2856   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2857 
   2858   // Since we have proxy, should try to establish tunnel.
   2859   MockWrite data_writes1[] = {
   2860     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2861               "Host: www.google.com\r\n"
   2862               "Proxy-Connection: keep-alive\r\n\r\n"),
   2863 
   2864     MockWrite("GET /1 HTTP/1.1\r\n"
   2865               "Host: www.google.com\r\n"
   2866               "Connection: keep-alive\r\n\r\n"),
   2867 
   2868     MockWrite("GET /2 HTTP/1.1\r\n"
   2869               "Host: www.google.com\r\n"
   2870               "Connection: keep-alive\r\n\r\n"),
   2871   };
   2872 
   2873   // The proxy responds to the connect with a 407, using a persistent
   2874   // connection.
   2875   MockRead data_reads1[] = {
   2876     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2877 
   2878     MockRead("HTTP/1.1 200 OK\r\n"),
   2879     MockRead("Content-Length: 1\r\n\r\n"),
   2880     MockRead(SYNCHRONOUS, "1"),
   2881 
   2882     MockRead("HTTP/1.1 200 OK\r\n"),
   2883     MockRead("Content-Length: 2\r\n\r\n"),
   2884     MockRead(SYNCHRONOUS, "22"),
   2885   };
   2886 
   2887   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2888                                  data_writes1, arraysize(data_writes1));
   2889   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2890   SSLSocketDataProvider ssl(ASYNC, OK);
   2891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2892 
   2893   TestCompletionCallback callback1;
   2894   scoped_ptr<HttpTransaction> trans1(
   2895       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2896 
   2897   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2898   EXPECT_EQ(ERR_IO_PENDING, rv);
   2899 
   2900   rv = callback1.WaitForResult();
   2901   EXPECT_EQ(OK, rv);
   2902 
   2903   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2904   ASSERT_TRUE(response1 != NULL);
   2905   ASSERT_TRUE(response1->headers.get() != NULL);
   2906   EXPECT_EQ(1, response1->headers->GetContentLength());
   2907 
   2908   LoadTimingInfo load_timing_info1;
   2909   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2910   TestLoadTimingNotReusedWithPac(load_timing_info1,
   2911                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2912 
   2913   trans1.reset();
   2914 
   2915   TestCompletionCallback callback2;
   2916   scoped_ptr<HttpTransaction> trans2(
   2917       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2918 
   2919   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2920   EXPECT_EQ(ERR_IO_PENDING, rv);
   2921 
   2922   rv = callback2.WaitForResult();
   2923   EXPECT_EQ(OK, rv);
   2924 
   2925   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2926   ASSERT_TRUE(response2 != NULL);
   2927   ASSERT_TRUE(response2->headers.get() != NULL);
   2928   EXPECT_EQ(2, response2->headers->GetContentLength());
   2929 
   2930   LoadTimingInfo load_timing_info2;
   2931   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2932   TestLoadTimingReusedWithPac(load_timing_info2);
   2933 
   2934   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2935 
   2936   trans2.reset();
   2937   session->CloseAllConnections();
   2938 }
   2939 
   2940 // Test a simple get through an HTTPS Proxy.
   2941 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
   2942   HttpRequestInfo request;
   2943   request.method = "GET";
   2944   request.url = GURL("http://www.google.com/");
   2945 
   2946   // Configure against https proxy server "proxy:70".
   2947   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2948       "https://proxy:70"));
   2949   CapturingBoundNetLog log;
   2950   session_deps_.net_log = log.bound().net_log();
   2951   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2952 
   2953   // Since we have proxy, should use full url
   2954   MockWrite data_writes1[] = {
   2955     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2956               "Host: www.google.com\r\n"
   2957               "Proxy-Connection: keep-alive\r\n\r\n"),
   2958   };
   2959 
   2960   MockRead data_reads1[] = {
   2961     MockRead("HTTP/1.1 200 OK\r\n"),
   2962     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2963     MockRead("Content-Length: 100\r\n\r\n"),
   2964     MockRead(SYNCHRONOUS, OK),
   2965   };
   2966 
   2967   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2968                                  data_writes1, arraysize(data_writes1));
   2969   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2970   SSLSocketDataProvider ssl(ASYNC, OK);
   2971   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2972 
   2973   TestCompletionCallback callback1;
   2974 
   2975   scoped_ptr<HttpTransaction> trans(
   2976       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2977 
   2978   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2979   EXPECT_EQ(ERR_IO_PENDING, rv);
   2980 
   2981   rv = callback1.WaitForResult();
   2982   EXPECT_EQ(OK, rv);
   2983 
   2984   LoadTimingInfo load_timing_info;
   2985   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2986   TestLoadTimingNotReused(load_timing_info,
   2987                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2988 
   2989   const HttpResponseInfo* response = trans->GetResponseInfo();
   2990   ASSERT_TRUE(response != NULL);
   2991 
   2992   EXPECT_TRUE(response->headers->IsKeepAlive());
   2993   EXPECT_EQ(200, response->headers->response_code());
   2994   EXPECT_EQ(100, response->headers->GetContentLength());
   2995   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2996 
   2997   // The password prompt info should not be set.
   2998   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2999 }
   3000 
   3001 // Test a SPDY get through an HTTPS Proxy.
   3002 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   3003   HttpRequestInfo request;
   3004   request.method = "GET";
   3005   request.url = GURL("http://www.google.com/");
   3006   request.load_flags = 0;
   3007 
   3008   // Configure against https proxy server "proxy:70".
   3009   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3010       "https://proxy:70"));
   3011   CapturingBoundNetLog log;
   3012   session_deps_.net_log = log.bound().net_log();
   3013   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3014 
   3015   // fetch http://www.google.com/ via SPDY
   3016   scoped_ptr<SpdyFrame> req(
   3017       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   3018   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   3019 
   3020   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3021   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3022   MockRead spdy_reads[] = {
   3023     CreateMockRead(*resp),
   3024     CreateMockRead(*data),
   3025     MockRead(ASYNC, 0, 0),
   3026   };
   3027 
   3028   DelayedSocketData spdy_data(
   3029       1,  // wait for one write to finish before reading.
   3030       spdy_reads, arraysize(spdy_reads),
   3031       spdy_writes, arraysize(spdy_writes));
   3032   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3033 
   3034   SSLSocketDataProvider ssl(ASYNC, OK);
   3035   ssl.SetNextProto(GetParam());
   3036   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3037 
   3038   TestCompletionCallback callback1;
   3039 
   3040   scoped_ptr<HttpTransaction> trans(
   3041       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3042 
   3043   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3044   EXPECT_EQ(ERR_IO_PENDING, rv);
   3045 
   3046   rv = callback1.WaitForResult();
   3047   EXPECT_EQ(OK, rv);
   3048 
   3049   LoadTimingInfo load_timing_info;
   3050   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3051   TestLoadTimingNotReused(load_timing_info,
   3052                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3053 
   3054   const HttpResponseInfo* response = trans->GetResponseInfo();
   3055   ASSERT_TRUE(response != NULL);
   3056   ASSERT_TRUE(response->headers.get() != NULL);
   3057   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3058 
   3059   std::string response_data;
   3060   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3061   EXPECT_EQ(kUploadData, response_data);
   3062 }
   3063 
   3064 // Verifies that a session which races and wins against the owning transaction
   3065 // (completing prior to host resolution), doesn't fail the transaction.
   3066 // Regression test for crbug.com/334413.
   3067 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
   3068   HttpRequestInfo request;
   3069   request.method = "GET";
   3070   request.url = GURL("http://www.google.com/");
   3071   request.load_flags = 0;
   3072 
   3073   // Configure SPDY proxy server "proxy:70".
   3074   session_deps_.proxy_service.reset(
   3075       ProxyService::CreateFixed("https://proxy:70"));
   3076   CapturingBoundNetLog log;
   3077   session_deps_.net_log = log.bound().net_log();
   3078   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3079 
   3080   // Fetch http://www.google.com/ through the SPDY proxy.
   3081   scoped_ptr<SpdyFrame> req(
   3082       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   3083   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
   3084 
   3085   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3086   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3087   MockRead spdy_reads[] = {
   3088       CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
   3089   };
   3090 
   3091   DelayedSocketData spdy_data(
   3092       1,  // wait for one write to finish before reading.
   3093       spdy_reads,
   3094       arraysize(spdy_reads),
   3095       spdy_writes,
   3096       arraysize(spdy_writes));
   3097   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3098 
   3099   SSLSocketDataProvider ssl(ASYNC, OK);
   3100   ssl.SetNextProto(GetParam());
   3101   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3102 
   3103   TestCompletionCallback callback1;
   3104 
   3105   scoped_ptr<HttpTransaction> trans(
   3106       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3107 
   3108   // Stall the hostname resolution begun by the transaction.
   3109   session_deps_.host_resolver->set_synchronous_mode(false);
   3110   session_deps_.host_resolver->set_ondemand_mode(true);
   3111 
   3112   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3113   EXPECT_EQ(ERR_IO_PENDING, rv);
   3114 
   3115   // Race a session to the proxy, which completes first.
   3116   session_deps_.host_resolver->set_ondemand_mode(false);
   3117   SpdySessionKey key(
   3118       HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   3119   base::WeakPtr<SpdySession> spdy_session =
   3120       CreateSecureSpdySession(session, key, log.bound());
   3121 
   3122   // Unstall the resolution begun by the transaction.
   3123   session_deps_.host_resolver->set_ondemand_mode(true);
   3124   session_deps_.host_resolver->ResolveAllPending();
   3125 
   3126   EXPECT_FALSE(callback1.have_result());
   3127   rv = callback1.WaitForResult();
   3128   EXPECT_EQ(OK, rv);
   3129 
   3130   const HttpResponseInfo* response = trans->GetResponseInfo();
   3131   ASSERT_TRUE(response != NULL);
   3132   ASSERT_TRUE(response->headers.get() != NULL);
   3133   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3134 
   3135   std::string response_data;
   3136   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3137   EXPECT_EQ(kUploadData, response_data);
   3138 }
   3139 
   3140 // Test a SPDY get through an HTTPS Proxy.
   3141 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   3142   HttpRequestInfo request;
   3143   request.method = "GET";
   3144   request.url = GURL("http://www.google.com/");
   3145   request.load_flags = 0;
   3146 
   3147   // Configure against https proxy server "myproxy:70".
   3148   session_deps_.proxy_service.reset(
   3149       ProxyService::CreateFixed("https://myproxy:70"));
   3150   CapturingBoundNetLog log;
   3151   session_deps_.net_log = log.bound().net_log();
   3152   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3153 
   3154   // The first request will be a bare GET, the second request will be a
   3155   // GET with a Proxy-Authorization header.
   3156   scoped_ptr<SpdyFrame> req_get(
   3157       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   3158   const char* const kExtraAuthorizationHeaders[] = {
   3159     "proxy-authorization", "Basic Zm9vOmJhcg=="
   3160   };
   3161   scoped_ptr<SpdyFrame> req_get_authorization(
   3162       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
   3163                                   arraysize(kExtraAuthorizationHeaders) / 2,
   3164                                   false,
   3165                                   3,
   3166                                   LOWEST,
   3167                                   false));
   3168   MockWrite spdy_writes[] = {
   3169     CreateMockWrite(*req_get, 1),
   3170     CreateMockWrite(*req_get_authorization, 4),
   3171   };
   3172 
   3173   // The first response is a 407 proxy authentication challenge, and the second
   3174   // response will be a 200 response since the second request includes a valid
   3175   // Authorization header.
   3176   const char* const kExtraAuthenticationHeaders[] = {
   3177     "proxy-authenticate", "Basic realm=\"MyRealm1\""
   3178   };
   3179   scoped_ptr<SpdyFrame> resp_authentication(
   3180       spdy_util_.ConstructSpdySynReplyError(
   3181           "407 Proxy Authentication Required",
   3182           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
   3183           1));
   3184   scoped_ptr<SpdyFrame> body_authentication(
   3185       spdy_util_.ConstructSpdyBodyFrame(1, true));
   3186   scoped_ptr<SpdyFrame> resp_data(
   3187       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3188   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
   3189   MockRead spdy_reads[] = {
   3190     CreateMockRead(*resp_authentication, 2),
   3191     CreateMockRead(*body_authentication, 3),
   3192     CreateMockRead(*resp_data, 5),
   3193     CreateMockRead(*body_data, 6),
   3194     MockRead(ASYNC, 0, 7),
   3195   };
   3196 
   3197   OrderedSocketData data(
   3198       spdy_reads, arraysize(spdy_reads),
   3199       spdy_writes, arraysize(spdy_writes));
   3200   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3201 
   3202   SSLSocketDataProvider ssl(ASYNC, OK);
   3203   ssl.SetNextProto(GetParam());
   3204   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3205 
   3206   TestCompletionCallback callback1;
   3207 
   3208   scoped_ptr<HttpTransaction> trans(
   3209       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3210 
   3211   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3212   EXPECT_EQ(ERR_IO_PENDING, rv);
   3213 
   3214   rv = callback1.WaitForResult();
   3215   EXPECT_EQ(OK, rv);
   3216 
   3217   const HttpResponseInfo* const response = trans->GetResponseInfo();
   3218 
   3219   ASSERT_TRUE(response != NULL);
   3220   ASSERT_TRUE(response->headers.get() != NULL);
   3221   EXPECT_EQ(407, response->headers->response_code());
   3222   EXPECT_TRUE(response->was_fetched_via_spdy);
   3223   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3224 
   3225   TestCompletionCallback callback2;
   3226 
   3227   rv = trans->RestartWithAuth(
   3228       AuthCredentials(kFoo, kBar), callback2.callback());
   3229   EXPECT_EQ(ERR_IO_PENDING, rv);
   3230 
   3231   rv = callback2.WaitForResult();
   3232   EXPECT_EQ(OK, rv);
   3233 
   3234   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   3235 
   3236   ASSERT_TRUE(response_restart != NULL);
   3237   ASSERT_TRUE(response_restart->headers.get() != NULL);
   3238   EXPECT_EQ(200, response_restart->headers->response_code());
   3239   // The password prompt info should not be set.
   3240   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   3241 }
   3242 
   3243 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
   3244 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   3245   HttpRequestInfo request;
   3246   request.method = "GET";
   3247   request.url = GURL("https://www.google.com/");
   3248   request.load_flags = 0;
   3249 
   3250   // Configure against https proxy server "proxy:70".
   3251   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3252       "https://proxy:70"));
   3253   CapturingBoundNetLog log;
   3254   session_deps_.net_log = log.bound().net_log();
   3255   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3256 
   3257   scoped_ptr<HttpTransaction> trans(
   3258       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3259 
   3260   // CONNECT to www.google.com:443 via SPDY
   3261   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3262                                                                 LOWEST));
   3263   // fetch https://www.google.com/ via HTTP
   3264 
   3265   const char get[] = "GET / HTTP/1.1\r\n"
   3266     "Host: www.google.com\r\n"
   3267     "Connection: keep-alive\r\n\r\n";
   3268   scoped_ptr<SpdyFrame> wrapped_get(
   3269       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
   3270   scoped_ptr<SpdyFrame> conn_resp(
   3271       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3272   const char resp[] = "HTTP/1.1 200 OK\r\n"
   3273       "Content-Length: 10\r\n\r\n";
   3274   scoped_ptr<SpdyFrame> wrapped_get_resp(
   3275       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
   3276   scoped_ptr<SpdyFrame> wrapped_body(
   3277       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
   3278   scoped_ptr<SpdyFrame> window_update(
   3279       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   3280 
   3281   MockWrite spdy_writes[] = {
   3282       CreateMockWrite(*connect, 1),
   3283       CreateMockWrite(*wrapped_get, 3),
   3284       CreateMockWrite(*window_update, 5),
   3285   };
   3286 
   3287   MockRead spdy_reads[] = {
   3288     CreateMockRead(*conn_resp, 2, ASYNC),
   3289     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   3290     CreateMockRead(*wrapped_body, 6, ASYNC),
   3291     CreateMockRead(*wrapped_body, 7, ASYNC),
   3292     MockRead(ASYNC, 0, 8),
   3293   };
   3294 
   3295   OrderedSocketData spdy_data(
   3296       spdy_reads, arraysize(spdy_reads),
   3297       spdy_writes, arraysize(spdy_writes));
   3298   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3299 
   3300   SSLSocketDataProvider ssl(ASYNC, OK);
   3301   ssl.SetNextProto(GetParam());
   3302   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3303   SSLSocketDataProvider ssl2(ASYNC, OK);
   3304   ssl2.was_npn_negotiated = false;
   3305   ssl2.protocol_negotiated = kProtoUnknown;
   3306   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3307 
   3308   TestCompletionCallback callback1;
   3309 
   3310   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3311   EXPECT_EQ(ERR_IO_PENDING, rv);
   3312 
   3313   rv = callback1.WaitForResult();
   3314   EXPECT_EQ(OK, rv);
   3315 
   3316   LoadTimingInfo load_timing_info;
   3317   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3318   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3319 
   3320   const HttpResponseInfo* response = trans->GetResponseInfo();
   3321   ASSERT_TRUE(response != NULL);
   3322   ASSERT_TRUE(response->headers.get() != NULL);
   3323   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3324 
   3325   std::string response_data;
   3326   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3327   EXPECT_EQ("1234567890", response_data);
   3328 }
   3329 
   3330 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
   3331 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   3332   HttpRequestInfo request;
   3333   request.method = "GET";
   3334   request.url = GURL("https://www.google.com/");
   3335   request.load_flags = 0;
   3336 
   3337   // Configure against https proxy server "proxy:70".
   3338   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3339       "https://proxy:70"));
   3340   CapturingBoundNetLog log;
   3341   session_deps_.net_log = log.bound().net_log();
   3342   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3343 
   3344   scoped_ptr<HttpTransaction> trans(
   3345       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3346 
   3347   // CONNECT to www.google.com:443 via SPDY
   3348   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3349                                                                 LOWEST));
   3350   // fetch https://www.google.com/ via SPDY
   3351   const char* const kMyUrl = "https://www.google.com/";
   3352   scoped_ptr<SpdyFrame> get(
   3353       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   3354   scoped_ptr<SpdyFrame> wrapped_get(
   3355       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
   3356   scoped_ptr<SpdyFrame> conn_resp(
   3357       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3358   scoped_ptr<SpdyFrame> get_resp(
   3359       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3360   scoped_ptr<SpdyFrame> wrapped_get_resp(
   3361       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
   3362   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3363   scoped_ptr<SpdyFrame> wrapped_body(
   3364       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
   3365   scoped_ptr<SpdyFrame> window_update_get_resp(
   3366       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   3367   scoped_ptr<SpdyFrame> window_update_body(
   3368       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
   3369 
   3370   MockWrite spdy_writes[] = {
   3371       CreateMockWrite(*connect, 1),
   3372       CreateMockWrite(*wrapped_get, 3),
   3373       CreateMockWrite(*window_update_get_resp, 5),
   3374       CreateMockWrite(*window_update_body, 7),
   3375   };
   3376 
   3377   MockRead spdy_reads[] = {
   3378     CreateMockRead(*conn_resp, 2, ASYNC),
   3379     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   3380     CreateMockRead(*wrapped_body, 6, ASYNC),
   3381     MockRead(ASYNC, 0, 8),
   3382   };
   3383 
   3384   OrderedSocketData spdy_data(
   3385       spdy_reads, arraysize(spdy_reads),
   3386       spdy_writes, arraysize(spdy_writes));
   3387   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3388 
   3389   SSLSocketDataProvider ssl(ASYNC, OK);
   3390   ssl.SetNextProto(GetParam());
   3391   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3392   SSLSocketDataProvider ssl2(ASYNC, OK);
   3393   ssl2.SetNextProto(GetParam());
   3394   ssl2.protocol_negotiated = GetParam();
   3395   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3396 
   3397   TestCompletionCallback callback1;
   3398 
   3399   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3400   EXPECT_EQ(ERR_IO_PENDING, rv);
   3401 
   3402   rv = callback1.WaitForResult();
   3403   EXPECT_EQ(OK, rv);
   3404 
   3405   LoadTimingInfo load_timing_info;
   3406   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3407   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3408 
   3409   const HttpResponseInfo* response = trans->GetResponseInfo();
   3410   ASSERT_TRUE(response != NULL);
   3411   ASSERT_TRUE(response->headers.get() != NULL);
   3412   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3413 
   3414   std::string response_data;
   3415   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3416   EXPECT_EQ(kUploadData, response_data);
   3417 }
   3418 
   3419 // Test a SPDY CONNECT failure through an HTTPS Proxy.
   3420 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   3421   HttpRequestInfo request;
   3422   request.method = "GET";
   3423   request.url = GURL("https://www.google.com/");
   3424   request.load_flags = 0;
   3425 
   3426   // Configure against https proxy server "proxy:70".
   3427   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3428       "https://proxy:70"));
   3429   CapturingBoundNetLog log;
   3430   session_deps_.net_log = log.bound().net_log();
   3431   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3432 
   3433   scoped_ptr<HttpTransaction> trans(
   3434       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3435 
   3436   // CONNECT to www.google.com:443 via SPDY
   3437   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3438                                                                 LOWEST));
   3439   scoped_ptr<SpdyFrame> get(
   3440       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   3441 
   3442   MockWrite spdy_writes[] = {
   3443       CreateMockWrite(*connect, 1),
   3444       CreateMockWrite(*get, 3),
   3445   };
   3446 
   3447   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
   3448   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3449   MockRead spdy_reads[] = {
   3450     CreateMockRead(*resp, 2, ASYNC),
   3451     MockRead(ASYNC, 0, 4),
   3452   };
   3453 
   3454   OrderedSocketData spdy_data(
   3455       spdy_reads, arraysize(spdy_reads),
   3456       spdy_writes, arraysize(spdy_writes));
   3457   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3458 
   3459   SSLSocketDataProvider ssl(ASYNC, OK);
   3460   ssl.SetNextProto(GetParam());
   3461   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3462   SSLSocketDataProvider ssl2(ASYNC, OK);
   3463   ssl2.SetNextProto(GetParam());
   3464   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3465 
   3466   TestCompletionCallback callback1;
   3467 
   3468   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3469   EXPECT_EQ(ERR_IO_PENDING, rv);
   3470 
   3471   rv = callback1.WaitForResult();
   3472   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3473 
   3474   // TODO(ttuttle): Anything else to check here?
   3475 }
   3476 
   3477 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3478 // HTTPS Proxy to different servers.
   3479 TEST_P(HttpNetworkTransactionTest,
   3480        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
   3481   // Configure against https proxy server "proxy:70".
   3482   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3483       "https://proxy:70"));
   3484   CapturingBoundNetLog log;
   3485   session_deps_.net_log = log.bound().net_log();
   3486   scoped_refptr<HttpNetworkSession> session(
   3487       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3488 
   3489   HttpRequestInfo request1;
   3490   request1.method = "GET";
   3491   request1.url = GURL("https://www.google.com/");
   3492   request1.load_flags = 0;
   3493 
   3494   HttpRequestInfo request2;
   3495   request2.method = "GET";
   3496   request2.url = GURL("https://news.google.com/");
   3497   request2.load_flags = 0;
   3498 
   3499   // CONNECT to www.google.com:443 via SPDY.
   3500   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3501                                                                  LOWEST));
   3502   scoped_ptr<SpdyFrame> conn_resp1(
   3503       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3504 
   3505   // Fetch https://www.google.com/ via HTTP.
   3506   const char get1[] = "GET / HTTP/1.1\r\n"
   3507       "Host: www.google.com\r\n"
   3508       "Connection: keep-alive\r\n\r\n";
   3509   scoped_ptr<SpdyFrame> wrapped_get1(
   3510       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3511   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3512       "Content-Length: 1\r\n\r\n";
   3513   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3514       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3515   scoped_ptr<SpdyFrame> wrapped_body1(
   3516       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3517   scoped_ptr<SpdyFrame> window_update(
   3518       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3519 
   3520   // CONNECT to news.google.com:443 via SPDY.
   3521   SpdyHeaderBlock connect2_block;
   3522   connect2_block[spdy_util_.GetMethodKey()] = "CONNECT";
   3523   connect2_block[spdy_util_.GetPathKey()] = "news.google.com:443";
   3524   connect2_block[spdy_util_.GetHostKey()] = "news.google.com";
   3525   spdy_util_.MaybeAddVersionHeader(&connect2_block);
   3526   scoped_ptr<SpdyFrame> connect2(
   3527       spdy_util_.ConstructSpdySyn(3, connect2_block, LOWEST, false, false));
   3528 
   3529   scoped_ptr<SpdyFrame> conn_resp2(
   3530       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3531 
   3532   // Fetch https://news.google.com/ via HTTP.
   3533   const char get2[] = "GET / HTTP/1.1\r\n"
   3534       "Host: news.google.com\r\n"
   3535       "Connection: keep-alive\r\n\r\n";
   3536   scoped_ptr<SpdyFrame> wrapped_get2(
   3537       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
   3538   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3539       "Content-Length: 2\r\n\r\n";
   3540   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3541       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
   3542   scoped_ptr<SpdyFrame> wrapped_body2(
   3543       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
   3544 
   3545   MockWrite spdy_writes[] = {
   3546       CreateMockWrite(*connect1, 0),
   3547       CreateMockWrite(*wrapped_get1, 2),
   3548       CreateMockWrite(*connect2, 5),
   3549       CreateMockWrite(*wrapped_get2, 7),
   3550   };
   3551 
   3552   MockRead spdy_reads[] = {
   3553     CreateMockRead(*conn_resp1, 1, ASYNC),
   3554     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3555     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3556     CreateMockRead(*conn_resp2, 6, ASYNC),
   3557     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
   3558     CreateMockRead(*wrapped_body2, 9, ASYNC),
   3559     MockRead(ASYNC, 0, 10),
   3560   };
   3561 
   3562   DeterministicSocketData spdy_data(
   3563       spdy_reads, arraysize(spdy_reads),
   3564       spdy_writes, arraysize(spdy_writes));
   3565   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3566 
   3567   SSLSocketDataProvider ssl(ASYNC, OK);
   3568   ssl.SetNextProto(GetParam());
   3569   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3570   SSLSocketDataProvider ssl2(ASYNC, OK);
   3571   ssl2.was_npn_negotiated = false;
   3572   ssl2.protocol_negotiated = kProtoUnknown;
   3573   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3574   SSLSocketDataProvider ssl3(ASYNC, OK);
   3575   ssl3.was_npn_negotiated = false;
   3576   ssl3.protocol_negotiated = kProtoUnknown;
   3577   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
   3578 
   3579   TestCompletionCallback callback;
   3580 
   3581   scoped_ptr<HttpTransaction> trans(
   3582       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3583   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3584   EXPECT_EQ(ERR_IO_PENDING, rv);
   3585   // The first connect and request, each of their responses, and the body.
   3586   spdy_data.RunFor(5);
   3587 
   3588   rv = callback.WaitForResult();
   3589   EXPECT_EQ(OK, rv);
   3590 
   3591   LoadTimingInfo load_timing_info;
   3592   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3593   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3594 
   3595   const HttpResponseInfo* response = trans->GetResponseInfo();
   3596   ASSERT_TRUE(response != NULL);
   3597   ASSERT_TRUE(response->headers.get() != NULL);
   3598   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3599 
   3600   std::string response_data;
   3601   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3602   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3603 
   3604   scoped_ptr<HttpTransaction> trans2(
   3605       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3606   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3607   EXPECT_EQ(ERR_IO_PENDING, rv);
   3608 
   3609   // The second connect and request, each of their responses, and the body.
   3610   spdy_data.RunFor(5);
   3611   rv = callback.WaitForResult();
   3612   EXPECT_EQ(OK, rv);
   3613 
   3614   LoadTimingInfo load_timing_info2;
   3615   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3616   // Even though the SPDY connection is reused, a new tunnelled connection has
   3617   // to be created, so the socket's load timing looks like a fresh connection.
   3618   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
   3619 
   3620   // The requests should have different IDs, since they each are using their own
   3621   // separate stream.
   3622   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3623 
   3624   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3625 }
   3626 
   3627 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3628 // HTTPS Proxy to the same server.
   3629 TEST_P(HttpNetworkTransactionTest,
   3630        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
   3631   // Configure against https proxy server "proxy:70".
   3632   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3633       "https://proxy:70"));
   3634   CapturingBoundNetLog log;
   3635   session_deps_.net_log = log.bound().net_log();
   3636   scoped_refptr<HttpNetworkSession> session(
   3637       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3638 
   3639   HttpRequestInfo request1;
   3640   request1.method = "GET";
   3641   request1.url = GURL("https://www.google.com/");
   3642   request1.load_flags = 0;
   3643 
   3644   HttpRequestInfo request2;
   3645   request2.method = "GET";
   3646   request2.url = GURL("https://www.google.com/2");
   3647   request2.load_flags = 0;
   3648 
   3649   // CONNECT to www.google.com:443 via SPDY.
   3650   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3651                                                                  LOWEST));
   3652   scoped_ptr<SpdyFrame> conn_resp1(
   3653       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3654 
   3655   // Fetch https://www.google.com/ via HTTP.
   3656   const char get1[] = "GET / HTTP/1.1\r\n"
   3657       "Host: www.google.com\r\n"
   3658       "Connection: keep-alive\r\n\r\n";
   3659   scoped_ptr<SpdyFrame> wrapped_get1(
   3660       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3661   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3662       "Content-Length: 1\r\n\r\n";
   3663   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3664       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3665   scoped_ptr<SpdyFrame> wrapped_body1(
   3666       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3667   scoped_ptr<SpdyFrame> window_update(
   3668       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3669 
   3670   // Fetch https://www.google.com/2 via HTTP.
   3671   const char get2[] = "GET /2 HTTP/1.1\r\n"
   3672       "Host: www.google.com\r\n"
   3673       "Connection: keep-alive\r\n\r\n";
   3674   scoped_ptr<SpdyFrame> wrapped_get2(
   3675       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
   3676   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3677       "Content-Length: 2\r\n\r\n";
   3678   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3679       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
   3680   scoped_ptr<SpdyFrame> wrapped_body2(
   3681       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
   3682 
   3683   MockWrite spdy_writes[] = {
   3684       CreateMockWrite(*connect1, 0),
   3685       CreateMockWrite(*wrapped_get1, 2),
   3686       CreateMockWrite(*wrapped_get2, 5),
   3687   };
   3688 
   3689   MockRead spdy_reads[] = {
   3690     CreateMockRead(*conn_resp1, 1, ASYNC),
   3691     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3692     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3693     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
   3694     CreateMockRead(*wrapped_body2, 7, ASYNC),
   3695     MockRead(ASYNC, 0, 8),
   3696   };
   3697 
   3698   DeterministicSocketData spdy_data(
   3699       spdy_reads, arraysize(spdy_reads),
   3700       spdy_writes, arraysize(spdy_writes));
   3701   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3702 
   3703   SSLSocketDataProvider ssl(ASYNC, OK);
   3704   ssl.SetNextProto(GetParam());
   3705   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3706   SSLSocketDataProvider ssl2(ASYNC, OK);
   3707   ssl2.was_npn_negotiated = false;
   3708   ssl2.protocol_negotiated = kProtoUnknown;
   3709   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3710 
   3711   TestCompletionCallback callback;
   3712 
   3713   scoped_ptr<HttpTransaction> trans(
   3714       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3715   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3716   EXPECT_EQ(ERR_IO_PENDING, rv);
   3717   // The first connect and request, each of their responses, and the body.
   3718   spdy_data.RunFor(5);
   3719 
   3720   rv = callback.WaitForResult();
   3721   EXPECT_EQ(OK, rv);
   3722 
   3723   LoadTimingInfo load_timing_info;
   3724   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3725   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3726 
   3727   const HttpResponseInfo* response = trans->GetResponseInfo();
   3728   ASSERT_TRUE(response != NULL);
   3729   ASSERT_TRUE(response->headers.get() != NULL);
   3730   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3731 
   3732   std::string response_data;
   3733   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3734   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3735   trans.reset();
   3736 
   3737   scoped_ptr<HttpTransaction> trans2(
   3738       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3739   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3740   EXPECT_EQ(ERR_IO_PENDING, rv);
   3741 
   3742   // The second request, response, and body.  There should not be a second
   3743   // connect.
   3744   spdy_data.RunFor(3);
   3745   rv = callback.WaitForResult();
   3746   EXPECT_EQ(OK, rv);
   3747 
   3748   LoadTimingInfo load_timing_info2;
   3749   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3750   TestLoadTimingReused(load_timing_info2);
   3751 
   3752   // The requests should have the same ID.
   3753   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3754 
   3755   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3756 }
   3757 
   3758 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
   3759 // Proxy to different servers.
   3760 TEST_P(HttpNetworkTransactionTest,
   3761        HttpsProxySpdyLoadTimingTwoHttpRequests) {
   3762   // Configure against https proxy server "proxy:70".
   3763   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3764       "https://proxy:70"));
   3765   CapturingBoundNetLog log;
   3766   session_deps_.net_log = log.bound().net_log();
   3767   scoped_refptr<HttpNetworkSession> session(
   3768       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3769 
   3770   HttpRequestInfo request1;
   3771   request1.method = "GET";
   3772   request1.url = GURL("http://www.google.com/");
   3773   request1.load_flags = 0;
   3774 
   3775   HttpRequestInfo request2;
   3776   request2.method = "GET";
   3777   request2.url = GURL("http://news.google.com/");
   3778   request2.load_flags = 0;
   3779 
   3780   // http://www.google.com/
   3781   scoped_ptr<SpdyHeaderBlock> headers(
   3782       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   3783   scoped_ptr<SpdyFrame> get1(
   3784       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
   3785   scoped_ptr<SpdyFrame> get_resp1(
   3786       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3787   scoped_ptr<SpdyFrame> body1(
   3788       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
   3789 
   3790   // http://news.google.com/
   3791   scoped_ptr<SpdyHeaderBlock> headers2(
   3792       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
   3793   scoped_ptr<SpdyFrame> get2(
   3794       spdy_util_.ConstructSpdySyn(3, *headers2, LOWEST, false, true));
   3795   scoped_ptr<SpdyFrame> get_resp2(
   3796       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3797   scoped_ptr<SpdyFrame> body2(
   3798       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
   3799 
   3800   MockWrite spdy_writes[] = {
   3801       CreateMockWrite(*get1, 0),
   3802       CreateMockWrite(*get2, 3),
   3803   };
   3804 
   3805   MockRead spdy_reads[] = {
   3806     CreateMockRead(*get_resp1, 1, ASYNC),
   3807     CreateMockRead(*body1, 2, ASYNC),
   3808     CreateMockRead(*get_resp2, 4, ASYNC),
   3809     CreateMockRead(*body2, 5, ASYNC),
   3810     MockRead(ASYNC, 0, 6),
   3811   };
   3812 
   3813   DeterministicSocketData spdy_data(
   3814       spdy_reads, arraysize(spdy_reads),
   3815       spdy_writes, arraysize(spdy_writes));
   3816   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3817 
   3818   SSLSocketDataProvider ssl(ASYNC, OK);
   3819   ssl.SetNextProto(GetParam());
   3820   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3821 
   3822   TestCompletionCallback callback;
   3823 
   3824   scoped_ptr<HttpTransaction> trans(
   3825       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3826   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3827   EXPECT_EQ(ERR_IO_PENDING, rv);
   3828   spdy_data.RunFor(2);
   3829 
   3830   rv = callback.WaitForResult();
   3831   EXPECT_EQ(OK, rv);
   3832 
   3833   LoadTimingInfo load_timing_info;
   3834   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3835   TestLoadTimingNotReused(load_timing_info,
   3836                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3837 
   3838   const HttpResponseInfo* response = trans->GetResponseInfo();
   3839   ASSERT_TRUE(response != NULL);
   3840   ASSERT_TRUE(response->headers.get() != NULL);
   3841   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3842 
   3843   std::string response_data;
   3844   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3845   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
   3846   spdy_data.RunFor(1);
   3847   EXPECT_EQ(1, callback.WaitForResult());
   3848   // Delete the first request, so the second one can reuse the socket.
   3849   trans.reset();
   3850 
   3851   scoped_ptr<HttpTransaction> trans2(
   3852       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3853   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3854   EXPECT_EQ(ERR_IO_PENDING, rv);
   3855 
   3856   spdy_data.RunFor(2);
   3857   rv = callback.WaitForResult();
   3858   EXPECT_EQ(OK, rv);
   3859 
   3860   LoadTimingInfo load_timing_info2;
   3861   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3862   TestLoadTimingReused(load_timing_info2);
   3863 
   3864   // The requests should have the same ID.
   3865   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3866 
   3867   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
   3868   spdy_data.RunFor(1);
   3869   EXPECT_EQ(2, callback.WaitForResult());
   3870 }
   3871 
   3872 // Test the challenge-response-retry sequence through an HTTPS Proxy
   3873 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   3874   HttpRequestInfo request;
   3875   request.method = "GET";
   3876   request.url = GURL("http://www.google.com/");
   3877   // when the no authentication data flag is set.
   3878   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   3879 
   3880   // Configure against https proxy server "myproxy:70".
   3881   session_deps_.proxy_service.reset(
   3882       ProxyService::CreateFixed("https://myproxy:70"));
   3883   CapturingBoundNetLog log;
   3884   session_deps_.net_log = log.bound().net_log();
   3885   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3886 
   3887   // Since we have proxy, should use full url
   3888   MockWrite data_writes1[] = {
   3889     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3890               "Host: www.google.com\r\n"
   3891               "Proxy-Connection: keep-alive\r\n\r\n"),
   3892 
   3893     // After calling trans->RestartWithAuth(), this is the request we should
   3894     // be issuing -- the final header line contains the credentials.
   3895     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3896               "Host: www.google.com\r\n"
   3897               "Proxy-Connection: keep-alive\r\n"
   3898               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3899   };
   3900 
   3901   // The proxy responds to the GET with a 407, using a persistent
   3902   // connection.
   3903   MockRead data_reads1[] = {
   3904     // No credentials.
   3905     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3906     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3907     MockRead("Proxy-Connection: keep-alive\r\n"),
   3908     MockRead("Content-Length: 0\r\n\r\n"),
   3909 
   3910     MockRead("HTTP/1.1 200 OK\r\n"),
   3911     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3912     MockRead("Content-Length: 100\r\n\r\n"),
   3913     MockRead(SYNCHRONOUS, OK),
   3914   };
   3915 
   3916   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3917                                  data_writes1, arraysize(data_writes1));
   3918   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3919   SSLSocketDataProvider ssl(ASYNC, OK);
   3920   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3921 
   3922   TestCompletionCallback callback1;
   3923 
   3924   scoped_ptr<HttpTransaction> trans(
   3925       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3926 
   3927   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3928   EXPECT_EQ(ERR_IO_PENDING, rv);
   3929 
   3930   rv = callback1.WaitForResult();
   3931   EXPECT_EQ(OK, rv);
   3932 
   3933   LoadTimingInfo load_timing_info;
   3934   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3935   TestLoadTimingNotReused(load_timing_info,
   3936                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3937 
   3938   const HttpResponseInfo* response = trans->GetResponseInfo();
   3939   ASSERT_TRUE(response != NULL);
   3940   ASSERT_FALSE(response->headers.get() == NULL);
   3941   EXPECT_EQ(407, response->headers->response_code());
   3942   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3943   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3944 
   3945   TestCompletionCallback callback2;
   3946 
   3947   rv = trans->RestartWithAuth(
   3948       AuthCredentials(kFoo, kBar), callback2.callback());
   3949   EXPECT_EQ(ERR_IO_PENDING, rv);
   3950 
   3951   rv = callback2.WaitForResult();
   3952   EXPECT_EQ(OK, rv);
   3953 
   3954   load_timing_info = LoadTimingInfo();
   3955   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3956   // Retrying with HTTP AUTH is considered to be reusing a socket.
   3957   TestLoadTimingReused(load_timing_info);
   3958 
   3959   response = trans->GetResponseInfo();
   3960   ASSERT_TRUE(response != NULL);
   3961 
   3962   EXPECT_TRUE(response->headers->IsKeepAlive());
   3963   EXPECT_EQ(200, response->headers->response_code());
   3964   EXPECT_EQ(100, response->headers->GetContentLength());
   3965   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3966 
   3967   // The password prompt info should not be set.
   3968   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3969 }
   3970 
   3971 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   3972     const MockRead& status, int expected_status) {
   3973   HttpRequestInfo request;
   3974   request.method = "GET";
   3975   request.url = GURL("https://www.google.com/");
   3976   request.load_flags = 0;
   3977 
   3978   // Configure against proxy server "myproxy:70".
   3979   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3980   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3981 
   3982   // Since we have proxy, should try to establish tunnel.
   3983   MockWrite data_writes[] = {
   3984     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   3985               "Host: www.google.com\r\n"
   3986               "Proxy-Connection: keep-alive\r\n\r\n"),
   3987   };
   3988 
   3989   MockRead data_reads[] = {
   3990     status,
   3991     MockRead("Content-Length: 10\r\n\r\n"),
   3992     // No response body because the test stops reading here.
   3993     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   3994   };
   3995 
   3996   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3997                                 data_writes, arraysize(data_writes));
   3998   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3999 
   4000   TestCompletionCallback callback;
   4001 
   4002   scoped_ptr<HttpTransaction> trans(
   4003       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4004 
   4005   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4006   EXPECT_EQ(ERR_IO_PENDING, rv);
   4007 
   4008   rv = callback.WaitForResult();
   4009   EXPECT_EQ(expected_status, rv);
   4010 }
   4011 
   4012 void HttpNetworkTransactionTest::ConnectStatusHelper(
   4013     const MockRead& status) {
   4014   ConnectStatusHelperWithExpectedStatus(
   4015       status, ERR_TUNNEL_CONNECTION_FAILED);
   4016 }
   4017 
   4018 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
   4019   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   4020 }
   4021 
   4022 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
   4023   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   4024 }
   4025 
   4026 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
   4027   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   4028 }
   4029 
   4030 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
   4031   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   4032 }
   4033 
   4034 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
   4035   ConnectStatusHelper(
   4036       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   4037 }
   4038 
   4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
   4040   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   4041 }
   4042 
   4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
   4044   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   4045 }
   4046 
   4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
   4048   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   4049 }
   4050 
   4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
   4052   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   4053 }
   4054 
   4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
   4056   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   4057 }
   4058 
   4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
   4060   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   4061 }
   4062 
   4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
   4064   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   4065 }
   4066 
   4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
   4068   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   4069 }
   4070 
   4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
   4072   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   4073 }
   4074 
   4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
   4076   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   4077 }
   4078 
   4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
   4080   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   4081 }
   4082 
   4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
   4084   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
   4085 }
   4086 
   4087 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
   4088   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   4089 }
   4090 
   4091 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
   4092   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   4093 }
   4094 
   4095 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
   4096   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   4097 }
   4098 
   4099 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
   4100   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   4101 }
   4102 
   4103 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
   4104   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   4105 }
   4106 
   4107 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
   4108   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   4109 }
   4110 
   4111 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
   4112   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   4113 }
   4114 
   4115 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
   4116   ConnectStatusHelperWithExpectedStatus(
   4117       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   4118       ERR_PROXY_AUTH_UNSUPPORTED);
   4119 }
   4120 
   4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
   4122   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   4123 }
   4124 
   4125 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
   4126   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   4127 }
   4128 
   4129 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
   4130   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   4131 }
   4132 
   4133 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
   4134   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   4135 }
   4136 
   4137 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
   4138   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   4139 }
   4140 
   4141 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
   4142   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   4143 }
   4144 
   4145 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
   4146   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   4147 }
   4148 
   4149 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
   4150   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   4151 }
   4152 
   4153 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
   4154   ConnectStatusHelper(
   4155       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   4156 }
   4157 
   4158 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
   4159   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   4160 }
   4161 
   4162 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
   4163   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   4164 }
   4165 
   4166 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
   4167   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   4168 }
   4169 
   4170 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
   4171   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   4172 }
   4173 
   4174 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
   4175   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   4176 }
   4177 
   4178 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
   4179   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   4180 }
   4181 
   4182 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
   4183   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   4184 }
   4185 
   4186 // Test the flow when both the proxy server AND origin server require
   4187 // authentication. Again, this uses basic auth for both since that is
   4188 // the simplest to mock.
   4189 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   4190   HttpRequestInfo request;
   4191   request.method = "GET";
   4192   request.url = GURL("http://www.google.com/");
   4193   request.load_flags = 0;
   4194 
   4195   // Configure against proxy server "myproxy:70".
   4196   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4198 
   4199   scoped_ptr<HttpTransaction> trans(
   4200       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4201 
   4202   MockWrite data_writes1[] = {
   4203     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4204               "Host: www.google.com\r\n"
   4205               "Proxy-Connection: keep-alive\r\n\r\n"),
   4206   };
   4207 
   4208   MockRead data_reads1[] = {
   4209     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   4210     // Give a couple authenticate options (only the middle one is actually
   4211     // supported).
   4212     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   4213     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4214     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   4215     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4216     // Large content-length -- won't matter, as connection will be reset.
   4217     MockRead("Content-Length: 10000\r\n\r\n"),
   4218     MockRead(SYNCHRONOUS, ERR_FAILED),
   4219   };
   4220 
   4221   // After calling trans->RestartWithAuth() the first time, this is the
   4222   // request we should be issuing -- the final header line contains the
   4223   // proxy's credentials.
   4224   MockWrite data_writes2[] = {
   4225     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4226               "Host: www.google.com\r\n"
   4227               "Proxy-Connection: keep-alive\r\n"
   4228               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4229   };
   4230 
   4231   // Now the proxy server lets the request pass through to origin server.
   4232   // The origin server responds with a 401.
   4233   MockRead data_reads2[] = {
   4234     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4235     // Note: We are using the same realm-name as the proxy server. This is
   4236     // completely valid, as realms are unique across hosts.
   4237     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4238     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4239     MockRead("Content-Length: 2000\r\n\r\n"),
   4240     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
   4241   };
   4242 
   4243   // After calling trans->RestartWithAuth() the second time, we should send
   4244   // the credentials for both the proxy and origin server.
   4245   MockWrite data_writes3[] = {
   4246     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4247               "Host: www.google.com\r\n"
   4248               "Proxy-Connection: keep-alive\r\n"
   4249               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   4250               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   4251   };
   4252 
   4253   // Lastly we get the desired content.
   4254   MockRead data_reads3[] = {
   4255     MockRead("HTTP/1.0 200 OK\r\n"),
   4256     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4257     MockRead("Content-Length: 100\r\n\r\n"),
   4258     MockRead(SYNCHRONOUS, OK),
   4259   };
   4260 
   4261   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4262                                  data_writes1, arraysize(data_writes1));
   4263   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4264                                  data_writes2, arraysize(data_writes2));
   4265   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4266                                  data_writes3, arraysize(data_writes3));
   4267   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4268   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4269   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4270 
   4271   TestCompletionCallback callback1;
   4272 
   4273   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4274   EXPECT_EQ(ERR_IO_PENDING, rv);
   4275 
   4276   rv = callback1.WaitForResult();
   4277   EXPECT_EQ(OK, rv);
   4278 
   4279   const HttpResponseInfo* response = trans->GetResponseInfo();
   4280   ASSERT_TRUE(response != NULL);
   4281   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   4282 
   4283   TestCompletionCallback callback2;
   4284 
   4285   rv = trans->RestartWithAuth(
   4286       AuthCredentials(kFoo, kBar), callback2.callback());
   4287   EXPECT_EQ(ERR_IO_PENDING, rv);
   4288 
   4289   rv = callback2.WaitForResult();
   4290   EXPECT_EQ(OK, rv);
   4291 
   4292   response = trans->GetResponseInfo();
   4293   ASSERT_TRUE(response != NULL);
   4294   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4295 
   4296   TestCompletionCallback callback3;
   4297 
   4298   rv = trans->RestartWithAuth(
   4299       AuthCredentials(kFoo2, kBar2), callback3.callback());
   4300   EXPECT_EQ(ERR_IO_PENDING, rv);
   4301 
   4302   rv = callback3.WaitForResult();
   4303   EXPECT_EQ(OK, rv);
   4304 
   4305   response = trans->GetResponseInfo();
   4306   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4307   EXPECT_EQ(100, response->headers->GetContentLength());
   4308 }
   4309 
   4310 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   4311 // can't hook into its internals to cause it to generate predictable NTLM
   4312 // authorization headers.
   4313 #if defined(NTLM_PORTABLE)
   4314 // The NTLM authentication unit tests were generated by capturing the HTTP
   4315 // requests and responses using Fiddler 2 and inspecting the generated random
   4316 // bytes in the debugger.
   4317 
   4318 // Enter the correct password and authenticate successfully.
   4319 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
   4320   HttpRequestInfo request;
   4321   request.method = "GET";
   4322   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   4323 
   4324   // Ensure load is not disrupted by flags which suppress behaviour specific
   4325   // to other auth schemes.
   4326   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   4327 
   4328   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   4329                                                     MockGetHostName);
   4330   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4331 
   4332   MockWrite data_writes1[] = {
   4333     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4334               "Host: 172.22.68.17\r\n"
   4335               "Connection: keep-alive\r\n\r\n"),
   4336   };
   4337 
   4338   MockRead data_reads1[] = {
   4339     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4340     // Negotiate and NTLM are often requested together.  However, we only want
   4341     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4342     // the header that requests Negotiate for this test.
   4343     MockRead("WWW-Authenticate: NTLM\r\n"),
   4344     MockRead("Connection: close\r\n"),
   4345     MockRead("Content-Length: 42\r\n"),
   4346     MockRead("Content-Type: text/html\r\n\r\n"),
   4347     // Missing content -- won't matter, as connection will be reset.
   4348     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4349   };
   4350 
   4351   MockWrite data_writes2[] = {
   4352     // After restarting with a null identity, this is the
   4353     // request we should be issuing -- the final header line contains a Type
   4354     // 1 message.
   4355     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4356               "Host: 172.22.68.17\r\n"
   4357               "Connection: keep-alive\r\n"
   4358               "Authorization: NTLM "
   4359               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4360 
   4361     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4362     // (the credentials for the origin server).  The second request continues
   4363     // on the same connection.
   4364     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4365               "Host: 172.22.68.17\r\n"
   4366               "Connection: keep-alive\r\n"
   4367               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4368               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4369               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   4370               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   4371               "ahlhx5I=\r\n\r\n"),
   4372   };
   4373 
   4374   MockRead data_reads2[] = {
   4375     // The origin server responds with a Type 2 message.
   4376     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4377     MockRead("WWW-Authenticate: NTLM "
   4378              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   4379              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4380              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4381              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4382              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4383              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4384              "BtAAAAAAA=\r\n"),
   4385     MockRead("Content-Length: 42\r\n"),
   4386     MockRead("Content-Type: text/html\r\n\r\n"),
   4387     MockRead("You are not authorized to view this page\r\n"),
   4388 
   4389     // Lastly we get the desired content.
   4390     MockRead("HTTP/1.1 200 OK\r\n"),
   4391     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4392     MockRead("Content-Length: 13\r\n\r\n"),
   4393     MockRead("Please Login\r\n"),
   4394     MockRead(SYNCHRONOUS, OK),
   4395   };
   4396 
   4397   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4398                                  data_writes1, arraysize(data_writes1));
   4399   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4400                                  data_writes2, arraysize(data_writes2));
   4401   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4402   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4403 
   4404   TestCompletionCallback callback1;
   4405 
   4406   scoped_ptr<HttpTransaction> trans(
   4407       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4408 
   4409   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4410   EXPECT_EQ(ERR_IO_PENDING, rv);
   4411 
   4412   rv = callback1.WaitForResult();
   4413   EXPECT_EQ(OK, rv);
   4414 
   4415   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4416 
   4417   const HttpResponseInfo* response = trans->GetResponseInfo();
   4418   ASSERT_FALSE(response == NULL);
   4419   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4420 
   4421   TestCompletionCallback callback2;
   4422 
   4423   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4424                               callback2.callback());
   4425   EXPECT_EQ(ERR_IO_PENDING, rv);
   4426 
   4427   rv = callback2.WaitForResult();
   4428   EXPECT_EQ(OK, rv);
   4429 
   4430   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4431 
   4432   response = trans->GetResponseInfo();
   4433   ASSERT_TRUE(response != NULL);
   4434   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4435 
   4436   TestCompletionCallback callback3;
   4437 
   4438   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4439   EXPECT_EQ(ERR_IO_PENDING, rv);
   4440 
   4441   rv = callback3.WaitForResult();
   4442   EXPECT_EQ(OK, rv);
   4443 
   4444   response = trans->GetResponseInfo();
   4445   ASSERT_TRUE(response != NULL);
   4446   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4447   EXPECT_EQ(13, response->headers->GetContentLength());
   4448 }
   4449 
   4450 // Enter a wrong password, and then the correct one.
   4451 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
   4452   HttpRequestInfo request;
   4453   request.method = "GET";
   4454   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   4455   request.load_flags = 0;
   4456 
   4457   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   4458                                                     MockGetHostName);
   4459   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4460 
   4461   MockWrite data_writes1[] = {
   4462     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4463               "Host: 172.22.68.17\r\n"
   4464               "Connection: keep-alive\r\n\r\n"),
   4465   };
   4466 
   4467   MockRead data_reads1[] = {
   4468     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4469     // Negotiate and NTLM are often requested together.  However, we only want
   4470     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4471     // the header that requests Negotiate for this test.
   4472     MockRead("WWW-Authenticate: NTLM\r\n"),
   4473     MockRead("Connection: close\r\n"),
   4474     MockRead("Content-Length: 42\r\n"),
   4475     MockRead("Content-Type: text/html\r\n\r\n"),
   4476     // Missing content -- won't matter, as connection will be reset.
   4477     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4478   };
   4479 
   4480   MockWrite data_writes2[] = {
   4481     // After restarting with a null identity, this is the
   4482     // request we should be issuing -- the final header line contains a Type
   4483     // 1 message.
   4484     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4485               "Host: 172.22.68.17\r\n"
   4486               "Connection: keep-alive\r\n"
   4487               "Authorization: NTLM "
   4488               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4489 
   4490     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4491     // (the credentials for the origin server).  The second request continues
   4492     // on the same connection.
   4493     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4494               "Host: 172.22.68.17\r\n"
   4495               "Connection: keep-alive\r\n"
   4496               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4497               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4498               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   4499               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   4500               "4Ww7b7E=\r\n\r\n"),
   4501   };
   4502 
   4503   MockRead data_reads2[] = {
   4504     // The origin server responds with a Type 2 message.
   4505     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4506     MockRead("WWW-Authenticate: NTLM "
   4507              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   4508              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4509              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4510              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4511              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4512              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4513              "BtAAAAAAA=\r\n"),
   4514     MockRead("Content-Length: 42\r\n"),
   4515     MockRead("Content-Type: text/html\r\n\r\n"),
   4516     MockRead("You are not authorized to view this page\r\n"),
   4517 
   4518     // Wrong password.
   4519     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4520     MockRead("WWW-Authenticate: NTLM\r\n"),
   4521     MockRead("Connection: close\r\n"),
   4522     MockRead("Content-Length: 42\r\n"),
   4523     MockRead("Content-Type: text/html\r\n\r\n"),
   4524     // Missing content -- won't matter, as connection will be reset.
   4525     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4526   };
   4527 
   4528   MockWrite data_writes3[] = {
   4529     // After restarting with a null identity, this is the
   4530     // request we should be issuing -- the final header line contains a Type
   4531     // 1 message.
   4532     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4533               "Host: 172.22.68.17\r\n"
   4534               "Connection: keep-alive\r\n"
   4535               "Authorization: NTLM "
   4536               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4537 
   4538     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4539     // (the credentials for the origin server).  The second request continues
   4540     // on the same connection.
   4541     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4542               "Host: 172.22.68.17\r\n"
   4543               "Connection: keep-alive\r\n"
   4544               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4545               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4546               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   4547               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   4548               "+4MUm7c=\r\n\r\n"),
   4549   };
   4550 
   4551   MockRead data_reads3[] = {
   4552     // The origin server responds with a Type 2 message.
   4553     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4554     MockRead("WWW-Authenticate: NTLM "
   4555              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   4556              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4557              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4558              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4559              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4560              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4561              "BtAAAAAAA=\r\n"),
   4562     MockRead("Content-Length: 42\r\n"),
   4563     MockRead("Content-Type: text/html\r\n\r\n"),
   4564     MockRead("You are not authorized to view this page\r\n"),
   4565 
   4566     // Lastly we get the desired content.
   4567     MockRead("HTTP/1.1 200 OK\r\n"),
   4568     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4569     MockRead("Content-Length: 13\r\n\r\n"),
   4570     MockRead("Please Login\r\n"),
   4571     MockRead(SYNCHRONOUS, OK),
   4572   };
   4573 
   4574   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4575                                  data_writes1, arraysize(data_writes1));
   4576   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4577                                  data_writes2, arraysize(data_writes2));
   4578   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4579                                  data_writes3, arraysize(data_writes3));
   4580   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4581   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4582   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4583 
   4584   TestCompletionCallback callback1;
   4585 
   4586   scoped_ptr<HttpTransaction> trans(
   4587       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4588 
   4589   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4590   EXPECT_EQ(ERR_IO_PENDING, rv);
   4591 
   4592   rv = callback1.WaitForResult();
   4593   EXPECT_EQ(OK, rv);
   4594 
   4595   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4596 
   4597   const HttpResponseInfo* response = trans->GetResponseInfo();
   4598   ASSERT_TRUE(response != NULL);
   4599   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4600 
   4601   TestCompletionCallback callback2;
   4602 
   4603   // Enter the wrong password.
   4604   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
   4605                               callback2.callback());
   4606   EXPECT_EQ(ERR_IO_PENDING, rv);
   4607 
   4608   rv = callback2.WaitForResult();
   4609   EXPECT_EQ(OK, rv);
   4610 
   4611   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4612   TestCompletionCallback callback3;
   4613   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4614   EXPECT_EQ(ERR_IO_PENDING, rv);
   4615   rv = callback3.WaitForResult();
   4616   EXPECT_EQ(OK, rv);
   4617   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4618 
   4619   response = trans->GetResponseInfo();
   4620   ASSERT_FALSE(response == NULL);
   4621   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4622 
   4623   TestCompletionCallback callback4;
   4624 
   4625   // Now enter the right password.
   4626   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4627                               callback4.callback());
   4628   EXPECT_EQ(ERR_IO_PENDING, rv);
   4629 
   4630   rv = callback4.WaitForResult();
   4631   EXPECT_EQ(OK, rv);
   4632 
   4633   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4634 
   4635   TestCompletionCallback callback5;
   4636 
   4637   // One more roundtrip
   4638   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
   4639   EXPECT_EQ(ERR_IO_PENDING, rv);
   4640 
   4641   rv = callback5.WaitForResult();
   4642   EXPECT_EQ(OK, rv);
   4643 
   4644   response = trans->GetResponseInfo();
   4645   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4646   EXPECT_EQ(13, response->headers->GetContentLength());
   4647 }
   4648 #endif  // NTLM_PORTABLE
   4649 
   4650 // Test reading a server response which has only headers, and no body.
   4651 // After some maximum number of bytes is consumed, the transaction should
   4652 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   4653 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   4654   HttpRequestInfo request;
   4655   request.method = "GET";
   4656   request.url = GURL("http://www.google.com/");
   4657   request.load_flags = 0;
   4658 
   4659   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4660   scoped_ptr<HttpTransaction> trans(
   4661       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4662 
   4663   // Respond with 300 kb of headers (we should fail after 256 kb).
   4664   std::string large_headers_string;
   4665   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   4666 
   4667   MockRead data_reads[] = {
   4668     MockRead("HTTP/1.0 200 OK\r\n"),
   4669     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
   4670     MockRead("\r\nBODY"),
   4671     MockRead(SYNCHRONOUS, OK),
   4672   };
   4673   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4674   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4675 
   4676   TestCompletionCallback callback;
   4677 
   4678   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4679   EXPECT_EQ(ERR_IO_PENDING, rv);
   4680 
   4681   rv = callback.WaitForResult();
   4682   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   4683 
   4684   const HttpResponseInfo* response = trans->GetResponseInfo();
   4685   EXPECT_TRUE(response == NULL);
   4686 }
   4687 
   4688 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   4689 // establish tunnel.
   4690 // http://code.google.com/p/chromium/issues/detail?id=3772
   4691 TEST_P(HttpNetworkTransactionTest,
   4692        DontRecycleTransportSocketForSSLTunnel) {
   4693   HttpRequestInfo request;
   4694   request.method = "GET";
   4695   request.url = GURL("https://www.google.com/");
   4696   request.load_flags = 0;
   4697 
   4698   // Configure against proxy server "myproxy:70".
   4699   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4700 
   4701   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4702 
   4703   scoped_ptr<HttpTransaction> trans(
   4704       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4705 
   4706   // Since we have proxy, should try to establish tunnel.
   4707   MockWrite data_writes1[] = {
   4708     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4709               "Host: www.google.com\r\n"
   4710               "Proxy-Connection: keep-alive\r\n\r\n"),
   4711   };
   4712 
   4713   // The proxy responds to the connect with a 404, using a persistent
   4714   // connection. Usually a proxy would return 501 (not implemented),
   4715   // or 200 (tunnel established).
   4716   MockRead data_reads1[] = {
   4717     MockRead("HTTP/1.1 404 Not Found\r\n"),
   4718     MockRead("Content-Length: 10\r\n\r\n"),
   4719     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   4720   };
   4721 
   4722   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4723                                  data_writes1, arraysize(data_writes1));
   4724   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4725 
   4726   TestCompletionCallback callback1;
   4727 
   4728   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4729   EXPECT_EQ(ERR_IO_PENDING, rv);
   4730 
   4731   rv = callback1.WaitForResult();
   4732   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   4733 
   4734   const HttpResponseInfo* response = trans->GetResponseInfo();
   4735   EXPECT_TRUE(response == NULL);
   4736 
   4737   // Empty the current queue.  This is necessary because idle sockets are
   4738   // added to the connection pool asynchronously with a PostTask.
   4739   base::MessageLoop::current()->RunUntilIdle();
   4740 
   4741   // We now check to make sure the TCPClientSocket was not added back to
   4742   // the pool.
   4743   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4744   trans.reset();
   4745   base::MessageLoop::current()->RunUntilIdle();
   4746   // Make sure that the socket didn't get recycled after calling the destructor.
   4747   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4748 }
   4749 
   4750 // Make sure that we recycle a socket after reading all of the response body.
   4751 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
   4752   HttpRequestInfo request;
   4753   request.method = "GET";
   4754   request.url = GURL("http://www.google.com/");
   4755   request.load_flags = 0;
   4756 
   4757   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4758 
   4759   scoped_ptr<HttpTransaction> trans(
   4760       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4761 
   4762   MockRead data_reads[] = {
   4763     // A part of the response body is received with the response headers.
   4764     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   4765     // The rest of the response body is received in two parts.
   4766     MockRead("lo"),
   4767     MockRead(" world"),
   4768     MockRead("junk"),  // Should not be read!!
   4769     MockRead(SYNCHRONOUS, OK),
   4770   };
   4771 
   4772   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4773   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4774 
   4775   TestCompletionCallback callback;
   4776 
   4777   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4778   EXPECT_EQ(ERR_IO_PENDING, rv);
   4779 
   4780   rv = callback.WaitForResult();
   4781   EXPECT_EQ(OK, rv);
   4782 
   4783   const HttpResponseInfo* response = trans->GetResponseInfo();
   4784   ASSERT_TRUE(response != NULL);
   4785 
   4786   EXPECT_TRUE(response->headers.get() != NULL);
   4787   std::string status_line = response->headers->GetStatusLine();
   4788   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   4789 
   4790   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4791 
   4792   std::string response_data;
   4793   rv = ReadTransaction(trans.get(), &response_data);
   4794   EXPECT_EQ(OK, rv);
   4795   EXPECT_EQ("hello world", response_data);
   4796 
   4797   // Empty the current queue.  This is necessary because idle sockets are
   4798   // added to the connection pool asynchronously with a PostTask.
   4799   base::MessageLoop::current()->RunUntilIdle();
   4800 
   4801   // We now check to make sure the socket was added back to the pool.
   4802   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4803 }
   4804 
   4805 // Make sure that we recycle a SSL socket after reading all of the response
   4806 // body.
   4807 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
   4808   HttpRequestInfo request;
   4809   request.method = "GET";
   4810   request.url = GURL("https://www.google.com/");
   4811   request.load_flags = 0;
   4812 
   4813   MockWrite data_writes[] = {
   4814     MockWrite("GET / HTTP/1.1\r\n"
   4815               "Host: www.google.com\r\n"
   4816               "Connection: keep-alive\r\n\r\n"),
   4817   };
   4818 
   4819   MockRead data_reads[] = {
   4820     MockRead("HTTP/1.1 200 OK\r\n"),
   4821     MockRead("Content-Length: 11\r\n\r\n"),
   4822     MockRead("hello world"),
   4823     MockRead(SYNCHRONOUS, OK),
   4824   };
   4825 
   4826   SSLSocketDataProvider ssl(ASYNC, OK);
   4827   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4828 
   4829   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4830                                 data_writes, arraysize(data_writes));
   4831   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4832 
   4833   TestCompletionCallback callback;
   4834 
   4835   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4836   scoped_ptr<HttpTransaction> trans(
   4837       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4838 
   4839   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4840 
   4841   EXPECT_EQ(ERR_IO_PENDING, rv);
   4842   EXPECT_EQ(OK, callback.WaitForResult());
   4843 
   4844   const HttpResponseInfo* response = trans->GetResponseInfo();
   4845   ASSERT_TRUE(response != NULL);
   4846   ASSERT_TRUE(response->headers.get() != NULL);
   4847   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4848 
   4849   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4850 
   4851   std::string response_data;
   4852   rv = ReadTransaction(trans.get(), &response_data);
   4853   EXPECT_EQ(OK, rv);
   4854   EXPECT_EQ("hello world", response_data);
   4855 
   4856   // Empty the current queue.  This is necessary because idle sockets are
   4857   // added to the connection pool asynchronously with a PostTask.
   4858   base::MessageLoop::current()->RunUntilIdle();
   4859 
   4860   // We now check to make sure the socket was added back to the pool.
   4861   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4862 }
   4863 
   4864 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
   4865 // from the pool and make sure that we recover okay.
   4866 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   4867   HttpRequestInfo request;
   4868   request.method = "GET";
   4869   request.url = GURL("https://www.google.com/");
   4870   request.load_flags = 0;
   4871 
   4872   MockWrite data_writes[] = {
   4873     MockWrite("GET / HTTP/1.1\r\n"
   4874               "Host: www.google.com\r\n"
   4875               "Connection: keep-alive\r\n\r\n"),
   4876     MockWrite("GET / HTTP/1.1\r\n"
   4877               "Host: www.google.com\r\n"
   4878               "Connection: keep-alive\r\n\r\n"),
   4879   };
   4880 
   4881   MockRead data_reads[] = {
   4882     MockRead("HTTP/1.1 200 OK\r\n"),
   4883     MockRead("Content-Length: 11\r\n\r\n"),
   4884     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   4885     MockRead("hello world"),
   4886     MockRead(ASYNC, 0, 0)   // EOF
   4887   };
   4888 
   4889   SSLSocketDataProvider ssl(ASYNC, OK);
   4890   SSLSocketDataProvider ssl2(ASYNC, OK);
   4891   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4892   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   4893 
   4894   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4895                                 data_writes, arraysize(data_writes));
   4896   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
   4897                                 data_writes, arraysize(data_writes));
   4898   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4899   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4900 
   4901   TestCompletionCallback callback;
   4902 
   4903   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4904   scoped_ptr<HttpTransaction> trans(
   4905       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4906 
   4907   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4908 
   4909   EXPECT_EQ(ERR_IO_PENDING, rv);
   4910   EXPECT_EQ(OK, callback.WaitForResult());
   4911 
   4912   const HttpResponseInfo* response = trans->GetResponseInfo();
   4913   ASSERT_TRUE(response != NULL);
   4914   ASSERT_TRUE(response->headers.get() != NULL);
   4915   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4916 
   4917   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4918 
   4919   std::string response_data;
   4920   rv = ReadTransaction(trans.get(), &response_data);
   4921   EXPECT_EQ(OK, rv);
   4922   EXPECT_EQ("hello world", response_data);
   4923 
   4924   // Empty the current queue.  This is necessary because idle sockets are
   4925   // added to the connection pool asynchronously with a PostTask.
   4926   base::MessageLoop::current()->RunUntilIdle();
   4927 
   4928   // We now check to make sure the socket was added back to the pool.
   4929   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4930 
   4931   // Now start the second transaction, which should reuse the previous socket.
   4932 
   4933   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4934 
   4935   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4936 
   4937   EXPECT_EQ(ERR_IO_PENDING, rv);
   4938   EXPECT_EQ(OK, callback.WaitForResult());
   4939 
   4940   response = trans->GetResponseInfo();
   4941   ASSERT_TRUE(response != NULL);
   4942   ASSERT_TRUE(response->headers.get() != NULL);
   4943   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4944 
   4945   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4946 
   4947   rv = ReadTransaction(trans.get(), &response_data);
   4948   EXPECT_EQ(OK, rv);
   4949   EXPECT_EQ("hello world", response_data);
   4950 
   4951   // Empty the current queue.  This is necessary because idle sockets are
   4952   // added to the connection pool asynchronously with a PostTask.
   4953   base::MessageLoop::current()->RunUntilIdle();
   4954 
   4955   // We now check to make sure the socket was added back to the pool.
   4956   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4957 }
   4958 
   4959 // Make sure that we recycle a socket after a zero-length response.
   4960 // http://crbug.com/9880
   4961 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   4962   HttpRequestInfo request;
   4963   request.method = "GET";
   4964   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   4965                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   4966                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   4967                      "rt=prt.2642,ol.2649,xjs.2951");
   4968   request.load_flags = 0;
   4969 
   4970   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4971 
   4972   scoped_ptr<HttpTransaction> trans(
   4973       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4974 
   4975   MockRead data_reads[] = {
   4976     MockRead("HTTP/1.1 204 No Content\r\n"
   4977              "Content-Length: 0\r\n"
   4978              "Content-Type: text/html\r\n\r\n"),
   4979     MockRead("junk"),  // Should not be read!!
   4980     MockRead(SYNCHRONOUS, OK),
   4981   };
   4982 
   4983   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4984   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4985 
   4986   TestCompletionCallback callback;
   4987 
   4988   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4989   EXPECT_EQ(ERR_IO_PENDING, rv);
   4990 
   4991   rv = callback.WaitForResult();
   4992   EXPECT_EQ(OK, rv);
   4993 
   4994   const HttpResponseInfo* response = trans->GetResponseInfo();
   4995   ASSERT_TRUE(response != NULL);
   4996 
   4997   EXPECT_TRUE(response->headers.get() != NULL);
   4998   std::string status_line = response->headers->GetStatusLine();
   4999   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   5000 
   5001   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   5002 
   5003   std::string response_data;
   5004   rv = ReadTransaction(trans.get(), &response_data);
   5005   EXPECT_EQ(OK, rv);
   5006   EXPECT_EQ("", response_data);
   5007 
   5008   // Empty the current queue.  This is necessary because idle sockets are
   5009   // added to the connection pool asynchronously with a PostTask.
   5010   base::MessageLoop::current()->RunUntilIdle();
   5011 
   5012   // We now check to make sure the socket was added back to the pool.
   5013   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   5014 }
   5015 
   5016 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   5017   ScopedVector<UploadElementReader> element_readers;
   5018   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   5019   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   5020 
   5021   HttpRequestInfo request[2];
   5022   // Transaction 1: a GET request that succeeds.  The socket is recycled
   5023   // after use.
   5024   request[0].method = "GET";
   5025   request[0].url = GURL("http://www.google.com/");
   5026   request[0].load_flags = 0;
   5027   // Transaction 2: a POST request.  Reuses the socket kept alive from
   5028   // transaction 1.  The first attempts fails when writing the POST data.
   5029   // This causes the transaction to retry with a new socket.  The second
   5030   // attempt succeeds.
   5031   request[1].method = "POST";
   5032   request[1].url = GURL("http://www.google.com/login.cgi");
   5033   request[1].upload_data_stream = &upload_data_stream;
   5034   request[1].load_flags = 0;
   5035 
   5036   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5037 
   5038   // The first socket is used for transaction 1 and the first attempt of
   5039   // transaction 2.
   5040 
   5041   // The response of transaction 1.
   5042   MockRead data_reads1[] = {
   5043     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   5044     MockRead("hello world"),
   5045     MockRead(SYNCHRONOUS, OK),
   5046   };
   5047   // The mock write results of transaction 1 and the first attempt of
   5048   // transaction 2.
   5049   MockWrite data_writes1[] = {
   5050     MockWrite(SYNCHRONOUS, 64),  // GET
   5051     MockWrite(SYNCHRONOUS, 93),  // POST
   5052     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
   5053   };
   5054   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5055                                  data_writes1, arraysize(data_writes1));
   5056 
   5057   // The second socket is used for the second attempt of transaction 2.
   5058 
   5059   // The response of transaction 2.
   5060   MockRead data_reads2[] = {
   5061     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   5062     MockRead("welcome"),
   5063     MockRead(SYNCHRONOUS, OK),
   5064   };
   5065   // The mock write results of the second attempt of transaction 2.
   5066   MockWrite data_writes2[] = {
   5067     MockWrite(SYNCHRONOUS, 93),  // POST
   5068     MockWrite(SYNCHRONOUS, 3),  // POST data
   5069   };
   5070   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5071                                  data_writes2, arraysize(data_writes2));
   5072 
   5073   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5074   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5075 
   5076   const char* kExpectedResponseData[] = {
   5077     "hello world", "welcome"
   5078   };
   5079 
   5080   for (int i = 0; i < 2; ++i) {
   5081     scoped_ptr<HttpTransaction> trans(
   5082         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5083 
   5084     TestCompletionCallback callback;
   5085 
   5086     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
   5087     EXPECT_EQ(ERR_IO_PENDING, rv);
   5088 
   5089     rv = callback.WaitForResult();
   5090     EXPECT_EQ(OK, rv);
   5091 
   5092     const HttpResponseInfo* response = trans->GetResponseInfo();
   5093     ASSERT_TRUE(response != NULL);
   5094 
   5095     EXPECT_TRUE(response->headers.get() != NULL);
   5096     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   5097 
   5098     std::string response_data;
   5099     rv = ReadTransaction(trans.get(), &response_data);
   5100     EXPECT_EQ(OK, rv);
   5101     EXPECT_EQ(kExpectedResponseData[i], response_data);
   5102   }
   5103 }
   5104 
   5105 // Test the request-challenge-retry sequence for basic auth when there is
   5106 // an identity in the URL. The request should be sent as normal, but when
   5107 // it fails the identity from the URL is used to answer the challenge.
   5108 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
   5109   HttpRequestInfo request;
   5110   request.method = "GET";
   5111   request.url = GURL("http://foo:b@r@www.google.com/");
   5112   request.load_flags = LOAD_NORMAL;
   5113 
   5114   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5115   scoped_ptr<HttpTransaction> trans(
   5116       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5117 
   5118   // The password contains an escaped character -- for this test to pass it
   5119   // will need to be unescaped by HttpNetworkTransaction.
   5120   EXPECT_EQ("b%40r", request.url.password());
   5121 
   5122   MockWrite data_writes1[] = {
   5123     MockWrite("GET / HTTP/1.1\r\n"
   5124               "Host: www.google.com\r\n"
   5125               "Connection: keep-alive\r\n\r\n"),
   5126   };
   5127 
   5128   MockRead data_reads1[] = {
   5129     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5130     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5131     MockRead("Content-Length: 10\r\n\r\n"),
   5132     MockRead(SYNCHRONOUS, ERR_FAILED),
   5133   };
   5134 
   5135   // After the challenge above, the transaction will be restarted using the
   5136   // identity from the url (foo, b@r) to answer the challenge.
   5137   MockWrite data_writes2[] = {
   5138     MockWrite("GET / HTTP/1.1\r\n"
   5139               "Host: www.google.com\r\n"
   5140               "Connection: keep-alive\r\n"
   5141               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   5142   };
   5143 
   5144   MockRead data_reads2[] = {
   5145     MockRead("HTTP/1.0 200 OK\r\n"),
   5146     MockRead("Content-Length: 100\r\n\r\n"),
   5147     MockRead(SYNCHRONOUS, OK),
   5148   };
   5149 
   5150   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5151                                  data_writes1, arraysize(data_writes1));
   5152   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5153                                  data_writes2, arraysize(data_writes2));
   5154   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5155   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5156 
   5157   TestCompletionCallback callback1;
   5158   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5159   EXPECT_EQ(ERR_IO_PENDING, rv);
   5160   rv = callback1.WaitForResult();
   5161   EXPECT_EQ(OK, rv);
   5162   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5163 
   5164   TestCompletionCallback callback2;
   5165   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5166   EXPECT_EQ(ERR_IO_PENDING, rv);
   5167   rv = callback2.WaitForResult();
   5168   EXPECT_EQ(OK, rv);
   5169   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5170 
   5171   const HttpResponseInfo* response = trans->GetResponseInfo();
   5172   ASSERT_TRUE(response != NULL);
   5173 
   5174   // There is no challenge info, since the identity in URL worked.
   5175   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5176 
   5177   EXPECT_EQ(100, response->headers->GetContentLength());
   5178 
   5179   // Empty the current queue.
   5180   base::MessageLoop::current()->RunUntilIdle();
   5181 }
   5182 
   5183 // Test the request-challenge-retry sequence for basic auth when there is an
   5184 // incorrect identity in the URL. The identity from the URL should be used only
   5185 // once.
   5186 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   5187   HttpRequestInfo request;
   5188   request.method = "GET";
   5189   // Note: the URL has a username:password in it.  The password "baz" is
   5190   // wrong (should be "bar").
   5191   request.url = GURL("http://foo:baz@www.google.com/");
   5192 
   5193   request.load_flags = LOAD_NORMAL;
   5194 
   5195   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5196   scoped_ptr<HttpTransaction> trans(
   5197       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5198 
   5199   MockWrite data_writes1[] = {
   5200     MockWrite("GET / HTTP/1.1\r\n"
   5201               "Host: www.google.com\r\n"
   5202               "Connection: keep-alive\r\n\r\n"),
   5203   };
   5204 
   5205   MockRead data_reads1[] = {
   5206     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5207     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5208     MockRead("Content-Length: 10\r\n\r\n"),
   5209     MockRead(SYNCHRONOUS, ERR_FAILED),
   5210   };
   5211 
   5212   // After the challenge above, the transaction will be restarted using the
   5213   // identity from the url (foo, baz) to answer the challenge.
   5214   MockWrite data_writes2[] = {
   5215     MockWrite("GET / HTTP/1.1\r\n"
   5216               "Host: www.google.com\r\n"
   5217               "Connection: keep-alive\r\n"
   5218               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   5219   };
   5220 
   5221   MockRead data_reads2[] = {
   5222     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5223     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5224     MockRead("Content-Length: 10\r\n\r\n"),
   5225     MockRead(SYNCHRONOUS, ERR_FAILED),
   5226   };
   5227 
   5228   // After the challenge above, the transaction will be restarted using the
   5229   // identity supplied by the user (foo, bar) to answer the challenge.
   5230   MockWrite data_writes3[] = {
   5231     MockWrite("GET / HTTP/1.1\r\n"
   5232               "Host: www.google.com\r\n"
   5233               "Connection: keep-alive\r\n"
   5234               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5235   };
   5236 
   5237   MockRead data_reads3[] = {
   5238     MockRead("HTTP/1.0 200 OK\r\n"),
   5239     MockRead("Content-Length: 100\r\n\r\n"),
   5240     MockRead(SYNCHRONOUS, OK),
   5241   };
   5242 
   5243   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5244                                  data_writes1, arraysize(data_writes1));
   5245   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5246                                  data_writes2, arraysize(data_writes2));
   5247   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5248                                  data_writes3, arraysize(data_writes3));
   5249   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5250   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5251   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5252 
   5253   TestCompletionCallback callback1;
   5254 
   5255   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5256   EXPECT_EQ(ERR_IO_PENDING, rv);
   5257 
   5258   rv = callback1.WaitForResult();
   5259   EXPECT_EQ(OK, rv);
   5260 
   5261   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5262   TestCompletionCallback callback2;
   5263   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5264   EXPECT_EQ(ERR_IO_PENDING, rv);
   5265   rv = callback2.WaitForResult();
   5266   EXPECT_EQ(OK, rv);
   5267   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5268 
   5269   const HttpResponseInfo* response = trans->GetResponseInfo();
   5270   ASSERT_TRUE(response != NULL);
   5271   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5272 
   5273   TestCompletionCallback callback3;
   5274   rv = trans->RestartWithAuth(
   5275       AuthCredentials(kFoo, kBar), callback3.callback());
   5276   EXPECT_EQ(ERR_IO_PENDING, rv);
   5277   rv = callback3.WaitForResult();
   5278   EXPECT_EQ(OK, rv);
   5279   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5280 
   5281   response = trans->GetResponseInfo();
   5282   ASSERT_TRUE(response != NULL);
   5283 
   5284   // There is no challenge info, since the identity worked.
   5285   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5286 
   5287   EXPECT_EQ(100, response->headers->GetContentLength());
   5288 
   5289   // Empty the current queue.
   5290   base::MessageLoop::current()->RunUntilIdle();
   5291 }
   5292 
   5293 
   5294 // Test the request-challenge-retry sequence for basic auth when there is a
   5295 // correct identity in the URL, but its use is being suppressed. The identity
   5296 // from the URL should never be used.
   5297 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
   5298   HttpRequestInfo request;
   5299   request.method = "GET";
   5300   request.url = GURL("http://foo:bar@www.google.com/");
   5301   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   5302 
   5303   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5304   scoped_ptr<HttpTransaction> trans(
   5305       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5306 
   5307   MockWrite data_writes1[] = {
   5308     MockWrite("GET / HTTP/1.1\r\n"
   5309               "Host: www.google.com\r\n"
   5310               "Connection: keep-alive\r\n\r\n"),
   5311   };
   5312 
   5313   MockRead data_reads1[] = {
   5314     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5315     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5316     MockRead("Content-Length: 10\r\n\r\n"),
   5317     MockRead(SYNCHRONOUS, ERR_FAILED),
   5318   };
   5319 
   5320   // After the challenge above, the transaction will be restarted using the
   5321   // identity supplied by the user, not the one in the URL, to answer the
   5322   // challenge.
   5323   MockWrite data_writes3[] = {
   5324     MockWrite("GET / HTTP/1.1\r\n"
   5325               "Host: www.google.com\r\n"
   5326               "Connection: keep-alive\r\n"
   5327               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5328   };
   5329 
   5330   MockRead data_reads3[] = {
   5331     MockRead("HTTP/1.0 200 OK\r\n"),
   5332     MockRead("Content-Length: 100\r\n\r\n"),
   5333     MockRead(SYNCHRONOUS, OK),
   5334   };
   5335 
   5336   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5337                                  data_writes1, arraysize(data_writes1));
   5338   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5339                                  data_writes3, arraysize(data_writes3));
   5340   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5341   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5342 
   5343   TestCompletionCallback callback1;
   5344   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5345   EXPECT_EQ(ERR_IO_PENDING, rv);
   5346   rv = callback1.WaitForResult();
   5347   EXPECT_EQ(OK, rv);
   5348   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5349 
   5350   const HttpResponseInfo* response = trans->GetResponseInfo();
   5351   ASSERT_TRUE(response != NULL);
   5352   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5353 
   5354   TestCompletionCallback callback3;
   5355   rv = trans->RestartWithAuth(
   5356       AuthCredentials(kFoo, kBar), callback3.callback());
   5357   EXPECT_EQ(ERR_IO_PENDING, rv);
   5358   rv = callback3.WaitForResult();
   5359   EXPECT_EQ(OK, rv);
   5360   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5361 
   5362   response = trans->GetResponseInfo();
   5363   ASSERT_TRUE(response != NULL);
   5364 
   5365   // There is no challenge info, since the identity worked.
   5366   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5367   EXPECT_EQ(100, response->headers->GetContentLength());
   5368 
   5369   // Empty the current queue.
   5370   base::MessageLoop::current()->RunUntilIdle();
   5371 }
   5372 
   5373 // Test that previously tried username/passwords for a realm get re-used.
   5374 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   5375   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5376 
   5377   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5378   {
   5379     HttpRequestInfo request;
   5380     request.method = "GET";
   5381     request.url = GURL("http://www.google.com/x/y/z");
   5382     request.load_flags = 0;
   5383 
   5384     scoped_ptr<HttpTransaction> trans(
   5385         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5386 
   5387     MockWrite data_writes1[] = {
   5388       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5389                 "Host: www.google.com\r\n"
   5390                 "Connection: keep-alive\r\n\r\n"),
   5391     };
   5392 
   5393     MockRead data_reads1[] = {
   5394       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5395       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5396       MockRead("Content-Length: 10000\r\n\r\n"),
   5397       MockRead(SYNCHRONOUS, ERR_FAILED),
   5398     };
   5399 
   5400     // Resend with authorization (username=foo, password=bar)
   5401     MockWrite data_writes2[] = {
   5402       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5403                 "Host: www.google.com\r\n"
   5404                 "Connection: keep-alive\r\n"
   5405                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5406     };
   5407 
   5408     // Sever accepts the authorization.
   5409     MockRead data_reads2[] = {
   5410       MockRead("HTTP/1.0 200 OK\r\n"),
   5411       MockRead("Content-Length: 100\r\n\r\n"),
   5412       MockRead(SYNCHRONOUS, OK),
   5413     };
   5414 
   5415     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5416                                    data_writes1, arraysize(data_writes1));
   5417     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5418                                    data_writes2, arraysize(data_writes2));
   5419     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5420     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5421 
   5422     TestCompletionCallback callback1;
   5423 
   5424     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5425     EXPECT_EQ(ERR_IO_PENDING, rv);
   5426 
   5427     rv = callback1.WaitForResult();
   5428     EXPECT_EQ(OK, rv);
   5429 
   5430     const HttpResponseInfo* response = trans->GetResponseInfo();
   5431     ASSERT_TRUE(response != NULL);
   5432     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5433 
   5434     TestCompletionCallback callback2;
   5435 
   5436     rv = trans->RestartWithAuth(
   5437         AuthCredentials(kFoo, kBar), callback2.callback());
   5438     EXPECT_EQ(ERR_IO_PENDING, rv);
   5439 
   5440     rv = callback2.WaitForResult();
   5441     EXPECT_EQ(OK, rv);
   5442 
   5443     response = trans->GetResponseInfo();
   5444     ASSERT_TRUE(response != NULL);
   5445     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5446     EXPECT_EQ(100, response->headers->GetContentLength());
   5447   }
   5448 
   5449   // ------------------------------------------------------------------------
   5450 
   5451   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   5452   {
   5453     HttpRequestInfo request;
   5454     request.method = "GET";
   5455     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5456     // protection space as MyRealm1.
   5457     request.url = GURL("http://www.google.com/x/y/a/b");
   5458     request.load_flags = 0;
   5459 
   5460     scoped_ptr<HttpTransaction> trans(
   5461         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5462 
   5463     MockWrite data_writes1[] = {
   5464       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5465                 "Host: www.google.com\r\n"
   5466                 "Connection: keep-alive\r\n"
   5467                 // Send preemptive authorization for MyRealm1
   5468                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5469     };
   5470 
   5471     // The server didn't like the preemptive authorization, and
   5472     // challenges us for a different realm (MyRealm2).
   5473     MockRead data_reads1[] = {
   5474       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5475       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   5476       MockRead("Content-Length: 10000\r\n\r\n"),
   5477       MockRead(SYNCHRONOUS, ERR_FAILED),
   5478     };
   5479 
   5480     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   5481     MockWrite data_writes2[] = {
   5482       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5483                 "Host: www.google.com\r\n"
   5484                 "Connection: keep-alive\r\n"
   5485                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   5486     };
   5487 
   5488     // Sever accepts the authorization.
   5489     MockRead data_reads2[] = {
   5490       MockRead("HTTP/1.0 200 OK\r\n"),
   5491       MockRead("Content-Length: 100\r\n\r\n"),
   5492       MockRead(SYNCHRONOUS, OK),
   5493     };
   5494 
   5495     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5496                                    data_writes1, arraysize(data_writes1));
   5497     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5498                                    data_writes2, arraysize(data_writes2));
   5499     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5500     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5501 
   5502     TestCompletionCallback callback1;
   5503 
   5504     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5505     EXPECT_EQ(ERR_IO_PENDING, rv);
   5506 
   5507     rv = callback1.WaitForResult();
   5508     EXPECT_EQ(OK, rv);
   5509 
   5510     const HttpResponseInfo* response = trans->GetResponseInfo();
   5511     ASSERT_TRUE(response != NULL);
   5512     ASSERT_TRUE(response->auth_challenge.get());
   5513     EXPECT_FALSE(response->auth_challenge->is_proxy);
   5514     EXPECT_EQ("www.google.com:80",
   5515               response->auth_challenge->challenger.ToString());
   5516     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
   5517     EXPECT_EQ("basic", response->auth_challenge->scheme);
   5518 
   5519     TestCompletionCallback callback2;
   5520 
   5521     rv = trans->RestartWithAuth(
   5522         AuthCredentials(kFoo2, kBar2), callback2.callback());
   5523     EXPECT_EQ(ERR_IO_PENDING, rv);
   5524 
   5525     rv = callback2.WaitForResult();
   5526     EXPECT_EQ(OK, rv);
   5527 
   5528     response = trans->GetResponseInfo();
   5529     ASSERT_TRUE(response != NULL);
   5530     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5531     EXPECT_EQ(100, response->headers->GetContentLength());
   5532   }
   5533 
   5534   // ------------------------------------------------------------------------
   5535 
   5536   // Transaction 3: Resend a request in MyRealm's protection space --
   5537   // succeed with preemptive authorization.
   5538   {
   5539     HttpRequestInfo request;
   5540     request.method = "GET";
   5541     request.url = GURL("http://www.google.com/x/y/z2");
   5542     request.load_flags = 0;
   5543 
   5544     scoped_ptr<HttpTransaction> trans(
   5545         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5546 
   5547     MockWrite data_writes1[] = {
   5548       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   5549                 "Host: www.google.com\r\n"
   5550                 "Connection: keep-alive\r\n"
   5551                 // The authorization for MyRealm1 gets sent preemptively
   5552                 // (since the url is in the same protection space)
   5553                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5554     };
   5555 
   5556     // Sever accepts the preemptive authorization
   5557     MockRead data_reads1[] = {
   5558       MockRead("HTTP/1.0 200 OK\r\n"),
   5559       MockRead("Content-Length: 100\r\n\r\n"),
   5560       MockRead(SYNCHRONOUS, OK),
   5561     };
   5562 
   5563     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5564                                    data_writes1, arraysize(data_writes1));
   5565     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5566 
   5567     TestCompletionCallback callback1;
   5568 
   5569     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5570     EXPECT_EQ(ERR_IO_PENDING, rv);
   5571 
   5572     rv = callback1.WaitForResult();
   5573     EXPECT_EQ(OK, rv);
   5574 
   5575     const HttpResponseInfo* response = trans->GetResponseInfo();
   5576     ASSERT_TRUE(response != NULL);
   5577 
   5578     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5579     EXPECT_EQ(100, response->headers->GetContentLength());
   5580   }
   5581 
   5582   // ------------------------------------------------------------------------
   5583 
   5584   // Transaction 4: request another URL in MyRealm (however the
   5585   // url is not known to belong to the protection space, so no pre-auth).
   5586   {
   5587     HttpRequestInfo request;
   5588     request.method = "GET";
   5589     request.url = GURL("http://www.google.com/x/1");
   5590     request.load_flags = 0;
   5591 
   5592     scoped_ptr<HttpTransaction> trans(
   5593         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5594 
   5595     MockWrite data_writes1[] = {
   5596       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5597                 "Host: www.google.com\r\n"
   5598                 "Connection: keep-alive\r\n\r\n"),
   5599     };
   5600 
   5601     MockRead data_reads1[] = {
   5602       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5603       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5604       MockRead("Content-Length: 10000\r\n\r\n"),
   5605       MockRead(SYNCHRONOUS, ERR_FAILED),
   5606     };
   5607 
   5608     // Resend with authorization from MyRealm's cache.
   5609     MockWrite data_writes2[] = {
   5610       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5611                 "Host: www.google.com\r\n"
   5612                 "Connection: keep-alive\r\n"
   5613                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5614     };
   5615 
   5616     // Sever accepts the authorization.
   5617     MockRead data_reads2[] = {
   5618       MockRead("HTTP/1.0 200 OK\r\n"),
   5619       MockRead("Content-Length: 100\r\n\r\n"),
   5620       MockRead(SYNCHRONOUS, OK),
   5621     };
   5622 
   5623     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5624                                    data_writes1, arraysize(data_writes1));
   5625     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5626                                    data_writes2, arraysize(data_writes2));
   5627     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5628     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5629 
   5630     TestCompletionCallback callback1;
   5631 
   5632     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5633     EXPECT_EQ(ERR_IO_PENDING, rv);
   5634 
   5635     rv = callback1.WaitForResult();
   5636     EXPECT_EQ(OK, rv);
   5637 
   5638     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5639     TestCompletionCallback callback2;
   5640     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5641     EXPECT_EQ(ERR_IO_PENDING, rv);
   5642     rv = callback2.WaitForResult();
   5643     EXPECT_EQ(OK, rv);
   5644     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5645 
   5646     const HttpResponseInfo* response = trans->GetResponseInfo();
   5647     ASSERT_TRUE(response != NULL);
   5648     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5649     EXPECT_EQ(100, response->headers->GetContentLength());
   5650   }
   5651 
   5652   // ------------------------------------------------------------------------
   5653 
   5654   // Transaction 5: request a URL in MyRealm, but the server rejects the
   5655   // cached identity. Should invalidate and re-prompt.
   5656   {
   5657     HttpRequestInfo request;
   5658     request.method = "GET";
   5659     request.url = GURL("http://www.google.com/p/q/t");
   5660     request.load_flags = 0;
   5661 
   5662     scoped_ptr<HttpTransaction> trans(
   5663         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5664 
   5665     MockWrite data_writes1[] = {
   5666       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5667                 "Host: www.google.com\r\n"
   5668                 "Connection: keep-alive\r\n\r\n"),
   5669     };
   5670 
   5671     MockRead data_reads1[] = {
   5672       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5673       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5674       MockRead("Content-Length: 10000\r\n\r\n"),
   5675       MockRead(SYNCHRONOUS, ERR_FAILED),
   5676     };
   5677 
   5678     // Resend with authorization from cache for MyRealm.
   5679     MockWrite data_writes2[] = {
   5680       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5681                 "Host: www.google.com\r\n"
   5682                 "Connection: keep-alive\r\n"
   5683                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5684     };
   5685 
   5686     // Sever rejects the authorization.
   5687     MockRead data_reads2[] = {
   5688       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5689       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5690       MockRead("Content-Length: 10000\r\n\r\n"),
   5691       MockRead(SYNCHRONOUS, ERR_FAILED),
   5692     };
   5693 
   5694     // At this point we should prompt for new credentials for MyRealm.
   5695     // Restart with username=foo3, password=foo4.
   5696     MockWrite data_writes3[] = {
   5697       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5698                 "Host: www.google.com\r\n"
   5699                 "Connection: keep-alive\r\n"
   5700                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   5701     };
   5702 
   5703     // Sever accepts the authorization.
   5704     MockRead data_reads3[] = {
   5705       MockRead("HTTP/1.0 200 OK\r\n"),
   5706       MockRead("Content-Length: 100\r\n\r\n"),
   5707       MockRead(SYNCHRONOUS, OK),
   5708     };
   5709 
   5710     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5711                                    data_writes1, arraysize(data_writes1));
   5712     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5713                                    data_writes2, arraysize(data_writes2));
   5714     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5715                                    data_writes3, arraysize(data_writes3));
   5716     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5717     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5718     session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5719 
   5720     TestCompletionCallback callback1;
   5721 
   5722     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5723     EXPECT_EQ(ERR_IO_PENDING, rv);
   5724 
   5725     rv = callback1.WaitForResult();
   5726     EXPECT_EQ(OK, rv);
   5727 
   5728     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5729     TestCompletionCallback callback2;
   5730     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5731     EXPECT_EQ(ERR_IO_PENDING, rv);
   5732     rv = callback2.WaitForResult();
   5733     EXPECT_EQ(OK, rv);
   5734     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5735 
   5736     const HttpResponseInfo* response = trans->GetResponseInfo();
   5737     ASSERT_TRUE(response != NULL);
   5738     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5739 
   5740     TestCompletionCallback callback3;
   5741 
   5742     rv = trans->RestartWithAuth(
   5743         AuthCredentials(kFoo3, kBar3), callback3.callback());
   5744     EXPECT_EQ(ERR_IO_PENDING, rv);
   5745 
   5746     rv = callback3.WaitForResult();
   5747     EXPECT_EQ(OK, rv);
   5748 
   5749     response = trans->GetResponseInfo();
   5750     ASSERT_TRUE(response != NULL);
   5751     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5752     EXPECT_EQ(100, response->headers->GetContentLength());
   5753   }
   5754 }
   5755 
   5756 // Tests that nonce count increments when multiple auth attempts
   5757 // are started with the same nonce.
   5758 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
   5759   HttpAuthHandlerDigest::Factory* digest_factory =
   5760       new HttpAuthHandlerDigest::Factory();
   5761   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
   5762       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
   5763   digest_factory->set_nonce_generator(nonce_generator);
   5764   session_deps_.http_auth_handler_factory.reset(digest_factory);
   5765   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5766 
   5767   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5768   {
   5769     HttpRequestInfo request;
   5770     request.method = "GET";
   5771     request.url = GURL("http://www.google.com/x/y/z");
   5772     request.load_flags = 0;
   5773 
   5774     scoped_ptr<HttpTransaction> trans(
   5775         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5776 
   5777     MockWrite data_writes1[] = {
   5778       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5779                 "Host: www.google.com\r\n"
   5780                 "Connection: keep-alive\r\n\r\n"),
   5781     };
   5782 
   5783     MockRead data_reads1[] = {
   5784       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5785       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
   5786                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
   5787       MockRead(SYNCHRONOUS, OK),
   5788     };
   5789 
   5790     // Resend with authorization (username=foo, password=bar)
   5791     MockWrite data_writes2[] = {
   5792       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5793                 "Host: www.google.com\r\n"
   5794                 "Connection: keep-alive\r\n"
   5795                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5796                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
   5797                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
   5798                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5799     };
   5800 
   5801     // Sever accepts the authorization.
   5802     MockRead data_reads2[] = {
   5803       MockRead("HTTP/1.0 200 OK\r\n"),
   5804       MockRead(SYNCHRONOUS, OK),
   5805     };
   5806 
   5807     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5808                                    data_writes1, arraysize(data_writes1));
   5809     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5810                                    data_writes2, arraysize(data_writes2));
   5811     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5812     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5813 
   5814     TestCompletionCallback callback1;
   5815 
   5816     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5817     EXPECT_EQ(ERR_IO_PENDING, rv);
   5818 
   5819     rv = callback1.WaitForResult();
   5820     EXPECT_EQ(OK, rv);
   5821 
   5822     const HttpResponseInfo* response = trans->GetResponseInfo();
   5823     ASSERT_TRUE(response != NULL);
   5824     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
   5825 
   5826     TestCompletionCallback callback2;
   5827 
   5828     rv = trans->RestartWithAuth(
   5829         AuthCredentials(kFoo, kBar), callback2.callback());
   5830     EXPECT_EQ(ERR_IO_PENDING, rv);
   5831 
   5832     rv = callback2.WaitForResult();
   5833     EXPECT_EQ(OK, rv);
   5834 
   5835     response = trans->GetResponseInfo();
   5836     ASSERT_TRUE(response != NULL);
   5837     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5838   }
   5839 
   5840   // ------------------------------------------------------------------------
   5841 
   5842   // Transaction 2: Request another resource in digestive's protection space.
   5843   // This will preemptively add an Authorization header which should have an
   5844   // "nc" value of 2 (as compared to 1 in the first use.
   5845   {
   5846     HttpRequestInfo request;
   5847     request.method = "GET";
   5848     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5849     // protection space as digest.
   5850     request.url = GURL("http://www.google.com/x/y/a/b");
   5851     request.load_flags = 0;
   5852 
   5853     scoped_ptr<HttpTransaction> trans(
   5854         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5855 
   5856     MockWrite data_writes1[] = {
   5857       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5858                 "Host: www.google.com\r\n"
   5859                 "Connection: keep-alive\r\n"
   5860                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5861                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
   5862                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
   5863                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5864     };
   5865 
   5866     // Sever accepts the authorization.
   5867     MockRead data_reads1[] = {
   5868       MockRead("HTTP/1.0 200 OK\r\n"),
   5869       MockRead("Content-Length: 100\r\n\r\n"),
   5870       MockRead(SYNCHRONOUS, OK),
   5871     };
   5872 
   5873     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5874                                    data_writes1, arraysize(data_writes1));
   5875     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5876 
   5877     TestCompletionCallback callback1;
   5878 
   5879     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5880     EXPECT_EQ(ERR_IO_PENDING, rv);
   5881 
   5882     rv = callback1.WaitForResult();
   5883     EXPECT_EQ(OK, rv);
   5884 
   5885     const HttpResponseInfo* response = trans->GetResponseInfo();
   5886     ASSERT_TRUE(response != NULL);
   5887     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5888   }
   5889 }
   5890 
   5891 // Test the ResetStateForRestart() private method.
   5892 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
   5893   // Create a transaction (the dependencies aren't important).
   5894   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5895   scoped_ptr<HttpNetworkTransaction> trans(
   5896       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5897 
   5898   // Setup some state (which we expect ResetStateForRestart() will clear).
   5899   trans->read_buf_ = new IOBuffer(15);
   5900   trans->read_buf_len_ = 15;
   5901   trans->request_headers_.SetHeader("Authorization", "NTLM");
   5902 
   5903   // Setup state in response_
   5904   HttpResponseInfo* response = &trans->response_;
   5905   response->auth_challenge = new AuthChallengeInfo();
   5906   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
   5907   response->response_time = base::Time::Now();
   5908   response->was_cached = true;  // (Wouldn't ever actually be true...)
   5909 
   5910   { // Setup state for response_.vary_data
   5911     HttpRequestInfo request;
   5912     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   5913     std::replace(temp.begin(), temp.end(), '\n', '\0');
   5914     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
   5915     request.extra_headers.SetHeader("Foo", "1");
   5916     request.extra_headers.SetHeader("bar", "23");
   5917     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
   5918   }
   5919 
   5920   // Cause the above state to be reset.
   5921   trans->ResetStateForRestart();
   5922 
   5923   // Verify that the state that needed to be reset, has been reset.
   5924   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   5925   EXPECT_EQ(0, trans->read_buf_len_);
   5926   EXPECT_TRUE(trans->request_headers_.IsEmpty());
   5927   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5928   EXPECT_TRUE(response->headers.get() == NULL);
   5929   EXPECT_FALSE(response->was_cached);
   5930   EXPECT_EQ(0U, response->ssl_info.cert_status);
   5931   EXPECT_FALSE(response->vary_data.is_valid());
   5932 }
   5933 
   5934 // Test HTTPS connections to a site with a bad certificate
   5935 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   5936   HttpRequestInfo request;
   5937   request.method = "GET";
   5938   request.url = GURL("https://www.google.com/");
   5939   request.load_flags = 0;
   5940 
   5941   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5942   scoped_ptr<HttpTransaction> trans(
   5943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5944 
   5945   MockWrite data_writes[] = {
   5946     MockWrite("GET / HTTP/1.1\r\n"
   5947               "Host: www.google.com\r\n"
   5948               "Connection: keep-alive\r\n\r\n"),
   5949   };
   5950 
   5951   MockRead data_reads[] = {
   5952     MockRead("HTTP/1.0 200 OK\r\n"),
   5953     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5954     MockRead("Content-Length: 100\r\n\r\n"),
   5955     MockRead(SYNCHRONOUS, OK),
   5956   };
   5957 
   5958   StaticSocketDataProvider ssl_bad_certificate;
   5959   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5960                                 data_writes, arraysize(data_writes));
   5961   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5962   SSLSocketDataProvider ssl(ASYNC, OK);
   5963 
   5964   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5965   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5966   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5967   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5968 
   5969   TestCompletionCallback callback;
   5970 
   5971   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5972   EXPECT_EQ(ERR_IO_PENDING, rv);
   5973 
   5974   rv = callback.WaitForResult();
   5975   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5976 
   5977   rv = trans->RestartIgnoringLastError(callback.callback());
   5978   EXPECT_EQ(ERR_IO_PENDING, rv);
   5979 
   5980   rv = callback.WaitForResult();
   5981   EXPECT_EQ(OK, rv);
   5982 
   5983   const HttpResponseInfo* response = trans->GetResponseInfo();
   5984 
   5985   ASSERT_TRUE(response != NULL);
   5986   EXPECT_EQ(100, response->headers->GetContentLength());
   5987 }
   5988 
   5989 // Test HTTPS connections to a site with a bad certificate, going through a
   5990 // proxy
   5991 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   5992   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   5993 
   5994   HttpRequestInfo request;
   5995   request.method = "GET";
   5996   request.url = GURL("https://www.google.com/");
   5997   request.load_flags = 0;
   5998 
   5999   MockWrite proxy_writes[] = {
   6000     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6001               "Host: www.google.com\r\n"
   6002               "Proxy-Connection: keep-alive\r\n\r\n"),
   6003   };
   6004 
   6005   MockRead proxy_reads[] = {
   6006     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6007     MockRead(SYNCHRONOUS, OK)
   6008   };
   6009 
   6010   MockWrite data_writes[] = {
   6011     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6012               "Host: www.google.com\r\n"
   6013               "Proxy-Connection: keep-alive\r\n\r\n"),
   6014     MockWrite("GET / HTTP/1.1\r\n"
   6015               "Host: www.google.com\r\n"
   6016               "Connection: keep-alive\r\n\r\n"),
   6017   };
   6018 
   6019   MockRead data_reads[] = {
   6020     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6021     MockRead("HTTP/1.0 200 OK\r\n"),
   6022     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6023     MockRead("Content-Length: 100\r\n\r\n"),
   6024     MockRead(SYNCHRONOUS, OK),
   6025   };
   6026 
   6027   StaticSocketDataProvider ssl_bad_certificate(
   6028       proxy_reads, arraysize(proxy_reads),
   6029       proxy_writes, arraysize(proxy_writes));
   6030   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6031                                 data_writes, arraysize(data_writes));
   6032   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6033   SSLSocketDataProvider ssl(ASYNC, OK);
   6034 
   6035   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6036   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6037   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6039 
   6040   TestCompletionCallback callback;
   6041 
   6042   for (int i = 0; i < 2; i++) {
   6043     session_deps_.socket_factory->ResetNextMockIndexes();
   6044 
   6045     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6046     scoped_ptr<HttpTransaction> trans(
   6047         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6048 
   6049     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6050     EXPECT_EQ(ERR_IO_PENDING, rv);
   6051 
   6052     rv = callback.WaitForResult();
   6053     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6054 
   6055     rv = trans->RestartIgnoringLastError(callback.callback());
   6056     EXPECT_EQ(ERR_IO_PENDING, rv);
   6057 
   6058     rv = callback.WaitForResult();
   6059     EXPECT_EQ(OK, rv);
   6060 
   6061     const HttpResponseInfo* response = trans->GetResponseInfo();
   6062 
   6063     ASSERT_TRUE(response != NULL);
   6064     EXPECT_EQ(100, response->headers->GetContentLength());
   6065   }
   6066 }
   6067 
   6068 
   6069 // Test HTTPS connections to a site, going through an HTTPS proxy
   6070 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
   6071   session_deps_.proxy_service.reset(
   6072       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   6073   CapturingNetLog net_log;
   6074   session_deps_.net_log = &net_log;
   6075 
   6076   HttpRequestInfo request;
   6077   request.method = "GET";
   6078   request.url = GURL("https://www.google.com/");
   6079   request.load_flags = 0;
   6080 
   6081   MockWrite data_writes[] = {
   6082     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6083               "Host: www.google.com\r\n"
   6084               "Proxy-Connection: keep-alive\r\n\r\n"),
   6085     MockWrite("GET / HTTP/1.1\r\n"
   6086               "Host: www.google.com\r\n"
   6087               "Connection: keep-alive\r\n\r\n"),
   6088   };
   6089 
   6090   MockRead data_reads[] = {
   6091     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6092     MockRead("HTTP/1.1 200 OK\r\n"),
   6093     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6094     MockRead("Content-Length: 100\r\n\r\n"),
   6095     MockRead(SYNCHRONOUS, OK),
   6096   };
   6097 
   6098   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6099                                 data_writes, arraysize(data_writes));
   6100   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6101   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
   6102 
   6103   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6104   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6105   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
   6106 
   6107   TestCompletionCallback callback;
   6108 
   6109   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6110   scoped_ptr<HttpTransaction> trans(
   6111       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6112 
   6113   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6114   EXPECT_EQ(ERR_IO_PENDING, rv);
   6115 
   6116   rv = callback.WaitForResult();
   6117   EXPECT_EQ(OK, rv);
   6118   const HttpResponseInfo* response = trans->GetResponseInfo();
   6119 
   6120   ASSERT_TRUE(response != NULL);
   6121 
   6122   EXPECT_TRUE(response->headers->IsKeepAlive());
   6123   EXPECT_EQ(200, response->headers->response_code());
   6124   EXPECT_EQ(100, response->headers->GetContentLength());
   6125   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6126 
   6127   LoadTimingInfo load_timing_info;
   6128   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6129   TestLoadTimingNotReusedWithPac(load_timing_info,
   6130                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6131 }
   6132 
   6133 // Test an HTTPS Proxy's ability to redirect a CONNECT request
   6134 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
   6135   session_deps_.proxy_service.reset(
   6136       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   6137   CapturingNetLog net_log;
   6138   session_deps_.net_log = &net_log;
   6139 
   6140   HttpRequestInfo request;
   6141   request.method = "GET";
   6142   request.url = GURL("https://www.google.com/");
   6143   request.load_flags = 0;
   6144 
   6145   MockWrite data_writes[] = {
   6146     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6147               "Host: www.google.com\r\n"
   6148               "Proxy-Connection: keep-alive\r\n\r\n"),
   6149   };
   6150 
   6151   MockRead data_reads[] = {
   6152     MockRead("HTTP/1.1 302 Redirect\r\n"),
   6153     MockRead("Location: http://login.example.com/\r\n"),
   6154     MockRead("Content-Length: 0\r\n\r\n"),
   6155     MockRead(SYNCHRONOUS, OK),
   6156   };
   6157 
   6158   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6159                                 data_writes, arraysize(data_writes));
   6160   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6161 
   6162   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6163   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6164 
   6165   TestCompletionCallback callback;
   6166 
   6167   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6168   scoped_ptr<HttpTransaction> trans(
   6169       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6170 
   6171   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6172   EXPECT_EQ(ERR_IO_PENDING, rv);
   6173 
   6174   rv = callback.WaitForResult();
   6175   EXPECT_EQ(OK, rv);
   6176   const HttpResponseInfo* response = trans->GetResponseInfo();
   6177 
   6178   ASSERT_TRUE(response != NULL);
   6179 
   6180   EXPECT_EQ(302, response->headers->response_code());
   6181   std::string url;
   6182   EXPECT_TRUE(response->headers->IsRedirect(&url));
   6183   EXPECT_EQ("http://login.example.com/", url);
   6184 
   6185   // In the case of redirects from proxies, HttpNetworkTransaction returns
   6186   // timing for the proxy connection instead of the connection to the host,
   6187   // and no send / receive times.
   6188   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
   6189   LoadTimingInfo load_timing_info;
   6190   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6191 
   6192   EXPECT_FALSE(load_timing_info.socket_reused);
   6193   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
   6194 
   6195   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
   6196   EXPECT_LE(load_timing_info.proxy_resolve_start,
   6197             load_timing_info.proxy_resolve_end);
   6198   EXPECT_LE(load_timing_info.proxy_resolve_end,
   6199             load_timing_info.connect_timing.connect_start);
   6200   ExpectConnectTimingHasTimes(
   6201       load_timing_info.connect_timing,
   6202       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
   6203 
   6204   EXPECT_TRUE(load_timing_info.send_start.is_null());
   6205   EXPECT_TRUE(load_timing_info.send_end.is_null());
   6206   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
   6207 }
   6208 
   6209 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
   6210 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
   6211   session_deps_.proxy_service.reset(
   6212       ProxyService::CreateFixed("https://proxy:70"));
   6213 
   6214   HttpRequestInfo request;
   6215   request.method = "GET";
   6216   request.url = GURL("https://www.google.com/");
   6217   request.load_flags = 0;
   6218 
   6219   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6220                                                              LOWEST));
   6221   scoped_ptr<SpdyFrame> goaway(
   6222       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6223   MockWrite data_writes[] = {
   6224     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   6225     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
   6226   };
   6227 
   6228   static const char* const kExtraHeaders[] = {
   6229     "location",
   6230     "http://login.example.com/",
   6231   };
   6232   scoped_ptr<SpdyFrame> resp(
   6233       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
   6234                                  arraysize(kExtraHeaders)/2, 1));
   6235   MockRead data_reads[] = {
   6236     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   6237     MockRead(ASYNC, 0, 2),  // EOF
   6238   };
   6239 
   6240   DelayedSocketData data(
   6241       1,  // wait for one write to finish before reading.
   6242       data_reads, arraysize(data_reads),
   6243       data_writes, arraysize(data_writes));
   6244   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6245   proxy_ssl.SetNextProto(GetParam());
   6246 
   6247   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6248   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6249 
   6250   TestCompletionCallback callback;
   6251 
   6252   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6253   scoped_ptr<HttpTransaction> trans(
   6254       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6255 
   6256   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6257   EXPECT_EQ(ERR_IO_PENDING, rv);
   6258 
   6259   rv = callback.WaitForResult();
   6260   EXPECT_EQ(OK, rv);
   6261   const HttpResponseInfo* response = trans->GetResponseInfo();
   6262 
   6263   ASSERT_TRUE(response != NULL);
   6264 
   6265   EXPECT_EQ(302, response->headers->response_code());
   6266   std::string url;
   6267   EXPECT_TRUE(response->headers->IsRedirect(&url));
   6268   EXPECT_EQ("http://login.example.com/", url);
   6269 }
   6270 
   6271 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
   6272 TEST_P(HttpNetworkTransactionTest,
   6273        ErrorResponseToHttpsConnectViaHttpsProxy) {
   6274   session_deps_.proxy_service.reset(
   6275       ProxyService::CreateFixed("https://proxy:70"));
   6276 
   6277   HttpRequestInfo request;
   6278   request.method = "GET";
   6279   request.url = GURL("https://www.google.com/");
   6280   request.load_flags = 0;
   6281 
   6282   MockWrite data_writes[] = {
   6283     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6284               "Host: www.google.com\r\n"
   6285               "Proxy-Connection: keep-alive\r\n\r\n"),
   6286   };
   6287 
   6288   MockRead data_reads[] = {
   6289     MockRead("HTTP/1.1 404 Not Found\r\n"),
   6290     MockRead("Content-Length: 23\r\n\r\n"),
   6291     MockRead("The host does not exist"),
   6292     MockRead(SYNCHRONOUS, OK),
   6293   };
   6294 
   6295   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6296                                 data_writes, arraysize(data_writes));
   6297   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6298 
   6299   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6300   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6301 
   6302   TestCompletionCallback callback;
   6303 
   6304   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6305   scoped_ptr<HttpTransaction> trans(
   6306       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6307 
   6308   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6309   EXPECT_EQ(ERR_IO_PENDING, rv);
   6310 
   6311   rv = callback.WaitForResult();
   6312   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   6313 
   6314   // TODO(ttuttle): Anything else to check here?
   6315 }
   6316 
   6317 // Test that a SPDY proxy's response to a CONNECT request is filtered.
   6318 TEST_P(HttpNetworkTransactionTest,
   6319        ErrorResponseToHttpsConnectViaSpdyProxy) {
   6320   session_deps_.proxy_service.reset(
   6321      ProxyService::CreateFixed("https://proxy:70"));
   6322 
   6323   HttpRequestInfo request;
   6324   request.method = "GET";
   6325   request.url = GURL("https://www.google.com/");
   6326   request.load_flags = 0;
   6327 
   6328   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6329                                                              LOWEST));
   6330   scoped_ptr<SpdyFrame> rst(
   6331       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6332   MockWrite data_writes[] = {
   6333     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   6334     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
   6335   };
   6336 
   6337   static const char* const kExtraHeaders[] = {
   6338     "location",
   6339     "http://login.example.com/",
   6340   };
   6341   scoped_ptr<SpdyFrame> resp(
   6342       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
   6343                                  arraysize(kExtraHeaders)/2, 1));
   6344   scoped_ptr<SpdyFrame> body(
   6345       spdy_util_.ConstructSpdyBodyFrame(
   6346           1, "The host does not exist", 23, true));
   6347   MockRead data_reads[] = {
   6348     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   6349     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
   6350     MockRead(ASYNC, 0, 4),  // EOF
   6351   };
   6352 
   6353   DelayedSocketData data(
   6354       1,  // wait for one write to finish before reading.
   6355       data_reads, arraysize(data_reads),
   6356       data_writes, arraysize(data_writes));
   6357   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6358   proxy_ssl.SetNextProto(GetParam());
   6359 
   6360   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6361   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6362 
   6363   TestCompletionCallback callback;
   6364 
   6365   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6366   scoped_ptr<HttpTransaction> trans(
   6367       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6368 
   6369   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6370   EXPECT_EQ(ERR_IO_PENDING, rv);
   6371 
   6372   rv = callback.WaitForResult();
   6373   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   6374 
   6375   // TODO(ttuttle): Anything else to check here?
   6376 }
   6377 
   6378 // Test the request-challenge-retry sequence for basic auth, through
   6379 // a SPDY proxy over a single SPDY session.
   6380 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
   6381   HttpRequestInfo request;
   6382   request.method = "GET";
   6383   request.url = GURL("https://www.google.com/");
   6384   // when the no authentication data flag is set.
   6385   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   6386 
   6387   // Configure against https proxy server "myproxy:70".
   6388   session_deps_.proxy_service.reset(
   6389       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   6390   CapturingBoundNetLog log;
   6391   session_deps_.net_log = log.bound().net_log();
   6392   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6393 
   6394   // Since we have proxy, should try to establish tunnel.
   6395   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6396                                                             LOWEST));
   6397   scoped_ptr<SpdyFrame> rst(
   6398       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6399 
   6400   // After calling trans->RestartWithAuth(), this is the request we should
   6401   // be issuing -- the final header line contains the credentials.
   6402   const char* const kAuthCredentials[] = {
   6403       "proxy-authorization", "Basic Zm9vOmJhcg==",
   6404   };
   6405   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
   6406       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
   6407   // fetch https://www.google.com/ via HTTP
   6408   const char get[] = "GET / HTTP/1.1\r\n"
   6409     "Host: www.google.com\r\n"
   6410     "Connection: keep-alive\r\n\r\n";
   6411   scoped_ptr<SpdyFrame> wrapped_get(
   6412       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
   6413 
   6414   MockWrite spdy_writes[] = {
   6415     CreateMockWrite(*req, 1, ASYNC),
   6416     CreateMockWrite(*rst, 4, ASYNC),
   6417     CreateMockWrite(*connect2, 5),
   6418     CreateMockWrite(*wrapped_get, 8),
   6419   };
   6420 
   6421   // The proxy responds to the connect with a 407, using a persistent
   6422   // connection.
   6423   const char* const kAuthStatus = "407";
   6424   const char* const kAuthChallenge[] = {
   6425     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
   6426   };
   6427   scoped_ptr<SpdyFrame> conn_auth_resp(spdy_util_.ConstructSpdySynReplyError(
   6428       kAuthStatus, kAuthChallenge, arraysize(kAuthChallenge) / 2, 1));
   6429 
   6430   scoped_ptr<SpdyFrame> conn_resp(
   6431       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   6432   const char resp[] = "HTTP/1.1 200 OK\r\n"
   6433       "Content-Length: 5\r\n\r\n";
   6434 
   6435   scoped_ptr<SpdyFrame> wrapped_get_resp(
   6436       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
   6437   scoped_ptr<SpdyFrame> wrapped_body(
   6438       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
   6439   MockRead spdy_reads[] = {
   6440     CreateMockRead(*conn_auth_resp, 2, ASYNC),
   6441     CreateMockRead(*conn_resp, 6, ASYNC),
   6442     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
   6443     CreateMockRead(*wrapped_body, 10, ASYNC),
   6444     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
   6445   };
   6446 
   6447   OrderedSocketData spdy_data(
   6448       spdy_reads, arraysize(spdy_reads),
   6449       spdy_writes, arraysize(spdy_writes));
   6450   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6451   // Negotiate SPDY to the proxy
   6452   SSLSocketDataProvider proxy(ASYNC, OK);
   6453   proxy.SetNextProto(GetParam());
   6454   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6455   // Vanilla SSL to the server
   6456   SSLSocketDataProvider server(ASYNC, OK);
   6457   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
   6458 
   6459   TestCompletionCallback callback1;
   6460 
   6461   scoped_ptr<HttpTransaction> trans(
   6462       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6463 
   6464   int rv = trans->Start(&request, callback1.callback(), log.bound());
   6465   EXPECT_EQ(ERR_IO_PENDING, rv);
   6466 
   6467   rv = callback1.WaitForResult();
   6468   EXPECT_EQ(OK, rv);
   6469   net::CapturingNetLog::CapturedEntryList entries;
   6470   log.GetEntries(&entries);
   6471   size_t pos = ExpectLogContainsSomewhere(
   6472       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   6473       NetLog::PHASE_NONE);
   6474   ExpectLogContainsSomewhere(
   6475       entries, pos,
   6476       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   6477       NetLog::PHASE_NONE);
   6478 
   6479   const HttpResponseInfo* response = trans->GetResponseInfo();
   6480   ASSERT_TRUE(response != NULL);
   6481   ASSERT_FALSE(response->headers.get() == NULL);
   6482   EXPECT_EQ(407, response->headers->response_code());
   6483   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6484   EXPECT_TRUE(response->auth_challenge.get() != NULL);
   6485   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   6486 
   6487   TestCompletionCallback callback2;
   6488 
   6489   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
   6490                               callback2.callback());
   6491   EXPECT_EQ(ERR_IO_PENDING, rv);
   6492 
   6493   rv = callback2.WaitForResult();
   6494   EXPECT_EQ(OK, rv);
   6495 
   6496   response = trans->GetResponseInfo();
   6497   ASSERT_TRUE(response != NULL);
   6498 
   6499   EXPECT_TRUE(response->headers->IsKeepAlive());
   6500   EXPECT_EQ(200, response->headers->response_code());
   6501   EXPECT_EQ(5, response->headers->GetContentLength());
   6502   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6503 
   6504   // The password prompt info should not be set.
   6505   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6506 
   6507   LoadTimingInfo load_timing_info;
   6508   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6509   TestLoadTimingNotReusedWithPac(load_timing_info,
   6510                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6511 
   6512   trans.reset();
   6513   session->CloseAllConnections();
   6514 }
   6515 
   6516 // Test that an explicitly trusted SPDY proxy can push a resource from an
   6517 // origin that is different from that of its associated resource.
   6518 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
   6519   HttpRequestInfo request;
   6520   HttpRequestInfo push_request;
   6521 
   6522   request.method = "GET";
   6523   request.url = GURL("http://www.google.com/");
   6524   push_request.method = "GET";
   6525   push_request.url = GURL("http://www.another-origin.com/foo.dat");
   6526 
   6527   // Configure against https proxy server "myproxy:70".
   6528   session_deps_.proxy_service.reset(
   6529       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   6530   CapturingBoundNetLog log;
   6531   session_deps_.net_log = log.bound().net_log();
   6532 
   6533   // Enable cross-origin push.
   6534   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6535 
   6536   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6537 
   6538   scoped_ptr<SpdyFrame> stream1_syn(
   6539       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6540 
   6541   MockWrite spdy_writes[] = {
   6542     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6543   };
   6544 
   6545   scoped_ptr<SpdyFrame>
   6546       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6547 
   6548   scoped_ptr<SpdyFrame>
   6549       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6550 
   6551   scoped_ptr<SpdyFrame>
   6552       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6553                                     0,
   6554                                     2,
   6555                                     1,
   6556                                     "http://www.another-origin.com/foo.dat"));
   6557   const char kPushedData[] = "pushed";
   6558   scoped_ptr<SpdyFrame> stream2_body(
   6559       spdy_util_.ConstructSpdyBodyFrame(
   6560           2, kPushedData, strlen(kPushedData), true));
   6561 
   6562   MockRead spdy_reads[] = {
   6563     CreateMockRead(*stream1_reply, 2, ASYNC),
   6564     CreateMockRead(*stream2_syn, 3, ASYNC),
   6565     CreateMockRead(*stream1_body, 4, ASYNC),
   6566     CreateMockRead(*stream2_body, 5, ASYNC),
   6567     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6568   };
   6569 
   6570   OrderedSocketData spdy_data(
   6571       spdy_reads, arraysize(spdy_reads),
   6572       spdy_writes, arraysize(spdy_writes));
   6573   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6574   // Negotiate SPDY to the proxy
   6575   SSLSocketDataProvider proxy(ASYNC, OK);
   6576   proxy.SetNextProto(GetParam());
   6577   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6578 
   6579   scoped_ptr<HttpTransaction> trans(
   6580       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6581   TestCompletionCallback callback;
   6582   int rv = trans->Start(&request, callback.callback(), log.bound());
   6583   EXPECT_EQ(ERR_IO_PENDING, rv);
   6584 
   6585   rv = callback.WaitForResult();
   6586   EXPECT_EQ(OK, rv);
   6587   const HttpResponseInfo* response = trans->GetResponseInfo();
   6588 
   6589   scoped_ptr<HttpTransaction> push_trans(
   6590       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6591   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
   6592   EXPECT_EQ(ERR_IO_PENDING, rv);
   6593 
   6594   rv = callback.WaitForResult();
   6595   EXPECT_EQ(OK, rv);
   6596   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
   6597 
   6598   ASSERT_TRUE(response != NULL);
   6599   EXPECT_TRUE(response->headers->IsKeepAlive());
   6600 
   6601   EXPECT_EQ(200, response->headers->response_code());
   6602   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6603 
   6604   std::string response_data;
   6605   rv = ReadTransaction(trans.get(), &response_data);
   6606   EXPECT_EQ(OK, rv);
   6607   EXPECT_EQ("hello!", response_data);
   6608 
   6609   LoadTimingInfo load_timing_info;
   6610   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6611   TestLoadTimingNotReusedWithPac(load_timing_info,
   6612                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6613 
   6614   // Verify the pushed stream.
   6615   EXPECT_TRUE(push_response->headers.get() != NULL);
   6616   EXPECT_EQ(200, push_response->headers->response_code());
   6617 
   6618   rv = ReadTransaction(push_trans.get(), &response_data);
   6619   EXPECT_EQ(OK, rv);
   6620   EXPECT_EQ("pushed", response_data);
   6621 
   6622   LoadTimingInfo push_load_timing_info;
   6623   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
   6624   TestLoadTimingReusedWithPac(push_load_timing_info);
   6625   // The transactions should share a socket ID, despite being for different
   6626   // origins.
   6627   EXPECT_EQ(load_timing_info.socket_log_id,
   6628             push_load_timing_info.socket_log_id);
   6629 
   6630   trans.reset();
   6631   push_trans.reset();
   6632   session->CloseAllConnections();
   6633 }
   6634 
   6635 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
   6636 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
   6637   HttpRequestInfo request;
   6638 
   6639   request.method = "GET";
   6640   request.url = GURL("http://www.google.com/");
   6641 
   6642   // Configure against https proxy server "myproxy:70".
   6643   session_deps_.proxy_service.reset(
   6644       ProxyService::CreateFixed("https://myproxy:70"));
   6645   CapturingBoundNetLog log;
   6646   session_deps_.net_log = log.bound().net_log();
   6647 
   6648   // Enable cross-origin push.
   6649   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6650 
   6651   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6652 
   6653   scoped_ptr<SpdyFrame> stream1_syn(
   6654       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6655 
   6656   scoped_ptr<SpdyFrame> push_rst(
   6657       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   6658 
   6659   MockWrite spdy_writes[] = {
   6660     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6661     CreateMockWrite(*push_rst, 4),
   6662   };
   6663 
   6664   scoped_ptr<SpdyFrame>
   6665       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6666 
   6667   scoped_ptr<SpdyFrame>
   6668       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6669 
   6670   scoped_ptr<SpdyFrame>
   6671       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6672                                     0,
   6673                                     2,
   6674                                     1,
   6675                                     "https://www.another-origin.com/foo.dat"));
   6676 
   6677   MockRead spdy_reads[] = {
   6678     CreateMockRead(*stream1_reply, 2, ASYNC),
   6679     CreateMockRead(*stream2_syn, 3, ASYNC),
   6680     CreateMockRead(*stream1_body, 5, ASYNC),
   6681     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6682   };
   6683 
   6684   OrderedSocketData spdy_data(
   6685       spdy_reads, arraysize(spdy_reads),
   6686       spdy_writes, arraysize(spdy_writes));
   6687   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6688   // Negotiate SPDY to the proxy
   6689   SSLSocketDataProvider proxy(ASYNC, OK);
   6690   proxy.SetNextProto(GetParam());
   6691   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6692 
   6693   scoped_ptr<HttpTransaction> trans(
   6694       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6695   TestCompletionCallback callback;
   6696   int rv = trans->Start(&request, callback.callback(), log.bound());
   6697   EXPECT_EQ(ERR_IO_PENDING, rv);
   6698 
   6699   rv = callback.WaitForResult();
   6700   EXPECT_EQ(OK, rv);
   6701   const HttpResponseInfo* response = trans->GetResponseInfo();
   6702 
   6703   ASSERT_TRUE(response != NULL);
   6704   EXPECT_TRUE(response->headers->IsKeepAlive());
   6705 
   6706   EXPECT_EQ(200, response->headers->response_code());
   6707   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6708 
   6709   std::string response_data;
   6710   rv = ReadTransaction(trans.get(), &response_data);
   6711   EXPECT_EQ(OK, rv);
   6712   EXPECT_EQ("hello!", response_data);
   6713 
   6714   trans.reset();
   6715   session->CloseAllConnections();
   6716 }
   6717 
   6718 // Test HTTPS connections to a site with a bad certificate, going through an
   6719 // HTTPS proxy
   6720 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
   6721   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   6722       "https://proxy:70"));
   6723 
   6724   HttpRequestInfo request;
   6725   request.method = "GET";
   6726   request.url = GURL("https://www.google.com/");
   6727   request.load_flags = 0;
   6728 
   6729   // Attempt to fetch the URL from a server with a bad cert
   6730   MockWrite bad_cert_writes[] = {
   6731     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6732               "Host: www.google.com\r\n"
   6733               "Proxy-Connection: keep-alive\r\n\r\n"),
   6734   };
   6735 
   6736   MockRead bad_cert_reads[] = {
   6737     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6738     MockRead(SYNCHRONOUS, OK)
   6739   };
   6740 
   6741   // Attempt to fetch the URL with a good cert
   6742   MockWrite good_data_writes[] = {
   6743     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6744               "Host: www.google.com\r\n"
   6745               "Proxy-Connection: keep-alive\r\n\r\n"),
   6746     MockWrite("GET / HTTP/1.1\r\n"
   6747               "Host: www.google.com\r\n"
   6748               "Connection: keep-alive\r\n\r\n"),
   6749   };
   6750 
   6751   MockRead good_cert_reads[] = {
   6752     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6753     MockRead("HTTP/1.0 200 OK\r\n"),
   6754     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6755     MockRead("Content-Length: 100\r\n\r\n"),
   6756     MockRead(SYNCHRONOUS, OK),
   6757   };
   6758 
   6759   StaticSocketDataProvider ssl_bad_certificate(
   6760       bad_cert_reads, arraysize(bad_cert_reads),
   6761       bad_cert_writes, arraysize(bad_cert_writes));
   6762   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
   6763                                 good_data_writes, arraysize(good_data_writes));
   6764   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6765   SSLSocketDataProvider ssl(ASYNC, OK);
   6766 
   6767   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
   6768   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6769   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6770   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6771 
   6772   // SSL to the proxy, then CONNECT request, then valid SSL certificate
   6773   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6774   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6775   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6776 
   6777   TestCompletionCallback callback;
   6778 
   6779   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6780   scoped_ptr<HttpTransaction> trans(
   6781       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6782 
   6783   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6784   EXPECT_EQ(ERR_IO_PENDING, rv);
   6785 
   6786   rv = callback.WaitForResult();
   6787   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6788 
   6789   rv = trans->RestartIgnoringLastError(callback.callback());
   6790   EXPECT_EQ(ERR_IO_PENDING, rv);
   6791 
   6792   rv = callback.WaitForResult();
   6793   EXPECT_EQ(OK, rv);
   6794 
   6795   const HttpResponseInfo* response = trans->GetResponseInfo();
   6796 
   6797   ASSERT_TRUE(response != NULL);
   6798   EXPECT_EQ(100, response->headers->GetContentLength());
   6799 }
   6800 
   6801 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   6802   HttpRequestInfo request;
   6803   request.method = "GET";
   6804   request.url = GURL("http://www.google.com/");
   6805   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6806                                   "Chromium Ultra Awesome X Edition");
   6807 
   6808   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6809   scoped_ptr<HttpTransaction> trans(
   6810       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6811 
   6812   MockWrite data_writes[] = {
   6813     MockWrite("GET / HTTP/1.1\r\n"
   6814               "Host: www.google.com\r\n"
   6815               "Connection: keep-alive\r\n"
   6816               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6817   };
   6818 
   6819   // Lastly, the server responds with the actual content.
   6820   MockRead data_reads[] = {
   6821     MockRead("HTTP/1.0 200 OK\r\n"),
   6822     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6823     MockRead("Content-Length: 100\r\n\r\n"),
   6824     MockRead(SYNCHRONOUS, OK),
   6825   };
   6826 
   6827   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6828                                 data_writes, arraysize(data_writes));
   6829   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6830 
   6831   TestCompletionCallback callback;
   6832 
   6833   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6834   EXPECT_EQ(ERR_IO_PENDING, rv);
   6835 
   6836   rv = callback.WaitForResult();
   6837   EXPECT_EQ(OK, rv);
   6838 }
   6839 
   6840 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   6841   HttpRequestInfo request;
   6842   request.method = "GET";
   6843   request.url = GURL("https://www.google.com/");
   6844   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6845                                   "Chromium Ultra Awesome X Edition");
   6846 
   6847   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   6848   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6849   scoped_ptr<HttpTransaction> trans(
   6850       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6851 
   6852   MockWrite data_writes[] = {
   6853     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6854               "Host: www.google.com\r\n"
   6855               "Proxy-Connection: keep-alive\r\n"
   6856               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6857   };
   6858   MockRead data_reads[] = {
   6859     // Return an error, so the transaction stops here (this test isn't
   6860     // interested in the rest).
   6861     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   6862     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   6863     MockRead("Proxy-Connection: close\r\n\r\n"),
   6864   };
   6865 
   6866   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6867                                 data_writes, arraysize(data_writes));
   6868   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6869 
   6870   TestCompletionCallback callback;
   6871 
   6872   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6873   EXPECT_EQ(ERR_IO_PENDING, rv);
   6874 
   6875   rv = callback.WaitForResult();
   6876   EXPECT_EQ(OK, rv);
   6877 }
   6878 
   6879 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
   6880   HttpRequestInfo request;
   6881   request.method = "GET";
   6882   request.url = GURL("http://www.google.com/");
   6883   request.load_flags = 0;
   6884   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
   6885                                   "http://the.previous.site.com/");
   6886 
   6887   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6888   scoped_ptr<HttpTransaction> trans(
   6889       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6890 
   6891   MockWrite data_writes[] = {
   6892     MockWrite("GET / HTTP/1.1\r\n"
   6893               "Host: www.google.com\r\n"
   6894               "Connection: keep-alive\r\n"
   6895               "Referer: http://the.previous.site.com/\r\n\r\n"),
   6896   };
   6897 
   6898   // Lastly, the server responds with the actual content.
   6899   MockRead data_reads[] = {
   6900     MockRead("HTTP/1.0 200 OK\r\n"),
   6901     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6902     MockRead("Content-Length: 100\r\n\r\n"),
   6903     MockRead(SYNCHRONOUS, OK),
   6904   };
   6905 
   6906   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6907                                 data_writes, arraysize(data_writes));
   6908   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6909 
   6910   TestCompletionCallback callback;
   6911 
   6912   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6913   EXPECT_EQ(ERR_IO_PENDING, rv);
   6914 
   6915   rv = callback.WaitForResult();
   6916   EXPECT_EQ(OK, rv);
   6917 }
   6918 
   6919 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   6920   HttpRequestInfo request;
   6921   request.method = "POST";
   6922   request.url = GURL("http://www.google.com/");
   6923 
   6924   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6925   scoped_ptr<HttpTransaction> trans(
   6926       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6927 
   6928   MockWrite data_writes[] = {
   6929     MockWrite("POST / HTTP/1.1\r\n"
   6930               "Host: www.google.com\r\n"
   6931               "Connection: keep-alive\r\n"
   6932               "Content-Length: 0\r\n\r\n"),
   6933   };
   6934 
   6935   // Lastly, the server responds with the actual content.
   6936   MockRead data_reads[] = {
   6937     MockRead("HTTP/1.0 200 OK\r\n"),
   6938     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6939     MockRead("Content-Length: 100\r\n\r\n"),
   6940     MockRead(SYNCHRONOUS, OK),
   6941   };
   6942 
   6943   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6944                                 data_writes, arraysize(data_writes));
   6945   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6946 
   6947   TestCompletionCallback callback;
   6948 
   6949   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6950   EXPECT_EQ(ERR_IO_PENDING, rv);
   6951 
   6952   rv = callback.WaitForResult();
   6953   EXPECT_EQ(OK, rv);
   6954 }
   6955 
   6956 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   6957   HttpRequestInfo request;
   6958   request.method = "PUT";
   6959   request.url = GURL("http://www.google.com/");
   6960 
   6961   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6962   scoped_ptr<HttpTransaction> trans(
   6963       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6964 
   6965   MockWrite data_writes[] = {
   6966     MockWrite("PUT / HTTP/1.1\r\n"
   6967               "Host: www.google.com\r\n"
   6968               "Connection: keep-alive\r\n"
   6969               "Content-Length: 0\r\n\r\n"),
   6970   };
   6971 
   6972   // Lastly, the server responds with the actual content.
   6973   MockRead data_reads[] = {
   6974     MockRead("HTTP/1.0 200 OK\r\n"),
   6975     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6976     MockRead("Content-Length: 100\r\n\r\n"),
   6977     MockRead(SYNCHRONOUS, OK),
   6978   };
   6979 
   6980   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6981                                 data_writes, arraysize(data_writes));
   6982   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6983 
   6984   TestCompletionCallback callback;
   6985 
   6986   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6987   EXPECT_EQ(ERR_IO_PENDING, rv);
   6988 
   6989   rv = callback.WaitForResult();
   6990   EXPECT_EQ(OK, rv);
   6991 }
   6992 
   6993 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   6994   HttpRequestInfo request;
   6995   request.method = "HEAD";
   6996   request.url = GURL("http://www.google.com/");
   6997 
   6998   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6999   scoped_ptr<HttpTransaction> trans(
   7000       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7001 
   7002   MockWrite data_writes[] = {
   7003     MockWrite("HEAD / HTTP/1.1\r\n"
   7004               "Host: www.google.com\r\n"
   7005               "Connection: keep-alive\r\n"
   7006               "Content-Length: 0\r\n\r\n"),
   7007   };
   7008 
   7009   // Lastly, the server responds with the actual content.
   7010   MockRead data_reads[] = {
   7011     MockRead("HTTP/1.0 200 OK\r\n"),
   7012     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7013     MockRead("Content-Length: 100\r\n\r\n"),
   7014     MockRead(SYNCHRONOUS, OK),
   7015   };
   7016 
   7017   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7018                                 data_writes, arraysize(data_writes));
   7019   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7020 
   7021   TestCompletionCallback callback;
   7022 
   7023   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7024   EXPECT_EQ(ERR_IO_PENDING, rv);
   7025 
   7026   rv = callback.WaitForResult();
   7027   EXPECT_EQ(OK, rv);
   7028 }
   7029 
   7030 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   7031   HttpRequestInfo request;
   7032   request.method = "GET";
   7033   request.url = GURL("http://www.google.com/");
   7034   request.load_flags = LOAD_BYPASS_CACHE;
   7035 
   7036   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7037   scoped_ptr<HttpTransaction> trans(
   7038       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7039 
   7040   MockWrite data_writes[] = {
   7041     MockWrite("GET / HTTP/1.1\r\n"
   7042               "Host: www.google.com\r\n"
   7043               "Connection: keep-alive\r\n"
   7044               "Pragma: no-cache\r\n"
   7045               "Cache-Control: no-cache\r\n\r\n"),
   7046   };
   7047 
   7048   // Lastly, the server responds with the actual content.
   7049   MockRead data_reads[] = {
   7050     MockRead("HTTP/1.0 200 OK\r\n"),
   7051     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7052     MockRead("Content-Length: 100\r\n\r\n"),
   7053     MockRead(SYNCHRONOUS, OK),
   7054   };
   7055 
   7056   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7057                                 data_writes, arraysize(data_writes));
   7058   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7059 
   7060   TestCompletionCallback callback;
   7061 
   7062   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7063   EXPECT_EQ(ERR_IO_PENDING, rv);
   7064 
   7065   rv = callback.WaitForResult();
   7066   EXPECT_EQ(OK, rv);
   7067 }
   7068 
   7069 TEST_P(HttpNetworkTransactionTest,
   7070        BuildRequest_CacheControlValidateCache) {
   7071   HttpRequestInfo request;
   7072   request.method = "GET";
   7073   request.url = GURL("http://www.google.com/");
   7074   request.load_flags = LOAD_VALIDATE_CACHE;
   7075 
   7076   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7077   scoped_ptr<HttpTransaction> trans(
   7078       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7079 
   7080   MockWrite data_writes[] = {
   7081     MockWrite("GET / HTTP/1.1\r\n"
   7082               "Host: www.google.com\r\n"
   7083               "Connection: keep-alive\r\n"
   7084               "Cache-Control: max-age=0\r\n\r\n"),
   7085   };
   7086 
   7087   // Lastly, the server responds with the actual content.
   7088   MockRead data_reads[] = {
   7089     MockRead("HTTP/1.0 200 OK\r\n"),
   7090     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7091     MockRead("Content-Length: 100\r\n\r\n"),
   7092     MockRead(SYNCHRONOUS, OK),
   7093   };
   7094 
   7095   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7096                                 data_writes, arraysize(data_writes));
   7097   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7098 
   7099   TestCompletionCallback callback;
   7100 
   7101   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7102   EXPECT_EQ(ERR_IO_PENDING, rv);
   7103 
   7104   rv = callback.WaitForResult();
   7105   EXPECT_EQ(OK, rv);
   7106 }
   7107 
   7108 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   7109   HttpRequestInfo request;
   7110   request.method = "GET";
   7111   request.url = GURL("http://www.google.com/");
   7112   request.extra_headers.SetHeader("FooHeader", "Bar");
   7113 
   7114   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7115   scoped_ptr<HttpTransaction> trans(
   7116       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7117 
   7118   MockWrite data_writes[] = {
   7119     MockWrite("GET / HTTP/1.1\r\n"
   7120               "Host: www.google.com\r\n"
   7121               "Connection: keep-alive\r\n"
   7122               "FooHeader: Bar\r\n\r\n"),
   7123   };
   7124 
   7125   // Lastly, the server responds with the actual content.
   7126   MockRead data_reads[] = {
   7127     MockRead("HTTP/1.0 200 OK\r\n"),
   7128     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7129     MockRead("Content-Length: 100\r\n\r\n"),
   7130     MockRead(SYNCHRONOUS, OK),
   7131   };
   7132 
   7133   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7134                                 data_writes, arraysize(data_writes));
   7135   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7136 
   7137   TestCompletionCallback callback;
   7138 
   7139   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7140   EXPECT_EQ(ERR_IO_PENDING, rv);
   7141 
   7142   rv = callback.WaitForResult();
   7143   EXPECT_EQ(OK, rv);
   7144 }
   7145 
   7146 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   7147   HttpRequestInfo request;
   7148   request.method = "GET";
   7149   request.url = GURL("http://www.google.com/");
   7150   request.extra_headers.SetHeader("referer", "www.foo.com");
   7151   request.extra_headers.SetHeader("hEllo", "Kitty");
   7152   request.extra_headers.SetHeader("FoO", "bar");
   7153 
   7154   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7155   scoped_ptr<HttpTransaction> trans(
   7156       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7157 
   7158   MockWrite data_writes[] = {
   7159     MockWrite("GET / HTTP/1.1\r\n"
   7160               "Host: www.google.com\r\n"
   7161               "Connection: keep-alive\r\n"
   7162               "referer: www.foo.com\r\n"
   7163               "hEllo: Kitty\r\n"
   7164               "FoO: bar\r\n\r\n"),
   7165   };
   7166 
   7167   // Lastly, the server responds with the actual content.
   7168   MockRead data_reads[] = {
   7169     MockRead("HTTP/1.0 200 OK\r\n"),
   7170     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7171     MockRead("Content-Length: 100\r\n\r\n"),
   7172     MockRead(SYNCHRONOUS, OK),
   7173   };
   7174 
   7175   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7176                                 data_writes, arraysize(data_writes));
   7177   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7178 
   7179   TestCompletionCallback callback;
   7180 
   7181   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7182   EXPECT_EQ(ERR_IO_PENDING, rv);
   7183 
   7184   rv = callback.WaitForResult();
   7185   EXPECT_EQ(OK, rv);
   7186 }
   7187 
   7188 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   7189   HttpRequestInfo request;
   7190   request.method = "GET";
   7191   request.url = GURL("http://www.google.com/");
   7192   request.load_flags = 0;
   7193 
   7194   session_deps_.proxy_service.reset(
   7195       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   7196   CapturingNetLog net_log;
   7197   session_deps_.net_log = &net_log;
   7198 
   7199   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7200   scoped_ptr<HttpTransaction> trans(
   7201       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7202 
   7203   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   7204   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   7205 
   7206   MockWrite data_writes[] = {
   7207     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   7208     MockWrite("GET / HTTP/1.1\r\n"
   7209               "Host: www.google.com\r\n"
   7210               "Connection: keep-alive\r\n\r\n")
   7211   };
   7212 
   7213   MockRead data_reads[] = {
   7214     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   7215     MockRead("HTTP/1.0 200 OK\r\n"),
   7216     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7217     MockRead("Payload"),
   7218     MockRead(SYNCHRONOUS, OK)
   7219   };
   7220 
   7221   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7222                                 data_writes, arraysize(data_writes));
   7223   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7224 
   7225   TestCompletionCallback callback;
   7226 
   7227   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7228   EXPECT_EQ(ERR_IO_PENDING, rv);
   7229 
   7230   rv = callback.WaitForResult();
   7231   EXPECT_EQ(OK, rv);
   7232 
   7233   const HttpResponseInfo* response = trans->GetResponseInfo();
   7234   ASSERT_TRUE(response != NULL);
   7235 
   7236   LoadTimingInfo load_timing_info;
   7237   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7238   TestLoadTimingNotReusedWithPac(load_timing_info,
   7239                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   7240 
   7241   std::string response_text;
   7242   rv = ReadTransaction(trans.get(), &response_text);
   7243   EXPECT_EQ(OK, rv);
   7244   EXPECT_EQ("Payload", response_text);
   7245 }
   7246 
   7247 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   7248   HttpRequestInfo request;
   7249   request.method = "GET";
   7250   request.url = GURL("https://www.google.com/");
   7251   request.load_flags = 0;
   7252 
   7253   session_deps_.proxy_service.reset(
   7254       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   7255   CapturingNetLog net_log;
   7256   session_deps_.net_log = &net_log;
   7257 
   7258   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7259   scoped_ptr<HttpTransaction> trans(
   7260       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7261 
   7262   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
   7263   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   7264 
   7265   MockWrite data_writes[] = {
   7266     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
   7267               arraysize(write_buffer)),
   7268     MockWrite("GET / HTTP/1.1\r\n"
   7269               "Host: www.google.com\r\n"
   7270               "Connection: keep-alive\r\n\r\n")
   7271   };
   7272 
   7273   MockRead data_reads[] = {
   7274     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
   7275              arraysize(read_buffer)),
   7276     MockRead("HTTP/1.0 200 OK\r\n"),
   7277     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7278     MockRead("Payload"),
   7279     MockRead(SYNCHRONOUS, OK)
   7280   };
   7281 
   7282   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7283                                 data_writes, arraysize(data_writes));
   7284   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7285 
   7286   SSLSocketDataProvider ssl(ASYNC, OK);
   7287   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   7288 
   7289   TestCompletionCallback callback;
   7290 
   7291   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7292   EXPECT_EQ(ERR_IO_PENDING, rv);
   7293 
   7294   rv = callback.WaitForResult();
   7295   EXPECT_EQ(OK, rv);
   7296 
   7297   LoadTimingInfo load_timing_info;
   7298   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7299   TestLoadTimingNotReusedWithPac(load_timing_info,
   7300                                  CONNECT_TIMING_HAS_SSL_TIMES);
   7301 
   7302   const HttpResponseInfo* response = trans->GetResponseInfo();
   7303   ASSERT_TRUE(response != NULL);
   7304 
   7305   std::string response_text;
   7306   rv = ReadTransaction(trans.get(), &response_text);
   7307   EXPECT_EQ(OK, rv);
   7308   EXPECT_EQ("Payload", response_text);
   7309 }
   7310 
   7311 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
   7312   HttpRequestInfo request;
   7313   request.method = "GET";
   7314   request.url = GURL("http://www.google.com/");
   7315   request.load_flags = 0;
   7316 
   7317   session_deps_.proxy_service.reset(
   7318       ProxyService::CreateFixed("socks4://myproxy:1080"));
   7319   CapturingNetLog net_log;
   7320   session_deps_.net_log = &net_log;
   7321 
   7322   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7323   scoped_ptr<HttpTransaction> trans(
   7324       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7325 
   7326   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   7327   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   7328 
   7329   MockWrite data_writes[] = {
   7330     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   7331     MockWrite("GET / HTTP/1.1\r\n"
   7332               "Host: www.google.com\r\n"
   7333               "Connection: keep-alive\r\n\r\n")
   7334   };
   7335 
   7336   MockRead data_reads[] = {
   7337     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   7338     MockRead("HTTP/1.0 200 OK\r\n"),
   7339     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7340     MockRead("Payload"),
   7341     MockRead(SYNCHRONOUS, OK)
   7342   };
   7343 
   7344   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7345                                 data_writes, arraysize(data_writes));
   7346   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7347 
   7348   TestCompletionCallback callback;
   7349 
   7350   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7351   EXPECT_EQ(ERR_IO_PENDING, rv);
   7352 
   7353   rv = callback.WaitForResult();
   7354   EXPECT_EQ(OK, rv);
   7355 
   7356   const HttpResponseInfo* response = trans->GetResponseInfo();
   7357   ASSERT_TRUE(response != NULL);
   7358 
   7359   LoadTimingInfo load_timing_info;
   7360   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7361   TestLoadTimingNotReused(load_timing_info,
   7362                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   7363 
   7364   std::string response_text;
   7365   rv = ReadTransaction(trans.get(), &response_text);
   7366   EXPECT_EQ(OK, rv);
   7367   EXPECT_EQ("Payload", response_text);
   7368 }
   7369 
   7370 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   7371   HttpRequestInfo request;
   7372   request.method = "GET";
   7373   request.url = GURL("http://www.google.com/");
   7374   request.load_flags = 0;
   7375 
   7376   session_deps_.proxy_service.reset(
   7377       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   7378   CapturingNetLog net_log;
   7379   session_deps_.net_log = &net_log;
   7380 
   7381   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7382   scoped_ptr<HttpTransaction> trans(
   7383       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7384 
   7385   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   7386   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   7387   const char kSOCKS5OkRequest[] = {
   7388     0x05,  // Version
   7389     0x01,  // Command (CONNECT)
   7390     0x00,  // Reserved.
   7391     0x03,  // Address type (DOMAINNAME).
   7392     0x0E,  // Length of domain (14)
   7393     // Domain string:
   7394     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   7395     0x00, 0x50,  // 16-bit port (80)
   7396   };
   7397   const char kSOCKS5OkResponse[] =
   7398       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
   7399 
   7400   MockWrite data_writes[] = {
   7401     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   7402     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
   7403     MockWrite("GET / HTTP/1.1\r\n"
   7404               "Host: www.google.com\r\n"
   7405               "Connection: keep-alive\r\n\r\n")
   7406   };
   7407 
   7408   MockRead data_reads[] = {
   7409     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   7410     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   7411     MockRead("HTTP/1.0 200 OK\r\n"),
   7412     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7413     MockRead("Payload"),
   7414     MockRead(SYNCHRONOUS, OK)
   7415   };
   7416 
   7417   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7418                                 data_writes, arraysize(data_writes));
   7419   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7420 
   7421   TestCompletionCallback callback;
   7422 
   7423   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7424   EXPECT_EQ(ERR_IO_PENDING, rv);
   7425 
   7426   rv = callback.WaitForResult();
   7427   EXPECT_EQ(OK, rv);
   7428 
   7429   const HttpResponseInfo* response = trans->GetResponseInfo();
   7430   ASSERT_TRUE(response != NULL);
   7431 
   7432   LoadTimingInfo load_timing_info;
   7433   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7434   TestLoadTimingNotReusedWithPac(load_timing_info,
   7435                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   7436 
   7437   std::string response_text;
   7438   rv = ReadTransaction(trans.get(), &response_text);
   7439   EXPECT_EQ(OK, rv);
   7440   EXPECT_EQ("Payload", response_text);
   7441 }
   7442 
   7443 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   7444   HttpRequestInfo request;
   7445   request.method = "GET";
   7446   request.url = GURL("https://www.google.com/");
   7447   request.load_flags = 0;
   7448 
   7449   session_deps_.proxy_service.reset(
   7450       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   7451   CapturingNetLog net_log;
   7452   session_deps_.net_log = &net_log;
   7453 
   7454   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7455   scoped_ptr<HttpTransaction> trans(
   7456       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7457 
   7458   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   7459   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   7460   const unsigned char kSOCKS5OkRequest[] = {
   7461     0x05,  // Version
   7462     0x01,  // Command (CONNECT)
   7463     0x00,  // Reserved.
   7464     0x03,  // Address type (DOMAINNAME).
   7465     0x0E,  // Length of domain (14)
   7466     // Domain string:
   7467     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   7468     0x01, 0xBB,  // 16-bit port (443)
   7469   };
   7470 
   7471   const char kSOCKS5OkResponse[] =
   7472       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
   7473 
   7474   MockWrite data_writes[] = {
   7475     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   7476     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
   7477               arraysize(kSOCKS5OkRequest)),
   7478     MockWrite("GET / HTTP/1.1\r\n"
   7479               "Host: www.google.com\r\n"
   7480               "Connection: keep-alive\r\n\r\n")
   7481   };
   7482 
   7483   MockRead data_reads[] = {
   7484     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   7485     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   7486     MockRead("HTTP/1.0 200 OK\r\n"),
   7487     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7488     MockRead("Payload"),
   7489     MockRead(SYNCHRONOUS, OK)
   7490   };
   7491 
   7492   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7493                                 data_writes, arraysize(data_writes));
   7494   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7495 
   7496   SSLSocketDataProvider ssl(ASYNC, OK);
   7497   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   7498 
   7499   TestCompletionCallback callback;
   7500 
   7501   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7502   EXPECT_EQ(ERR_IO_PENDING, rv);
   7503 
   7504   rv = callback.WaitForResult();
   7505   EXPECT_EQ(OK, rv);
   7506 
   7507   const HttpResponseInfo* response = trans->GetResponseInfo();
   7508   ASSERT_TRUE(response != NULL);
   7509 
   7510   LoadTimingInfo load_timing_info;
   7511   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7512   TestLoadTimingNotReusedWithPac(load_timing_info,
   7513                                  CONNECT_TIMING_HAS_SSL_TIMES);
   7514 
   7515   std::string response_text;
   7516   rv = ReadTransaction(trans.get(), &response_text);
   7517   EXPECT_EQ(OK, rv);
   7518   EXPECT_EQ("Payload", response_text);
   7519 }
   7520 
   7521 namespace {
   7522 
   7523 // Tests that for connection endpoints the group names are correctly set.
   7524 
   7525 struct GroupNameTest {
   7526   std::string proxy_server;
   7527   std::string url;
   7528   std::string expected_group_name;
   7529   bool ssl;
   7530 };
   7531 
   7532 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
   7533     NextProto next_proto,
   7534     SpdySessionDependencies* session_deps_) {
   7535   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
   7536 
   7537   base::WeakPtr<HttpServerProperties> http_server_properties =
   7538       session->http_server_properties();
   7539   http_server_properties->SetAlternateProtocol(
   7540       HostPortPair("host.with.alternate", 80), 443,
   7541       AlternateProtocolFromNextProto(next_proto), 1);
   7542 
   7543   return session;
   7544 }
   7545 
   7546 int GroupNameTransactionHelper(
   7547     const std::string& url,
   7548     const scoped_refptr<HttpNetworkSession>& session) {
   7549   HttpRequestInfo request;
   7550   request.method = "GET";
   7551   request.url = GURL(url);
   7552   request.load_flags = 0;
   7553 
   7554   scoped_ptr<HttpTransaction> trans(
   7555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7556 
   7557   TestCompletionCallback callback;
   7558 
   7559   // We do not complete this request, the dtor will clean the transaction up.
   7560   return trans->Start(&request, callback.callback(), BoundNetLog());
   7561 }
   7562 
   7563 }  // namespace
   7564 
   7565 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
   7566   const GroupNameTest tests[] = {
   7567     {
   7568       "",  // unused
   7569       "http://www.google.com/direct",
   7570       "www.google.com:80",
   7571       false,
   7572     },
   7573     {
   7574       "",  // unused
   7575       "http://[2001:1418:13:1::25]/direct",
   7576       "[2001:1418:13:1::25]:80",
   7577       false,
   7578     },
   7579 
   7580     // SSL Tests
   7581     {
   7582       "",  // unused
   7583       "https://www.google.com/direct_ssl",
   7584       "ssl/www.google.com:443",
   7585       true,
   7586     },
   7587     {
   7588       "",  // unused
   7589       "https://[2001:1418:13:1::25]/direct",
   7590       "ssl/[2001:1418:13:1::25]:443",
   7591       true,
   7592     },
   7593     {
   7594       "",  // unused
   7595       "http://host.with.alternate/direct",
   7596       "ssl/host.with.alternate:443",
   7597       true,
   7598     },
   7599   };
   7600 
   7601   session_deps_.use_alternate_protocols = true;
   7602 
   7603   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7604     session_deps_.proxy_service.reset(
   7605         ProxyService::CreateFixed(tests[i].proxy_server));
   7606     scoped_refptr<HttpNetworkSession> session(
   7607         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7608 
   7609     HttpNetworkSessionPeer peer(session);
   7610     CaptureGroupNameTransportSocketPool* transport_conn_pool =
   7611         new CaptureGroupNameTransportSocketPool(NULL, NULL);
   7612     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7613         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7614     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7615         new MockClientSocketPoolManager);
   7616     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
   7617     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
   7618     peer.SetClientSocketPoolManager(
   7619         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7620 
   7621     EXPECT_EQ(ERR_IO_PENDING,
   7622               GroupNameTransactionHelper(tests[i].url, session));
   7623     if (tests[i].ssl)
   7624       EXPECT_EQ(tests[i].expected_group_name,
   7625                 ssl_conn_pool->last_group_name_received());
   7626     else
   7627       EXPECT_EQ(tests[i].expected_group_name,
   7628                 transport_conn_pool->last_group_name_received());
   7629   }
   7630 
   7631 }
   7632 
   7633 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
   7634   const GroupNameTest tests[] = {
   7635     {
   7636       "http_proxy",
   7637       "http://www.google.com/http_proxy_normal",
   7638       "www.google.com:80",
   7639       false,
   7640     },
   7641 
   7642     // SSL Tests
   7643     {
   7644       "http_proxy",
   7645       "https://www.google.com/http_connect_ssl",
   7646       "ssl/www.google.com:443",
   7647       true,
   7648     },
   7649 
   7650     {
   7651       "http_proxy",
   7652       "http://host.with.alternate/direct",
   7653       "ssl/host.with.alternate:443",
   7654       true,
   7655     },
   7656 
   7657     {
   7658       "http_proxy",
   7659       "ftp://ftp.google.com/http_proxy_normal",
   7660       "ftp/ftp.google.com:21",
   7661       false,
   7662     },
   7663   };
   7664 
   7665   session_deps_.use_alternate_protocols = true;
   7666 
   7667   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7668     session_deps_.proxy_service.reset(
   7669         ProxyService::CreateFixed(tests[i].proxy_server));
   7670     scoped_refptr<HttpNetworkSession> session(
   7671         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7672 
   7673     HttpNetworkSessionPeer peer(session);
   7674 
   7675     HostPortPair proxy_host("http_proxy", 80);
   7676     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
   7677         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
   7678     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7679         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7680 
   7681     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7682         new MockClientSocketPoolManager);
   7683     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
   7684     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7685     peer.SetClientSocketPoolManager(
   7686         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7687 
   7688     EXPECT_EQ(ERR_IO_PENDING,
   7689               GroupNameTransactionHelper(tests[i].url, session));
   7690     if (tests[i].ssl)
   7691       EXPECT_EQ(tests[i].expected_group_name,
   7692                 ssl_conn_pool->last_group_name_received());
   7693     else
   7694       EXPECT_EQ(tests[i].expected_group_name,
   7695                 http_proxy_pool->last_group_name_received());
   7696   }
   7697 }
   7698 
   7699 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
   7700   const GroupNameTest tests[] = {
   7701     {
   7702       "socks4://socks_proxy:1080",
   7703       "http://www.google.com/socks4_direct",
   7704       "socks4/www.google.com:80",
   7705       false,
   7706     },
   7707     {
   7708       "socks5://socks_proxy:1080",
   7709       "http://www.google.com/socks5_direct",
   7710       "socks5/www.google.com:80",
   7711       false,
   7712     },
   7713 
   7714     // SSL Tests
   7715     {
   7716       "socks4://socks_proxy:1080",
   7717       "https://www.google.com/socks4_ssl",
   7718       "socks4/ssl/www.google.com:443",
   7719       true,
   7720     },
   7721     {
   7722       "socks5://socks_proxy:1080",
   7723       "https://www.google.com/socks5_ssl",
   7724       "socks5/ssl/www.google.com:443",
   7725       true,
   7726     },
   7727 
   7728     {
   7729       "socks4://socks_proxy:1080",
   7730       "http://host.with.alternate/direct",
   7731       "socks4/ssl/host.with.alternate:443",
   7732       true,
   7733     },
   7734   };
   7735 
   7736   session_deps_.use_alternate_protocols = true;
   7737 
   7738   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7739     session_deps_.proxy_service.reset(
   7740         ProxyService::CreateFixed(tests[i].proxy_server));
   7741     scoped_refptr<HttpNetworkSession> session(
   7742         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7743 
   7744     HttpNetworkSessionPeer peer(session);
   7745 
   7746     HostPortPair proxy_host("socks_proxy", 1080);
   7747     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
   7748         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
   7749     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7750         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7751 
   7752     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7753         new MockClientSocketPoolManager);
   7754     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
   7755     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7756     peer.SetClientSocketPoolManager(
   7757         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7758 
   7759     scoped_ptr<HttpTransaction> trans(
   7760         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7761 
   7762     EXPECT_EQ(ERR_IO_PENDING,
   7763               GroupNameTransactionHelper(tests[i].url, session));
   7764     if (tests[i].ssl)
   7765       EXPECT_EQ(tests[i].expected_group_name,
   7766                 ssl_conn_pool->last_group_name_received());
   7767     else
   7768       EXPECT_EQ(tests[i].expected_group_name,
   7769                 socks_conn_pool->last_group_name_received());
   7770   }
   7771 }
   7772 
   7773 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   7774   HttpRequestInfo request;
   7775   request.method = "GET";
   7776   request.url = GURL("http://www.google.com/");
   7777 
   7778   session_deps_.proxy_service.reset(
   7779       ProxyService::CreateFixed("myproxy:70;foobar:80"));
   7780 
   7781   // This simulates failure resolving all hostnames; that means we will fail
   7782   // connecting to both proxies (myproxy:70 and foobar:80).
   7783   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
   7784 
   7785   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7786   scoped_ptr<HttpTransaction> trans(
   7787       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7788 
   7789   TestCompletionCallback callback;
   7790 
   7791   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7792   EXPECT_EQ(ERR_IO_PENDING, rv);
   7793 
   7794   rv = callback.WaitForResult();
   7795   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
   7796 }
   7797 
   7798 // Base test to make sure that when the load flags for a request specify to
   7799 // bypass the cache, the DNS cache is not used.
   7800 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
   7801     int load_flags) {
   7802   // Issue a request, asking to bypass the cache(s).
   7803   HttpRequestInfo request;
   7804   request.method = "GET";
   7805   request.load_flags = load_flags;
   7806   request.url = GURL("http://www.google.com/");
   7807 
   7808   // Select a host resolver that does caching.
   7809   session_deps_.host_resolver.reset(new MockCachingHostResolver);
   7810 
   7811   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7812   scoped_ptr<HttpTransaction> trans(
   7813       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7814 
   7815   // Warm up the host cache so it has an entry for "www.google.com".
   7816   AddressList addrlist;
   7817   TestCompletionCallback callback;
   7818   int rv = session_deps_.host_resolver->Resolve(
   7819       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
   7820       DEFAULT_PRIORITY,
   7821       &addrlist,
   7822       callback.callback(),
   7823       NULL,
   7824       BoundNetLog());
   7825   EXPECT_EQ(ERR_IO_PENDING, rv);
   7826   rv = callback.WaitForResult();
   7827   EXPECT_EQ(OK, rv);
   7828 
   7829   // Verify that it was added to host cache, by doing a subsequent async lookup
   7830   // and confirming it completes synchronously.
   7831   rv = session_deps_.host_resolver->Resolve(
   7832       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
   7833       DEFAULT_PRIORITY,
   7834       &addrlist,
   7835       callback.callback(),
   7836       NULL,
   7837       BoundNetLog());
   7838   ASSERT_EQ(OK, rv);
   7839 
   7840   // Inject a failure the next time that "www.google.com" is resolved. This way
   7841   // we can tell if the next lookup hit the cache, or the "network".
   7842   // (cache --> success, "network" --> failure).
   7843   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
   7844 
   7845   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   7846   // first read -- this won't be reached as the host resolution will fail first.
   7847   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
   7848   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7849   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7850 
   7851   // Run the request.
   7852   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7853   ASSERT_EQ(ERR_IO_PENDING, rv);
   7854   rv = callback.WaitForResult();
   7855 
   7856   // If we bypassed the cache, we would have gotten a failure while resolving
   7857   // "www.google.com".
   7858   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   7859 }
   7860 
   7861 // There are multiple load flags that should trigger the host cache bypass.
   7862 // Test each in isolation:
   7863 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
   7864   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
   7865 }
   7866 
   7867 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
   7868   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
   7869 }
   7870 
   7871 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
   7872   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
   7873 }
   7874 
   7875 // Make sure we can handle an error when writing the request.
   7876 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
   7877   HttpRequestInfo request;
   7878   request.method = "GET";
   7879   request.url = GURL("http://www.foo.com/");
   7880   request.load_flags = 0;
   7881 
   7882   MockWrite write_failure[] = {
   7883     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   7884   };
   7885   StaticSocketDataProvider data(NULL, 0,
   7886                                 write_failure, arraysize(write_failure));
   7887   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7888   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7889 
   7890   TestCompletionCallback callback;
   7891 
   7892   scoped_ptr<HttpTransaction> trans(
   7893       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7894 
   7895   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7896   EXPECT_EQ(ERR_IO_PENDING, rv);
   7897 
   7898   rv = callback.WaitForResult();
   7899   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   7900 }
   7901 
   7902 // Check that a connection closed after the start of the headers finishes ok.
   7903 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
   7904   HttpRequestInfo request;
   7905   request.method = "GET";
   7906   request.url = GURL("http://www.foo.com/");
   7907   request.load_flags = 0;
   7908 
   7909   MockRead data_reads[] = {
   7910     MockRead("HTTP/1."),
   7911     MockRead(SYNCHRONOUS, OK),
   7912   };
   7913 
   7914   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7915   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7916   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7917 
   7918   TestCompletionCallback callback;
   7919 
   7920   scoped_ptr<HttpTransaction> trans(
   7921       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7922 
   7923   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7924   EXPECT_EQ(ERR_IO_PENDING, rv);
   7925 
   7926   rv = callback.WaitForResult();
   7927   EXPECT_EQ(OK, rv);
   7928 
   7929   const HttpResponseInfo* response = trans->GetResponseInfo();
   7930   ASSERT_TRUE(response != NULL);
   7931 
   7932   EXPECT_TRUE(response->headers.get() != NULL);
   7933   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7934 
   7935   std::string response_data;
   7936   rv = ReadTransaction(trans.get(), &response_data);
   7937   EXPECT_EQ(OK, rv);
   7938   EXPECT_EQ("", response_data);
   7939 }
   7940 
   7941 // Make sure that a dropped connection while draining the body for auth
   7942 // restart does the right thing.
   7943 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
   7944   HttpRequestInfo request;
   7945   request.method = "GET";
   7946   request.url = GURL("http://www.google.com/");
   7947   request.load_flags = 0;
   7948 
   7949   MockWrite data_writes1[] = {
   7950     MockWrite("GET / HTTP/1.1\r\n"
   7951               "Host: www.google.com\r\n"
   7952               "Connection: keep-alive\r\n\r\n"),
   7953   };
   7954 
   7955   MockRead data_reads1[] = {
   7956     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   7957     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   7958     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7959     MockRead("Content-Length: 14\r\n\r\n"),
   7960     MockRead("Unauth"),
   7961     MockRead(ASYNC, ERR_CONNECTION_RESET),
   7962   };
   7963 
   7964   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   7965                                  data_writes1, arraysize(data_writes1));
   7966   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   7967 
   7968   // After calling trans->RestartWithAuth(), this is the request we should
   7969   // be issuing -- the final header line contains the credentials.
   7970   MockWrite data_writes2[] = {
   7971     MockWrite("GET / HTTP/1.1\r\n"
   7972               "Host: www.google.com\r\n"
   7973               "Connection: keep-alive\r\n"
   7974               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   7975   };
   7976 
   7977   // Lastly, the server responds with the actual content.
   7978   MockRead data_reads2[] = {
   7979     MockRead("HTTP/1.1 200 OK\r\n"),
   7980     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7981     MockRead("Content-Length: 100\r\n\r\n"),
   7982     MockRead(SYNCHRONOUS, OK),
   7983   };
   7984 
   7985   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   7986                                  data_writes2, arraysize(data_writes2));
   7987   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   7988   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7989 
   7990   TestCompletionCallback callback1;
   7991 
   7992   scoped_ptr<HttpTransaction> trans(
   7993       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7994 
   7995   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7996   EXPECT_EQ(ERR_IO_PENDING, rv);
   7997 
   7998   rv = callback1.WaitForResult();
   7999   EXPECT_EQ(OK, rv);
   8000 
   8001   const HttpResponseInfo* response = trans->GetResponseInfo();
   8002   ASSERT_TRUE(response != NULL);
   8003   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   8004 
   8005   TestCompletionCallback callback2;
   8006 
   8007   rv = trans->RestartWithAuth(
   8008       AuthCredentials(kFoo, kBar), callback2.callback());
   8009   EXPECT_EQ(ERR_IO_PENDING, rv);
   8010 
   8011   rv = callback2.WaitForResult();
   8012   EXPECT_EQ(OK, rv);
   8013 
   8014   response = trans->GetResponseInfo();
   8015   ASSERT_TRUE(response != NULL);
   8016   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   8017   EXPECT_EQ(100, response->headers->GetContentLength());
   8018 }
   8019 
   8020 // Test HTTPS connections going through a proxy that sends extra data.
   8021 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
   8022   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   8023 
   8024   HttpRequestInfo request;
   8025   request.method = "GET";
   8026   request.url = GURL("https://www.google.com/");
   8027   request.load_flags = 0;
   8028 
   8029   MockRead proxy_reads[] = {
   8030     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
   8031     MockRead(SYNCHRONOUS, OK)
   8032   };
   8033 
   8034   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
   8035   SSLSocketDataProvider ssl(ASYNC, OK);
   8036 
   8037   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8038   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8039 
   8040   TestCompletionCallback callback;
   8041 
   8042   session_deps_.socket_factory->ResetNextMockIndexes();
   8043 
   8044   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8045   scoped_ptr<HttpTransaction> trans(
   8046       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8047 
   8048   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8049   EXPECT_EQ(ERR_IO_PENDING, rv);
   8050 
   8051   rv = callback.WaitForResult();
   8052   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   8053 }
   8054 
   8055 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   8056   HttpRequestInfo request;
   8057   request.method = "GET";
   8058   request.url = GURL("http://www.google.com/");
   8059   request.load_flags = 0;
   8060 
   8061   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8062   scoped_ptr<HttpTransaction> trans(
   8063       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8064 
   8065   MockRead data_reads[] = {
   8066     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
   8067     MockRead(SYNCHRONOUS, OK),
   8068   };
   8069 
   8070   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   8071   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8072 
   8073   TestCompletionCallback callback;
   8074 
   8075   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8076   EXPECT_EQ(ERR_IO_PENDING, rv);
   8077 
   8078   EXPECT_EQ(OK, callback.WaitForResult());
   8079 
   8080   const HttpResponseInfo* response = trans->GetResponseInfo();
   8081   ASSERT_TRUE(response != NULL);
   8082 
   8083   EXPECT_TRUE(response->headers.get() != NULL);
   8084   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   8085 
   8086   std::string response_data;
   8087   rv = ReadTransaction(trans.get(), &response_data);
   8088   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   8089 }
   8090 
   8091 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
   8092   base::FilePath temp_file_path;
   8093   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
   8094   const uint64 kFakeSize = 100000;  // file is actually blank
   8095   UploadFileElementReader::ScopedOverridingContentLengthForTests
   8096       overriding_content_length(kFakeSize);
   8097 
   8098   ScopedVector<UploadElementReader> element_readers;
   8099   element_readers.push_back(
   8100       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   8101                                   temp_file_path,
   8102                                   0,
   8103                                   kuint64max,
   8104                                   base::Time()));
   8105   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   8106 
   8107   HttpRequestInfo request;
   8108   request.method = "POST";
   8109   request.url = GURL("http://www.google.com/upload");
   8110   request.upload_data_stream = &upload_data_stream;
   8111   request.load_flags = 0;
   8112 
   8113   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8114   scoped_ptr<HttpTransaction> trans(
   8115       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8116 
   8117   MockRead data_reads[] = {
   8118     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   8119     MockRead("hello world"),
   8120     MockRead(SYNCHRONOUS, OK),
   8121   };
   8122   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   8123   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8124 
   8125   TestCompletionCallback callback;
   8126 
   8127   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8128   EXPECT_EQ(ERR_IO_PENDING, rv);
   8129 
   8130   rv = callback.WaitForResult();
   8131   EXPECT_EQ(OK, rv);
   8132 
   8133   const HttpResponseInfo* response = trans->GetResponseInfo();
   8134   ASSERT_TRUE(response != NULL);
   8135 
   8136   EXPECT_TRUE(response->headers.get() != NULL);
   8137   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   8138 
   8139   std::string response_data;
   8140   rv = ReadTransaction(trans.get(), &response_data);
   8141   EXPECT_EQ(OK, rv);
   8142   EXPECT_EQ("hello world", response_data);
   8143 
   8144   base::DeleteFile(temp_file_path, false);
   8145 }
   8146 
   8147 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
   8148   base::FilePath temp_file;
   8149   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
   8150   std::string temp_file_content("Unreadable file.");
   8151   ASSERT_TRUE(base::WriteFile(temp_file, temp_file_content.c_str(),
   8152                                    temp_file_content.length()));
   8153   ASSERT_TRUE(base::MakeFileUnreadable(temp_file));
   8154 
   8155   ScopedVector<UploadElementReader> element_readers;
   8156   element_readers.push_back(
   8157       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   8158                                   temp_file,
   8159                                   0,
   8160                                   kuint64max,
   8161                                   base::Time()));
   8162   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   8163 
   8164   HttpRequestInfo request;
   8165   request.method = "POST";
   8166   request.url = GURL("http://www.google.com/upload");
   8167   request.upload_data_stream = &upload_data_stream;
   8168   request.load_flags = 0;
   8169 
   8170   // If we try to upload an unreadable file, the transaction should fail.
   8171   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8172   scoped_ptr<HttpTransaction> trans(
   8173       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8174 
   8175   StaticSocketDataProvider data(NULL, 0, NULL, 0);
   8176   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8177 
   8178   TestCompletionCallback callback;
   8179 
   8180   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8181   EXPECT_EQ(ERR_IO_PENDING, rv);
   8182 
   8183   rv = callback.WaitForResult();
   8184   EXPECT_EQ(ERR_ACCESS_DENIED, rv);
   8185 
   8186   const HttpResponseInfo* response = trans->GetResponseInfo();
   8187   EXPECT_FALSE(response);
   8188 
   8189   base::DeleteFile(temp_file, false);
   8190 }
   8191 
   8192 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
   8193   class FakeUploadElementReader : public UploadElementReader {
   8194    public:
   8195     FakeUploadElementReader() {}
   8196     virtual ~FakeUploadElementReader() {}
   8197 
   8198     const CompletionCallback& callback() const { return callback_; }
   8199 
   8200     // UploadElementReader overrides:
   8201     virtual int Init(const CompletionCallback& callback) OVERRIDE {
   8202       callback_ = callback;
   8203       return ERR_IO_PENDING;
   8204     }
   8205     virtual uint64 GetContentLength() const OVERRIDE { return 0; }
   8206     virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
   8207     virtual int Read(IOBuffer* buf,
   8208                      int buf_length,
   8209                      const CompletionCallback& callback) OVERRIDE {
   8210       return ERR_FAILED;
   8211     }
   8212 
   8213    private:
   8214     CompletionCallback callback_;
   8215   };
   8216 
   8217   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
   8218   ScopedVector<UploadElementReader> element_readers;
   8219   element_readers.push_back(fake_reader);
   8220   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   8221 
   8222   HttpRequestInfo request;
   8223   request.method = "POST";
   8224   request.url = GURL("http://www.google.com/upload");
   8225   request.upload_data_stream = &upload_data_stream;
   8226   request.load_flags = 0;
   8227 
   8228   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8229   scoped_ptr<HttpTransaction> trans(
   8230       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8231 
   8232   StaticSocketDataProvider data;
   8233   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8234 
   8235   TestCompletionCallback callback;
   8236   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8237   EXPECT_EQ(ERR_IO_PENDING, rv);
   8238   base::MessageLoop::current()->RunUntilIdle();
   8239 
   8240   // Transaction is pending on request body initialization.
   8241   ASSERT_FALSE(fake_reader->callback().is_null());
   8242 
   8243   // Return Init()'s result after the transaction gets destroyed.
   8244   trans.reset();
   8245   fake_reader->callback().Run(OK);  // Should not crash.
   8246 }
   8247 
   8248 // Tests that changes to Auth realms are treated like auth rejections.
   8249 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
   8250 
   8251   HttpRequestInfo request;
   8252   request.method = "GET";
   8253   request.url = GURL("http://www.google.com/");
   8254   request.load_flags = 0;
   8255 
   8256   // First transaction will request a resource and receive a Basic challenge
   8257   // with realm="first_realm".
   8258   MockWrite data_writes1[] = {
   8259     MockWrite("GET / HTTP/1.1\r\n"
   8260               "Host: www.google.com\r\n"
   8261               "Connection: keep-alive\r\n"
   8262               "\r\n"),
   8263   };
   8264   MockRead data_reads1[] = {
   8265     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   8266              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   8267              "\r\n"),
   8268   };
   8269 
   8270   // After calling trans->RestartWithAuth(), provide an Authentication header
   8271   // for first_realm. The server will reject and provide a challenge with
   8272   // second_realm.
   8273   MockWrite data_writes2[] = {
   8274     MockWrite("GET / HTTP/1.1\r\n"
   8275               "Host: www.google.com\r\n"
   8276               "Connection: keep-alive\r\n"
   8277               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
   8278               "\r\n"),
   8279   };
   8280   MockRead data_reads2[] = {
   8281     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   8282              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
   8283              "\r\n"),
   8284   };
   8285 
   8286   // This again fails, and goes back to first_realm. Make sure that the
   8287   // entry is removed from cache.
   8288   MockWrite data_writes3[] = {
   8289     MockWrite("GET / HTTP/1.1\r\n"
   8290               "Host: www.google.com\r\n"
   8291               "Connection: keep-alive\r\n"
   8292               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
   8293               "\r\n"),
   8294   };
   8295   MockRead data_reads3[] = {
   8296     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   8297              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   8298              "\r\n"),
   8299   };
   8300 
   8301   // Try one last time (with the correct password) and get the resource.
   8302   MockWrite data_writes4[] = {
   8303     MockWrite("GET / HTTP/1.1\r\n"
   8304               "Host: www.google.com\r\n"
   8305               "Connection: keep-alive\r\n"
   8306               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
   8307               "\r\n"),
   8308   };
   8309   MockRead data_reads4[] = {
   8310     MockRead("HTTP/1.1 200 OK\r\n"
   8311              "Content-Type: text/html; charset=iso-8859-1\r\n"
   8312              "Content-Length: 5\r\n"
   8313              "\r\n"
   8314              "hello"),
   8315   };
   8316 
   8317   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   8318                                  data_writes1, arraysize(data_writes1));
   8319   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   8320                                  data_writes2, arraysize(data_writes2));
   8321   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   8322                                  data_writes3, arraysize(data_writes3));
   8323   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
   8324                                  data_writes4, arraysize(data_writes4));
   8325   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   8326   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   8327   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   8328   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   8329 
   8330   TestCompletionCallback callback1;
   8331 
   8332   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8333   scoped_ptr<HttpTransaction> trans(
   8334       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8335 
   8336   // Issue the first request with Authorize headers. There should be a
   8337   // password prompt for first_realm waiting to be filled in after the
   8338   // transaction completes.
   8339   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   8340   EXPECT_EQ(ERR_IO_PENDING, rv);
   8341   rv = callback1.WaitForResult();
   8342   EXPECT_EQ(OK, rv);
   8343   const HttpResponseInfo* response = trans->GetResponseInfo();
   8344   ASSERT_TRUE(response != NULL);
   8345   const AuthChallengeInfo* challenge = response->auth_challenge.get();
   8346   ASSERT_FALSE(challenge == NULL);
   8347   EXPECT_FALSE(challenge->is_proxy);
   8348   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   8349   EXPECT_EQ("first_realm", challenge->realm);
   8350   EXPECT_EQ("basic", challenge->scheme);
   8351 
   8352   // Issue the second request with an incorrect password. There should be a
   8353   // password prompt for second_realm waiting to be filled in after the
   8354   // transaction completes.
   8355   TestCompletionCallback callback2;
   8356   rv = trans->RestartWithAuth(
   8357       AuthCredentials(kFirst, kBaz), callback2.callback());
   8358   EXPECT_EQ(ERR_IO_PENDING, rv);
   8359   rv = callback2.WaitForResult();
   8360   EXPECT_EQ(OK, rv);
   8361   response = trans->GetResponseInfo();
   8362   ASSERT_TRUE(response != NULL);
   8363   challenge = response->auth_challenge.get();
   8364   ASSERT_FALSE(challenge == NULL);
   8365   EXPECT_FALSE(challenge->is_proxy);
   8366   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   8367   EXPECT_EQ("second_realm", challenge->realm);
   8368   EXPECT_EQ("basic", challenge->scheme);
   8369 
   8370   // Issue the third request with another incorrect password. There should be
   8371   // a password prompt for first_realm waiting to be filled in. If the password
   8372   // prompt is not present, it indicates that the HttpAuthCacheEntry for
   8373   // first_realm was not correctly removed.
   8374   TestCompletionCallback callback3;
   8375   rv = trans->RestartWithAuth(
   8376       AuthCredentials(kSecond, kFou), callback3.callback());
   8377   EXPECT_EQ(ERR_IO_PENDING, rv);
   8378   rv = callback3.WaitForResult();
   8379   EXPECT_EQ(OK, rv);
   8380   response = trans->GetResponseInfo();
   8381   ASSERT_TRUE(response != NULL);
   8382   challenge = response->auth_challenge.get();
   8383   ASSERT_FALSE(challenge == NULL);
   8384   EXPECT_FALSE(challenge->is_proxy);
   8385   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   8386   EXPECT_EQ("first_realm", challenge->realm);
   8387   EXPECT_EQ("basic", challenge->scheme);
   8388 
   8389   // Issue the fourth request with the correct password and username.
   8390   TestCompletionCallback callback4;
   8391   rv = trans->RestartWithAuth(
   8392       AuthCredentials(kFirst, kBar), callback4.callback());
   8393   EXPECT_EQ(ERR_IO_PENDING, rv);
   8394   rv = callback4.WaitForResult();
   8395   EXPECT_EQ(OK, rv);
   8396   response = trans->GetResponseInfo();
   8397   ASSERT_TRUE(response != NULL);
   8398   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   8399 }
   8400 
   8401 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
   8402   session_deps_.next_protos = SpdyNextProtos();
   8403   session_deps_.use_alternate_protocols = true;
   8404 
   8405   std::string alternate_protocol_http_header =
   8406       GetAlternateProtocolHttpHeader();
   8407 
   8408   MockRead data_reads[] = {
   8409     MockRead("HTTP/1.1 200 OK\r\n"),
   8410     MockRead(alternate_protocol_http_header.c_str()),
   8411     MockRead("hello world"),
   8412     MockRead(SYNCHRONOUS, OK),
   8413   };
   8414 
   8415   HttpRequestInfo request;
   8416   request.method = "GET";
   8417   request.url = GURL("http://www.google.com/");
   8418   request.load_flags = 0;
   8419 
   8420   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   8421 
   8422   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8423 
   8424   TestCompletionCallback callback;
   8425 
   8426   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8427   scoped_ptr<HttpTransaction> trans(
   8428       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8429 
   8430   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8431   EXPECT_EQ(ERR_IO_PENDING, rv);
   8432 
   8433   HostPortPair http_host_port_pair("www.google.com", 80);
   8434   HttpServerProperties& http_server_properties =
   8435       *session->http_server_properties();
   8436   EXPECT_FALSE(
   8437       http_server_properties.HasAlternateProtocol(http_host_port_pair));
   8438 
   8439   EXPECT_EQ(OK, callback.WaitForResult());
   8440 
   8441   const HttpResponseInfo* response = trans->GetResponseInfo();
   8442   ASSERT_TRUE(response != NULL);
   8443   ASSERT_TRUE(response->headers.get() != NULL);
   8444   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8445   EXPECT_FALSE(response->was_fetched_via_spdy);
   8446   EXPECT_FALSE(response->was_npn_negotiated);
   8447 
   8448   std::string response_data;
   8449   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8450   EXPECT_EQ("hello world", response_data);
   8451 
   8452   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
   8453   const AlternateProtocolInfo alternate =
   8454       http_server_properties.GetAlternateProtocol(http_host_port_pair);
   8455   AlternateProtocolInfo expected_alternate(
   8456       443, AlternateProtocolFromNextProto(GetParam()), 1);
   8457   EXPECT_TRUE(expected_alternate.Equals(alternate));
   8458 }
   8459 
   8460 TEST_P(HttpNetworkTransactionTest,
   8461        MarkBrokenAlternateProtocolAndFallback) {
   8462   session_deps_.use_alternate_protocols = true;
   8463 
   8464   HttpRequestInfo request;
   8465   request.method = "GET";
   8466   request.url = GURL("http://www.google.com/");
   8467   request.load_flags = 0;
   8468 
   8469   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8470   StaticSocketDataProvider first_data;
   8471   first_data.set_connect_data(mock_connect);
   8472   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8473 
   8474   MockRead data_reads[] = {
   8475     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8476     MockRead("hello world"),
   8477     MockRead(ASYNC, OK),
   8478   };
   8479   StaticSocketDataProvider second_data(
   8480       data_reads, arraysize(data_reads), NULL, 0);
   8481   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8482 
   8483   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8484 
   8485   base::WeakPtr<HttpServerProperties> http_server_properties =
   8486       session->http_server_properties();
   8487   // Port must be < 1024, or the header will be ignored (since initial port was
   8488   // port 80 (another restricted port).
   8489   http_server_properties->SetAlternateProtocol(
   8490       HostPortPair::FromURL(request.url),
   8491       666 /* port is ignored by MockConnect anyway */,
   8492       AlternateProtocolFromNextProto(GetParam()), 1);
   8493 
   8494   scoped_ptr<HttpTransaction> trans(
   8495       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8496   TestCompletionCallback callback;
   8497 
   8498   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8499   EXPECT_EQ(ERR_IO_PENDING, rv);
   8500   EXPECT_EQ(OK, callback.WaitForResult());
   8501 
   8502   const HttpResponseInfo* response = trans->GetResponseInfo();
   8503   ASSERT_TRUE(response != NULL);
   8504   ASSERT_TRUE(response->headers.get() != NULL);
   8505   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8506 
   8507   std::string response_data;
   8508   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8509   EXPECT_EQ("hello world", response_data);
   8510 
   8511   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
   8512       HostPortPair::FromURL(request.url)));
   8513   const AlternateProtocolInfo alternate =
   8514       http_server_properties->GetAlternateProtocol(
   8515           HostPortPair::FromURL(request.url));
   8516   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
   8517 }
   8518 
   8519 TEST_P(HttpNetworkTransactionTest,
   8520        AlternateProtocolPortRestrictedBlocked) {
   8521   // Ensure that we're not allowed to redirect traffic via an alternate
   8522   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8523   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8524   // other cases.
   8525   session_deps_.use_alternate_protocols = true;
   8526 
   8527   HttpRequestInfo restricted_port_request;
   8528   restricted_port_request.method = "GET";
   8529   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8530   restricted_port_request.load_flags = 0;
   8531 
   8532   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8533   StaticSocketDataProvider first_data;
   8534   first_data.set_connect_data(mock_connect);
   8535   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8536 
   8537   MockRead data_reads[] = {
   8538     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8539     MockRead("hello world"),
   8540     MockRead(ASYNC, OK),
   8541   };
   8542   StaticSocketDataProvider second_data(
   8543       data_reads, arraysize(data_reads), NULL, 0);
   8544   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8545 
   8546   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8547 
   8548   base::WeakPtr<HttpServerProperties> http_server_properties =
   8549       session->http_server_properties();
   8550   const int kUnrestrictedAlternatePort = 1024;
   8551   http_server_properties->SetAlternateProtocol(
   8552       HostPortPair::FromURL(restricted_port_request.url),
   8553       kUnrestrictedAlternatePort,
   8554       AlternateProtocolFromNextProto(GetParam()), 1);
   8555 
   8556   scoped_ptr<HttpTransaction> trans(
   8557       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8558   TestCompletionCallback callback;
   8559 
   8560   int rv = trans->Start(
   8561       &restricted_port_request,
   8562       callback.callback(), BoundNetLog());
   8563   EXPECT_EQ(ERR_IO_PENDING, rv);
   8564   // Invalid change to unrestricted port should fail.
   8565   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
   8566 }
   8567 
   8568 TEST_P(HttpNetworkTransactionTest,
   8569        AlternateProtocolPortRestrictedPermitted) {
   8570   // Ensure that we're allowed to redirect traffic via an alternate
   8571   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8572   // on a restricted port (port < 1024) if we set
   8573   // enable_user_alternate_protocol_ports.
   8574 
   8575   session_deps_.use_alternate_protocols = true;
   8576   session_deps_.enable_user_alternate_protocol_ports = true;
   8577 
   8578   HttpRequestInfo restricted_port_request;
   8579   restricted_port_request.method = "GET";
   8580   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8581   restricted_port_request.load_flags = 0;
   8582 
   8583   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8584   StaticSocketDataProvider first_data;
   8585   first_data.set_connect_data(mock_connect);
   8586   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8587 
   8588   MockRead data_reads[] = {
   8589     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8590     MockRead("hello world"),
   8591     MockRead(ASYNC, OK),
   8592   };
   8593   StaticSocketDataProvider second_data(
   8594       data_reads, arraysize(data_reads), NULL, 0);
   8595   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8596 
   8597   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8598 
   8599   base::WeakPtr<HttpServerProperties> http_server_properties =
   8600       session->http_server_properties();
   8601   const int kUnrestrictedAlternatePort = 1024;
   8602   http_server_properties->SetAlternateProtocol(
   8603       HostPortPair::FromURL(restricted_port_request.url),
   8604       kUnrestrictedAlternatePort,
   8605       AlternateProtocolFromNextProto(GetParam()), 1);
   8606 
   8607   scoped_ptr<HttpTransaction> trans(
   8608       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8609   TestCompletionCallback callback;
   8610 
   8611   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
   8612       &restricted_port_request,
   8613       callback.callback(), BoundNetLog()));
   8614   // Change to unrestricted port should succeed.
   8615   EXPECT_EQ(OK, callback.WaitForResult());
   8616 }
   8617 
   8618 TEST_P(HttpNetworkTransactionTest,
   8619        AlternateProtocolPortRestrictedAllowed) {
   8620   // Ensure that we're not allowed to redirect traffic via an alternate
   8621   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8622   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8623   // other cases.
   8624   session_deps_.use_alternate_protocols = true;
   8625 
   8626   HttpRequestInfo restricted_port_request;
   8627   restricted_port_request.method = "GET";
   8628   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8629   restricted_port_request.load_flags = 0;
   8630 
   8631   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8632   StaticSocketDataProvider first_data;
   8633   first_data.set_connect_data(mock_connect);
   8634   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8635 
   8636   MockRead data_reads[] = {
   8637     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8638     MockRead("hello world"),
   8639     MockRead(ASYNC, OK),
   8640   };
   8641   StaticSocketDataProvider second_data(
   8642       data_reads, arraysize(data_reads), NULL, 0);
   8643   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8644 
   8645   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8646 
   8647   base::WeakPtr<HttpServerProperties> http_server_properties =
   8648       session->http_server_properties();
   8649   const int kRestrictedAlternatePort = 80;
   8650   http_server_properties->SetAlternateProtocol(
   8651       HostPortPair::FromURL(restricted_port_request.url),
   8652       kRestrictedAlternatePort,
   8653       AlternateProtocolFromNextProto(GetParam()), 1);
   8654 
   8655   scoped_ptr<HttpTransaction> trans(
   8656       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8657   TestCompletionCallback callback;
   8658 
   8659   int rv = trans->Start(
   8660       &restricted_port_request,
   8661       callback.callback(), BoundNetLog());
   8662   EXPECT_EQ(ERR_IO_PENDING, rv);
   8663   // Valid change to restricted port should pass.
   8664   EXPECT_EQ(OK, callback.WaitForResult());
   8665 }
   8666 
   8667 TEST_P(HttpNetworkTransactionTest,
   8668        AlternateProtocolPortUnrestrictedAllowed1) {
   8669   // Ensure that we're not allowed to redirect traffic via an alternate
   8670   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8671   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8672   // other cases.
   8673   session_deps_.use_alternate_protocols = true;
   8674 
   8675   HttpRequestInfo unrestricted_port_request;
   8676   unrestricted_port_request.method = "GET";
   8677   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8678   unrestricted_port_request.load_flags = 0;
   8679 
   8680   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8681   StaticSocketDataProvider first_data;
   8682   first_data.set_connect_data(mock_connect);
   8683   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8684 
   8685   MockRead data_reads[] = {
   8686     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8687     MockRead("hello world"),
   8688     MockRead(ASYNC, OK),
   8689   };
   8690   StaticSocketDataProvider second_data(
   8691       data_reads, arraysize(data_reads), NULL, 0);
   8692   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8693 
   8694   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8695 
   8696   base::WeakPtr<HttpServerProperties> http_server_properties =
   8697       session->http_server_properties();
   8698   const int kRestrictedAlternatePort = 80;
   8699   http_server_properties->SetAlternateProtocol(
   8700       HostPortPair::FromURL(unrestricted_port_request.url),
   8701       kRestrictedAlternatePort,
   8702       AlternateProtocolFromNextProto(GetParam()), 1);
   8703 
   8704   scoped_ptr<HttpTransaction> trans(
   8705       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8706   TestCompletionCallback callback;
   8707 
   8708   int rv = trans->Start(
   8709       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8710   EXPECT_EQ(ERR_IO_PENDING, rv);
   8711   // Valid change to restricted port should pass.
   8712   EXPECT_EQ(OK, callback.WaitForResult());
   8713 }
   8714 
   8715 TEST_P(HttpNetworkTransactionTest,
   8716        AlternateProtocolPortUnrestrictedAllowed2) {
   8717   // Ensure that we're not allowed to redirect traffic via an alternate
   8718   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8719   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8720   // other cases.
   8721   session_deps_.use_alternate_protocols = true;
   8722 
   8723   HttpRequestInfo unrestricted_port_request;
   8724   unrestricted_port_request.method = "GET";
   8725   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8726   unrestricted_port_request.load_flags = 0;
   8727 
   8728   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8729   StaticSocketDataProvider first_data;
   8730   first_data.set_connect_data(mock_connect);
   8731   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8732 
   8733   MockRead data_reads[] = {
   8734     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8735     MockRead("hello world"),
   8736     MockRead(ASYNC, OK),
   8737   };
   8738   StaticSocketDataProvider second_data(
   8739       data_reads, arraysize(data_reads), NULL, 0);
   8740   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8741 
   8742   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8743 
   8744   base::WeakPtr<HttpServerProperties> http_server_properties =
   8745       session->http_server_properties();
   8746   const int kUnrestrictedAlternatePort = 1024;
   8747   http_server_properties->SetAlternateProtocol(
   8748       HostPortPair::FromURL(unrestricted_port_request.url),
   8749       kUnrestrictedAlternatePort,
   8750       AlternateProtocolFromNextProto(GetParam()), 1);
   8751 
   8752   scoped_ptr<HttpTransaction> trans(
   8753       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8754   TestCompletionCallback callback;
   8755 
   8756   int rv = trans->Start(
   8757       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8758   EXPECT_EQ(ERR_IO_PENDING, rv);
   8759   // Valid change to an unrestricted port should pass.
   8760   EXPECT_EQ(OK, callback.WaitForResult());
   8761 }
   8762 
   8763 TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) {
   8764   // Ensure that we're not allowed to redirect traffic via an alternate
   8765   // protocol to an unsafe port, and that we resume the second
   8766   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
   8767   session_deps_.use_alternate_protocols = true;
   8768 
   8769   HttpRequestInfo request;
   8770   request.method = "GET";
   8771   request.url = GURL("http://www.google.com/");
   8772   request.load_flags = 0;
   8773 
   8774   // The alternate protocol request will error out before we attempt to connect,
   8775   // so only the standard HTTP request will try to connect.
   8776   MockRead data_reads[] = {
   8777     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8778     MockRead("hello world"),
   8779     MockRead(ASYNC, OK),
   8780   };
   8781   StaticSocketDataProvider data(
   8782       data_reads, arraysize(data_reads), NULL, 0);
   8783   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8784 
   8785   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8786 
   8787   base::WeakPtr<HttpServerProperties> http_server_properties =
   8788       session->http_server_properties();
   8789   const int kUnsafePort = 7;
   8790   http_server_properties->SetAlternateProtocol(
   8791       HostPortPair::FromURL(request.url),
   8792       kUnsafePort,
   8793       AlternateProtocolFromNextProto(GetParam()), 1);
   8794 
   8795   scoped_ptr<HttpTransaction> trans(
   8796       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8797   TestCompletionCallback callback;
   8798 
   8799   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8800   EXPECT_EQ(ERR_IO_PENDING, rv);
   8801   // The HTTP request should succeed.
   8802   EXPECT_EQ(OK, callback.WaitForResult());
   8803 
   8804   // Disable alternate protocol before the asserts.
   8805  // HttpStreamFactory::set_use_alternate_protocols(false);
   8806 
   8807   const HttpResponseInfo* response = trans->GetResponseInfo();
   8808   ASSERT_TRUE(response != NULL);
   8809   ASSERT_TRUE(response->headers.get() != NULL);
   8810   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8811 
   8812   std::string response_data;
   8813   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8814   EXPECT_EQ("hello world", response_data);
   8815 }
   8816 
   8817 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
   8818   session_deps_.use_alternate_protocols = true;
   8819   session_deps_.next_protos = SpdyNextProtos();
   8820 
   8821   HttpRequestInfo request;
   8822   request.method = "GET";
   8823   request.url = GURL("http://www.google.com/");
   8824   request.load_flags = 0;
   8825 
   8826   std::string alternate_protocol_http_header =
   8827       GetAlternateProtocolHttpHeader();
   8828 
   8829   MockRead data_reads[] = {
   8830     MockRead("HTTP/1.1 200 OK\r\n"),
   8831     MockRead(alternate_protocol_http_header.c_str()),
   8832     MockRead("hello world"),
   8833     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8834     MockRead(ASYNC, OK)
   8835   };
   8836 
   8837   StaticSocketDataProvider first_transaction(
   8838       data_reads, arraysize(data_reads), NULL, 0);
   8839   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8840 
   8841   SSLSocketDataProvider ssl(ASYNC, OK);
   8842   ssl.SetNextProto(GetParam());
   8843   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8844 
   8845   scoped_ptr<SpdyFrame> req(
   8846       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8847   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8848 
   8849   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8850   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8851   MockRead spdy_reads[] = {
   8852     CreateMockRead(*resp),
   8853     CreateMockRead(*data),
   8854     MockRead(ASYNC, 0, 0),
   8855   };
   8856 
   8857   DelayedSocketData spdy_data(
   8858       1,  // wait for one write to finish before reading.
   8859       spdy_reads, arraysize(spdy_reads),
   8860       spdy_writes, arraysize(spdy_writes));
   8861   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8862 
   8863   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8864   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8865       NULL, 0, NULL, 0);
   8866   hanging_non_alternate_protocol_socket.set_connect_data(
   8867       never_finishing_connect);
   8868   session_deps_.socket_factory->AddSocketDataProvider(
   8869       &hanging_non_alternate_protocol_socket);
   8870 
   8871   TestCompletionCallback callback;
   8872 
   8873   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8874   scoped_ptr<HttpTransaction> trans(
   8875       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8876 
   8877   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8878   EXPECT_EQ(ERR_IO_PENDING, rv);
   8879   EXPECT_EQ(OK, callback.WaitForResult());
   8880 
   8881   const HttpResponseInfo* response = trans->GetResponseInfo();
   8882   ASSERT_TRUE(response != NULL);
   8883   ASSERT_TRUE(response->headers.get() != NULL);
   8884   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8885 
   8886   std::string response_data;
   8887   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8888   EXPECT_EQ("hello world", response_data);
   8889 
   8890   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8891 
   8892   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8893   EXPECT_EQ(ERR_IO_PENDING, rv);
   8894   EXPECT_EQ(OK, callback.WaitForResult());
   8895 
   8896   response = trans->GetResponseInfo();
   8897   ASSERT_TRUE(response != NULL);
   8898   ASSERT_TRUE(response->headers.get() != NULL);
   8899   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8900   EXPECT_TRUE(response->was_fetched_via_spdy);
   8901   EXPECT_TRUE(response->was_npn_negotiated);
   8902 
   8903   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8904   EXPECT_EQ("hello!", response_data);
   8905 }
   8906 
   8907 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
   8908   session_deps_.use_alternate_protocols = true;
   8909   session_deps_.next_protos = SpdyNextProtos();
   8910 
   8911   HttpRequestInfo request;
   8912   request.method = "GET";
   8913   request.url = GURL("http://www.google.com/");
   8914   request.load_flags = 0;
   8915 
   8916   std::string alternate_protocol_http_header =
   8917       GetAlternateProtocolHttpHeader();
   8918 
   8919   MockRead data_reads[] = {
   8920     MockRead("HTTP/1.1 200 OK\r\n"),
   8921     MockRead(alternate_protocol_http_header.c_str()),
   8922     MockRead("hello world"),
   8923     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8924     MockRead(ASYNC, OK),
   8925   };
   8926 
   8927   StaticSocketDataProvider first_transaction(
   8928       data_reads, arraysize(data_reads), NULL, 0);
   8929   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
   8930   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8931 
   8932   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8933   StaticSocketDataProvider hanging_socket(
   8934       NULL, 0, NULL, 0);
   8935   hanging_socket.set_connect_data(never_finishing_connect);
   8936   // Socket 2 and 3 are the hanging Alternate-Protocol and
   8937   // non-Alternate-Protocol jobs from the 2nd transaction.
   8938   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8939   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8940 
   8941   SSLSocketDataProvider ssl(ASYNC, OK);
   8942   ssl.SetNextProto(GetParam());
   8943   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8944 
   8945   scoped_ptr<SpdyFrame> req1(
   8946       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8947   scoped_ptr<SpdyFrame> req2(
   8948       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   8949   MockWrite spdy_writes[] = {
   8950     CreateMockWrite(*req1),
   8951     CreateMockWrite(*req2),
   8952   };
   8953   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8954   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8955   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   8956   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   8957   MockRead spdy_reads[] = {
   8958     CreateMockRead(*resp1),
   8959     CreateMockRead(*data1),
   8960     CreateMockRead(*resp2),
   8961     CreateMockRead(*data2),
   8962     MockRead(ASYNC, 0, 0),
   8963   };
   8964 
   8965   DelayedSocketData spdy_data(
   8966       2,  // wait for writes to finish before reading.
   8967       spdy_reads, arraysize(spdy_reads),
   8968       spdy_writes, arraysize(spdy_writes));
   8969   // Socket 4 is the successful Alternate-Protocol for transaction 3.
   8970   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8971 
   8972   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
   8973   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8974 
   8975   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8976   TestCompletionCallback callback1;
   8977   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   8978 
   8979   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
   8980   EXPECT_EQ(ERR_IO_PENDING, rv);
   8981   EXPECT_EQ(OK, callback1.WaitForResult());
   8982 
   8983   const HttpResponseInfo* response = trans1.GetResponseInfo();
   8984   ASSERT_TRUE(response != NULL);
   8985   ASSERT_TRUE(response->headers.get() != NULL);
   8986   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8987 
   8988   std::string response_data;
   8989   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   8990   EXPECT_EQ("hello world", response_data);
   8991 
   8992   TestCompletionCallback callback2;
   8993   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   8994   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
   8995   EXPECT_EQ(ERR_IO_PENDING, rv);
   8996 
   8997   TestCompletionCallback callback3;
   8998   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
   8999   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
   9000   EXPECT_EQ(ERR_IO_PENDING, rv);
   9001 
   9002   EXPECT_EQ(OK, callback2.WaitForResult());
   9003   EXPECT_EQ(OK, callback3.WaitForResult());
   9004 
   9005   response = trans2.GetResponseInfo();
   9006   ASSERT_TRUE(response != NULL);
   9007   ASSERT_TRUE(response->headers.get() != NULL);
   9008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9009   EXPECT_TRUE(response->was_fetched_via_spdy);
   9010   EXPECT_TRUE(response->was_npn_negotiated);
   9011   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   9012   EXPECT_EQ("hello!", response_data);
   9013 
   9014   response = trans3.GetResponseInfo();
   9015   ASSERT_TRUE(response != NULL);
   9016   ASSERT_TRUE(response->headers.get() != NULL);
   9017   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9018   EXPECT_TRUE(response->was_fetched_via_spdy);
   9019   EXPECT_TRUE(response->was_npn_negotiated);
   9020   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
   9021   EXPECT_EQ("hello!", response_data);
   9022 }
   9023 
   9024 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
   9025   session_deps_.use_alternate_protocols = true;
   9026   session_deps_.next_protos = SpdyNextProtos();
   9027 
   9028   HttpRequestInfo request;
   9029   request.method = "GET";
   9030   request.url = GURL("http://www.google.com/");
   9031   request.load_flags = 0;
   9032 
   9033   std::string alternate_protocol_http_header =
   9034       GetAlternateProtocolHttpHeader();
   9035 
   9036   MockRead data_reads[] = {
   9037     MockRead("HTTP/1.1 200 OK\r\n"),
   9038     MockRead(alternate_protocol_http_header.c_str()),
   9039     MockRead("hello world"),
   9040     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9041     MockRead(ASYNC, OK),
   9042   };
   9043 
   9044   StaticSocketDataProvider first_transaction(
   9045       data_reads, arraysize(data_reads), NULL, 0);
   9046   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   9047 
   9048   SSLSocketDataProvider ssl(ASYNC, OK);
   9049   ssl.SetNextProto(GetParam());
   9050   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9051 
   9052   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   9053   StaticSocketDataProvider hanging_alternate_protocol_socket(
   9054       NULL, 0, NULL, 0);
   9055   hanging_alternate_protocol_socket.set_connect_data(
   9056       never_finishing_connect);
   9057   session_deps_.socket_factory->AddSocketDataProvider(
   9058       &hanging_alternate_protocol_socket);
   9059 
   9060   // 2nd request is just a copy of the first one, over HTTP again.
   9061   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   9062 
   9063   TestCompletionCallback callback;
   9064 
   9065   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9066   scoped_ptr<HttpTransaction> trans(
   9067       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9068 
   9069   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9070   EXPECT_EQ(ERR_IO_PENDING, rv);
   9071   EXPECT_EQ(OK, callback.WaitForResult());
   9072 
   9073   const HttpResponseInfo* response = trans->GetResponseInfo();
   9074   ASSERT_TRUE(response != NULL);
   9075   ASSERT_TRUE(response->headers.get() != NULL);
   9076   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9077 
   9078   std::string response_data;
   9079   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9080   EXPECT_EQ("hello world", response_data);
   9081 
   9082   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9083 
   9084   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9085   EXPECT_EQ(ERR_IO_PENDING, rv);
   9086   EXPECT_EQ(OK, callback.WaitForResult());
   9087 
   9088   response = trans->GetResponseInfo();
   9089   ASSERT_TRUE(response != NULL);
   9090   ASSERT_TRUE(response->headers.get() != NULL);
   9091   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9092   EXPECT_FALSE(response->was_fetched_via_spdy);
   9093   EXPECT_FALSE(response->was_npn_negotiated);
   9094 
   9095   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9096   EXPECT_EQ("hello world", response_data);
   9097 }
   9098 
   9099 class CapturingProxyResolver : public ProxyResolver {
   9100  public:
   9101   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
   9102   virtual ~CapturingProxyResolver() {}
   9103 
   9104   virtual int GetProxyForURL(const GURL& url,
   9105                              ProxyInfo* results,
   9106                              const CompletionCallback& callback,
   9107                              RequestHandle* request,
   9108                              const BoundNetLog& net_log) OVERRIDE {
   9109     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
   9110                              HostPortPair("myproxy", 80));
   9111     results->UseProxyServer(proxy_server);
   9112     resolved_.push_back(url);
   9113     return OK;
   9114   }
   9115 
   9116   virtual void CancelRequest(RequestHandle request) OVERRIDE {
   9117     NOTREACHED();
   9118   }
   9119 
   9120   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
   9121     NOTREACHED();
   9122     return LOAD_STATE_IDLE;
   9123   }
   9124 
   9125   virtual void CancelSetPacScript() OVERRIDE {
   9126     NOTREACHED();
   9127   }
   9128 
   9129   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
   9130                            const CompletionCallback& /*callback*/) OVERRIDE {
   9131     return OK;
   9132   }
   9133 
   9134   const std::vector<GURL>& resolved() const { return resolved_; }
   9135 
   9136  private:
   9137   std::vector<GURL> resolved_;
   9138 
   9139   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
   9140 };
   9141 
   9142 TEST_P(HttpNetworkTransactionTest,
   9143        UseAlternateProtocolForTunneledNpnSpdy) {
   9144   session_deps_.use_alternate_protocols = true;
   9145   session_deps_.next_protos = SpdyNextProtos();
   9146 
   9147   ProxyConfig proxy_config;
   9148   proxy_config.set_auto_detect(true);
   9149   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
   9150 
   9151   CapturingProxyResolver* capturing_proxy_resolver =
   9152       new CapturingProxyResolver();
   9153   session_deps_.proxy_service.reset(new ProxyService(
   9154       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   9155       NULL));
   9156   CapturingNetLog net_log;
   9157   session_deps_.net_log = &net_log;
   9158 
   9159   HttpRequestInfo request;
   9160   request.method = "GET";
   9161   request.url = GURL("http://www.google.com/");
   9162   request.load_flags = 0;
   9163 
   9164   std::string alternate_protocol_http_header =
   9165       GetAlternateProtocolHttpHeader();
   9166 
   9167   MockRead data_reads[] = {
   9168     MockRead("HTTP/1.1 200 OK\r\n"),
   9169     MockRead(alternate_protocol_http_header.c_str()),
   9170     MockRead("hello world"),
   9171     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9172     MockRead(ASYNC, OK),
   9173   };
   9174 
   9175   StaticSocketDataProvider first_transaction(
   9176       data_reads, arraysize(data_reads), NULL, 0);
   9177   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   9178 
   9179   SSLSocketDataProvider ssl(ASYNC, OK);
   9180   ssl.SetNextProto(GetParam());
   9181   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9182 
   9183   scoped_ptr<SpdyFrame> req(
   9184       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9185   MockWrite spdy_writes[] = {
   9186     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9187               "Host: www.google.com\r\n"
   9188               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
   9189     CreateMockWrite(*req),                              // 3
   9190   };
   9191 
   9192   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   9193 
   9194   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   9195   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   9196   MockRead spdy_reads[] = {
   9197     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
   9198     CreateMockRead(*resp.get(), 4),  // 2, 4
   9199     CreateMockRead(*data.get(), 4),  // 5
   9200     MockRead(ASYNC, 0, 0, 4),  // 6
   9201   };
   9202 
   9203   OrderedSocketData spdy_data(
   9204       spdy_reads, arraysize(spdy_reads),
   9205       spdy_writes, arraysize(spdy_writes));
   9206   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   9207 
   9208   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   9209   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   9210       NULL, 0, NULL, 0);
   9211   hanging_non_alternate_protocol_socket.set_connect_data(
   9212       never_finishing_connect);
   9213   session_deps_.socket_factory->AddSocketDataProvider(
   9214       &hanging_non_alternate_protocol_socket);
   9215 
   9216   TestCompletionCallback callback;
   9217 
   9218   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9219   scoped_ptr<HttpTransaction> trans(
   9220       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9221 
   9222   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9223   EXPECT_EQ(ERR_IO_PENDING, rv);
   9224   EXPECT_EQ(OK, callback.WaitForResult());
   9225 
   9226   const HttpResponseInfo* response = trans->GetResponseInfo();
   9227   ASSERT_TRUE(response != NULL);
   9228   ASSERT_TRUE(response->headers.get() != NULL);
   9229   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9230   EXPECT_FALSE(response->was_fetched_via_spdy);
   9231   EXPECT_FALSE(response->was_npn_negotiated);
   9232 
   9233   std::string response_data;
   9234   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9235   EXPECT_EQ("hello world", response_data);
   9236 
   9237   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9238 
   9239   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9240   EXPECT_EQ(ERR_IO_PENDING, rv);
   9241   EXPECT_EQ(OK, callback.WaitForResult());
   9242 
   9243   response = trans->GetResponseInfo();
   9244   ASSERT_TRUE(response != NULL);
   9245   ASSERT_TRUE(response->headers.get() != NULL);
   9246   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9247   EXPECT_TRUE(response->was_fetched_via_spdy);
   9248   EXPECT_TRUE(response->was_npn_negotiated);
   9249 
   9250   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9251   EXPECT_EQ("hello!", response_data);
   9252   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
   9253   EXPECT_EQ("http://www.google.com/",
   9254             capturing_proxy_resolver->resolved()[0].spec());
   9255   EXPECT_EQ("https://www.google.com/",
   9256             capturing_proxy_resolver->resolved()[1].spec());
   9257 
   9258   LoadTimingInfo load_timing_info;
   9259   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   9260   TestLoadTimingNotReusedWithPac(load_timing_info,
   9261                                  CONNECT_TIMING_HAS_SSL_TIMES);
   9262 }
   9263 
   9264 TEST_P(HttpNetworkTransactionTest,
   9265        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
   9266   session_deps_.use_alternate_protocols = true;
   9267   session_deps_.next_protos = SpdyNextProtos();
   9268 
   9269   HttpRequestInfo request;
   9270   request.method = "GET";
   9271   request.url = GURL("http://www.google.com/");
   9272   request.load_flags = 0;
   9273 
   9274   std::string alternate_protocol_http_header =
   9275       GetAlternateProtocolHttpHeader();
   9276 
   9277   MockRead data_reads[] = {
   9278     MockRead("HTTP/1.1 200 OK\r\n"),
   9279     MockRead(alternate_protocol_http_header.c_str()),
   9280     MockRead("hello world"),
   9281     MockRead(ASYNC, OK),
   9282   };
   9283 
   9284   StaticSocketDataProvider first_transaction(
   9285       data_reads, arraysize(data_reads), NULL, 0);
   9286   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   9287 
   9288   SSLSocketDataProvider ssl(ASYNC, OK);
   9289   ssl.SetNextProto(GetParam());
   9290   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9291 
   9292   scoped_ptr<SpdyFrame> req(
   9293       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9294   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   9295 
   9296   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   9297   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   9298   MockRead spdy_reads[] = {
   9299     CreateMockRead(*resp),
   9300     CreateMockRead(*data),
   9301     MockRead(ASYNC, 0, 0),
   9302   };
   9303 
   9304   DelayedSocketData spdy_data(
   9305       1,  // wait for one write to finish before reading.
   9306       spdy_reads, arraysize(spdy_reads),
   9307       spdy_writes, arraysize(spdy_writes));
   9308   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   9309 
   9310   TestCompletionCallback callback;
   9311 
   9312   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9313 
   9314   scoped_ptr<HttpTransaction> trans(
   9315       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9316 
   9317   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9318   EXPECT_EQ(ERR_IO_PENDING, rv);
   9319   EXPECT_EQ(OK, callback.WaitForResult());
   9320 
   9321   const HttpResponseInfo* response = trans->GetResponseInfo();
   9322   ASSERT_TRUE(response != NULL);
   9323   ASSERT_TRUE(response->headers.get() != NULL);
   9324   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9325 
   9326   std::string response_data;
   9327   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9328   EXPECT_EQ("hello world", response_data);
   9329 
   9330   // Set up an initial SpdySession in the pool to reuse.
   9331   HostPortPair host_port_pair("www.google.com", 443);
   9332   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   9333                      PRIVACY_MODE_DISABLED);
   9334   base::WeakPtr<SpdySession> spdy_session =
   9335       CreateSecureSpdySession(session, key, BoundNetLog());
   9336 
   9337   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9338 
   9339   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9340   EXPECT_EQ(ERR_IO_PENDING, rv);
   9341   EXPECT_EQ(OK, callback.WaitForResult());
   9342 
   9343   response = trans->GetResponseInfo();
   9344   ASSERT_TRUE(response != NULL);
   9345   ASSERT_TRUE(response->headers.get() != NULL);
   9346   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9347   EXPECT_TRUE(response->was_fetched_via_spdy);
   9348   EXPECT_TRUE(response->was_npn_negotiated);
   9349 
   9350   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9351   EXPECT_EQ("hello!", response_data);
   9352 }
   9353 
   9354 // GenerateAuthToken is a mighty big test.
   9355 // It tests all permutation of GenerateAuthToken behavior:
   9356 //   - Synchronous and Asynchronous completion.
   9357 //   - OK or error on completion.
   9358 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
   9359 //   - HTTP or HTTPS backend (to include proxy tunneling).
   9360 //   - Non-authenticating and authenticating backend.
   9361 //
   9362 // In all, there are 44 reasonable permuations (for example, if there are
   9363 // problems generating an auth token for an authenticating proxy, we don't
   9364 // need to test all permutations of the backend server).
   9365 //
   9366 // The test proceeds by going over each of the configuration cases, and
   9367 // potentially running up to three rounds in each of the tests. The TestConfig
   9368 // specifies both the configuration for the test as well as the expectations
   9369 // for the results.
   9370 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
   9371   static const char kServer[] = "http://www.example.com";
   9372   static const char kSecureServer[] = "https://www.example.com";
   9373   static const char kProxy[] = "myproxy:70";
   9374   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
   9375 
   9376   enum AuthTiming {
   9377     AUTH_NONE,
   9378     AUTH_SYNC,
   9379     AUTH_ASYNC,
   9380   };
   9381 
   9382   const MockWrite kGet(
   9383       "GET / HTTP/1.1\r\n"
   9384       "Host: www.example.com\r\n"
   9385       "Connection: keep-alive\r\n\r\n");
   9386   const MockWrite kGetProxy(
   9387       "GET http://www.example.com/ HTTP/1.1\r\n"
   9388       "Host: www.example.com\r\n"
   9389       "Proxy-Connection: keep-alive\r\n\r\n");
   9390   const MockWrite kGetAuth(
   9391       "GET / HTTP/1.1\r\n"
   9392       "Host: www.example.com\r\n"
   9393       "Connection: keep-alive\r\n"
   9394       "Authorization: auth_token\r\n\r\n");
   9395   const MockWrite kGetProxyAuth(
   9396       "GET http://www.example.com/ HTTP/1.1\r\n"
   9397       "Host: www.example.com\r\n"
   9398       "Proxy-Connection: keep-alive\r\n"
   9399       "Proxy-Authorization: auth_token\r\n\r\n");
   9400   const MockWrite kGetAuthThroughProxy(
   9401       "GET http://www.example.com/ HTTP/1.1\r\n"
   9402       "Host: www.example.com\r\n"
   9403       "Proxy-Connection: keep-alive\r\n"
   9404       "Authorization: auth_token\r\n\r\n");
   9405   const MockWrite kGetAuthWithProxyAuth(
   9406       "GET http://www.example.com/ HTTP/1.1\r\n"
   9407       "Host: www.example.com\r\n"
   9408       "Proxy-Connection: keep-alive\r\n"
   9409       "Proxy-Authorization: auth_token\r\n"
   9410       "Authorization: auth_token\r\n\r\n");
   9411   const MockWrite kConnect(
   9412       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   9413       "Host: www.example.com\r\n"
   9414       "Proxy-Connection: keep-alive\r\n\r\n");
   9415   const MockWrite kConnectProxyAuth(
   9416       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   9417       "Host: www.example.com\r\n"
   9418       "Proxy-Connection: keep-alive\r\n"
   9419       "Proxy-Authorization: auth_token\r\n\r\n");
   9420 
   9421   const MockRead kSuccess(
   9422       "HTTP/1.1 200 OK\r\n"
   9423       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9424       "Content-Length: 3\r\n\r\n"
   9425       "Yes");
   9426   const MockRead kFailure(
   9427       "Should not be called.");
   9428   const MockRead kServerChallenge(
   9429       "HTTP/1.1 401 Unauthorized\r\n"
   9430       "WWW-Authenticate: Mock realm=server\r\n"
   9431       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9432       "Content-Length: 14\r\n\r\n"
   9433       "Unauthorized\r\n");
   9434   const MockRead kProxyChallenge(
   9435       "HTTP/1.1 407 Unauthorized\r\n"
   9436       "Proxy-Authenticate: Mock realm=proxy\r\n"
   9437       "Proxy-Connection: close\r\n"
   9438       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9439       "Content-Length: 14\r\n\r\n"
   9440       "Unauthorized\r\n");
   9441   const MockRead kProxyConnected(
   9442       "HTTP/1.1 200 Connection Established\r\n\r\n");
   9443 
   9444   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
   9445   // no constructors, but the C++ compiler on Windows warns about
   9446   // unspecified data in compound literals. So, moved to using constructors,
   9447   // and TestRound's created with the default constructor should not be used.
   9448   struct TestRound {
   9449     TestRound()
   9450         : expected_rv(ERR_UNEXPECTED),
   9451           extra_write(NULL),
   9452           extra_read(NULL) {
   9453     }
   9454     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   9455               int expected_rv_arg)
   9456         : write(write_arg),
   9457           read(read_arg),
   9458           expected_rv(expected_rv_arg),
   9459           extra_write(NULL),
   9460           extra_read(NULL) {
   9461     }
   9462     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   9463               int expected_rv_arg, const MockWrite* extra_write_arg,
   9464               const MockRead* extra_read_arg)
   9465         : write(write_arg),
   9466           read(read_arg),
   9467           expected_rv(expected_rv_arg),
   9468           extra_write(extra_write_arg),
   9469           extra_read(extra_read_arg) {
   9470     }
   9471     MockWrite write;
   9472     MockRead read;
   9473     int expected_rv;
   9474     const MockWrite* extra_write;
   9475     const MockRead* extra_read;
   9476   };
   9477 
   9478   static const int kNoSSL = 500;
   9479 
   9480   struct TestConfig {
   9481     const char* proxy_url;
   9482     AuthTiming proxy_auth_timing;
   9483     int proxy_auth_rv;
   9484     const char* server_url;
   9485     AuthTiming server_auth_timing;
   9486     int server_auth_rv;
   9487     int num_auth_rounds;
   9488     int first_ssl_round;
   9489     TestRound rounds[3];
   9490   } test_configs[] = {
   9491     // Non-authenticating HTTP server with a direct connection.
   9492     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   9493       { TestRound(kGet, kSuccess, OK)}},
   9494     // Authenticating HTTP server with a direct connection.
   9495     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9496       { TestRound(kGet, kServerChallenge, OK),
   9497         TestRound(kGetAuth, kSuccess, OK)}},
   9498     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9499       { TestRound(kGet, kServerChallenge, OK),
   9500         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9501     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9502       { TestRound(kGet, kServerChallenge, OK),
   9503         TestRound(kGetAuth, kSuccess, OK)}},
   9504     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9505       { TestRound(kGet, kServerChallenge, OK),
   9506         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9507     // Non-authenticating HTTP server through a non-authenticating proxy.
   9508     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   9509       { TestRound(kGetProxy, kSuccess, OK)}},
   9510     // Authenticating HTTP server through a non-authenticating proxy.
   9511     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9512       { TestRound(kGetProxy, kServerChallenge, OK),
   9513         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9514     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9515       { TestRound(kGetProxy, kServerChallenge, OK),
   9516         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9517     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9518       { TestRound(kGetProxy, kServerChallenge, OK),
   9519         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9520     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9521       { TestRound(kGetProxy, kServerChallenge, OK),
   9522         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9523     // Non-authenticating HTTP server through an authenticating proxy.
   9524     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9525       { TestRound(kGetProxy, kProxyChallenge, OK),
   9526         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9527     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9528       { TestRound(kGetProxy, kProxyChallenge, OK),
   9529         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9530     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9531       { TestRound(kGetProxy, kProxyChallenge, OK),
   9532         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9533     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9534       { TestRound(kGetProxy, kProxyChallenge, OK),
   9535         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9536     // Authenticating HTTP server through an authenticating proxy.
   9537     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9538       { TestRound(kGetProxy, kProxyChallenge, OK),
   9539         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9540         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9541     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9542       { TestRound(kGetProxy, kProxyChallenge, OK),
   9543         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9544         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9545     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9546       { TestRound(kGetProxy, kProxyChallenge, OK),
   9547         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9548         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9549     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9550       { TestRound(kGetProxy, kProxyChallenge, OK),
   9551         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9552         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9553     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9554       { TestRound(kGetProxy, kProxyChallenge, OK),
   9555         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9556         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9557     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9558       { TestRound(kGetProxy, kProxyChallenge, OK),
   9559         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9560         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9561     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9562       { TestRound(kGetProxy, kProxyChallenge, OK),
   9563         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9564         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9565     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9566       { TestRound(kGetProxy, kProxyChallenge, OK),
   9567         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9568         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9569     // Non-authenticating HTTPS server with a direct connection.
   9570     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9571       { TestRound(kGet, kSuccess, OK)}},
   9572     // Authenticating HTTPS server with a direct connection.
   9573     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9574       { TestRound(kGet, kServerChallenge, OK),
   9575         TestRound(kGetAuth, kSuccess, OK)}},
   9576     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9577       { TestRound(kGet, kServerChallenge, OK),
   9578         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9579     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9580       { TestRound(kGet, kServerChallenge, OK),
   9581         TestRound(kGetAuth, kSuccess, OK)}},
   9582     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9583       { TestRound(kGet, kServerChallenge, OK),
   9584         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9585     // Non-authenticating HTTPS server with a non-authenticating proxy.
   9586     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9587       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
   9588     // Authenticating HTTPS server through a non-authenticating proxy.
   9589     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9590       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9591         TestRound(kGetAuth, kSuccess, OK)}},
   9592     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9593       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9594         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9595     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9596       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9597         TestRound(kGetAuth, kSuccess, OK)}},
   9598     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9599       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9600         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9601     // Non-Authenticating HTTPS server through an authenticating proxy.
   9602     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9603       { TestRound(kConnect, kProxyChallenge, OK),
   9604         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9605     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9606       { TestRound(kConnect, kProxyChallenge, OK),
   9607         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9608     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9609       { TestRound(kConnect, kProxyChallenge, OK),
   9610         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9611     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9612       { TestRound(kConnect, kProxyChallenge, OK),
   9613         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9614     // Authenticating HTTPS server through an authenticating proxy.
   9615     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9616       { TestRound(kConnect, kProxyChallenge, OK),
   9617         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9618                   &kGet, &kServerChallenge),
   9619         TestRound(kGetAuth, kSuccess, OK)}},
   9620     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9621       { TestRound(kConnect, kProxyChallenge, OK),
   9622         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9623                   &kGet, &kServerChallenge),
   9624         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9625     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9626       { TestRound(kConnect, kProxyChallenge, OK),
   9627         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9628                   &kGet, &kServerChallenge),
   9629         TestRound(kGetAuth, kSuccess, OK)}},
   9630     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9631       { TestRound(kConnect, kProxyChallenge, OK),
   9632         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9633                   &kGet, &kServerChallenge),
   9634         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9635     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9636       { TestRound(kConnect, kProxyChallenge, OK),
   9637         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9638                   &kGet, &kServerChallenge),
   9639         TestRound(kGetAuth, kSuccess, OK)}},
   9640     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9641       { TestRound(kConnect, kProxyChallenge, OK),
   9642         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9643                   &kGet, &kServerChallenge),
   9644         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9645     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9646       { TestRound(kConnect, kProxyChallenge, OK),
   9647         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9648                   &kGet, &kServerChallenge),
   9649         TestRound(kGetAuth, kSuccess, OK)}},
   9650     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9651       { TestRound(kConnect, kProxyChallenge, OK),
   9652         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9653                   &kGet, &kServerChallenge),
   9654         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9655   };
   9656 
   9657   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
   9658     HttpAuthHandlerMock::Factory* auth_factory(
   9659         new HttpAuthHandlerMock::Factory());
   9660     session_deps_.http_auth_handler_factory.reset(auth_factory);
   9661     const TestConfig& test_config = test_configs[i];
   9662 
   9663     // Set up authentication handlers as necessary.
   9664     if (test_config.proxy_auth_timing != AUTH_NONE) {
   9665       for (int n = 0; n < 2; n++) {
   9666         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9667         std::string auth_challenge = "Mock realm=proxy";
   9668         GURL origin(test_config.proxy_url);
   9669         HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
   9670                                              auth_challenge.end());
   9671         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
   9672                                         origin, BoundNetLog());
   9673         auth_handler->SetGenerateExpectation(
   9674             test_config.proxy_auth_timing == AUTH_ASYNC,
   9675             test_config.proxy_auth_rv);
   9676         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   9677       }
   9678     }
   9679     if (test_config.server_auth_timing != AUTH_NONE) {
   9680       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9681       std::string auth_challenge = "Mock realm=server";
   9682       GURL origin(test_config.server_url);
   9683       HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
   9684                                            auth_challenge.end());
   9685       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9686                                       origin, BoundNetLog());
   9687       auth_handler->SetGenerateExpectation(
   9688           test_config.server_auth_timing == AUTH_ASYNC,
   9689           test_config.server_auth_rv);
   9690       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9691     }
   9692     if (test_config.proxy_url) {
   9693       session_deps_.proxy_service.reset(
   9694           ProxyService::CreateFixed(test_config.proxy_url));
   9695     } else {
   9696       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9697     }
   9698 
   9699     HttpRequestInfo request;
   9700     request.method = "GET";
   9701     request.url = GURL(test_config.server_url);
   9702     request.load_flags = 0;
   9703 
   9704     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9705     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
   9706 
   9707     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
   9708       const TestRound& read_write_round = test_config.rounds[round];
   9709 
   9710       // Set up expected reads and writes.
   9711       MockRead reads[2];
   9712       reads[0] = read_write_round.read;
   9713       size_t length_reads = 1;
   9714       if (read_write_round.extra_read) {
   9715         reads[1] = *read_write_round.extra_read;
   9716         length_reads = 2;
   9717       }
   9718 
   9719       MockWrite writes[2];
   9720       writes[0] = read_write_round.write;
   9721       size_t length_writes = 1;
   9722       if (read_write_round.extra_write) {
   9723         writes[1] = *read_write_round.extra_write;
   9724         length_writes = 2;
   9725       }
   9726       StaticSocketDataProvider data_provider(
   9727           reads, length_reads, writes, length_writes);
   9728       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9729 
   9730       // Add an SSL sequence if necessary.
   9731       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
   9732       if (round >= test_config.first_ssl_round)
   9733         session_deps_.socket_factory->AddSSLSocketDataProvider(
   9734             &ssl_socket_data_provider);
   9735 
   9736       // Start or restart the transaction.
   9737       TestCompletionCallback callback;
   9738       int rv;
   9739       if (round == 0) {
   9740         rv = trans.Start(&request, callback.callback(), BoundNetLog());
   9741       } else {
   9742         rv = trans.RestartWithAuth(
   9743             AuthCredentials(kFoo, kBar), callback.callback());
   9744       }
   9745       if (rv == ERR_IO_PENDING)
   9746         rv = callback.WaitForResult();
   9747 
   9748       // Compare results with expected data.
   9749       EXPECT_EQ(read_write_round.expected_rv, rv);
   9750       const HttpResponseInfo* response = trans.GetResponseInfo();
   9751       if (read_write_round.expected_rv == OK) {
   9752         ASSERT_TRUE(response != NULL);
   9753       } else {
   9754         EXPECT_TRUE(response == NULL);
   9755         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
   9756         continue;
   9757       }
   9758       if (round + 1 < test_config.num_auth_rounds) {
   9759         EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9760       } else {
   9761         EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9762       }
   9763     }
   9764   }
   9765 }
   9766 
   9767 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
   9768   // Do multi-round authentication and make sure it works correctly.
   9769   HttpAuthHandlerMock::Factory* auth_factory(
   9770       new HttpAuthHandlerMock::Factory());
   9771   session_deps_.http_auth_handler_factory.reset(auth_factory);
   9772   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9773   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
   9774   session_deps_.host_resolver->set_synchronous_mode(true);
   9775 
   9776   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9777   auth_handler->set_connection_based(true);
   9778   std::string auth_challenge = "Mock realm=server";
   9779   GURL origin("http://www.example.com");
   9780   HttpAuthChallengeTokenizer tokenizer(auth_challenge.begin(),
   9781                                        auth_challenge.end());
   9782   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9783                                   origin, BoundNetLog());
   9784   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9785 
   9786   int rv = OK;
   9787   const HttpResponseInfo* response = NULL;
   9788   HttpRequestInfo request;
   9789   request.method = "GET";
   9790   request.url = origin;
   9791   request.load_flags = 0;
   9792 
   9793   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9794 
   9795   // Use a TCP Socket Pool with only one connection per group. This is used
   9796   // to validate that the TCP socket is not released to the pool between
   9797   // each round of multi-round authentication.
   9798   HttpNetworkSessionPeer session_peer(session);
   9799   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
   9800   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
   9801       50,  // Max sockets for pool
   9802       1,   // Max sockets per group
   9803       &transport_pool_histograms,
   9804       session_deps_.host_resolver.get(),
   9805       session_deps_.socket_factory.get(),
   9806       session_deps_.net_log);
   9807   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   9808       new MockClientSocketPoolManager);
   9809   mock_pool_manager->SetTransportSocketPool(transport_pool);
   9810   session_peer.SetClientSocketPoolManager(
   9811       mock_pool_manager.PassAs<ClientSocketPoolManager>());
   9812 
   9813   scoped_ptr<HttpTransaction> trans(
   9814       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9815   TestCompletionCallback callback;
   9816 
   9817   const MockWrite kGet(
   9818       "GET / HTTP/1.1\r\n"
   9819       "Host: www.example.com\r\n"
   9820       "Connection: keep-alive\r\n\r\n");
   9821   const MockWrite kGetAuth(
   9822       "GET / HTTP/1.1\r\n"
   9823       "Host: www.example.com\r\n"
   9824       "Connection: keep-alive\r\n"
   9825       "Authorization: auth_token\r\n\r\n");
   9826 
   9827   const MockRead kServerChallenge(
   9828       "HTTP/1.1 401 Unauthorized\r\n"
   9829       "WWW-Authenticate: Mock realm=server\r\n"
   9830       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9831       "Content-Length: 14\r\n\r\n"
   9832       "Unauthorized\r\n");
   9833   const MockRead kSuccess(
   9834       "HTTP/1.1 200 OK\r\n"
   9835       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9836       "Content-Length: 3\r\n\r\n"
   9837       "Yes");
   9838 
   9839   MockWrite writes[] = {
   9840     // First round
   9841     kGet,
   9842     // Second round
   9843     kGetAuth,
   9844     // Third round
   9845     kGetAuth,
   9846     // Fourth round
   9847     kGetAuth,
   9848     // Competing request
   9849     kGet,
   9850   };
   9851   MockRead reads[] = {
   9852     // First round
   9853     kServerChallenge,
   9854     // Second round
   9855     kServerChallenge,
   9856     // Third round
   9857     kServerChallenge,
   9858     // Fourth round
   9859     kSuccess,
   9860     // Competing response
   9861     kSuccess,
   9862   };
   9863   StaticSocketDataProvider data_provider(reads, arraysize(reads),
   9864                                          writes, arraysize(writes));
   9865   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9866 
   9867   const char* const kSocketGroup = "www.example.com:80";
   9868 
   9869   // First round of authentication.
   9870   auth_handler->SetGenerateExpectation(false, OK);
   9871   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9872   if (rv == ERR_IO_PENDING)
   9873     rv = callback.WaitForResult();
   9874   EXPECT_EQ(OK, rv);
   9875   response = trans->GetResponseInfo();
   9876   ASSERT_TRUE(response != NULL);
   9877   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9878   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9879 
   9880   // In between rounds, another request comes in for the same domain.
   9881   // It should not be able to grab the TCP socket that trans has already
   9882   // claimed.
   9883   scoped_ptr<HttpTransaction> trans_compete(
   9884       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9885   TestCompletionCallback callback_compete;
   9886   rv = trans_compete->Start(
   9887       &request, callback_compete.callback(), BoundNetLog());
   9888   EXPECT_EQ(ERR_IO_PENDING, rv);
   9889   // callback_compete.WaitForResult at this point would stall forever,
   9890   // since the HttpNetworkTransaction does not release the request back to
   9891   // the pool until after authentication completes.
   9892 
   9893   // Second round of authentication.
   9894   auth_handler->SetGenerateExpectation(false, OK);
   9895   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
   9896   if (rv == ERR_IO_PENDING)
   9897     rv = callback.WaitForResult();
   9898   EXPECT_EQ(OK, rv);
   9899   response = trans->GetResponseInfo();
   9900   ASSERT_TRUE(response != NULL);
   9901   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9902   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9903 
   9904   // Third round of authentication.
   9905   auth_handler->SetGenerateExpectation(false, OK);
   9906   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9907   if (rv == ERR_IO_PENDING)
   9908     rv = callback.WaitForResult();
   9909   EXPECT_EQ(OK, rv);
   9910   response = trans->GetResponseInfo();
   9911   ASSERT_TRUE(response != NULL);
   9912   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9913   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9914 
   9915   // Fourth round of authentication, which completes successfully.
   9916   auth_handler->SetGenerateExpectation(false, OK);
   9917   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9918   if (rv == ERR_IO_PENDING)
   9919     rv = callback.WaitForResult();
   9920   EXPECT_EQ(OK, rv);
   9921   response = trans->GetResponseInfo();
   9922   ASSERT_TRUE(response != NULL);
   9923   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9924   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9925 
   9926   // Read the body since the fourth round was successful. This will also
   9927   // release the socket back to the pool.
   9928   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
   9929   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9930   if (rv == ERR_IO_PENDING)
   9931     rv = callback.WaitForResult();
   9932   EXPECT_EQ(3, rv);
   9933   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9934   EXPECT_EQ(0, rv);
   9935   // There are still 0 idle sockets, since the trans_compete transaction
   9936   // will be handed it immediately after trans releases it to the group.
   9937   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9938 
   9939   // The competing request can now finish. Wait for the headers and then
   9940   // read the body.
   9941   rv = callback_compete.WaitForResult();
   9942   EXPECT_EQ(OK, rv);
   9943   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9944   if (rv == ERR_IO_PENDING)
   9945     rv = callback.WaitForResult();
   9946   EXPECT_EQ(3, rv);
   9947   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9948   EXPECT_EQ(0, rv);
   9949 
   9950   // Finally, the socket is released to the group.
   9951   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9952 }
   9953 
   9954 // This tests the case that a request is issued via http instead of spdy after
   9955 // npn is negotiated.
   9956 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
   9957   session_deps_.use_alternate_protocols = true;
   9958   NextProtoVector next_protos;
   9959   next_protos.push_back(kProtoHTTP11);
   9960   session_deps_.next_protos = next_protos;
   9961 
   9962   HttpRequestInfo request;
   9963   request.method = "GET";
   9964   request.url = GURL("https://www.google.com/");
   9965   request.load_flags = 0;
   9966 
   9967   MockWrite data_writes[] = {
   9968     MockWrite("GET / HTTP/1.1\r\n"
   9969               "Host: www.google.com\r\n"
   9970               "Connection: keep-alive\r\n\r\n"),
   9971   };
   9972 
   9973   std::string alternate_protocol_http_header =
   9974       GetAlternateProtocolHttpHeader();
   9975 
   9976   MockRead data_reads[] = {
   9977     MockRead("HTTP/1.1 200 OK\r\n"),
   9978     MockRead(alternate_protocol_http_header.c_str()),
   9979     MockRead("hello world"),
   9980     MockRead(SYNCHRONOUS, OK),
   9981   };
   9982 
   9983   SSLSocketDataProvider ssl(ASYNC, OK);
   9984   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   9985   ssl.next_proto = "http/1.1";
   9986   ssl.protocol_negotiated = kProtoHTTP11;
   9987 
   9988   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9989 
   9990   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   9991                                 data_writes, arraysize(data_writes));
   9992   session_deps_.socket_factory->AddSocketDataProvider(&data);
   9993 
   9994   TestCompletionCallback callback;
   9995 
   9996   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9997   scoped_ptr<HttpTransaction> trans(
   9998       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9999 
   10000   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   10001 
   10002   EXPECT_EQ(ERR_IO_PENDING, rv);
   10003   EXPECT_EQ(OK, callback.WaitForResult());
   10004 
   10005   const HttpResponseInfo* response = trans->GetResponseInfo();
   10006   ASSERT_TRUE(response != NULL);
   10007   ASSERT_TRUE(response->headers.get() != NULL);
   10008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10009 
   10010   std::string response_data;
   10011   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   10012   EXPECT_EQ("hello world", response_data);
   10013 
   10014   EXPECT_FALSE(response->was_fetched_via_spdy);
   10015   EXPECT_TRUE(response->was_npn_negotiated);
   10016 }
   10017 
   10018 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
   10019   // Simulate the SSL handshake completing with an NPN negotiation
   10020   // followed by an immediate server closing of the socket.
   10021   // Fix crash:  http://crbug.com/46369
   10022   session_deps_.use_alternate_protocols = true;
   10023   session_deps_.next_protos = SpdyNextProtos();
   10024 
   10025   HttpRequestInfo request;
   10026   request.method = "GET";
   10027   request.url = GURL("https://www.google.com/");
   10028   request.load_flags = 0;
   10029 
   10030   SSLSocketDataProvider ssl(ASYNC, OK);
   10031   ssl.SetNextProto(GetParam());
   10032   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10033 
   10034   scoped_ptr<SpdyFrame> req(
   10035       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   10036   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   10037 
   10038   MockRead spdy_reads[] = {
   10039     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
   10040   };
   10041 
   10042   DelayedSocketData spdy_data(
   10043       0,  // don't wait in this case, immediate hangup.
   10044       spdy_reads, arraysize(spdy_reads),
   10045       spdy_writes, arraysize(spdy_writes));
   10046   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10047 
   10048   TestCompletionCallback callback;
   10049 
   10050   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10051   scoped_ptr<HttpTransaction> trans(
   10052       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10053 
   10054   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   10055   EXPECT_EQ(ERR_IO_PENDING, rv);
   10056   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
   10057 }
   10058 
   10059 // A subclass of HttpAuthHandlerMock that records the request URL when
   10060 // it gets it. This is needed since the auth handler may get destroyed
   10061 // before we get a chance to query it.
   10062 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
   10063  public:
   10064   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
   10065 
   10066   virtual ~UrlRecordingHttpAuthHandlerMock() {}
   10067 
   10068  protected:
   10069   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
   10070                                     const HttpRequestInfo* request,
   10071                                     const CompletionCallback& callback,
   10072                                     std::string* auth_token) OVERRIDE {
   10073     *url_ = request->url;
   10074     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
   10075         credentials, request, callback, auth_token);
   10076   }
   10077 
   10078  private:
   10079   GURL* url_;
   10080 };
   10081 
   10082 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
   10083   // This test ensures that the URL passed into the proxy is upgraded
   10084   // to https when doing an Alternate Protocol upgrade.
   10085   session_deps_.use_alternate_protocols = true;
   10086   session_deps_.next_protos = SpdyNextProtos();
   10087 
   10088   session_deps_.proxy_service.reset(
   10089       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   10090   CapturingNetLog net_log;
   10091   session_deps_.net_log = &net_log;
   10092   GURL request_url;
   10093   {
   10094     HttpAuthHandlerMock::Factory* auth_factory =
   10095         new HttpAuthHandlerMock::Factory();
   10096     UrlRecordingHttpAuthHandlerMock* auth_handler =
   10097         new UrlRecordingHttpAuthHandlerMock(&request_url);
   10098     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   10099     auth_factory->set_do_init_from_challenge(true);
   10100     session_deps_.http_auth_handler_factory.reset(auth_factory);
   10101   }
   10102 
   10103   HttpRequestInfo request;
   10104   request.method = "GET";
   10105   request.url = GURL("http://www.google.com");
   10106   request.load_flags = 0;
   10107 
   10108   // First round goes unauthenticated through the proxy.
   10109   MockWrite data_writes_1[] = {
   10110     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   10111               "Host: www.google.com\r\n"
   10112               "Proxy-Connection: keep-alive\r\n"
   10113               "\r\n"),
   10114   };
   10115   MockRead data_reads_1[] = {
   10116     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   10117     MockRead("HTTP/1.1 200 OK\r\n"
   10118              "Alternate-Protocol: 443:npn-spdy/2\r\n"
   10119              "Proxy-Connection: close\r\n"
   10120              "\r\n"),
   10121   };
   10122   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
   10123                                   data_writes_1, arraysize(data_writes_1));
   10124 
   10125   // Second round tries to tunnel to www.google.com due to the
   10126   // Alternate-Protocol announcement in the first round. It fails due
   10127   // to a proxy authentication challenge.
   10128   // After the failure, a tunnel is established to www.google.com using
   10129   // Proxy-Authorization headers. There is then a SPDY request round.
   10130   //
   10131   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
   10132   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
   10133   // does a Disconnect and Connect on the same socket, rather than trying
   10134   // to obtain a new one.
   10135   //
   10136   // NOTE: Originally, the proxy response to the second CONNECT request
   10137   // simply returned another 407 so the unit test could skip the SSL connection
   10138   // establishment and SPDY framing issues. Alas, the
   10139   // retry-http-when-alternate-protocol fails logic kicks in, which was more
   10140   // complicated to set up expectations for than the SPDY session.
   10141 
   10142   scoped_ptr<SpdyFrame> req(
   10143       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   10144   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10145   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10146 
   10147   MockWrite data_writes_2[] = {
   10148     // First connection attempt without Proxy-Authorization.
   10149     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   10150               "Host: www.google.com\r\n"
   10151               "Proxy-Connection: keep-alive\r\n"
   10152               "\r\n"),
   10153 
   10154     // Second connection attempt with Proxy-Authorization.
   10155     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   10156               "Host: www.google.com\r\n"
   10157               "Proxy-Connection: keep-alive\r\n"
   10158               "Proxy-Authorization: auth_token\r\n"
   10159               "\r\n"),
   10160 
   10161     // SPDY request
   10162     CreateMockWrite(*req),
   10163   };
   10164   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
   10165                                          "Proxy-Authenticate: Mock\r\n"
   10166                                          "Proxy-Connection: close\r\n"
   10167                                          "\r\n");
   10168   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   10169   MockRead data_reads_2[] = {
   10170     // First connection attempt fails
   10171     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
   10172     MockRead(ASYNC, kRejectConnectResponse,
   10173              arraysize(kRejectConnectResponse) - 1, 1),
   10174 
   10175     // Second connection attempt passes
   10176     MockRead(ASYNC, kAcceptConnectResponse,
   10177              arraysize(kAcceptConnectResponse) -1, 4),
   10178 
   10179     // SPDY response
   10180     CreateMockRead(*resp.get(), 6),
   10181     CreateMockRead(*data.get(), 6),
   10182     MockRead(ASYNC, 0, 0, 6),
   10183   };
   10184   OrderedSocketData data_2(
   10185       data_reads_2, arraysize(data_reads_2),
   10186       data_writes_2, arraysize(data_writes_2));
   10187 
   10188   SSLSocketDataProvider ssl(ASYNC, OK);
   10189   ssl.SetNextProto(GetParam());
   10190 
   10191   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   10192   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   10193       NULL, 0, NULL, 0);
   10194   hanging_non_alternate_protocol_socket.set_connect_data(
   10195       never_finishing_connect);
   10196 
   10197   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
   10198   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
   10199   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10200   session_deps_.socket_factory->AddSocketDataProvider(
   10201       &hanging_non_alternate_protocol_socket);
   10202   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10203 
   10204   // First round should work and provide the Alternate-Protocol state.
   10205   TestCompletionCallback callback_1;
   10206   scoped_ptr<HttpTransaction> trans_1(
   10207       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10208   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
   10209   EXPECT_EQ(ERR_IO_PENDING, rv);
   10210   EXPECT_EQ(OK, callback_1.WaitForResult());
   10211 
   10212   // Second round should attempt a tunnel connect and get an auth challenge.
   10213   TestCompletionCallback callback_2;
   10214   scoped_ptr<HttpTransaction> trans_2(
   10215       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10216   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
   10217   EXPECT_EQ(ERR_IO_PENDING, rv);
   10218   EXPECT_EQ(OK, callback_2.WaitForResult());
   10219   const HttpResponseInfo* response = trans_2->GetResponseInfo();
   10220   ASSERT_TRUE(response != NULL);
   10221   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   10222 
   10223   // Restart with auth. Tunnel should work and response received.
   10224   TestCompletionCallback callback_3;
   10225   rv = trans_2->RestartWithAuth(
   10226       AuthCredentials(kFoo, kBar), callback_3.callback());
   10227   EXPECT_EQ(ERR_IO_PENDING, rv);
   10228   EXPECT_EQ(OK, callback_3.WaitForResult());
   10229 
   10230   // After all that work, these two lines (or actually, just the scheme) are
   10231   // what this test is all about. Make sure it happens correctly.
   10232   EXPECT_EQ("https", request_url.scheme());
   10233   EXPECT_EQ("www.google.com", request_url.host());
   10234 
   10235   LoadTimingInfo load_timing_info;
   10236   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
   10237   TestLoadTimingNotReusedWithPac(load_timing_info,
   10238                                  CONNECT_TIMING_HAS_SSL_TIMES);
   10239 }
   10240 
   10241 // Test that if we cancel the transaction as the connection is completing, that
   10242 // everything tears down correctly.
   10243 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
   10244   // Setup everything about the connection to complete synchronously, so that
   10245   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
   10246   // for is the callback from the HttpStreamRequest.
   10247   // Then cancel the transaction.
   10248   // Verify that we don't crash.
   10249   MockConnect mock_connect(SYNCHRONOUS, OK);
   10250   MockRead data_reads[] = {
   10251     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
   10252     MockRead(SYNCHRONOUS, "hello world"),
   10253     MockRead(SYNCHRONOUS, OK),
   10254   };
   10255 
   10256   HttpRequestInfo request;
   10257   request.method = "GET";
   10258   request.url = GURL("http://www.google.com/");
   10259   request.load_flags = 0;
   10260 
   10261   session_deps_.host_resolver->set_synchronous_mode(true);
   10262   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10263   scoped_ptr<HttpTransaction> trans(
   10264       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10265 
   10266   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   10267   data.set_connect_data(mock_connect);
   10268   session_deps_.socket_factory->AddSocketDataProvider(&data);
   10269 
   10270   TestCompletionCallback callback;
   10271 
   10272   CapturingBoundNetLog log;
   10273   int rv = trans->Start(&request, callback.callback(), log.bound());
   10274   EXPECT_EQ(ERR_IO_PENDING, rv);
   10275   trans.reset();  // Cancel the transaction here.
   10276 
   10277   base::MessageLoop::current()->RunUntilIdle();
   10278 }
   10279 
   10280 // Test that if a transaction is cancelled after receiving the headers, the
   10281 // stream is drained properly and added back to the socket pool.  The main
   10282 // purpose of this test is to make sure that an HttpStreamParser can be read
   10283 // from after the HttpNetworkTransaction and the objects it owns have been
   10284 // deleted.
   10285 // See http://crbug.com/368418
   10286 TEST_P(HttpNetworkTransactionTest, CancelAfterHeaders) {
   10287   MockRead data_reads[] = {
   10288     MockRead(ASYNC, "HTTP/1.1 200 OK\r\n"),
   10289     MockRead(ASYNC, "Content-Length: 2\r\n"),
   10290     MockRead(ASYNC, "Connection: Keep-Alive\r\n\r\n"),
   10291     MockRead(ASYNC, "1"),
   10292     // 2 async reads are necessary to trigger a ReadResponseBody call after the
   10293     // HttpNetworkTransaction has been deleted.
   10294     MockRead(ASYNC, "2"),
   10295     MockRead(SYNCHRONOUS, ERR_IO_PENDING),  // Should never read this.
   10296   };
   10297   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   10298   session_deps_.socket_factory->AddSocketDataProvider(&data);
   10299 
   10300   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10301 
   10302   {
   10303     HttpRequestInfo request;
   10304     request.method = "GET";
   10305     request.url = GURL("http://www.google.com/");
   10306     request.load_flags = 0;
   10307 
   10308     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session.get());
   10309     TestCompletionCallback callback;
   10310 
   10311     int rv = trans.Start(&request, callback.callback(), BoundNetLog());
   10312     EXPECT_EQ(ERR_IO_PENDING, rv);
   10313     callback.WaitForResult();
   10314 
   10315     const HttpResponseInfo* response = trans.GetResponseInfo();
   10316     ASSERT_TRUE(response != NULL);
   10317     EXPECT_TRUE(response->headers.get() != NULL);
   10318     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10319 
   10320     // The transaction and HttpRequestInfo are deleted.
   10321   }
   10322 
   10323   // Let the HttpResponseBodyDrainer drain the socket.
   10324   base::MessageLoop::current()->RunUntilIdle();
   10325 
   10326   // Socket should now be idle, waiting to be reused.
   10327   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   10328 }
   10329 
   10330 // Test a basic GET request through a proxy.
   10331 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
   10332   session_deps_.proxy_service.reset(
   10333       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   10334   CapturingBoundNetLog log;
   10335   session_deps_.net_log = log.bound().net_log();
   10336   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10337 
   10338   HttpRequestInfo request;
   10339   request.method = "GET";
   10340   request.url = GURL("http://www.google.com/");
   10341 
   10342   MockWrite data_writes1[] = {
   10343     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   10344               "Host: www.google.com\r\n"
   10345               "Proxy-Connection: keep-alive\r\n\r\n"),
   10346   };
   10347 
   10348   MockRead data_reads1[] = {
   10349     MockRead("HTTP/1.1 200 OK\r\n"),
   10350     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   10351     MockRead("Content-Length: 100\r\n\r\n"),
   10352     MockRead(SYNCHRONOUS, OK),
   10353   };
   10354 
   10355   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   10356                                  data_writes1, arraysize(data_writes1));
   10357   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10358 
   10359   TestCompletionCallback callback1;
   10360 
   10361   scoped_ptr<HttpTransaction> trans(
   10362       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10363   BeforeProxyHeadersSentHandler proxy_headers_handler;
   10364   trans->SetBeforeProxyHeadersSentCallback(
   10365       base::Bind(&BeforeProxyHeadersSentHandler::OnBeforeProxyHeadersSent,
   10366                  base::Unretained(&proxy_headers_handler)));
   10367 
   10368   int rv = trans->Start(&request, callback1.callback(), log.bound());
   10369   EXPECT_EQ(ERR_IO_PENDING, rv);
   10370 
   10371   rv = callback1.WaitForResult();
   10372   EXPECT_EQ(OK, rv);
   10373 
   10374   const HttpResponseInfo* response = trans->GetResponseInfo();
   10375   ASSERT_TRUE(response != NULL);
   10376 
   10377   EXPECT_TRUE(response->headers->IsKeepAlive());
   10378   EXPECT_EQ(200, response->headers->response_code());
   10379   EXPECT_EQ(100, response->headers->GetContentLength());
   10380   EXPECT_TRUE(response->was_fetched_via_proxy);
   10381   EXPECT_TRUE(
   10382       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
   10383   EXPECT_TRUE(proxy_headers_handler.observed_before_proxy_headers_sent());
   10384   EXPECT_EQ("myproxy:70", proxy_headers_handler.observed_proxy_server_uri());
   10385   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   10386 
   10387   LoadTimingInfo load_timing_info;
   10388   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   10389   TestLoadTimingNotReusedWithPac(load_timing_info,
   10390                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   10391 }
   10392 
   10393 // Test a basic HTTPS GET request through a proxy.
   10394 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
   10395   session_deps_.proxy_service.reset(
   10396       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   10397   CapturingBoundNetLog log;
   10398   session_deps_.net_log = log.bound().net_log();
   10399   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10400 
   10401   HttpRequestInfo request;
   10402   request.method = "GET";
   10403   request.url = GURL("https://www.google.com/");
   10404 
   10405   // Since we have proxy, should try to establish tunnel.
   10406   MockWrite data_writes1[] = {
   10407     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   10408               "Host: www.google.com\r\n"
   10409               "Proxy-Connection: keep-alive\r\n\r\n"),
   10410 
   10411     MockWrite("GET / HTTP/1.1\r\n"
   10412               "Host: www.google.com\r\n"
   10413               "Connection: keep-alive\r\n\r\n"),
   10414   };
   10415 
   10416   MockRead data_reads1[] = {
   10417     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   10418 
   10419     MockRead("HTTP/1.1 200 OK\r\n"),
   10420     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   10421     MockRead("Content-Length: 100\r\n\r\n"),
   10422     MockRead(SYNCHRONOUS, OK),
   10423   };
   10424 
   10425   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   10426                                  data_writes1, arraysize(data_writes1));
   10427   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10428   SSLSocketDataProvider ssl(ASYNC, OK);
   10429   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10430 
   10431   TestCompletionCallback callback1;
   10432 
   10433   scoped_ptr<HttpTransaction> trans(
   10434       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10435 
   10436   int rv = trans->Start(&request, callback1.callback(), log.bound());
   10437   EXPECT_EQ(ERR_IO_PENDING, rv);
   10438 
   10439   rv = callback1.WaitForResult();
   10440   EXPECT_EQ(OK, rv);
   10441   net::CapturingNetLog::CapturedEntryList entries;
   10442   log.GetEntries(&entries);
   10443   size_t pos = ExpectLogContainsSomewhere(
   10444       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   10445       NetLog::PHASE_NONE);
   10446   ExpectLogContainsSomewhere(
   10447       entries, pos,
   10448       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   10449       NetLog::PHASE_NONE);
   10450 
   10451   const HttpResponseInfo* response = trans->GetResponseInfo();
   10452   ASSERT_TRUE(response != NULL);
   10453 
   10454   EXPECT_TRUE(response->headers->IsKeepAlive());
   10455   EXPECT_EQ(200, response->headers->response_code());
   10456   EXPECT_EQ(100, response->headers->GetContentLength());
   10457   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   10458   EXPECT_TRUE(response->was_fetched_via_proxy);
   10459   EXPECT_TRUE(
   10460       response->proxy_server.Equals(HostPortPair::FromString("myproxy:70")));
   10461 
   10462   LoadTimingInfo load_timing_info;
   10463   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   10464   TestLoadTimingNotReusedWithPac(load_timing_info,
   10465                                  CONNECT_TIMING_HAS_SSL_TIMES);
   10466 }
   10467 
   10468 // Test a basic HTTPS GET request through a proxy, but the server hangs up
   10469 // while establishing the tunnel.
   10470 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
   10471   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   10472   CapturingBoundNetLog log;
   10473   session_deps_.net_log = log.bound().net_log();
   10474   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10475 
   10476   HttpRequestInfo request;
   10477   request.method = "GET";
   10478   request.url = GURL("https://www.google.com/");
   10479 
   10480   // Since we have proxy, should try to establish tunnel.
   10481   MockWrite data_writes1[] = {
   10482     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   10483               "Host: www.google.com\r\n"
   10484               "Proxy-Connection: keep-alive\r\n\r\n"),
   10485 
   10486     MockWrite("GET / HTTP/1.1\r\n"
   10487               "Host: www.google.com\r\n"
   10488               "Connection: keep-alive\r\n\r\n"),
   10489   };
   10490 
   10491   MockRead data_reads1[] = {
   10492     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   10493     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   10494     MockRead(ASYNC, 0, 0),  // EOF
   10495   };
   10496 
   10497   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   10498                                  data_writes1, arraysize(data_writes1));
   10499   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10500   SSLSocketDataProvider ssl(ASYNC, OK);
   10501   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10502 
   10503   TestCompletionCallback callback1;
   10504 
   10505   scoped_ptr<HttpTransaction> trans(
   10506       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10507 
   10508   int rv = trans->Start(&request, callback1.callback(), log.bound());
   10509   EXPECT_EQ(ERR_IO_PENDING, rv);
   10510 
   10511   rv = callback1.WaitForResult();
   10512   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   10513   net::CapturingNetLog::CapturedEntryList entries;
   10514   log.GetEntries(&entries);
   10515   size_t pos = ExpectLogContainsSomewhere(
   10516       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   10517       NetLog::PHASE_NONE);
   10518   ExpectLogContainsSomewhere(
   10519       entries, pos,
   10520       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   10521       NetLog::PHASE_NONE);
   10522 }
   10523 
   10524 // Test for crbug.com/55424.
   10525 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
   10526   scoped_ptr<SpdyFrame> req(
   10527       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10528   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   10529 
   10530   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10531   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10532   MockRead spdy_reads[] = {
   10533     CreateMockRead(*resp),
   10534     CreateMockRead(*data),
   10535     MockRead(ASYNC, 0, 0),
   10536   };
   10537 
   10538   DelayedSocketData spdy_data(
   10539       1,  // wait for one write to finish before reading.
   10540       spdy_reads, arraysize(spdy_reads),
   10541       spdy_writes, arraysize(spdy_writes));
   10542   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10543 
   10544   SSLSocketDataProvider ssl(ASYNC, OK);
   10545   ssl.SetNextProto(GetParam());
   10546   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10547 
   10548   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10549 
   10550   // Set up an initial SpdySession in the pool to reuse.
   10551   HostPortPair host_port_pair("www.google.com", 443);
   10552   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   10553                      PRIVACY_MODE_DISABLED);
   10554   base::WeakPtr<SpdySession> spdy_session =
   10555       CreateInsecureSpdySession(session, key, BoundNetLog());
   10556 
   10557   HttpRequestInfo request;
   10558   request.method = "GET";
   10559   request.url = GURL("https://www.google.com/");
   10560   request.load_flags = 0;
   10561 
   10562   // This is the important line that marks this as a preconnect.
   10563   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
   10564 
   10565   scoped_ptr<HttpTransaction> trans(
   10566       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10567 
   10568   TestCompletionCallback callback;
   10569   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   10570   EXPECT_EQ(ERR_IO_PENDING, rv);
   10571   EXPECT_EQ(OK, callback.WaitForResult());
   10572 }
   10573 
   10574 // Given a net error, cause that error to be returned from the first Write()
   10575 // call and verify that the HttpTransaction fails with that error.
   10576 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
   10577     int error, IoMode mode) {
   10578   net::HttpRequestInfo request_info;
   10579   request_info.url = GURL("https://www.example.com/");
   10580   request_info.method = "GET";
   10581   request_info.load_flags = net::LOAD_NORMAL;
   10582 
   10583   SSLSocketDataProvider ssl_data(mode, OK);
   10584   net::MockWrite data_writes[] = {
   10585     net::MockWrite(mode, error),
   10586   };
   10587   net::StaticSocketDataProvider data(NULL, 0,
   10588                                      data_writes, arraysize(data_writes));
   10589   session_deps_.socket_factory->AddSocketDataProvider(&data);
   10590   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   10591 
   10592   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10593   scoped_ptr<HttpTransaction> trans(
   10594       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10595 
   10596   TestCompletionCallback callback;
   10597   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10598   if (rv == net::ERR_IO_PENDING)
   10599     rv = callback.WaitForResult();
   10600   ASSERT_EQ(error, rv);
   10601 }
   10602 
   10603 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
   10604   // Just check a grab bag of cert errors.
   10605   static const int kErrors[] = {
   10606     ERR_CERT_COMMON_NAME_INVALID,
   10607     ERR_CERT_AUTHORITY_INVALID,
   10608     ERR_CERT_DATE_INVALID,
   10609   };
   10610   for (size_t i = 0; i < arraysize(kErrors); i++) {
   10611     CheckErrorIsPassedBack(kErrors[i], ASYNC);
   10612     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
   10613   }
   10614 }
   10615 
   10616 // Ensure that a client certificate is removed from the SSL client auth
   10617 // cache when:
   10618 //  1) No proxy is involved.
   10619 //  2) TLS False Start is disabled.
   10620 //  3) The initial TLS handshake requests a client certificate.
   10621 //  4) The client supplies an invalid/unacceptable certificate.
   10622 TEST_P(HttpNetworkTransactionTest,
   10623        ClientAuthCertCache_Direct_NoFalseStart) {
   10624   net::HttpRequestInfo request_info;
   10625   request_info.url = GURL("https://www.example.com/");
   10626   request_info.method = "GET";
   10627   request_info.load_flags = net::LOAD_NORMAL;
   10628 
   10629   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10630   cert_request->host_and_port = HostPortPair("www.example.com", 443);
   10631 
   10632   // [ssl_]data1 contains the data for the first SSL handshake. When a
   10633   // CertificateRequest is received for the first time, the handshake will
   10634   // be aborted to allow the caller to provide a certificate.
   10635   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10636   ssl_data1.cert_request_info = cert_request.get();
   10637   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10638   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10639   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10640 
   10641   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
   10642   // False Start is not being used, the result of the SSL handshake will be
   10643   // returned as part of the SSLClientSocket::Connect() call. This test
   10644   // matches the result of a server sending a handshake_failure alert,
   10645   // rather than a Finished message, because it requires a client
   10646   // certificate and none was supplied.
   10647   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10648   ssl_data2.cert_request_info = cert_request.get();
   10649   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10650   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10651   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10652 
   10653   // [ssl_]data3 contains the data for the third SSL handshake. When a
   10654   // connection to a server fails during an SSL handshake,
   10655   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
   10656   // connection was attempted with TLSv1.1. This is transparent to the caller
   10657   // of the HttpNetworkTransaction. Because this test failure is due to
   10658   // requiring a client certificate, this fallback handshake should also
   10659   // fail.
   10660   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10661   ssl_data3.cert_request_info = cert_request.get();
   10662   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10663   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10664   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10665 
   10666   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
   10667   // connection to a server fails during an SSL handshake,
   10668   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
   10669   // connection was attempted with TLSv1. This is transparent to the caller
   10670   // of the HttpNetworkTransaction. Because this test failure is due to
   10671   // requiring a client certificate, this fallback handshake should also
   10672   // fail.
   10673   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10674   ssl_data4.cert_request_info = cert_request.get();
   10675   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10676   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
   10677   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10678 
   10679   // Need one more if TLSv1.2 is enabled.
   10680   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10681   ssl_data5.cert_request_info = cert_request.get();
   10682   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10683   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
   10684   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10685 
   10686   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10687   scoped_ptr<HttpTransaction> trans(
   10688       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10689 
   10690   // Begin the SSL handshake with the peer. This consumes ssl_data1.
   10691   TestCompletionCallback callback;
   10692   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10693   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10694 
   10695   // Complete the SSL handshake, which should abort due to requiring a
   10696   // client certificate.
   10697   rv = callback.WaitForResult();
   10698   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10699 
   10700   // Indicate that no certificate should be supplied. From the perspective
   10701   // of SSLClientCertCache, NULL is just as meaningful as a real
   10702   // certificate, so this is the same as supply a
   10703   // legitimate-but-unacceptable certificate.
   10704   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10705   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10706 
   10707   // Ensure the certificate was added to the client auth cache before
   10708   // allowing the connection to continue restarting.
   10709   scoped_refptr<X509Certificate> client_cert;
   10710   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
   10711       HostPortPair("www.example.com", 443), &client_cert));
   10712   ASSERT_EQ(NULL, client_cert.get());
   10713 
   10714   // Restart the handshake. This will consume ssl_data2, which fails, and
   10715   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10716   // The result code is checked against what ssl_data4 should return.
   10717   rv = callback.WaitForResult();
   10718   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10719 
   10720   // Ensure that the client certificate is removed from the cache on a
   10721   // handshake failure.
   10722   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
   10723       HostPortPair("www.example.com", 443), &client_cert));
   10724 }
   10725 
   10726 // Ensure that a client certificate is removed from the SSL client auth
   10727 // cache when:
   10728 //  1) No proxy is involved.
   10729 //  2) TLS False Start is enabled.
   10730 //  3) The initial TLS handshake requests a client certificate.
   10731 //  4) The client supplies an invalid/unacceptable certificate.
   10732 TEST_P(HttpNetworkTransactionTest,
   10733        ClientAuthCertCache_Direct_FalseStart) {
   10734   net::HttpRequestInfo request_info;
   10735   request_info.url = GURL("https://www.example.com/");
   10736   request_info.method = "GET";
   10737   request_info.load_flags = net::LOAD_NORMAL;
   10738 
   10739   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10740   cert_request->host_and_port = HostPortPair("www.example.com", 443);
   10741 
   10742   // When TLS False Start is used, SSLClientSocket::Connect() calls will
   10743   // return successfully after reading up to the peer's Certificate message.
   10744   // This is to allow the caller to call SSLClientSocket::Write(), which can
   10745   // enqueue application data to be sent in the same packet as the
   10746   // ChangeCipherSpec and Finished messages.
   10747   // The actual handshake will be finished when SSLClientSocket::Read() is
   10748   // called, which expects to process the peer's ChangeCipherSpec and
   10749   // Finished messages. If there was an error negotiating with the peer,
   10750   // such as due to the peer requiring a client certificate when none was
   10751   // supplied, the alert sent by the peer won't be processed until Read() is
   10752   // called.
   10753 
   10754   // Like the non-False Start case, when a client certificate is requested by
   10755   // the peer, the handshake is aborted during the Connect() call.
   10756   // [ssl_]data1 represents the initial SSL handshake with the peer.
   10757   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10758   ssl_data1.cert_request_info = cert_request.get();
   10759   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10760   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10761   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10762 
   10763   // When a client certificate is supplied, Connect() will not be aborted
   10764   // when the peer requests the certificate. Instead, the handshake will
   10765   // artificially succeed, allowing the caller to write the HTTP request to
   10766   // the socket. The handshake messages are not processed until Read() is
   10767   // called, which then detects that the handshake was aborted, due to the
   10768   // peer sending a handshake_failure because it requires a client
   10769   // certificate.
   10770   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
   10771   ssl_data2.cert_request_info = cert_request.get();
   10772   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10773   net::MockRead data2_reads[] = {
   10774     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
   10775   };
   10776   net::StaticSocketDataProvider data2(
   10777       data2_reads, arraysize(data2_reads), NULL, 0);
   10778   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10779 
   10780   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
   10781   // the data for the SSL handshake once the TLSv1.1 connection falls back to
   10782   // TLSv1. It has the same behaviour as [ssl_]data2.
   10783   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
   10784   ssl_data3.cert_request_info = cert_request.get();
   10785   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10786   net::StaticSocketDataProvider data3(
   10787       data2_reads, arraysize(data2_reads), NULL, 0);
   10788   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10789 
   10790   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
   10791   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
   10792   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
   10793   ssl_data4.cert_request_info = cert_request.get();
   10794   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10795   net::StaticSocketDataProvider data4(
   10796       data2_reads, arraysize(data2_reads), NULL, 0);
   10797   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10798 
   10799   // Need one more if TLSv1.2 is enabled.
   10800   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
   10801   ssl_data5.cert_request_info = cert_request.get();
   10802   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10803   net::StaticSocketDataProvider data5(
   10804       data2_reads, arraysize(data2_reads), NULL, 0);
   10805   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10806 
   10807   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10808   scoped_ptr<HttpTransaction> trans(
   10809       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10810 
   10811   // Begin the initial SSL handshake.
   10812   TestCompletionCallback callback;
   10813   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10814   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10815 
   10816   // Complete the SSL handshake, which should abort due to requiring a
   10817   // client certificate.
   10818   rv = callback.WaitForResult();
   10819   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10820 
   10821   // Indicate that no certificate should be supplied. From the perspective
   10822   // of SSLClientCertCache, NULL is just as meaningful as a real
   10823   // certificate, so this is the same as supply a
   10824   // legitimate-but-unacceptable certificate.
   10825   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10826   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10827 
   10828   // Ensure the certificate was added to the client auth cache before
   10829   // allowing the connection to continue restarting.
   10830   scoped_refptr<X509Certificate> client_cert;
   10831   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
   10832       HostPortPair("www.example.com", 443), &client_cert));
   10833   ASSERT_EQ(NULL, client_cert.get());
   10834 
   10835   // Restart the handshake. This will consume ssl_data2, which fails, and
   10836   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10837   // The result code is checked against what ssl_data4 should return.
   10838   rv = callback.WaitForResult();
   10839   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10840 
   10841   // Ensure that the client certificate is removed from the cache on a
   10842   // handshake failure.
   10843   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
   10844       HostPortPair("www.example.com", 443), &client_cert));
   10845 }
   10846 
   10847 // Ensure that a client certificate is removed from the SSL client auth
   10848 // cache when:
   10849 //  1) An HTTPS proxy is involved.
   10850 //  3) The HTTPS proxy requests a client certificate.
   10851 //  4) The client supplies an invalid/unacceptable certificate for the
   10852 //     proxy.
   10853 // The test is repeated twice, first for connecting to an HTTPS endpoint,
   10854 // then for connecting to an HTTP endpoint.
   10855 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
   10856   session_deps_.proxy_service.reset(
   10857       ProxyService::CreateFixed("https://proxy:70"));
   10858   CapturingBoundNetLog log;
   10859   session_deps_.net_log = log.bound().net_log();
   10860 
   10861   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10862   cert_request->host_and_port = HostPortPair("proxy", 70);
   10863 
   10864   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
   10865   // [ssl_]data[1-3]. Rather than represending the endpoint
   10866   // (www.example.com:443), they represent failures with the HTTPS proxy
   10867   // (proxy:70).
   10868   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10869   ssl_data1.cert_request_info = cert_request.get();
   10870   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10871   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10872   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10873 
   10874   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10875   ssl_data2.cert_request_info = cert_request.get();
   10876   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10877   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10878   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10879 
   10880   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
   10881 #if 0
   10882   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10883   ssl_data3.cert_request_info = cert_request.get();
   10884   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10885   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10886   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10887 #endif
   10888 
   10889   net::HttpRequestInfo requests[2];
   10890   requests[0].url = GURL("https://www.example.com/");
   10891   requests[0].method = "GET";
   10892   requests[0].load_flags = net::LOAD_NORMAL;
   10893 
   10894   requests[1].url = GURL("http://www.example.com/");
   10895   requests[1].method = "GET";
   10896   requests[1].load_flags = net::LOAD_NORMAL;
   10897 
   10898   for (size_t i = 0; i < arraysize(requests); ++i) {
   10899     session_deps_.socket_factory->ResetNextMockIndexes();
   10900     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10901     scoped_ptr<HttpNetworkTransaction> trans(
   10902         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10903 
   10904     // Begin the SSL handshake with the proxy.
   10905     TestCompletionCallback callback;
   10906     int rv = trans->Start(
   10907         &requests[i], callback.callback(), net::BoundNetLog());
   10908     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10909 
   10910     // Complete the SSL handshake, which should abort due to requiring a
   10911     // client certificate.
   10912     rv = callback.WaitForResult();
   10913     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10914 
   10915     // Indicate that no certificate should be supplied. From the perspective
   10916     // of SSLClientCertCache, NULL is just as meaningful as a real
   10917     // certificate, so this is the same as supply a
   10918     // legitimate-but-unacceptable certificate.
   10919     rv = trans->RestartWithCertificate(NULL, callback.callback());
   10920     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10921 
   10922     // Ensure the certificate was added to the client auth cache before
   10923     // allowing the connection to continue restarting.
   10924     scoped_refptr<X509Certificate> client_cert;
   10925     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup(
   10926         HostPortPair("proxy", 70), &client_cert));
   10927     ASSERT_EQ(NULL, client_cert.get());
   10928     // Ensure the certificate was NOT cached for the endpoint. This only
   10929     // applies to HTTPS requests, but is fine to check for HTTP requests.
   10930     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
   10931         HostPortPair("www.example.com", 443), &client_cert));
   10932 
   10933     // Restart the handshake. This will consume ssl_data2, which fails, and
   10934     // then consume ssl_data3, which should also fail. The result code is
   10935     // checked against what ssl_data3 should return.
   10936     rv = callback.WaitForResult();
   10937     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
   10938 
   10939     // Now that the new handshake has failed, ensure that the client
   10940     // certificate was removed from the client auth cache.
   10941     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
   10942         HostPortPair("proxy", 70), &client_cert));
   10943     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup(
   10944         HostPortPair("www.example.com", 443), &client_cert));
   10945   }
   10946 }
   10947 
   10948 // Unlike TEST/TEST_F, which are macros that expand to further macros,
   10949 // TEST_P is a macro that expands directly to code that stringizes the
   10950 // arguments. As a result, macros passed as parameters (such as prefix
   10951 // or test_case_name) will not be expanded by the preprocessor. To
   10952 // work around this, indirect the macro for TEST_P, so that the
   10953 // pre-processor will expand macros such as MAYBE_test_name before
   10954 // instantiating the test.
   10955 #define WRAPPED_TEST_P(test_case_name, test_name) \
   10956   TEST_P(test_case_name, test_name)
   10957 
   10958 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   10959 #if defined(OS_WIN)
   10960 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
   10961 #else
   10962 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
   10963 #endif
   10964 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
   10965   session_deps_.use_alternate_protocols = true;
   10966   session_deps_.next_protos = SpdyNextProtos();
   10967 
   10968   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   10969   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   10970   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10971   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10972   pool_peer.DisableDomainAuthenticationVerification();
   10973 
   10974   SSLSocketDataProvider ssl(ASYNC, OK);
   10975   ssl.SetNextProto(GetParam());
   10976   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10977 
   10978   scoped_ptr<SpdyFrame> host1_req(
   10979       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10980   scoped_ptr<SpdyFrame> host2_req(
   10981       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10982   MockWrite spdy_writes[] = {
   10983     CreateMockWrite(*host1_req, 1),
   10984     CreateMockWrite(*host2_req, 4),
   10985   };
   10986   scoped_ptr<SpdyFrame> host1_resp(
   10987       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10988   scoped_ptr<SpdyFrame> host1_resp_body(
   10989       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10990   scoped_ptr<SpdyFrame> host2_resp(
   10991       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10992   scoped_ptr<SpdyFrame> host2_resp_body(
   10993       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10994   MockRead spdy_reads[] = {
   10995     CreateMockRead(*host1_resp, 2),
   10996     CreateMockRead(*host1_resp_body, 3),
   10997     CreateMockRead(*host2_resp, 5),
   10998     CreateMockRead(*host2_resp_body, 6),
   10999     MockRead(ASYNC, 0, 7),
   11000   };
   11001 
   11002   IPAddressNumber ip;
   11003   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   11004   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11005   MockConnect connect(ASYNC, OK, peer_addr);
   11006   OrderedSocketData spdy_data(
   11007       connect,
   11008       spdy_reads, arraysize(spdy_reads),
   11009       spdy_writes, arraysize(spdy_writes));
   11010   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   11011 
   11012   TestCompletionCallback callback;
   11013   HttpRequestInfo request1;
   11014   request1.method = "GET";
   11015   request1.url = GURL("https://www.google.com/");
   11016   request1.load_flags = 0;
   11017   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   11018 
   11019   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   11020   EXPECT_EQ(ERR_IO_PENDING, rv);
   11021   EXPECT_EQ(OK, callback.WaitForResult());
   11022 
   11023   const HttpResponseInfo* response = trans1.GetResponseInfo();
   11024   ASSERT_TRUE(response != NULL);
   11025   ASSERT_TRUE(response->headers.get() != NULL);
   11026   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11027 
   11028   std::string response_data;
   11029   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   11030   EXPECT_EQ("hello!", response_data);
   11031 
   11032   // Preload www.gmail.com into HostCache.
   11033   HostPortPair host_port("www.gmail.com", 443);
   11034   HostResolver::RequestInfo resolve_info(host_port);
   11035   AddressList ignored;
   11036   rv = session_deps_.host_resolver->Resolve(resolve_info,
   11037                                             DEFAULT_PRIORITY,
   11038                                             &ignored,
   11039                                             callback.callback(),
   11040                                             NULL,
   11041                                             BoundNetLog());
   11042   EXPECT_EQ(ERR_IO_PENDING, rv);
   11043   rv = callback.WaitForResult();
   11044   EXPECT_EQ(OK, rv);
   11045 
   11046   HttpRequestInfo request2;
   11047   request2.method = "GET";
   11048   request2.url = GURL("https://www.gmail.com/");
   11049   request2.load_flags = 0;
   11050   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   11051 
   11052   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   11053   EXPECT_EQ(ERR_IO_PENDING, rv);
   11054   EXPECT_EQ(OK, callback.WaitForResult());
   11055 
   11056   response = trans2.GetResponseInfo();
   11057   ASSERT_TRUE(response != NULL);
   11058   ASSERT_TRUE(response->headers.get() != NULL);
   11059   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11060   EXPECT_TRUE(response->was_fetched_via_spdy);
   11061   EXPECT_TRUE(response->was_npn_negotiated);
   11062   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   11063   EXPECT_EQ("hello!", response_data);
   11064 }
   11065 #undef MAYBE_UseIPConnectionPooling
   11066 
   11067 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
   11068   session_deps_.use_alternate_protocols = true;
   11069   session_deps_.next_protos = SpdyNextProtos();
   11070 
   11071   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   11072   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   11073   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11074   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   11075   pool_peer.DisableDomainAuthenticationVerification();
   11076 
   11077   SSLSocketDataProvider ssl(ASYNC, OK);
   11078   ssl.SetNextProto(GetParam());
   11079   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11080 
   11081   scoped_ptr<SpdyFrame> host1_req(
   11082       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   11083   scoped_ptr<SpdyFrame> host2_req(
   11084       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   11085   MockWrite spdy_writes[] = {
   11086     CreateMockWrite(*host1_req, 1),
   11087     CreateMockWrite(*host2_req, 4),
   11088   };
   11089   scoped_ptr<SpdyFrame> host1_resp(
   11090       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11091   scoped_ptr<SpdyFrame> host1_resp_body(
   11092       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11093   scoped_ptr<SpdyFrame> host2_resp(
   11094       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11095   scoped_ptr<SpdyFrame> host2_resp_body(
   11096       spdy_util_.ConstructSpdyBodyFrame(3, true));
   11097   MockRead spdy_reads[] = {
   11098     CreateMockRead(*host1_resp, 2),
   11099     CreateMockRead(*host1_resp_body, 3),
   11100     CreateMockRead(*host2_resp, 5),
   11101     CreateMockRead(*host2_resp_body, 6),
   11102     MockRead(ASYNC, 0, 7),
   11103   };
   11104 
   11105   IPAddressNumber ip;
   11106   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   11107   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11108   MockConnect connect(ASYNC, OK, peer_addr);
   11109   OrderedSocketData spdy_data(
   11110       connect,
   11111       spdy_reads, arraysize(spdy_reads),
   11112       spdy_writes, arraysize(spdy_writes));
   11113   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   11114 
   11115   TestCompletionCallback callback;
   11116   HttpRequestInfo request1;
   11117   request1.method = "GET";
   11118   request1.url = GURL("https://www.google.com/");
   11119   request1.load_flags = 0;
   11120   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   11121 
   11122   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   11123   EXPECT_EQ(ERR_IO_PENDING, rv);
   11124   EXPECT_EQ(OK, callback.WaitForResult());
   11125 
   11126   const HttpResponseInfo* response = trans1.GetResponseInfo();
   11127   ASSERT_TRUE(response != NULL);
   11128   ASSERT_TRUE(response->headers.get() != NULL);
   11129   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11130 
   11131   std::string response_data;
   11132   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   11133   EXPECT_EQ("hello!", response_data);
   11134 
   11135   HttpRequestInfo request2;
   11136   request2.method = "GET";
   11137   request2.url = GURL("https://www.gmail.com/");
   11138   request2.load_flags = 0;
   11139   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   11140 
   11141   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   11142   EXPECT_EQ(ERR_IO_PENDING, rv);
   11143   EXPECT_EQ(OK, callback.WaitForResult());
   11144 
   11145   response = trans2.GetResponseInfo();
   11146   ASSERT_TRUE(response != NULL);
   11147   ASSERT_TRUE(response->headers.get() != NULL);
   11148   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11149   EXPECT_TRUE(response->was_fetched_via_spdy);
   11150   EXPECT_TRUE(response->was_npn_negotiated);
   11151   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   11152   EXPECT_EQ("hello!", response_data);
   11153 }
   11154 
   11155 class OneTimeCachingHostResolver : public net::HostResolver {
   11156  public:
   11157   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
   11158       : host_port_(host_port) {}
   11159   virtual ~OneTimeCachingHostResolver() {}
   11160 
   11161   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
   11162 
   11163   // HostResolver methods:
   11164   virtual int Resolve(const RequestInfo& info,
   11165                       RequestPriority priority,
   11166                       AddressList* addresses,
   11167                       const CompletionCallback& callback,
   11168                       RequestHandle* out_req,
   11169                       const BoundNetLog& net_log) OVERRIDE {
   11170     return host_resolver_.Resolve(
   11171         info, priority, addresses, callback, out_req, net_log);
   11172   }
   11173 
   11174   virtual int ResolveFromCache(const RequestInfo& info,
   11175                                AddressList* addresses,
   11176                                const BoundNetLog& net_log) OVERRIDE {
   11177     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
   11178     if (rv == OK && info.host_port_pair().Equals(host_port_))
   11179       host_resolver_.GetHostCache()->clear();
   11180     return rv;
   11181   }
   11182 
   11183   virtual void CancelRequest(RequestHandle req) OVERRIDE {
   11184     host_resolver_.CancelRequest(req);
   11185   }
   11186 
   11187   MockCachingHostResolver* GetMockHostResolver() {
   11188     return &host_resolver_;
   11189   }
   11190 
   11191  private:
   11192   MockCachingHostResolver host_resolver_;
   11193   const HostPortPair host_port_;
   11194 };
   11195 
   11196 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   11197 #if defined(OS_WIN)
   11198 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   11199     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
   11200 #else
   11201 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   11202     UseIPConnectionPoolingWithHostCacheExpiration
   11203 #endif
   11204 WRAPPED_TEST_P(HttpNetworkTransactionTest,
   11205                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
   11206 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
   11207 // prefix doesn't work with parametrized tests).
   11208 #if defined(OS_WIN)
   11209   return;
   11210 #else
   11211   session_deps_.use_alternate_protocols = true;
   11212   session_deps_.next_protos = SpdyNextProtos();
   11213 
   11214   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
   11215   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
   11216   HttpNetworkSession::Params params =
   11217       SpdySessionDependencies::CreateSessionParams(&session_deps_);
   11218   params.host_resolver = &host_resolver;
   11219   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11220   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   11221   pool_peer.DisableDomainAuthenticationVerification();
   11222 
   11223   SSLSocketDataProvider ssl(ASYNC, OK);
   11224   ssl.SetNextProto(GetParam());
   11225   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11226 
   11227   scoped_ptr<SpdyFrame> host1_req(
   11228       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   11229   scoped_ptr<SpdyFrame> host2_req(
   11230       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   11231   MockWrite spdy_writes[] = {
   11232     CreateMockWrite(*host1_req, 1),
   11233     CreateMockWrite(*host2_req, 4),
   11234   };
   11235   scoped_ptr<SpdyFrame> host1_resp(
   11236       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11237   scoped_ptr<SpdyFrame> host1_resp_body(
   11238       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11239   scoped_ptr<SpdyFrame> host2_resp(
   11240       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11241   scoped_ptr<SpdyFrame> host2_resp_body(
   11242       spdy_util_.ConstructSpdyBodyFrame(3, true));
   11243   MockRead spdy_reads[] = {
   11244     CreateMockRead(*host1_resp, 2),
   11245     CreateMockRead(*host1_resp_body, 3),
   11246     CreateMockRead(*host2_resp, 5),
   11247     CreateMockRead(*host2_resp_body, 6),
   11248     MockRead(ASYNC, 0, 7),
   11249   };
   11250 
   11251   IPAddressNumber ip;
   11252   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   11253   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11254   MockConnect connect(ASYNC, OK, peer_addr);
   11255   OrderedSocketData spdy_data(
   11256       connect,
   11257       spdy_reads, arraysize(spdy_reads),
   11258       spdy_writes, arraysize(spdy_writes));
   11259   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   11260 
   11261   TestCompletionCallback callback;
   11262   HttpRequestInfo request1;
   11263   request1.method = "GET";
   11264   request1.url = GURL("https://www.google.com/");
   11265   request1.load_flags = 0;
   11266   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   11267 
   11268   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   11269   EXPECT_EQ(ERR_IO_PENDING, rv);
   11270   EXPECT_EQ(OK, callback.WaitForResult());
   11271 
   11272   const HttpResponseInfo* response = trans1.GetResponseInfo();
   11273   ASSERT_TRUE(response != NULL);
   11274   ASSERT_TRUE(response->headers.get() != NULL);
   11275   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11276 
   11277   std::string response_data;
   11278   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   11279   EXPECT_EQ("hello!", response_data);
   11280 
   11281   // Preload cache entries into HostCache.
   11282   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
   11283   AddressList ignored;
   11284   rv = host_resolver.Resolve(resolve_info,
   11285                              DEFAULT_PRIORITY,
   11286                              &ignored,
   11287                              callback.callback(),
   11288                              NULL,
   11289                              BoundNetLog());
   11290   EXPECT_EQ(ERR_IO_PENDING, rv);
   11291   rv = callback.WaitForResult();
   11292   EXPECT_EQ(OK, rv);
   11293 
   11294   HttpRequestInfo request2;
   11295   request2.method = "GET";
   11296   request2.url = GURL("https://www.gmail.com/");
   11297   request2.load_flags = 0;
   11298   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   11299 
   11300   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   11301   EXPECT_EQ(ERR_IO_PENDING, rv);
   11302   EXPECT_EQ(OK, callback.WaitForResult());
   11303 
   11304   response = trans2.GetResponseInfo();
   11305   ASSERT_TRUE(response != NULL);
   11306   ASSERT_TRUE(response->headers.get() != NULL);
   11307   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11308   EXPECT_TRUE(response->was_fetched_via_spdy);
   11309   EXPECT_TRUE(response->was_npn_negotiated);
   11310   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   11311   EXPECT_EQ("hello!", response_data);
   11312 #endif
   11313 }
   11314 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
   11315 
   11316 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
   11317   const std::string https_url = "https://www.google.com/";
   11318   const std::string http_url = "http://www.google.com:443/";
   11319 
   11320   // SPDY GET for HTTPS URL
   11321   scoped_ptr<SpdyFrame> req1(
   11322       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   11323 
   11324   MockWrite writes1[] = {
   11325     CreateMockWrite(*req1, 0),
   11326   };
   11327 
   11328   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11329   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11330   MockRead reads1[] = {
   11331     CreateMockRead(*resp1, 1),
   11332     CreateMockRead(*body1, 2),
   11333     MockRead(ASYNC, ERR_IO_PENDING, 3)
   11334   };
   11335 
   11336   DelayedSocketData data1(
   11337       1, reads1, arraysize(reads1),
   11338       writes1, arraysize(writes1));
   11339   MockConnect connect_data1(ASYNC, OK);
   11340   data1.set_connect_data(connect_data1);
   11341 
   11342   // HTTP GET for the HTTP URL
   11343   MockWrite writes2[] = {
   11344     MockWrite(ASYNC, 4,
   11345               "GET / HTTP/1.1\r\n"
   11346               "Host: www.google.com:443\r\n"
   11347               "Connection: keep-alive\r\n\r\n"),
   11348   };
   11349 
   11350   MockRead reads2[] = {
   11351     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   11352     MockRead(ASYNC, 6, "hello"),
   11353     MockRead(ASYNC, 7, OK),
   11354   };
   11355 
   11356   DelayedSocketData data2(
   11357       1, reads2, arraysize(reads2),
   11358       writes2, arraysize(writes2));
   11359 
   11360   SSLSocketDataProvider ssl(ASYNC, OK);
   11361   ssl.SetNextProto(GetParam());
   11362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11363   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   11364   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   11365 
   11366   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11367 
   11368   // Start the first transaction to set up the SpdySession
   11369   HttpRequestInfo request1;
   11370   request1.method = "GET";
   11371   request1.url = GURL(https_url);
   11372   request1.load_flags = 0;
   11373   HttpNetworkTransaction trans1(LOWEST, session.get());
   11374   TestCompletionCallback callback1;
   11375   EXPECT_EQ(ERR_IO_PENDING,
   11376             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11377   base::MessageLoop::current()->RunUntilIdle();
   11378 
   11379   EXPECT_EQ(OK, callback1.WaitForResult());
   11380   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11381 
   11382   // Now, start the HTTP request
   11383   HttpRequestInfo request2;
   11384   request2.method = "GET";
   11385   request2.url = GURL(http_url);
   11386   request2.load_flags = 0;
   11387   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11388   TestCompletionCallback callback2;
   11389   EXPECT_EQ(ERR_IO_PENDING,
   11390             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11391   base::MessageLoop::current()->RunUntilIdle();
   11392 
   11393   EXPECT_EQ(OK, callback2.WaitForResult());
   11394   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11395 }
   11396 
   11397 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
   11398   const std::string https_url = "https://www.google.com/";
   11399   const std::string http_url = "http://www.google.com:443/";
   11400 
   11401   // SPDY GET for HTTPS URL (through CONNECT tunnel)
   11402   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   11403                                                                 LOWEST));
   11404   scoped_ptr<SpdyFrame> req1(
   11405       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   11406   scoped_ptr<SpdyFrame> wrapped_req1(
   11407       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
   11408 
   11409   // SPDY GET for HTTP URL (through the proxy, but not the tunnel).
   11410   SpdyHeaderBlock req2_block;
   11411   req2_block[spdy_util_.GetMethodKey()] = "GET";
   11412   req2_block[spdy_util_.GetPathKey()] =
   11413       spdy_util_.is_spdy2() ? http_url.c_str() : "/";
   11414   req2_block[spdy_util_.GetHostKey()] = "www.google.com:443";
   11415   req2_block[spdy_util_.GetSchemeKey()] = "http";
   11416   spdy_util_.MaybeAddVersionHeader(&req2_block);
   11417   scoped_ptr<SpdyFrame> req2(
   11418       spdy_util_.ConstructSpdySyn(3, req2_block, MEDIUM, false, true));
   11419 
   11420   MockWrite writes1[] = {
   11421     CreateMockWrite(*connect, 0),
   11422     CreateMockWrite(*wrapped_req1, 2),
   11423     CreateMockWrite(*req2, 5),
   11424   };
   11425 
   11426   scoped_ptr<SpdyFrame> conn_resp(
   11427       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11428   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11429   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11430   scoped_ptr<SpdyFrame> wrapped_resp1(
   11431       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
   11432   scoped_ptr<SpdyFrame> wrapped_body1(
   11433       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
   11434   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11435   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   11436   MockRead reads1[] = {
   11437     CreateMockRead(*conn_resp, 1),
   11438     CreateMockRead(*wrapped_resp1, 3),
   11439     CreateMockRead(*wrapped_body1, 4),
   11440     CreateMockRead(*resp2, 6),
   11441     CreateMockRead(*body2, 7),
   11442     MockRead(ASYNC, ERR_IO_PENDING, 8)
   11443   };
   11444 
   11445   DeterministicSocketData data1(reads1, arraysize(reads1),
   11446                                 writes1, arraysize(writes1));
   11447   MockConnect connect_data1(ASYNC, OK);
   11448   data1.set_connect_data(connect_data1);
   11449 
   11450   session_deps_.proxy_service.reset(
   11451       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   11452   CapturingNetLog log;
   11453   session_deps_.net_log = &log;
   11454   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   11455   ssl1.SetNextProto(GetParam());
   11456   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11457   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   11458   ssl2.SetNextProto(GetParam());
   11459   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11460   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
   11461 
   11462   scoped_refptr<HttpNetworkSession> session(
   11463       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11464 
   11465   // Start the first transaction to set up the SpdySession
   11466   HttpRequestInfo request1;
   11467   request1.method = "GET";
   11468   request1.url = GURL(https_url);
   11469   request1.load_flags = 0;
   11470   HttpNetworkTransaction trans1(LOWEST, session.get());
   11471   TestCompletionCallback callback1;
   11472   EXPECT_EQ(ERR_IO_PENDING,
   11473             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11474   base::MessageLoop::current()->RunUntilIdle();
   11475   data1.RunFor(4);
   11476 
   11477   EXPECT_EQ(OK, callback1.WaitForResult());
   11478   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11479 
   11480   LoadTimingInfo load_timing_info1;
   11481   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
   11482   TestLoadTimingNotReusedWithPac(load_timing_info1,
   11483                                  CONNECT_TIMING_HAS_SSL_TIMES);
   11484 
   11485   // Now, start the HTTP request
   11486   HttpRequestInfo request2;
   11487   request2.method = "GET";
   11488   request2.url = GURL(http_url);
   11489   request2.load_flags = 0;
   11490   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11491   TestCompletionCallback callback2;
   11492   EXPECT_EQ(ERR_IO_PENDING,
   11493             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11494   base::MessageLoop::current()->RunUntilIdle();
   11495   data1.RunFor(3);
   11496 
   11497   EXPECT_EQ(OK, callback2.WaitForResult());
   11498   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11499 
   11500   LoadTimingInfo load_timing_info2;
   11501   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
   11502   // The established SPDY sessions is considered reused by the HTTP request.
   11503   TestLoadTimingReusedWithPac(load_timing_info2);
   11504   // HTTP requests over a SPDY session should have a different connection
   11505   // socket_log_id than requests over a tunnel.
   11506   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   11507 }
   11508 
   11509 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
   11510   session_deps_.force_spdy_always = true;
   11511   const std::string https_url = "https://www.google.com/";
   11512   const std::string http_url = "http://www.google.com:443/";
   11513 
   11514   // SPDY GET for HTTPS URL
   11515   scoped_ptr<SpdyFrame> req1(
   11516       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   11517   // SPDY GET for the HTTP URL
   11518   scoped_ptr<SpdyFrame> req2(
   11519       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
   11520 
   11521   MockWrite writes[] = {
   11522     CreateMockWrite(*req1, 1),
   11523     CreateMockWrite(*req2, 4),
   11524   };
   11525 
   11526   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11527   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11528   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11529   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   11530   MockRead reads[] = {
   11531     CreateMockRead(*resp1, 2),
   11532     CreateMockRead(*body1, 3),
   11533     CreateMockRead(*resp2, 5),
   11534     CreateMockRead(*body2, 6),
   11535     MockRead(ASYNC, ERR_IO_PENDING, 7)
   11536   };
   11537 
   11538   OrderedSocketData data(reads, arraysize(reads),
   11539                          writes, arraysize(writes));
   11540 
   11541   SSLSocketDataProvider ssl(ASYNC, OK);
   11542   ssl.SetNextProto(GetParam());
   11543   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11544   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11545 
   11546   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11547 
   11548   // Start the first transaction to set up the SpdySession
   11549   HttpRequestInfo request1;
   11550   request1.method = "GET";
   11551   request1.url = GURL(https_url);
   11552   request1.load_flags = 0;
   11553   HttpNetworkTransaction trans1(LOWEST, session.get());
   11554   TestCompletionCallback callback1;
   11555   EXPECT_EQ(ERR_IO_PENDING,
   11556             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11557   base::MessageLoop::current()->RunUntilIdle();
   11558 
   11559   EXPECT_EQ(OK, callback1.WaitForResult());
   11560   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11561 
   11562   // Now, start the HTTP request
   11563   HttpRequestInfo request2;
   11564   request2.method = "GET";
   11565   request2.url = GURL(http_url);
   11566   request2.load_flags = 0;
   11567   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11568   TestCompletionCallback callback2;
   11569   EXPECT_EQ(ERR_IO_PENDING,
   11570             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11571   base::MessageLoop::current()->RunUntilIdle();
   11572 
   11573   EXPECT_EQ(OK, callback2.WaitForResult());
   11574   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11575 }
   11576 
   11577 // Test that in the case where we have a SPDY session to a SPDY proxy
   11578 // that we do not pool other origins that resolve to the same IP when
   11579 // the certificate does not match the new origin.
   11580 // http://crbug.com/134690
   11581 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
   11582   const std::string url1 = "http://www.google.com/";
   11583   const std::string url2 = "https://mail.google.com/";
   11584   const std::string ip_addr = "1.2.3.4";
   11585 
   11586   // SPDY GET for HTTP URL (through SPDY proxy)
   11587   scoped_ptr<SpdyHeaderBlock> headers(
   11588       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   11589   scoped_ptr<SpdyFrame> req1(
   11590       spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
   11591 
   11592   MockWrite writes1[] = {
   11593     CreateMockWrite(*req1, 0),
   11594   };
   11595 
   11596   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11597   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11598   MockRead reads1[] = {
   11599     CreateMockRead(*resp1, 1),
   11600     CreateMockRead(*body1, 2),
   11601     MockRead(ASYNC, OK, 3) // EOF
   11602   };
   11603 
   11604   scoped_ptr<DeterministicSocketData> data1(
   11605       new DeterministicSocketData(reads1, arraysize(reads1),
   11606                                   writes1, arraysize(writes1)));
   11607   IPAddressNumber ip;
   11608   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
   11609   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11610   MockConnect connect_data1(ASYNC, OK, peer_addr);
   11611   data1->set_connect_data(connect_data1);
   11612 
   11613   // SPDY GET for HTTPS URL (direct)
   11614   scoped_ptr<SpdyFrame> req2(
   11615       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
   11616 
   11617   MockWrite writes2[] = {
   11618     CreateMockWrite(*req2, 0),
   11619   };
   11620 
   11621   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11622   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11623   MockRead reads2[] = {
   11624     CreateMockRead(*resp2, 1),
   11625     CreateMockRead(*body2, 2),
   11626     MockRead(ASYNC, OK, 3) // EOF
   11627   };
   11628 
   11629   scoped_ptr<DeterministicSocketData> data2(
   11630       new DeterministicSocketData(reads2, arraysize(reads2),
   11631                                   writes2, arraysize(writes2)));
   11632   MockConnect connect_data2(ASYNC, OK);
   11633   data2->set_connect_data(connect_data2);
   11634 
   11635   // Set up a proxy config that sends HTTP requests to a proxy, and
   11636   // all others direct.
   11637   ProxyConfig proxy_config;
   11638   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
   11639   CapturingProxyResolver* capturing_proxy_resolver =
   11640       new CapturingProxyResolver();
   11641   session_deps_.proxy_service.reset(new ProxyService(
   11642       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   11643       NULL));
   11644 
   11645   // Load a valid cert.  Note, that this does not need to
   11646   // be valid for proxy because the MockSSLClientSocket does
   11647   // not actually verify it.  But SpdySession will use this
   11648   // to see if it is valid for the new origin
   11649   base::FilePath certs_dir = GetTestCertsDirectory();
   11650   scoped_refptr<X509Certificate> server_cert(
   11651       ImportCertFromFile(certs_dir, "ok_cert.pem"));
   11652   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
   11653 
   11654   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   11655   ssl1.SetNextProto(GetParam());
   11656   ssl1.cert = server_cert;
   11657   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11658   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11659       data1.get());
   11660 
   11661   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   11662   ssl2.SetNextProto(GetParam());
   11663   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11664   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11665       data2.get());
   11666 
   11667   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   11668   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
   11669   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
   11670 
   11671   scoped_refptr<HttpNetworkSession> session(
   11672       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11673 
   11674   // Start the first transaction to set up the SpdySession
   11675   HttpRequestInfo request1;
   11676   request1.method = "GET";
   11677   request1.url = GURL(url1);
   11678   request1.load_flags = 0;
   11679   HttpNetworkTransaction trans1(LOWEST, session.get());
   11680   TestCompletionCallback callback1;
   11681   ASSERT_EQ(ERR_IO_PENDING,
   11682             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11683   data1->RunFor(3);
   11684 
   11685   ASSERT_TRUE(callback1.have_result());
   11686   EXPECT_EQ(OK, callback1.WaitForResult());
   11687   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11688 
   11689   // Now, start the HTTP request
   11690   HttpRequestInfo request2;
   11691   request2.method = "GET";
   11692   request2.url = GURL(url2);
   11693   request2.load_flags = 0;
   11694   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11695   TestCompletionCallback callback2;
   11696   EXPECT_EQ(ERR_IO_PENDING,
   11697             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11698   base::MessageLoop::current()->RunUntilIdle();
   11699   data2->RunFor(3);
   11700 
   11701   ASSERT_TRUE(callback2.have_result());
   11702   EXPECT_EQ(OK, callback2.WaitForResult());
   11703   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11704 }
   11705 
   11706 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
   11707 // error) in SPDY session, removes the socket from pool and closes the SPDY
   11708 // session. Verify that new url's from the same HttpNetworkSession (and a new
   11709 // SpdySession) do work. http://crbug.com/224701
   11710 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
   11711   const std::string https_url = "https://www.google.com/";
   11712 
   11713   MockRead reads1[] = {
   11714     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
   11715   };
   11716 
   11717   scoped_ptr<DeterministicSocketData> data1(
   11718       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
   11719   data1->SetStop(1);
   11720 
   11721   scoped_ptr<SpdyFrame> req2(
   11722       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
   11723   MockWrite writes2[] = {
   11724     CreateMockWrite(*req2, 0),
   11725   };
   11726 
   11727   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11728   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11729   MockRead reads2[] = {
   11730     CreateMockRead(*resp2, 1),
   11731     CreateMockRead(*body2, 2),
   11732     MockRead(ASYNC, OK, 3)  // EOF
   11733   };
   11734 
   11735   scoped_ptr<DeterministicSocketData> data2(
   11736       new DeterministicSocketData(reads2, arraysize(reads2),
   11737                                   writes2, arraysize(writes2)));
   11738 
   11739   SSLSocketDataProvider ssl1(ASYNC, OK);
   11740   ssl1.SetNextProto(GetParam());
   11741   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11742   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11743       data1.get());
   11744 
   11745   SSLSocketDataProvider ssl2(ASYNC, OK);
   11746   ssl2.SetNextProto(GetParam());
   11747   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11748   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11749       data2.get());
   11750 
   11751   scoped_refptr<HttpNetworkSession> session(
   11752       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11753 
   11754   // Start the first transaction to set up the SpdySession and verify that
   11755   // connection was closed.
   11756   HttpRequestInfo request1;
   11757   request1.method = "GET";
   11758   request1.url = GURL(https_url);
   11759   request1.load_flags = 0;
   11760   HttpNetworkTransaction trans1(MEDIUM, session.get());
   11761   TestCompletionCallback callback1;
   11762   EXPECT_EQ(ERR_IO_PENDING,
   11763             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11764   base::MessageLoop::current()->RunUntilIdle();
   11765   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
   11766 
   11767   // Now, start the second request and make sure it succeeds.
   11768   HttpRequestInfo request2;
   11769   request2.method = "GET";
   11770   request2.url = GURL(https_url);
   11771   request2.load_flags = 0;
   11772   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11773   TestCompletionCallback callback2;
   11774   EXPECT_EQ(ERR_IO_PENDING,
   11775             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11776   base::MessageLoop::current()->RunUntilIdle();
   11777   data2->RunFor(3);
   11778 
   11779   ASSERT_TRUE(callback2.have_result());
   11780   EXPECT_EQ(OK, callback2.WaitForResult());
   11781   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11782 }
   11783 
   11784 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
   11785   session_deps_.next_protos = SpdyNextProtos();
   11786   ClientSocketPoolManager::set_max_sockets_per_group(
   11787       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11788   ClientSocketPoolManager::set_max_sockets_per_pool(
   11789       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11790 
   11791   // Use two different hosts with different IPs so they don't get pooled.
   11792   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
   11793   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
   11794   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11795 
   11796   SSLSocketDataProvider ssl1(ASYNC, OK);
   11797   ssl1.SetNextProto(GetParam());
   11798   SSLSocketDataProvider ssl2(ASYNC, OK);
   11799   ssl2.SetNextProto(GetParam());
   11800   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   11801   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   11802 
   11803   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
   11804       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
   11805   MockWrite spdy1_writes[] = {
   11806     CreateMockWrite(*host1_req, 1),
   11807   };
   11808   scoped_ptr<SpdyFrame> host1_resp(
   11809       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11810   scoped_ptr<SpdyFrame> host1_resp_body(
   11811       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11812   MockRead spdy1_reads[] = {
   11813     CreateMockRead(*host1_resp, 2),
   11814     CreateMockRead(*host1_resp_body, 3),
   11815     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11816   };
   11817 
   11818   scoped_ptr<OrderedSocketData> spdy1_data(
   11819       new OrderedSocketData(
   11820           spdy1_reads, arraysize(spdy1_reads),
   11821           spdy1_writes, arraysize(spdy1_writes)));
   11822   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
   11823 
   11824   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
   11825       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
   11826   MockWrite spdy2_writes[] = {
   11827     CreateMockWrite(*host2_req, 1),
   11828   };
   11829   scoped_ptr<SpdyFrame> host2_resp(
   11830       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11831   scoped_ptr<SpdyFrame> host2_resp_body(
   11832       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11833   MockRead spdy2_reads[] = {
   11834     CreateMockRead(*host2_resp, 2),
   11835     CreateMockRead(*host2_resp_body, 3),
   11836     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11837   };
   11838 
   11839   scoped_ptr<OrderedSocketData> spdy2_data(
   11840       new OrderedSocketData(
   11841           spdy2_reads, arraysize(spdy2_reads),
   11842           spdy2_writes, arraysize(spdy2_writes)));
   11843   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
   11844 
   11845   MockWrite http_write[] = {
   11846     MockWrite("GET / HTTP/1.1\r\n"
   11847               "Host: www.a.com\r\n"
   11848               "Connection: keep-alive\r\n\r\n"),
   11849   };
   11850 
   11851   MockRead http_read[] = {
   11852     MockRead("HTTP/1.1 200 OK\r\n"),
   11853     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   11854     MockRead("Content-Length: 6\r\n\r\n"),
   11855     MockRead("hello!"),
   11856   };
   11857   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
   11858                                      http_write, arraysize(http_write));
   11859   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   11860 
   11861   HostPortPair host_port_pair_a("www.a.com", 443);
   11862   SpdySessionKey spdy_session_key_a(
   11863       host_port_pair_a, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   11864   EXPECT_FALSE(
   11865       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11866 
   11867   TestCompletionCallback callback;
   11868   HttpRequestInfo request1;
   11869   request1.method = "GET";
   11870   request1.url = GURL("https://www.a.com/");
   11871   request1.load_flags = 0;
   11872   scoped_ptr<HttpNetworkTransaction> trans(
   11873       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11874 
   11875   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   11876   EXPECT_EQ(ERR_IO_PENDING, rv);
   11877   EXPECT_EQ(OK, callback.WaitForResult());
   11878 
   11879   const HttpResponseInfo* response = trans->GetResponseInfo();
   11880   ASSERT_TRUE(response != NULL);
   11881   ASSERT_TRUE(response->headers.get() != NULL);
   11882   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11883   EXPECT_TRUE(response->was_fetched_via_spdy);
   11884   EXPECT_TRUE(response->was_npn_negotiated);
   11885 
   11886   std::string response_data;
   11887   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11888   EXPECT_EQ("hello!", response_data);
   11889   trans.reset();
   11890   EXPECT_TRUE(
   11891       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11892 
   11893   HostPortPair host_port_pair_b("www.b.com", 443);
   11894   SpdySessionKey spdy_session_key_b(
   11895       host_port_pair_b, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   11896   EXPECT_FALSE(
   11897       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11898   HttpRequestInfo request2;
   11899   request2.method = "GET";
   11900   request2.url = GURL("https://www.b.com/");
   11901   request2.load_flags = 0;
   11902   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11903 
   11904   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
   11905   EXPECT_EQ(ERR_IO_PENDING, rv);
   11906   EXPECT_EQ(OK, callback.WaitForResult());
   11907 
   11908   response = trans->GetResponseInfo();
   11909   ASSERT_TRUE(response != NULL);
   11910   ASSERT_TRUE(response->headers.get() != NULL);
   11911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11912   EXPECT_TRUE(response->was_fetched_via_spdy);
   11913   EXPECT_TRUE(response->was_npn_negotiated);
   11914   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11915   EXPECT_EQ("hello!", response_data);
   11916   EXPECT_FALSE(
   11917       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11918   EXPECT_TRUE(
   11919       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11920 
   11921   HostPortPair host_port_pair_a1("www.a.com", 80);
   11922   SpdySessionKey spdy_session_key_a1(
   11923       host_port_pair_a1, ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   11924   EXPECT_FALSE(
   11925       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
   11926   HttpRequestInfo request3;
   11927   request3.method = "GET";
   11928   request3.url = GURL("http://www.a.com/");
   11929   request3.load_flags = 0;
   11930   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11931 
   11932   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
   11933   EXPECT_EQ(ERR_IO_PENDING, rv);
   11934   EXPECT_EQ(OK, callback.WaitForResult());
   11935 
   11936   response = trans->GetResponseInfo();
   11937   ASSERT_TRUE(response != NULL);
   11938   ASSERT_TRUE(response->headers.get() != NULL);
   11939   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11940   EXPECT_FALSE(response->was_fetched_via_spdy);
   11941   EXPECT_FALSE(response->was_npn_negotiated);
   11942   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11943   EXPECT_EQ("hello!", response_data);
   11944   EXPECT_FALSE(
   11945       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11946   EXPECT_FALSE(
   11947       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11948 }
   11949 
   11950 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
   11951   HttpRequestInfo request;
   11952   request.method = "GET";
   11953   request.url = GURL("http://www.google.com/");
   11954   request.load_flags = 0;
   11955 
   11956   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11957   scoped_ptr<HttpTransaction> trans(
   11958       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11959 
   11960   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
   11961   StaticSocketDataProvider data;
   11962   data.set_connect_data(mock_connect);
   11963   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11964 
   11965   TestCompletionCallback callback;
   11966 
   11967   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11968   EXPECT_EQ(ERR_IO_PENDING, rv);
   11969 
   11970   rv = callback.WaitForResult();
   11971   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   11972 
   11973   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11974 
   11975   // We don't care whether this succeeds or fails, but it shouldn't crash.
   11976   HttpRequestHeaders request_headers;
   11977   trans->GetFullRequestHeaders(&request_headers);
   11978 }
   11979 
   11980 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
   11981   HttpRequestInfo request;
   11982   request.method = "GET";
   11983   request.url = GURL("http://www.google.com/");
   11984   request.load_flags = 0;
   11985 
   11986   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11987   scoped_ptr<HttpTransaction> trans(
   11988       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11989 
   11990   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   11991   StaticSocketDataProvider data;
   11992   data.set_connect_data(mock_connect);
   11993   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11994 
   11995   TestCompletionCallback callback;
   11996 
   11997   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11998   EXPECT_EQ(ERR_IO_PENDING, rv);
   11999 
   12000   rv = callback.WaitForResult();
   12001   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   12002 
   12003   EXPECT_EQ(NULL, trans->GetResponseInfo());
   12004 
   12005   // We don't care whether this succeeds or fails, but it shouldn't crash.
   12006   HttpRequestHeaders request_headers;
   12007   trans->GetFullRequestHeaders(&request_headers);
   12008 }
   12009 
   12010 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
   12011   HttpRequestInfo request;
   12012   request.method = "GET";
   12013   request.url = GURL("http://www.google.com/");
   12014   request.load_flags = 0;
   12015 
   12016   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12017   scoped_ptr<HttpTransaction> trans(
   12018       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12019 
   12020   MockWrite data_writes[] = {
   12021     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12022   };
   12023   MockRead data_reads[] = {
   12024     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   12025   };
   12026 
   12027   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   12028                                 data_writes, arraysize(data_writes));
   12029   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12030 
   12031   TestCompletionCallback callback;
   12032 
   12033   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12034   EXPECT_EQ(ERR_IO_PENDING, rv);
   12035 
   12036   rv = callback.WaitForResult();
   12037   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   12038 
   12039   EXPECT_EQ(NULL, trans->GetResponseInfo());
   12040 
   12041   HttpRequestHeaders request_headers;
   12042   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   12043   EXPECT_TRUE(request_headers.HasHeader("Host"));
   12044 }
   12045 
   12046 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
   12047   HttpRequestInfo request;
   12048   request.method = "GET";
   12049   request.url = GURL("http://www.google.com/");
   12050   request.load_flags = 0;
   12051 
   12052   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12053   scoped_ptr<HttpTransaction> trans(
   12054       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12055 
   12056   MockWrite data_writes[] = {
   12057     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   12058   };
   12059   MockRead data_reads[] = {
   12060     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   12061   };
   12062 
   12063   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   12064                                 data_writes, arraysize(data_writes));
   12065   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12066 
   12067   TestCompletionCallback callback;
   12068 
   12069   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12070   EXPECT_EQ(ERR_IO_PENDING, rv);
   12071 
   12072   rv = callback.WaitForResult();
   12073   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   12074 
   12075   EXPECT_EQ(NULL, trans->GetResponseInfo());
   12076 
   12077   HttpRequestHeaders request_headers;
   12078   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   12079   EXPECT_TRUE(request_headers.HasHeader("Host"));
   12080 }
   12081 
   12082 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
   12083   HttpRequestInfo request;
   12084   request.method = "GET";
   12085   request.url = GURL("http://www.google.com/");
   12086   request.load_flags = 0;
   12087 
   12088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12089   scoped_ptr<HttpTransaction> trans(
   12090       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12091 
   12092   MockWrite data_writes[] = {
   12093     MockWrite("GET / HTTP/1.1\r\n"
   12094               "Host: www.google.com\r\n"
   12095               "Connection: keep-alive\r\n\r\n"),
   12096   };
   12097   MockRead data_reads[] = {
   12098     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12099   };
   12100 
   12101   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   12102                                 data_writes, arraysize(data_writes));
   12103   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12104 
   12105   TestCompletionCallback callback;
   12106 
   12107   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12108   EXPECT_EQ(ERR_IO_PENDING, rv);
   12109 
   12110   rv = callback.WaitForResult();
   12111   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   12112 
   12113   EXPECT_EQ(NULL, trans->GetResponseInfo());
   12114 
   12115   HttpRequestHeaders request_headers;
   12116   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   12117   EXPECT_TRUE(request_headers.HasHeader("Host"));
   12118 }
   12119 
   12120 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
   12121   HttpRequestInfo request;
   12122   request.method = "GET";
   12123   request.url = GURL("http://www.google.com/");
   12124   request.load_flags = 0;
   12125 
   12126   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12127   scoped_ptr<HttpTransaction> trans(
   12128       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12129 
   12130   MockWrite data_writes[] = {
   12131     MockWrite("GET / HTTP/1.1\r\n"
   12132               "Host: www.google.com\r\n"
   12133               "Connection: keep-alive\r\n\r\n"),
   12134   };
   12135   MockRead data_reads[] = {
   12136     MockRead(ASYNC, ERR_CONNECTION_RESET),
   12137   };
   12138 
   12139   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   12140                                 data_writes, arraysize(data_writes));
   12141   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12142 
   12143   TestCompletionCallback callback;
   12144 
   12145   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12146   EXPECT_EQ(ERR_IO_PENDING, rv);
   12147 
   12148   rv = callback.WaitForResult();
   12149   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   12150 
   12151   EXPECT_EQ(NULL, trans->GetResponseInfo());
   12152 
   12153   HttpRequestHeaders request_headers;
   12154   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   12155   EXPECT_TRUE(request_headers.HasHeader("Host"));
   12156 }
   12157 
   12158 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
   12159   HttpRequestInfo request;
   12160   request.method = "GET";
   12161   request.url = GURL("http://www.google.com/");
   12162   request.load_flags = 0;
   12163   request.extra_headers.SetHeader("X-Foo", "bar");
   12164 
   12165   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12166   scoped_ptr<HttpTransaction> trans(
   12167       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12168 
   12169   MockWrite data_writes[] = {
   12170     MockWrite("GET / HTTP/1.1\r\n"
   12171               "Host: www.google.com\r\n"
   12172               "Connection: keep-alive\r\n"
   12173               "X-Foo: bar\r\n\r\n"),
   12174   };
   12175   MockRead data_reads[] = {
   12176     MockRead("HTTP/1.1 200 OK\r\n"
   12177              "Content-Length: 5\r\n\r\n"
   12178              "hello"),
   12179     MockRead(ASYNC, ERR_UNEXPECTED),
   12180   };
   12181 
   12182   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   12183                                 data_writes, arraysize(data_writes));
   12184   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12185 
   12186   TestCompletionCallback callback;
   12187 
   12188   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12189   EXPECT_EQ(ERR_IO_PENDING, rv);
   12190 
   12191   rv = callback.WaitForResult();
   12192   EXPECT_EQ(OK, rv);
   12193 
   12194   HttpRequestHeaders request_headers;
   12195   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   12196   std::string foo;
   12197   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
   12198   EXPECT_EQ("bar", foo);
   12199 }
   12200 
   12201 namespace {
   12202 
   12203 // Fake HttpStreamBase that simply records calls to SetPriority().
   12204 class FakeStream : public HttpStreamBase,
   12205                    public base::SupportsWeakPtr<FakeStream> {
   12206  public:
   12207   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
   12208   virtual ~FakeStream() {}
   12209 
   12210   RequestPriority priority() const { return priority_; }
   12211 
   12212   virtual int InitializeStream(const HttpRequestInfo* request_info,
   12213                                RequestPriority priority,
   12214                                const BoundNetLog& net_log,
   12215                                const CompletionCallback& callback) OVERRIDE {
   12216     return ERR_IO_PENDING;
   12217   }
   12218 
   12219   virtual int SendRequest(const HttpRequestHeaders& request_headers,
   12220                           HttpResponseInfo* response,
   12221                           const CompletionCallback& callback) OVERRIDE {
   12222     ADD_FAILURE();
   12223     return ERR_UNEXPECTED;
   12224   }
   12225 
   12226   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
   12227     ADD_FAILURE();
   12228     return ERR_UNEXPECTED;
   12229   }
   12230 
   12231   virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
   12232                                const CompletionCallback& callback) OVERRIDE {
   12233     ADD_FAILURE();
   12234     return ERR_UNEXPECTED;
   12235   }
   12236 
   12237   virtual void Close(bool not_reusable) OVERRIDE {}
   12238 
   12239   virtual bool IsResponseBodyComplete() const OVERRIDE {
   12240     ADD_FAILURE();
   12241     return false;
   12242   }
   12243 
   12244   virtual bool CanFindEndOfResponse() const OVERRIDE {
   12245     return false;
   12246   }
   12247 
   12248   virtual bool IsConnectionReused() const OVERRIDE {
   12249     ADD_FAILURE();
   12250     return false;
   12251   }
   12252 
   12253   virtual void SetConnectionReused() OVERRIDE {
   12254     ADD_FAILURE();
   12255   }
   12256 
   12257   virtual bool IsConnectionReusable() const OVERRIDE {
   12258     ADD_FAILURE();
   12259     return false;
   12260   }
   12261 
   12262   virtual int64 GetTotalReceivedBytes() const OVERRIDE {
   12263     ADD_FAILURE();
   12264     return 0;
   12265   }
   12266 
   12267   virtual bool GetLoadTimingInfo(
   12268       LoadTimingInfo* load_timing_info) const OVERRIDE {
   12269     ADD_FAILURE();
   12270     return false;
   12271   }
   12272 
   12273   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
   12274     ADD_FAILURE();
   12275   }
   12276 
   12277   virtual void GetSSLCertRequestInfo(
   12278       SSLCertRequestInfo* cert_request_info) OVERRIDE {
   12279     ADD_FAILURE();
   12280   }
   12281 
   12282   virtual bool IsSpdyHttpStream() const OVERRIDE {
   12283     ADD_FAILURE();
   12284     return false;
   12285   }
   12286 
   12287   virtual void Drain(HttpNetworkSession* session) OVERRIDE {
   12288     ADD_FAILURE();
   12289   }
   12290 
   12291   virtual void SetPriority(RequestPriority priority) OVERRIDE {
   12292     priority_ = priority;
   12293   }
   12294 
   12295  private:
   12296   RequestPriority priority_;
   12297 
   12298   DISALLOW_COPY_AND_ASSIGN(FakeStream);
   12299 };
   12300 
   12301 // Fake HttpStreamRequest that simply records calls to SetPriority()
   12302 // and vends FakeStreams with its current priority.
   12303 class FakeStreamRequest : public HttpStreamRequest,
   12304                           public base::SupportsWeakPtr<FakeStreamRequest> {
   12305  public:
   12306   FakeStreamRequest(RequestPriority priority,
   12307                     HttpStreamRequest::Delegate* delegate)
   12308       : priority_(priority),
   12309         delegate_(delegate),
   12310         websocket_stream_create_helper_(NULL) {}
   12311 
   12312   FakeStreamRequest(RequestPriority priority,
   12313                     HttpStreamRequest::Delegate* delegate,
   12314                     WebSocketHandshakeStreamBase::CreateHelper* create_helper)
   12315       : priority_(priority),
   12316         delegate_(delegate),
   12317         websocket_stream_create_helper_(create_helper) {}
   12318 
   12319   virtual ~FakeStreamRequest() {}
   12320 
   12321   RequestPriority priority() const { return priority_; }
   12322 
   12323   const WebSocketHandshakeStreamBase::CreateHelper*
   12324   websocket_stream_create_helper() const {
   12325     return websocket_stream_create_helper_;
   12326   }
   12327 
   12328   // Create a new FakeStream and pass it to the request's
   12329   // delegate. Returns a weak pointer to the FakeStream.
   12330   base::WeakPtr<FakeStream> FinishStreamRequest() {
   12331     FakeStream* fake_stream = new FakeStream(priority_);
   12332     // Do this before calling OnStreamReady() as OnStreamReady() may
   12333     // immediately delete |fake_stream|.
   12334     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
   12335     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
   12336     return weak_stream;
   12337   }
   12338 
   12339   virtual int RestartTunnelWithProxyAuth(
   12340       const AuthCredentials& credentials) OVERRIDE {
   12341     ADD_FAILURE();
   12342     return ERR_UNEXPECTED;
   12343   }
   12344 
   12345   virtual LoadState GetLoadState() const OVERRIDE {
   12346     ADD_FAILURE();
   12347     return LoadState();
   12348   }
   12349 
   12350   virtual void SetPriority(RequestPriority priority) OVERRIDE {
   12351     priority_ = priority;
   12352   }
   12353 
   12354   virtual bool was_npn_negotiated() const OVERRIDE {
   12355     return false;
   12356   }
   12357 
   12358   virtual NextProto protocol_negotiated() const OVERRIDE {
   12359     return kProtoUnknown;
   12360   }
   12361 
   12362   virtual bool using_spdy() const OVERRIDE {
   12363     return false;
   12364   }
   12365 
   12366  private:
   12367   RequestPriority priority_;
   12368   HttpStreamRequest::Delegate* const delegate_;
   12369   WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
   12370 
   12371   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
   12372 };
   12373 
   12374 // Fake HttpStreamFactory that vends FakeStreamRequests.
   12375 class FakeStreamFactory : public HttpStreamFactory {
   12376  public:
   12377   FakeStreamFactory() {}
   12378   virtual ~FakeStreamFactory() {}
   12379 
   12380   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
   12381   // RequestStream() (which may be NULL if it was destroyed already).
   12382   base::WeakPtr<FakeStreamRequest> last_stream_request() {
   12383     return last_stream_request_;
   12384   }
   12385 
   12386   virtual HttpStreamRequest* RequestStream(
   12387       const HttpRequestInfo& info,
   12388       RequestPriority priority,
   12389       const SSLConfig& server_ssl_config,
   12390       const SSLConfig& proxy_ssl_config,
   12391       HttpStreamRequest::Delegate* delegate,
   12392       const BoundNetLog& net_log) OVERRIDE {
   12393     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
   12394     last_stream_request_ = fake_request->AsWeakPtr();
   12395     return fake_request;
   12396   }
   12397 
   12398   virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
   12399       const HttpRequestInfo& info,
   12400       RequestPriority priority,
   12401       const SSLConfig& server_ssl_config,
   12402       const SSLConfig& proxy_ssl_config,
   12403       HttpStreamRequest::Delegate* delegate,
   12404       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
   12405       const BoundNetLog& net_log) OVERRIDE {
   12406     FakeStreamRequest* fake_request =
   12407         new FakeStreamRequest(priority, delegate, create_helper);
   12408     last_stream_request_ = fake_request->AsWeakPtr();
   12409     return fake_request;
   12410   }
   12411 
   12412   virtual void PreconnectStreams(int num_streams,
   12413                                  const HttpRequestInfo& info,
   12414                                  RequestPriority priority,
   12415                                  const SSLConfig& server_ssl_config,
   12416                                  const SSLConfig& proxy_ssl_config) OVERRIDE {
   12417     ADD_FAILURE();
   12418   }
   12419 
   12420   virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
   12421     ADD_FAILURE();
   12422     return NULL;
   12423   }
   12424 
   12425  private:
   12426   base::WeakPtr<FakeStreamRequest> last_stream_request_;
   12427 
   12428   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
   12429 };
   12430 
   12431 // TODO(yhirano): Split this class out into a net/websockets file, if it is
   12432 // worth doing.
   12433 class FakeWebSocketStreamCreateHelper :
   12434       public WebSocketHandshakeStreamBase::CreateHelper {
   12435  public:
   12436   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
   12437       scoped_ptr<ClientSocketHandle> connection,
   12438       bool using_proxy) OVERRIDE {
   12439     NOTREACHED();
   12440     return NULL;
   12441   }
   12442 
   12443   virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
   12444       const base::WeakPtr<SpdySession>& session,
   12445       bool use_relative_url) OVERRIDE {
   12446     NOTREACHED();
   12447     return NULL;
   12448   };
   12449 
   12450   virtual ~FakeWebSocketStreamCreateHelper() {}
   12451 
   12452   virtual scoped_ptr<WebSocketStream> Upgrade() {
   12453     NOTREACHED();
   12454     return scoped_ptr<WebSocketStream>();
   12455   }
   12456 };
   12457 
   12458 }  // namespace
   12459 
   12460 // Make sure that HttpNetworkTransaction passes on its priority to its
   12461 // stream request on start.
   12462 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
   12463   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12464   HttpNetworkSessionPeer peer(session);
   12465   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12466   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12467 
   12468   HttpNetworkTransaction trans(LOW, session.get());
   12469 
   12470   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
   12471 
   12472   HttpRequestInfo request;
   12473   TestCompletionCallback callback;
   12474   EXPECT_EQ(ERR_IO_PENDING,
   12475             trans.Start(&request, callback.callback(), BoundNetLog()));
   12476 
   12477   base::WeakPtr<FakeStreamRequest> fake_request =
   12478       fake_factory->last_stream_request();
   12479   ASSERT_TRUE(fake_request != NULL);
   12480   EXPECT_EQ(LOW, fake_request->priority());
   12481 }
   12482 
   12483 // Make sure that HttpNetworkTransaction passes on its priority
   12484 // updates to its stream request.
   12485 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
   12486   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12487   HttpNetworkSessionPeer peer(session);
   12488   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12489   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12490 
   12491   HttpNetworkTransaction trans(LOW, session.get());
   12492 
   12493   HttpRequestInfo request;
   12494   TestCompletionCallback callback;
   12495   EXPECT_EQ(ERR_IO_PENDING,
   12496             trans.Start(&request, callback.callback(), BoundNetLog()));
   12497 
   12498   base::WeakPtr<FakeStreamRequest> fake_request =
   12499       fake_factory->last_stream_request();
   12500   ASSERT_TRUE(fake_request != NULL);
   12501   EXPECT_EQ(LOW, fake_request->priority());
   12502 
   12503   trans.SetPriority(LOWEST);
   12504   ASSERT_TRUE(fake_request != NULL);
   12505   EXPECT_EQ(LOWEST, fake_request->priority());
   12506 }
   12507 
   12508 // Make sure that HttpNetworkTransaction passes on its priority
   12509 // updates to its stream.
   12510 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
   12511   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12512   HttpNetworkSessionPeer peer(session);
   12513   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12514   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12515 
   12516   HttpNetworkTransaction trans(LOW, session.get());
   12517 
   12518   HttpRequestInfo request;
   12519   TestCompletionCallback callback;
   12520   EXPECT_EQ(ERR_IO_PENDING,
   12521             trans.Start(&request, callback.callback(), BoundNetLog()));
   12522 
   12523   base::WeakPtr<FakeStreamRequest> fake_request =
   12524       fake_factory->last_stream_request();
   12525   ASSERT_TRUE(fake_request != NULL);
   12526   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
   12527   ASSERT_TRUE(fake_stream != NULL);
   12528   EXPECT_EQ(LOW, fake_stream->priority());
   12529 
   12530   trans.SetPriority(LOWEST);
   12531   EXPECT_EQ(LOWEST, fake_stream->priority());
   12532 }
   12533 
   12534 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
   12535   // The same logic needs to be tested for both ws: and wss: schemes, but this
   12536   // test is already parameterised on NextProto, so it uses a loop to verify
   12537   // that the different schemes work.
   12538   std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
   12539   for (size_t i = 0; i < arraysize(test_cases); ++i) {
   12540     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12541     HttpNetworkSessionPeer peer(session);
   12542     FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12543     FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
   12544     peer.SetHttpStreamFactoryForWebSocket(
   12545         scoped_ptr<HttpStreamFactory>(fake_factory));
   12546 
   12547     HttpNetworkTransaction trans(LOW, session.get());
   12548     trans.SetWebSocketHandshakeStreamCreateHelper(
   12549         &websocket_stream_create_helper);
   12550 
   12551     HttpRequestInfo request;
   12552     TestCompletionCallback callback;
   12553     request.method = "GET";
   12554     request.url = GURL(test_cases[i]);
   12555 
   12556     EXPECT_EQ(ERR_IO_PENDING,
   12557               trans.Start(&request, callback.callback(), BoundNetLog()));
   12558 
   12559     base::WeakPtr<FakeStreamRequest> fake_request =
   12560         fake_factory->last_stream_request();
   12561     ASSERT_TRUE(fake_request != NULL);
   12562     EXPECT_EQ(&websocket_stream_create_helper,
   12563               fake_request->websocket_stream_create_helper());
   12564   }
   12565 }
   12566 
   12567 // Tests that when a used socket is returned to the SSL socket pool, it's closed
   12568 // if the transport socket pool is stalled on the global socket limit.
   12569 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
   12570   ClientSocketPoolManager::set_max_sockets_per_group(
   12571       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12572   ClientSocketPoolManager::set_max_sockets_per_pool(
   12573       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12574 
   12575   // Set up SSL request.
   12576 
   12577   HttpRequestInfo ssl_request;
   12578   ssl_request.method = "GET";
   12579   ssl_request.url = GURL("https://www.google.com/");
   12580 
   12581   MockWrite ssl_writes[] = {
   12582     MockWrite("GET / HTTP/1.1\r\n"
   12583               "Host: www.google.com\r\n"
   12584               "Connection: keep-alive\r\n\r\n"),
   12585   };
   12586   MockRead ssl_reads[] = {
   12587     MockRead("HTTP/1.1 200 OK\r\n"),
   12588     MockRead("Content-Length: 11\r\n\r\n"),
   12589     MockRead("hello world"),
   12590     MockRead(SYNCHRONOUS, OK),
   12591   };
   12592   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
   12593                                     ssl_writes, arraysize(ssl_writes));
   12594   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
   12595 
   12596   SSLSocketDataProvider ssl(ASYNC, OK);
   12597   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   12598 
   12599   // Set up HTTP request.
   12600 
   12601   HttpRequestInfo http_request;
   12602   http_request.method = "GET";
   12603   http_request.url = GURL("http://www.google.com/");
   12604 
   12605   MockWrite http_writes[] = {
   12606     MockWrite("GET / HTTP/1.1\r\n"
   12607               "Host: www.google.com\r\n"
   12608               "Connection: keep-alive\r\n\r\n"),
   12609   };
   12610   MockRead http_reads[] = {
   12611     MockRead("HTTP/1.1 200 OK\r\n"),
   12612     MockRead("Content-Length: 7\r\n\r\n"),
   12613     MockRead("falafel"),
   12614     MockRead(SYNCHRONOUS, OK),
   12615   };
   12616   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
   12617                                      http_writes, arraysize(http_writes));
   12618   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   12619 
   12620   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12621 
   12622   // Start the SSL request.
   12623   TestCompletionCallback ssl_callback;
   12624   scoped_ptr<HttpTransaction> ssl_trans(
   12625       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12626   ASSERT_EQ(ERR_IO_PENDING,
   12627             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
   12628             BoundNetLog()));
   12629 
   12630   // Start the HTTP request.  Pool should stall.
   12631   TestCompletionCallback http_callback;
   12632   scoped_ptr<HttpTransaction> http_trans(
   12633       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12634   ASSERT_EQ(ERR_IO_PENDING,
   12635             http_trans->Start(&http_request, http_callback.callback(),
   12636                               BoundNetLog()));
   12637   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
   12638 
   12639   // Wait for response from SSL request.
   12640   ASSERT_EQ(OK, ssl_callback.WaitForResult());
   12641   std::string response_data;
   12642   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
   12643   EXPECT_EQ("hello world", response_data);
   12644 
   12645   // The SSL socket should automatically be closed, so the HTTP request can
   12646   // start.
   12647   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
   12648   ASSERT_FALSE(IsTransportSocketPoolStalled(session.get()));
   12649 
   12650   // The HTTP request can now complete.
   12651   ASSERT_EQ(OK, http_callback.WaitForResult());
   12652   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
   12653   EXPECT_EQ("falafel", response_data);
   12654 
   12655   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   12656 }
   12657 
   12658 // Tests that when a SSL connection is established but there's no corresponding
   12659 // request that needs it, the new socket is closed if the transport socket pool
   12660 // is stalled on the global socket limit.
   12661 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
   12662   ClientSocketPoolManager::set_max_sockets_per_group(
   12663       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12664   ClientSocketPoolManager::set_max_sockets_per_pool(
   12665       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12666 
   12667   // Set up an ssl request.
   12668 
   12669   HttpRequestInfo ssl_request;
   12670   ssl_request.method = "GET";
   12671   ssl_request.url = GURL("https://www.foopy.com/");
   12672 
   12673   // No data will be sent on the SSL socket.
   12674   StaticSocketDataProvider ssl_data;
   12675   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
   12676 
   12677   SSLSocketDataProvider ssl(ASYNC, OK);
   12678   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   12679 
   12680   // Set up HTTP request.
   12681 
   12682   HttpRequestInfo http_request;
   12683   http_request.method = "GET";
   12684   http_request.url = GURL("http://www.google.com/");
   12685 
   12686   MockWrite http_writes[] = {
   12687     MockWrite("GET / HTTP/1.1\r\n"
   12688               "Host: www.google.com\r\n"
   12689               "Connection: keep-alive\r\n\r\n"),
   12690   };
   12691   MockRead http_reads[] = {
   12692     MockRead("HTTP/1.1 200 OK\r\n"),
   12693     MockRead("Content-Length: 7\r\n\r\n"),
   12694     MockRead("falafel"),
   12695     MockRead(SYNCHRONOUS, OK),
   12696   };
   12697   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
   12698                                      http_writes, arraysize(http_writes));
   12699   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   12700 
   12701   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12702 
   12703   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
   12704   // cancelled when a normal transaction is cancelled.
   12705   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
   12706   net::SSLConfig ssl_config;
   12707   session->ssl_config_service()->GetSSLConfig(&ssl_config);
   12708   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
   12709                                          ssl_config, ssl_config);
   12710   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session.get()));
   12711 
   12712   // Start the HTTP request.  Pool should stall.
   12713   TestCompletionCallback http_callback;
   12714   scoped_ptr<HttpTransaction> http_trans(
   12715       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12716   ASSERT_EQ(ERR_IO_PENDING,
   12717             http_trans->Start(&http_request, http_callback.callback(),
   12718                               BoundNetLog()));
   12719   EXPECT_TRUE(IsTransportSocketPoolStalled(session.get()));
   12720 
   12721   // The SSL connection will automatically be closed once the connection is
   12722   // established, to let the HTTP request start.
   12723   ASSERT_EQ(OK, http_callback.WaitForResult());
   12724   std::string response_data;
   12725   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
   12726   EXPECT_EQ("falafel", response_data);
   12727 
   12728   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   12729 }
   12730 
   12731 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterReset) {
   12732   ScopedVector<UploadElementReader> element_readers;
   12733   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   12734   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   12735 
   12736   HttpRequestInfo request;
   12737   request.method = "POST";
   12738   request.url = GURL("http://www.foo.com/");
   12739   request.upload_data_stream = &upload_data_stream;
   12740   request.load_flags = 0;
   12741 
   12742   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12743   scoped_ptr<HttpTransaction> trans(
   12744       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12745   // Send headers successfully, but get an error while sending the body.
   12746   MockWrite data_writes[] = {
   12747     MockWrite("POST / HTTP/1.1\r\n"
   12748               "Host: www.foo.com\r\n"
   12749               "Connection: keep-alive\r\n"
   12750               "Content-Length: 3\r\n\r\n"),
   12751     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12752   };
   12753 
   12754   MockRead data_reads[] = {
   12755     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
   12756     MockRead("hello world"),
   12757     MockRead(SYNCHRONOUS, OK),
   12758   };
   12759   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   12760                                 arraysize(data_writes));
   12761   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12762 
   12763   TestCompletionCallback callback;
   12764 
   12765   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12766   EXPECT_EQ(ERR_IO_PENDING, rv);
   12767 
   12768   rv = callback.WaitForResult();
   12769   EXPECT_EQ(OK, rv);
   12770 
   12771   const HttpResponseInfo* response = trans->GetResponseInfo();
   12772   ASSERT_TRUE(response != NULL);
   12773 
   12774   EXPECT_TRUE(response->headers.get() != NULL);
   12775   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
   12776 
   12777   std::string response_data;
   12778   rv = ReadTransaction(trans.get(), &response_data);
   12779   EXPECT_EQ(OK, rv);
   12780   EXPECT_EQ("hello world", response_data);
   12781 }
   12782 
   12783 // This test makes sure the retry logic doesn't trigger when reading an error
   12784 // response from a server that rejected a POST with a CONNECTION_RESET.
   12785 TEST_P(HttpNetworkTransactionTest,
   12786        PostReadsErrorResponseAfterResetOnReusedSocket) {
   12787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12788   MockWrite data_writes[] = {
   12789     MockWrite("GET / HTTP/1.1\r\n"
   12790               "Host: www.foo.com\r\n"
   12791               "Connection: keep-alive\r\n\r\n"),
   12792     MockWrite("POST / HTTP/1.1\r\n"
   12793               "Host: www.foo.com\r\n"
   12794               "Connection: keep-alive\r\n"
   12795               "Content-Length: 3\r\n\r\n"),
   12796     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12797   };
   12798 
   12799   MockRead data_reads[] = {
   12800     MockRead("HTTP/1.1 200 Peachy\r\n"
   12801              "Content-Length: 14\r\n\r\n"),
   12802     MockRead("first response"),
   12803     MockRead("HTTP/1.1 400 Not OK\r\n"
   12804              "Content-Length: 15\r\n\r\n"),
   12805     MockRead("second response"),
   12806     MockRead(SYNCHRONOUS, OK),
   12807   };
   12808   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   12809                                 arraysize(data_writes));
   12810   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12811 
   12812   TestCompletionCallback callback;
   12813   HttpRequestInfo request1;
   12814   request1.method = "GET";
   12815   request1.url = GURL("http://www.foo.com/");
   12816   request1.load_flags = 0;
   12817 
   12818   scoped_ptr<HttpTransaction> trans1(
   12819       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12820   int rv = trans1->Start(&request1, callback.callback(), BoundNetLog());
   12821   EXPECT_EQ(ERR_IO_PENDING, rv);
   12822 
   12823   rv = callback.WaitForResult();
   12824   EXPECT_EQ(OK, rv);
   12825 
   12826   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   12827   ASSERT_TRUE(response1 != NULL);
   12828 
   12829   EXPECT_TRUE(response1->headers.get() != NULL);
   12830   EXPECT_EQ("HTTP/1.1 200 Peachy", response1->headers->GetStatusLine());
   12831 
   12832   std::string response_data1;
   12833   rv = ReadTransaction(trans1.get(), &response_data1);
   12834   EXPECT_EQ(OK, rv);
   12835   EXPECT_EQ("first response", response_data1);
   12836   // Delete the transaction to release the socket back into the socket pool.
   12837   trans1.reset();
   12838 
   12839   ScopedVector<UploadElementReader> element_readers;
   12840   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   12841   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   12842 
   12843   HttpRequestInfo request2;
   12844   request2.method = "POST";
   12845   request2.url = GURL("http://www.foo.com/");
   12846   request2.upload_data_stream = &upload_data_stream;
   12847   request2.load_flags = 0;
   12848 
   12849   scoped_ptr<HttpTransaction> trans2(
   12850       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12851   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   12852   EXPECT_EQ(ERR_IO_PENDING, rv);
   12853 
   12854   rv = callback.WaitForResult();
   12855   EXPECT_EQ(OK, rv);
   12856 
   12857   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   12858   ASSERT_TRUE(response2 != NULL);
   12859 
   12860   EXPECT_TRUE(response2->headers.get() != NULL);
   12861   EXPECT_EQ("HTTP/1.1 400 Not OK", response2->headers->GetStatusLine());
   12862 
   12863   std::string response_data2;
   12864   rv = ReadTransaction(trans2.get(), &response_data2);
   12865   EXPECT_EQ(OK, rv);
   12866   EXPECT_EQ("second response", response_data2);
   12867 }
   12868 
   12869 TEST_P(HttpNetworkTransactionTest,
   12870        PostReadsErrorResponseAfterResetPartialBodySent) {
   12871   ScopedVector<UploadElementReader> element_readers;
   12872   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   12873   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   12874 
   12875   HttpRequestInfo request;
   12876   request.method = "POST";
   12877   request.url = GURL("http://www.foo.com/");
   12878   request.upload_data_stream = &upload_data_stream;
   12879   request.load_flags = 0;
   12880 
   12881   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12882   scoped_ptr<HttpTransaction> trans(
   12883       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12884   // Send headers successfully, but get an error while sending the body.
   12885   MockWrite data_writes[] = {
   12886     MockWrite("POST / HTTP/1.1\r\n"
   12887               "Host: www.foo.com\r\n"
   12888               "Connection: keep-alive\r\n"
   12889               "Content-Length: 3\r\n\r\n"
   12890               "fo"),
   12891     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12892   };
   12893 
   12894   MockRead data_reads[] = {
   12895     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
   12896     MockRead("hello world"),
   12897     MockRead(SYNCHRONOUS, OK),
   12898   };
   12899   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   12900                                 arraysize(data_writes));
   12901   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12902 
   12903   TestCompletionCallback callback;
   12904 
   12905   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12906   EXPECT_EQ(ERR_IO_PENDING, rv);
   12907 
   12908   rv = callback.WaitForResult();
   12909   EXPECT_EQ(OK, rv);
   12910 
   12911   const HttpResponseInfo* response = trans->GetResponseInfo();
   12912   ASSERT_TRUE(response != NULL);
   12913 
   12914   EXPECT_TRUE(response->headers.get() != NULL);
   12915   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
   12916 
   12917   std::string response_data;
   12918   rv = ReadTransaction(trans.get(), &response_data);
   12919   EXPECT_EQ(OK, rv);
   12920   EXPECT_EQ("hello world", response_data);
   12921 }
   12922 
   12923 // This tests the more common case than the previous test, where headers and
   12924 // body are not merged into a single request.
   12925 TEST_P(HttpNetworkTransactionTest, ChunkedPostReadsErrorResponseAfterReset) {
   12926   ScopedVector<UploadElementReader> element_readers;
   12927   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   12928   UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0);
   12929 
   12930   HttpRequestInfo request;
   12931   request.method = "POST";
   12932   request.url = GURL("http://www.foo.com/");
   12933   request.upload_data_stream = &upload_data_stream;
   12934   request.load_flags = 0;
   12935 
   12936   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12937   scoped_ptr<HttpTransaction> trans(
   12938       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12939   // Send headers successfully, but get an error while sending the body.
   12940   MockWrite data_writes[] = {
   12941     MockWrite("POST / HTTP/1.1\r\n"
   12942               "Host: www.foo.com\r\n"
   12943               "Connection: keep-alive\r\n"
   12944               "Transfer-Encoding: chunked\r\n\r\n"),
   12945     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   12946   };
   12947 
   12948   MockRead data_reads[] = {
   12949     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
   12950     MockRead("hello world"),
   12951     MockRead(SYNCHRONOUS, OK),
   12952   };
   12953   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   12954                                 arraysize(data_writes));
   12955   session_deps_.socket_factory->AddSocketDataProvider(&data);
   12956 
   12957   TestCompletionCallback callback;
   12958 
   12959   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   12960   EXPECT_EQ(ERR_IO_PENDING, rv);
   12961   // Make sure the headers are sent before adding a chunk.  This ensures that
   12962   // they can't be merged with the body in a single send.  Not currently
   12963   // necessary since a chunked body is never merged with headers, but this makes
   12964   // the test more future proof.
   12965   base::RunLoop().RunUntilIdle();
   12966 
   12967   upload_data_stream.AppendChunk("last chunk", 10, true);
   12968 
   12969   rv = callback.WaitForResult();
   12970   EXPECT_EQ(OK, rv);
   12971 
   12972   const HttpResponseInfo* response = trans->GetResponseInfo();
   12973   ASSERT_TRUE(response != NULL);
   12974 
   12975   EXPECT_TRUE(response->headers.get() != NULL);
   12976   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
   12977 
   12978   std::string response_data;
   12979   rv = ReadTransaction(trans.get(), &response_data);
   12980   EXPECT_EQ(OK, rv);
   12981   EXPECT_EQ("hello world", response_data);
   12982 }
   12983 
   12984 TEST_P(HttpNetworkTransactionTest, PostReadsErrorResponseAfterResetAnd100) {
   12985   ScopedVector<UploadElementReader> element_readers;
   12986   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   12987   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   12988 
   12989   HttpRequestInfo request;
   12990   request.method = "POST";
   12991   request.url = GURL("http://www.foo.com/");
   12992   request.upload_data_stream = &upload_data_stream;
   12993   request.load_flags = 0;
   12994 
   12995   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12996   scoped_ptr<HttpTransaction> trans(
   12997       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12998 
   12999   MockWrite data_writes[] = {
   13000     MockWrite("POST / HTTP/1.1\r\n"
   13001               "Host: www.foo.com\r\n"
   13002               "Connection: keep-alive\r\n"
   13003               "Content-Length: 3\r\n\r\n"),
   13004     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   13005   };
   13006 
   13007   MockRead data_reads[] = {
   13008     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   13009     MockRead("HTTP/1.0 400 Not OK\r\n\r\n"),
   13010     MockRead("hello world"),
   13011     MockRead(SYNCHRONOUS, OK),
   13012   };
   13013   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   13014                                 arraysize(data_writes));
   13015   session_deps_.socket_factory->AddSocketDataProvider(&data);
   13016 
   13017   TestCompletionCallback callback;
   13018 
   13019   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   13020   EXPECT_EQ(ERR_IO_PENDING, rv);
   13021 
   13022   rv = callback.WaitForResult();
   13023   EXPECT_EQ(OK, rv);
   13024 
   13025   const HttpResponseInfo* response = trans->GetResponseInfo();
   13026   ASSERT_TRUE(response != NULL);
   13027 
   13028   EXPECT_TRUE(response->headers.get() != NULL);
   13029   EXPECT_EQ("HTTP/1.0 400 Not OK", response->headers->GetStatusLine());
   13030 
   13031   std::string response_data;
   13032   rv = ReadTransaction(trans.get(), &response_data);
   13033   EXPECT_EQ(OK, rv);
   13034   EXPECT_EQ("hello world", response_data);
   13035 }
   13036 
   13037 TEST_P(HttpNetworkTransactionTest, PostIgnoresNonErrorResponseAfterReset) {
   13038   ScopedVector<UploadElementReader> element_readers;
   13039   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   13040   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   13041 
   13042   HttpRequestInfo request;
   13043   request.method = "POST";
   13044   request.url = GURL("http://www.foo.com/");
   13045   request.upload_data_stream = &upload_data_stream;
   13046   request.load_flags = 0;
   13047 
   13048   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   13049   scoped_ptr<HttpTransaction> trans(
   13050       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   13051   // Send headers successfully, but get an error while sending the body.
   13052   MockWrite data_writes[] = {
   13053     MockWrite("POST / HTTP/1.1\r\n"
   13054               "Host: www.foo.com\r\n"
   13055               "Connection: keep-alive\r\n"
   13056               "Content-Length: 3\r\n\r\n"),
   13057     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   13058   };
   13059 
   13060   MockRead data_reads[] = {
   13061     MockRead("HTTP/1.0 200 Just Dandy\r\n\r\n"),
   13062     MockRead("hello world"),
   13063     MockRead(SYNCHRONOUS, OK),
   13064   };
   13065   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   13066                                 arraysize(data_writes));
   13067   session_deps_.socket_factory->AddSocketDataProvider(&data);
   13068 
   13069   TestCompletionCallback callback;
   13070 
   13071   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   13072   EXPECT_EQ(ERR_IO_PENDING, rv);
   13073 
   13074   rv = callback.WaitForResult();
   13075   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   13076 
   13077   const HttpResponseInfo* response = trans->GetResponseInfo();
   13078   EXPECT_TRUE(response == NULL);
   13079 }
   13080 
   13081 TEST_P(HttpNetworkTransactionTest,
   13082        PostIgnoresNonErrorResponseAfterResetAnd100) {
   13083   ScopedVector<UploadElementReader> element_readers;
   13084   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   13085   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   13086 
   13087   HttpRequestInfo request;
   13088   request.method = "POST";
   13089   request.url = GURL("http://www.foo.com/");
   13090   request.upload_data_stream = &upload_data_stream;
   13091   request.load_flags = 0;
   13092 
   13093   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   13094   scoped_ptr<HttpTransaction> trans(
   13095       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   13096   // Send headers successfully, but get an error while sending the body.
   13097   MockWrite data_writes[] = {
   13098     MockWrite("POST / HTTP/1.1\r\n"
   13099               "Host: www.foo.com\r\n"
   13100               "Connection: keep-alive\r\n"
   13101               "Content-Length: 3\r\n\r\n"),
   13102     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   13103   };
   13104 
   13105   MockRead data_reads[] = {
   13106     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   13107     MockRead("HTTP/1.0 302 Redirect\r\n"),
   13108     MockRead("Location: http://somewhere-else.com/\r\n"),
   13109     MockRead("Content-Length: 0\r\n\r\n"),
   13110     MockRead(SYNCHRONOUS, OK),
   13111   };
   13112   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   13113                                 arraysize(data_writes));
   13114   session_deps_.socket_factory->AddSocketDataProvider(&data);
   13115 
   13116   TestCompletionCallback callback;
   13117 
   13118   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   13119   EXPECT_EQ(ERR_IO_PENDING, rv);
   13120 
   13121   rv = callback.WaitForResult();
   13122   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   13123 
   13124   const HttpResponseInfo* response = trans->GetResponseInfo();
   13125   EXPECT_TRUE(response == NULL);
   13126 }
   13127 
   13128 TEST_P(HttpNetworkTransactionTest, PostIgnoresHttp09ResponseAfterReset) {
   13129   ScopedVector<UploadElementReader> element_readers;
   13130   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   13131   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   13132 
   13133   HttpRequestInfo request;
   13134   request.method = "POST";
   13135   request.url = GURL("http://www.foo.com/");
   13136   request.upload_data_stream = &upload_data_stream;
   13137   request.load_flags = 0;
   13138 
   13139   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   13140   scoped_ptr<HttpTransaction> trans(
   13141       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   13142   // Send headers successfully, but get an error while sending the body.
   13143   MockWrite data_writes[] = {
   13144     MockWrite("POST / HTTP/1.1\r\n"
   13145               "Host: www.foo.com\r\n"
   13146               "Connection: keep-alive\r\n"
   13147               "Content-Length: 3\r\n\r\n"),
   13148     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   13149   };
   13150 
   13151   MockRead data_reads[] = {
   13152     MockRead("HTTP 0.9 rocks!"),
   13153     MockRead(SYNCHRONOUS, OK),
   13154   };
   13155   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   13156                                 arraysize(data_writes));
   13157   session_deps_.socket_factory->AddSocketDataProvider(&data);
   13158 
   13159   TestCompletionCallback callback;
   13160 
   13161   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   13162   EXPECT_EQ(ERR_IO_PENDING, rv);
   13163 
   13164   rv = callback.WaitForResult();
   13165   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   13166 
   13167   const HttpResponseInfo* response = trans->GetResponseInfo();
   13168   EXPECT_TRUE(response == NULL);
   13169 }
   13170 
   13171 TEST_P(HttpNetworkTransactionTest, PostIgnoresPartial400HeadersAfterReset) {
   13172   ScopedVector<UploadElementReader> element_readers;
   13173   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   13174   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   13175 
   13176   HttpRequestInfo request;
   13177   request.method = "POST";
   13178   request.url = GURL("http://www.foo.com/");
   13179   request.upload_data_stream = &upload_data_stream;
   13180   request.load_flags = 0;
   13181 
   13182   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   13183   scoped_ptr<HttpTransaction> trans(
   13184       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   13185   // Send headers successfully, but get an error while sending the body.
   13186   MockWrite data_writes[] = {
   13187     MockWrite("POST / HTTP/1.1\r\n"
   13188               "Host: www.foo.com\r\n"
   13189               "Connection: keep-alive\r\n"
   13190               "Content-Length: 3\r\n\r\n"),
   13191     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   13192   };
   13193 
   13194   MockRead data_reads[] = {
   13195     MockRead("HTTP/1.0 400 Not a Full Response\r\n"),
   13196     MockRead(SYNCHRONOUS, OK),
   13197   };
   13198   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   13199                                 arraysize(data_writes));
   13200   session_deps_.socket_factory->AddSocketDataProvider(&data);
   13201 
   13202   TestCompletionCallback callback;
   13203 
   13204   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   13205   EXPECT_EQ(ERR_IO_PENDING, rv);
   13206 
   13207   rv = callback.WaitForResult();
   13208   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   13209 
   13210   const HttpResponseInfo* response = trans->GetResponseInfo();
   13211   EXPECT_TRUE(response == NULL);
   13212 }
   13213 
   13214 }  // namespace net
   13215