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/file_util.h"
     15 #include "base/files/file_path.h"
     16 #include "base/json/json_writer.h"
     17 #include "base/memory/scoped_ptr.h"
     18 #include "base/strings/string_util.h"
     19 #include "base/strings/utf_string_conversions.h"
     20 #include "base/test/test_file_util.h"
     21 #include "net/base/auth.h"
     22 #include "net/base/capturing_net_log.h"
     23 #include "net/base/completion_callback.h"
     24 #include "net/base/load_timing_info.h"
     25 #include "net/base/load_timing_info_test_util.h"
     26 #include "net/base/net_log.h"
     27 #include "net/base/net_log_unittest.h"
     28 #include "net/base/request_priority.h"
     29 #include "net/base/test_completion_callback.h"
     30 #include "net/base/test_data_directory.h"
     31 #include "net/base/upload_bytes_element_reader.h"
     32 #include "net/base/upload_data_stream.h"
     33 #include "net/base/upload_file_element_reader.h"
     34 #include "net/cert/mock_cert_verifier.h"
     35 #include "net/dns/host_cache.h"
     36 #include "net/dns/mock_host_resolver.h"
     37 #include "net/http/http_auth_handler_digest.h"
     38 #include "net/http/http_auth_handler_mock.h"
     39 #include "net/http/http_auth_handler_ntlm.h"
     40 #include "net/http/http_basic_stream.h"
     41 #include "net/http/http_network_session.h"
     42 #include "net/http/http_network_session_peer.h"
     43 #include "net/http/http_server_properties_impl.h"
     44 #include "net/http/http_stream.h"
     45 #include "net/http/http_stream_factory.h"
     46 #include "net/http/http_transaction_unittest.h"
     47 #include "net/proxy/proxy_config_service_fixed.h"
     48 #include "net/proxy/proxy_resolver.h"
     49 #include "net/proxy/proxy_service.h"
     50 #include "net/socket/client_socket_factory.h"
     51 #include "net/socket/client_socket_pool_manager.h"
     52 #include "net/socket/mock_client_socket_pool_manager.h"
     53 #include "net/socket/next_proto.h"
     54 #include "net/socket/socket_test_util.h"
     55 #include "net/socket/ssl_client_socket.h"
     56 #include "net/spdy/spdy_framer.h"
     57 #include "net/spdy/spdy_session.h"
     58 #include "net/spdy/spdy_session_pool.h"
     59 #include "net/spdy/spdy_test_util_common.h"
     60 #include "net/ssl/ssl_cert_request_info.h"
     61 #include "net/ssl/ssl_config_service_defaults.h"
     62 #include "net/ssl/ssl_info.h"
     63 #include "net/test/cert_test_util.h"
     64 #include "testing/gtest/include/gtest/gtest.h"
     65 #include "testing/platform_test.h"
     66 #include "url/gurl.h"
     67 
     68 //-----------------------------------------------------------------------------
     69 
     70 namespace {
     71 
     72 const base::string16 kBar(ASCIIToUTF16("bar"));
     73 const base::string16 kBar2(ASCIIToUTF16("bar2"));
     74 const base::string16 kBar3(ASCIIToUTF16("bar3"));
     75 const base::string16 kBaz(ASCIIToUTF16("baz"));
     76 const base::string16 kFirst(ASCIIToUTF16("first"));
     77 const base::string16 kFoo(ASCIIToUTF16("foo"));
     78 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
     79 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
     80 const base::string16 kFou(ASCIIToUTF16("fou"));
     81 const base::string16 kSecond(ASCIIToUTF16("second"));
     82 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
     83 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
     84 
     85 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
     86   return session->GetTransportSocketPool(
     87       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     88 }
     89 
     90 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
     91   return session->GetSSLSocketPool(
     92       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     93 }
     94 
     95 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
     96 // a JSONified list of headers as a single string.  Uses single quotes instead
     97 // of double quotes for easier comparison.  Returns false on failure.
     98 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
     99   if (!params)
    100     return false;
    101   base::ListValue* header_list;
    102   if (!params->GetList("headers", &header_list))
    103     return false;
    104   std::string double_quote_headers;
    105   base::JSONWriter::Write(header_list, &double_quote_headers);
    106   ReplaceChars(double_quote_headers, "\"", "'", headers);
    107   return true;
    108 }
    109 
    110 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
    111 // used.
    112 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
    113   EXPECT_TRUE(load_timing_info.socket_reused);
    114   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    115 
    116   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    117   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    118 
    119   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    120   EXPECT_FALSE(load_timing_info.send_start.is_null());
    121 
    122   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    123 
    124   // Set at a higher level.
    125   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    126   EXPECT_TRUE(load_timing_info.request_start.is_null());
    127   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    128 }
    129 
    130 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
    131 // used.
    132 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
    133                              int connect_timing_flags) {
    134   EXPECT_FALSE(load_timing_info.socket_reused);
    135   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    136 
    137   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    138   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    139 
    140   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    141                                    connect_timing_flags);
    142   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    143             load_timing_info.send_start);
    144 
    145   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    146 
    147   // Set at a higher level.
    148   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    149   EXPECT_TRUE(load_timing_info.request_start.is_null());
    150   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    151 }
    152 
    153 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
    154 // used.
    155 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
    156   EXPECT_TRUE(load_timing_info.socket_reused);
    157   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    158 
    159   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    160 
    161   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    162   EXPECT_LE(load_timing_info.proxy_resolve_start,
    163             load_timing_info.proxy_resolve_end);
    164   EXPECT_LE(load_timing_info.proxy_resolve_end,
    165             load_timing_info.send_start);
    166   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    167 
    168   // Set at a higher level.
    169   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    170   EXPECT_TRUE(load_timing_info.request_start.is_null());
    171   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    172 }
    173 
    174 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
    175 // used.
    176 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
    177                                     int connect_timing_flags) {
    178   EXPECT_FALSE(load_timing_info.socket_reused);
    179   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    180 
    181   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    182   EXPECT_LE(load_timing_info.proxy_resolve_start,
    183             load_timing_info.proxy_resolve_end);
    184   EXPECT_LE(load_timing_info.proxy_resolve_end,
    185             load_timing_info.connect_timing.connect_start);
    186   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    187                                    connect_timing_flags);
    188   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    189             load_timing_info.send_start);
    190 
    191   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    192 
    193   // Set at a higher level.
    194   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    195   EXPECT_TRUE(load_timing_info.request_start.is_null());
    196   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    197 }
    198 
    199 }  // namespace
    200 
    201 namespace net {
    202 
    203 namespace {
    204 
    205 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
    206   return SpdySessionDependencies::SpdyCreateSession(session_deps);
    207 }
    208 
    209 }  // namespace
    210 
    211 class HttpNetworkTransactionTest
    212     : public PlatformTest,
    213       public ::testing::WithParamInterface<NextProto> {
    214  public:
    215   virtual ~HttpNetworkTransactionTest() {
    216     // Important to restore the per-pool limit first, since the pool limit must
    217     // always be greater than group limit, and the tests reduce both limits.
    218     ClientSocketPoolManager::set_max_sockets_per_pool(
    219         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    220     ClientSocketPoolManager::set_max_sockets_per_group(
    221         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    222   }
    223 
    224  protected:
    225   HttpNetworkTransactionTest()
    226       : spdy_util_(GetParam()),
    227         session_deps_(GetParam()),
    228         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    229             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    230         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    231             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
    232   }
    233 
    234   struct SimpleGetHelperResult {
    235     int rv;
    236     std::string status_line;
    237     std::string response_data;
    238     LoadTimingInfo load_timing_info;
    239   };
    240 
    241   virtual void SetUp() {
    242     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    243     base::MessageLoop::current()->RunUntilIdle();
    244   }
    245 
    246   virtual void TearDown() {
    247     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    248     base::MessageLoop::current()->RunUntilIdle();
    249     // Empty the current queue.
    250     base::MessageLoop::current()->RunUntilIdle();
    251     PlatformTest::TearDown();
    252     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    253     base::MessageLoop::current()->RunUntilIdle();
    254     HttpStreamFactory::set_use_alternate_protocols(false);
    255     HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
    256   }
    257 
    258   // This is the expected return from a current server advertising SPDY.
    259   std::string GetAlternateProtocolHttpHeader() {
    260     return
    261         std::string("Alternate-Protocol: 443:") +
    262         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
    263         "\r\n\r\n";
    264   }
    265 
    266   // Either |write_failure| specifies a write failure or |read_failure|
    267   // specifies a read failure when using a reused socket.  In either case, the
    268   // failure should cause the network transaction to resend the request, and the
    269   // other argument should be NULL.
    270   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
    271                                             const MockRead* read_failure);
    272 
    273   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
    274                                                size_t data_count) {
    275     SimpleGetHelperResult out;
    276 
    277     HttpRequestInfo request;
    278     request.method = "GET";
    279     request.url = GURL("http://www.google.com/");
    280     request.load_flags = 0;
    281 
    282     CapturingBoundNetLog log;
    283     session_deps_.net_log = log.bound().net_log();
    284     scoped_ptr<HttpTransaction> trans(
    285         new HttpNetworkTransaction(DEFAULT_PRIORITY,
    286                                    CreateSession(&session_deps_)));
    287 
    288     for (size_t i = 0; i < data_count; ++i) {
    289       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
    290     }
    291 
    292     TestCompletionCallback callback;
    293 
    294     EXPECT_TRUE(log.bound().IsLoggingAllEvents());
    295     int rv = trans->Start(&request, callback.callback(), log.bound());
    296     EXPECT_EQ(ERR_IO_PENDING, rv);
    297 
    298     out.rv = callback.WaitForResult();
    299 
    300     // Even in the failure cases that use this function, connections are always
    301     // successfully established before the error.
    302     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
    303     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
    304 
    305     if (out.rv != OK)
    306       return out;
    307 
    308     const HttpResponseInfo* response = trans->GetResponseInfo();
    309     // Can't use ASSERT_* inside helper functions like this, so
    310     // return an error.
    311     if (response == NULL || response->headers.get() == NULL) {
    312       out.rv = ERR_UNEXPECTED;
    313       return out;
    314     }
    315     out.status_line = response->headers->GetStatusLine();
    316 
    317     EXPECT_EQ("127.0.0.1", response->socket_address.host());
    318     EXPECT_EQ(80, response->socket_address.port());
    319 
    320     rv = ReadTransaction(trans.get(), &out.response_data);
    321     EXPECT_EQ(OK, rv);
    322 
    323     net::CapturingNetLog::CapturedEntryList entries;
    324     log.GetEntries(&entries);
    325     size_t pos = ExpectLogContainsSomewhere(
    326         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
    327         NetLog::PHASE_NONE);
    328     ExpectLogContainsSomewhere(
    329         entries, pos,
    330         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
    331         NetLog::PHASE_NONE);
    332 
    333     std::string line;
    334     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
    335     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
    336 
    337     HttpRequestHeaders request_headers;
    338     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
    339     std::string value;
    340     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
    341     EXPECT_EQ("www.google.com", value);
    342     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
    343     EXPECT_EQ("keep-alive", value);
    344 
    345     std::string response_headers;
    346     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
    347     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
    348               response_headers);
    349 
    350     return out;
    351   }
    352 
    353   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
    354                                         size_t reads_count) {
    355     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
    356     StaticSocketDataProvider* data[] = { &reads };
    357     return SimpleGetHelperForData(data, 1);
    358   }
    359 
    360   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    361                                              int expected_status);
    362 
    363   void ConnectStatusHelper(const MockRead& status);
    364 
    365   void BypassHostCacheOnRefreshHelper(int load_flags);
    366 
    367   void CheckErrorIsPassedBack(int error, IoMode mode);
    368 
    369   SpdyTestUtil spdy_util_;
    370   SpdySessionDependencies session_deps_;
    371 
    372   // Original socket limits.  Some tests set these.  Safest to always restore
    373   // them once each test has been run.
    374   int old_max_group_sockets_;
    375   int old_max_pool_sockets_;
    376 };
    377 
    378 INSTANTIATE_TEST_CASE_P(
    379     NextProto,
    380     HttpNetworkTransactionTest,
    381     testing::Values(kProtoSPDY2, kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
    382                     kProtoHTTP2Draft04));
    383 
    384 namespace {
    385 
    386 // Fill |str| with a long header list that consumes >= |size| bytes.
    387 void FillLargeHeadersString(std::string* str, int size) {
    388   const char* row =
    389       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    390   const int sizeof_row = strlen(row);
    391   const int num_rows = static_cast<int>(
    392       ceil(static_cast<float>(size) / sizeof_row));
    393   const int sizeof_data = num_rows * sizeof_row;
    394   DCHECK(sizeof_data >= size);
    395   str->reserve(sizeof_data);
    396 
    397   for (int i = 0; i < num_rows; ++i)
    398     str->append(row, sizeof_row);
    399 }
    400 
    401 // Alternative functions that eliminate randomness and dependency on the local
    402 // host name so that the generated NTLM messages are reproducible.
    403 void MockGenerateRandom1(uint8* output, size_t n) {
    404   static const uint8 bytes[] = {
    405     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    406   };
    407   static size_t current_byte = 0;
    408   for (size_t i = 0; i < n; ++i) {
    409     output[i] = bytes[current_byte++];
    410     current_byte %= arraysize(bytes);
    411   }
    412 }
    413 
    414 void MockGenerateRandom2(uint8* output, size_t n) {
    415   static const uint8 bytes[] = {
    416     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    417     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    418   };
    419   static size_t current_byte = 0;
    420   for (size_t i = 0; i < n; ++i) {
    421     output[i] = bytes[current_byte++];
    422     current_byte %= arraysize(bytes);
    423   }
    424 }
    425 
    426 std::string MockGetHostName() {
    427   return "WTC-WIN7";
    428 }
    429 
    430 template<typename ParentPool>
    431 class CaptureGroupNameSocketPool : public ParentPool {
    432  public:
    433   CaptureGroupNameSocketPool(HostResolver* host_resolver,
    434                              CertVerifier* cert_verifier);
    435 
    436   const std::string last_group_name_received() const {
    437     return last_group_name_;
    438   }
    439 
    440   virtual int RequestSocket(const std::string& group_name,
    441                             const void* socket_params,
    442                             RequestPriority priority,
    443                             ClientSocketHandle* handle,
    444                             const CompletionCallback& callback,
    445                             const BoundNetLog& net_log) {
    446     last_group_name_ = group_name;
    447     return ERR_IO_PENDING;
    448   }
    449   virtual void CancelRequest(const std::string& group_name,
    450                              ClientSocketHandle* handle) {}
    451   virtual void ReleaseSocket(const std::string& group_name,
    452                              StreamSocket* socket,
    453                              int id) {}
    454   virtual void CloseIdleSockets() {}
    455   virtual int IdleSocketCount() const {
    456     return 0;
    457   }
    458   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    459     return 0;
    460   }
    461   virtual LoadState GetLoadState(const std::string& group_name,
    462                                  const ClientSocketHandle* handle) const {
    463     return LOAD_STATE_IDLE;
    464   }
    465   virtual base::TimeDelta ConnectionTimeout() const {
    466     return base::TimeDelta();
    467   }
    468 
    469  private:
    470   std::string last_group_name_;
    471 };
    472 
    473 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
    474 CaptureGroupNameTransportSocketPool;
    475 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
    476 CaptureGroupNameHttpProxySocketPool;
    477 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
    478 CaptureGroupNameSOCKSSocketPool;
    479 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
    480 CaptureGroupNameSSLSocketPool;
    481 
    482 template<typename ParentPool>
    483 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
    484     HostResolver* host_resolver,
    485     CertVerifier* /* cert_verifier */)
    486     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
    487 
    488 template<>
    489 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
    490     HostResolver* host_resolver,
    491     CertVerifier* /* cert_verifier */)
    492     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
    493 
    494 template <>
    495 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
    496     HostResolver* host_resolver,
    497     CertVerifier* cert_verifier)
    498     : SSLClientSocketPool(0,
    499                           0,
    500                           NULL,
    501                           host_resolver,
    502                           cert_verifier,
    503                           NULL,
    504                           NULL,
    505                           std::string(),
    506                           NULL,
    507                           NULL,
    508                           NULL,
    509                           NULL,
    510                           NULL,
    511                           NULL) {}
    512 
    513 //-----------------------------------------------------------------------------
    514 
    515 // Helper functions for validating that AuthChallengeInfo's are correctly
    516 // configured for common cases.
    517 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
    518   if (!auth_challenge)
    519     return false;
    520   EXPECT_FALSE(auth_challenge->is_proxy);
    521   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    522   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    523   EXPECT_EQ("basic", auth_challenge->scheme);
    524   return true;
    525 }
    526 
    527 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
    528   if (!auth_challenge)
    529     return false;
    530   EXPECT_TRUE(auth_challenge->is_proxy);
    531   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
    532   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    533   EXPECT_EQ("basic", auth_challenge->scheme);
    534   return true;
    535 }
    536 
    537 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
    538   if (!auth_challenge)
    539     return false;
    540   EXPECT_FALSE(auth_challenge->is_proxy);
    541   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    542   EXPECT_EQ("digestive", auth_challenge->realm);
    543   EXPECT_EQ("digest", auth_challenge->scheme);
    544   return true;
    545 }
    546 
    547 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
    548   if (!auth_challenge)
    549     return false;
    550   EXPECT_FALSE(auth_challenge->is_proxy);
    551   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
    552   EXPECT_EQ(std::string(), auth_challenge->realm);
    553   EXPECT_EQ("ntlm", auth_challenge->scheme);
    554   return true;
    555 }
    556 
    557 }  // namespace
    558 
    559 TEST_P(HttpNetworkTransactionTest, Basic) {
    560   scoped_ptr<HttpTransaction> trans(
    561       new HttpNetworkTransaction(DEFAULT_PRIORITY,
    562                                  CreateSession(&session_deps_)));
    563 }
    564 
    565 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
    566   MockRead data_reads[] = {
    567     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    568     MockRead("hello world"),
    569     MockRead(SYNCHRONOUS, OK),
    570   };
    571   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    572                                               arraysize(data_reads));
    573   EXPECT_EQ(OK, out.rv);
    574   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    575   EXPECT_EQ("hello world", out.response_data);
    576 }
    577 
    578 // Response with no status line.
    579 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    580   MockRead data_reads[] = {
    581     MockRead("hello world"),
    582     MockRead(SYNCHRONOUS, OK),
    583   };
    584   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    585                                               arraysize(data_reads));
    586   EXPECT_EQ(OK, out.rv);
    587   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    588   EXPECT_EQ("hello world", out.response_data);
    589 }
    590 
    591 // Allow up to 4 bytes of junk to precede status line.
    592 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
    593   MockRead data_reads[] = {
    594     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    595     MockRead(SYNCHRONOUS, OK),
    596   };
    597   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    598                                               arraysize(data_reads));
    599   EXPECT_EQ(OK, out.rv);
    600   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    601   EXPECT_EQ("DATA", out.response_data);
    602 }
    603 
    604 // Allow up to 4 bytes of junk to precede status line.
    605 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    606   MockRead data_reads[] = {
    607     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    608     MockRead(SYNCHRONOUS, OK),
    609   };
    610   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    611                                               arraysize(data_reads));
    612   EXPECT_EQ(OK, out.rv);
    613   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    614   EXPECT_EQ("DATA", out.response_data);
    615 }
    616 
    617 // Beyond 4 bytes of slop and it should fail to find a status line.
    618 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    619   MockRead data_reads[] = {
    620     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    621     MockRead(SYNCHRONOUS, OK),
    622   };
    623   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    624                                               arraysize(data_reads));
    625   EXPECT_EQ(OK, out.rv);
    626   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    627   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    628 }
    629 
    630 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    631 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    632   MockRead data_reads[] = {
    633     MockRead("\n"),
    634     MockRead("\n"),
    635     MockRead("Q"),
    636     MockRead("J"),
    637     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    638     MockRead(SYNCHRONOUS, OK),
    639   };
    640   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    641                                               arraysize(data_reads));
    642   EXPECT_EQ(OK, out.rv);
    643   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    644   EXPECT_EQ("DATA", out.response_data);
    645 }
    646 
    647 // Close the connection before enough bytes to have a status line.
    648 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
    649   MockRead data_reads[] = {
    650     MockRead("HTT"),
    651     MockRead(SYNCHRONOUS, OK),
    652   };
    653   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    654                                               arraysize(data_reads));
    655   EXPECT_EQ(OK, out.rv);
    656   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    657   EXPECT_EQ("HTT", out.response_data);
    658 }
    659 
    660 // Simulate a 204 response, lacking a Content-Length header, sent over a
    661 // persistent connection.  The response should still terminate since a 204
    662 // cannot have a response body.
    663 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
    664   MockRead data_reads[] = {
    665     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    666     MockRead("junk"),  // Should not be read!!
    667     MockRead(SYNCHRONOUS, OK),
    668   };
    669   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    670                                               arraysize(data_reads));
    671   EXPECT_EQ(OK, out.rv);
    672   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    673   EXPECT_EQ("", out.response_data);
    674 }
    675 
    676 // A simple request using chunked encoding with some extra data after.
    677 // (Like might be seen in a pipelined response.)
    678 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
    679   MockRead data_reads[] = {
    680     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    681     MockRead("5\r\nHello\r\n"),
    682     MockRead("1\r\n"),
    683     MockRead(" \r\n"),
    684     MockRead("5\r\nworld\r\n"),
    685     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    686     MockRead(SYNCHRONOUS, OK),
    687   };
    688   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    689                                               arraysize(data_reads));
    690   EXPECT_EQ(OK, out.rv);
    691   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    692   EXPECT_EQ("Hello world", out.response_data);
    693 }
    694 
    695 // Next tests deal with http://crbug.com/56344.
    696 
    697 TEST_P(HttpNetworkTransactionTest,
    698        MultipleContentLengthHeadersNoTransferEncoding) {
    699   MockRead data_reads[] = {
    700     MockRead("HTTP/1.1 200 OK\r\n"),
    701     MockRead("Content-Length: 10\r\n"),
    702     MockRead("Content-Length: 5\r\n\r\n"),
    703   };
    704   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    705                                               arraysize(data_reads));
    706   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    707 }
    708 
    709 TEST_P(HttpNetworkTransactionTest,
    710        DuplicateContentLengthHeadersNoTransferEncoding) {
    711   MockRead data_reads[] = {
    712     MockRead("HTTP/1.1 200 OK\r\n"),
    713     MockRead("Content-Length: 5\r\n"),
    714     MockRead("Content-Length: 5\r\n\r\n"),
    715     MockRead("Hello"),
    716   };
    717   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    718                                               arraysize(data_reads));
    719   EXPECT_EQ(OK, out.rv);
    720   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    721   EXPECT_EQ("Hello", out.response_data);
    722 }
    723 
    724 TEST_P(HttpNetworkTransactionTest,
    725        ComplexContentLengthHeadersNoTransferEncoding) {
    726   // More than 2 dupes.
    727   {
    728     MockRead data_reads[] = {
    729       MockRead("HTTP/1.1 200 OK\r\n"),
    730       MockRead("Content-Length: 5\r\n"),
    731       MockRead("Content-Length: 5\r\n"),
    732       MockRead("Content-Length: 5\r\n\r\n"),
    733       MockRead("Hello"),
    734     };
    735     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    736                                                 arraysize(data_reads));
    737     EXPECT_EQ(OK, out.rv);
    738     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    739     EXPECT_EQ("Hello", out.response_data);
    740   }
    741   // HTTP/1.0
    742   {
    743     MockRead data_reads[] = {
    744       MockRead("HTTP/1.0 200 OK\r\n"),
    745       MockRead("Content-Length: 5\r\n"),
    746       MockRead("Content-Length: 5\r\n"),
    747       MockRead("Content-Length: 5\r\n\r\n"),
    748       MockRead("Hello"),
    749     };
    750     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    751                                                 arraysize(data_reads));
    752     EXPECT_EQ(OK, out.rv);
    753     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    754     EXPECT_EQ("Hello", out.response_data);
    755   }
    756   // 2 dupes and one mismatched.
    757   {
    758     MockRead data_reads[] = {
    759       MockRead("HTTP/1.1 200 OK\r\n"),
    760       MockRead("Content-Length: 10\r\n"),
    761       MockRead("Content-Length: 10\r\n"),
    762       MockRead("Content-Length: 5\r\n\r\n"),
    763     };
    764     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    765                                                 arraysize(data_reads));
    766     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    767   }
    768 }
    769 
    770 TEST_P(HttpNetworkTransactionTest,
    771        MultipleContentLengthHeadersTransferEncoding) {
    772   MockRead data_reads[] = {
    773     MockRead("HTTP/1.1 200 OK\r\n"),
    774     MockRead("Content-Length: 666\r\n"),
    775     MockRead("Content-Length: 1337\r\n"),
    776     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
    777     MockRead("5\r\nHello\r\n"),
    778     MockRead("1\r\n"),
    779     MockRead(" \r\n"),
    780     MockRead("5\r\nworld\r\n"),
    781     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    782     MockRead(SYNCHRONOUS, OK),
    783   };
    784   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    785                                               arraysize(data_reads));
    786   EXPECT_EQ(OK, out.rv);
    787   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    788   EXPECT_EQ("Hello world", out.response_data);
    789 }
    790 
    791 // Next tests deal with http://crbug.com/98895.
    792 
    793 // Checks that a single Content-Disposition header results in no error.
    794 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
    795   MockRead data_reads[] = {
    796     MockRead("HTTP/1.1 200 OK\r\n"),
    797     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
    798     MockRead("Content-Length: 5\r\n\r\n"),
    799     MockRead("Hello"),
    800   };
    801   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    802                                               arraysize(data_reads));
    803   EXPECT_EQ(OK, out.rv);
    804   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    805   EXPECT_EQ("Hello", out.response_data);
    806 }
    807 
    808 // Checks that two identical Content-Disposition headers result in no error.
    809 TEST_P(HttpNetworkTransactionTest,
    810        TwoIdenticalContentDispositionHeaders) {
    811   MockRead data_reads[] = {
    812     MockRead("HTTP/1.1 200 OK\r\n"),
    813     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    814     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    815     MockRead("Content-Length: 5\r\n\r\n"),
    816     MockRead("Hello"),
    817   };
    818   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    819                                               arraysize(data_reads));
    820   EXPECT_EQ(OK, out.rv);
    821   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    822   EXPECT_EQ("Hello", out.response_data);
    823 }
    824 
    825 // Checks that two distinct Content-Disposition headers result in an error.
    826 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
    827   MockRead data_reads[] = {
    828     MockRead("HTTP/1.1 200 OK\r\n"),
    829     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    830     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
    831     MockRead("Content-Length: 5\r\n\r\n"),
    832     MockRead("Hello"),
    833   };
    834   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    835                                               arraysize(data_reads));
    836   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
    837 }
    838 
    839 // Checks that two identical Location headers result in no error.
    840 // Also tests Location header behavior.
    841 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
    842   MockRead data_reads[] = {
    843     MockRead("HTTP/1.1 302 Redirect\r\n"),
    844     MockRead("Location: http://good.com/\r\n"),
    845     MockRead("Location: http://good.com/\r\n"),
    846     MockRead("Content-Length: 0\r\n\r\n"),
    847     MockRead(SYNCHRONOUS, OK),
    848   };
    849 
    850   HttpRequestInfo request;
    851   request.method = "GET";
    852   request.url = GURL("http://redirect.com/");
    853   request.load_flags = 0;
    854 
    855   scoped_ptr<HttpTransaction> trans(
    856       new HttpNetworkTransaction(DEFAULT_PRIORITY,
    857                                  CreateSession(&session_deps_)));
    858 
    859   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    860   session_deps_.socket_factory->AddSocketDataProvider(&data);
    861 
    862   TestCompletionCallback callback;
    863 
    864   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    865   EXPECT_EQ(ERR_IO_PENDING, rv);
    866 
    867   EXPECT_EQ(OK, callback.WaitForResult());
    868 
    869   const HttpResponseInfo* response = trans->GetResponseInfo();
    870   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
    871   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
    872   std::string url;
    873   EXPECT_TRUE(response->headers->IsRedirect(&url));
    874   EXPECT_EQ("http://good.com/", url);
    875 }
    876 
    877 // Checks that two distinct Location headers result in an error.
    878 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
    879   MockRead data_reads[] = {
    880     MockRead("HTTP/1.1 302 Redirect\r\n"),
    881     MockRead("Location: http://good.com/\r\n"),
    882     MockRead("Location: http://evil.com/\r\n"),
    883     MockRead("Content-Length: 0\r\n\r\n"),
    884     MockRead(SYNCHRONOUS, OK),
    885   };
    886   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    887                                               arraysize(data_reads));
    888   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
    889 }
    890 
    891 // Do a request using the HEAD method. Verify that we don't try to read the
    892 // message body (since HEAD has none).
    893 TEST_P(HttpNetworkTransactionTest, Head) {
    894   HttpRequestInfo request;
    895   request.method = "HEAD";
    896   request.url = GURL("http://www.google.com/");
    897   request.load_flags = 0;
    898 
    899   scoped_ptr<HttpTransaction> trans(
    900       new HttpNetworkTransaction(DEFAULT_PRIORITY,
    901                                  CreateSession(&session_deps_)));
    902 
    903   MockWrite data_writes1[] = {
    904     MockWrite("HEAD / HTTP/1.1\r\n"
    905               "Host: www.google.com\r\n"
    906               "Connection: keep-alive\r\n"
    907               "Content-Length: 0\r\n\r\n"),
    908   };
    909   MockRead data_reads1[] = {
    910     MockRead("HTTP/1.1 404 Not Found\r\n"),
    911     MockRead("Server: Blah\r\n"),
    912     MockRead("Content-Length: 1234\r\n\r\n"),
    913 
    914     // No response body because the test stops reading here.
    915     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
    916   };
    917 
    918   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
    919                                  data_writes1, arraysize(data_writes1));
    920   session_deps_.socket_factory->AddSocketDataProvider(&data1);
    921 
    922   TestCompletionCallback callback1;
    923 
    924   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
    925   EXPECT_EQ(ERR_IO_PENDING, rv);
    926 
    927   rv = callback1.WaitForResult();
    928   EXPECT_EQ(OK, rv);
    929 
    930   const HttpResponseInfo* response = trans->GetResponseInfo();
    931   ASSERT_TRUE(response != NULL);
    932 
    933   // Check that the headers got parsed.
    934   EXPECT_TRUE(response->headers.get() != NULL);
    935   EXPECT_EQ(1234, response->headers->GetContentLength());
    936   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
    937 
    938   std::string server_header;
    939   void* iter = NULL;
    940   bool has_server_header = response->headers->EnumerateHeader(
    941       &iter, "Server", &server_header);
    942   EXPECT_TRUE(has_server_header);
    943   EXPECT_EQ("Blah", server_header);
    944 
    945   // Reading should give EOF right away, since there is no message body
    946   // (despite non-zero content-length).
    947   std::string response_data;
    948   rv = ReadTransaction(trans.get(), &response_data);
    949   EXPECT_EQ(OK, rv);
    950   EXPECT_EQ("", response_data);
    951 }
    952 
    953 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
    954   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    955 
    956   MockRead data_reads[] = {
    957     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    958     MockRead("hello"),
    959     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    960     MockRead("world"),
    961     MockRead(SYNCHRONOUS, OK),
    962   };
    963   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    964   session_deps_.socket_factory->AddSocketDataProvider(&data);
    965 
    966   const char* const kExpectedResponseData[] = {
    967     "hello", "world"
    968   };
    969 
    970   for (int i = 0; i < 2; ++i) {
    971     HttpRequestInfo request;
    972     request.method = "GET";
    973     request.url = GURL("http://www.google.com/");
    974     request.load_flags = 0;
    975 
    976     scoped_ptr<HttpTransaction> trans(
    977         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
    978 
    979     TestCompletionCallback callback;
    980 
    981     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    982     EXPECT_EQ(ERR_IO_PENDING, rv);
    983 
    984     rv = callback.WaitForResult();
    985     EXPECT_EQ(OK, rv);
    986 
    987     const HttpResponseInfo* response = trans->GetResponseInfo();
    988     ASSERT_TRUE(response != NULL);
    989 
    990     EXPECT_TRUE(response->headers.get() != NULL);
    991     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    992 
    993     std::string response_data;
    994     rv = ReadTransaction(trans.get(), &response_data);
    995     EXPECT_EQ(OK, rv);
    996     EXPECT_EQ(kExpectedResponseData[i], response_data);
    997   }
    998 }
    999 
   1000 TEST_P(HttpNetworkTransactionTest, Ignores100) {
   1001   ScopedVector<UploadElementReader> element_readers;
   1002   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   1003   UploadDataStream upload_data_stream(&element_readers, 0);
   1004 
   1005   HttpRequestInfo request;
   1006   request.method = "POST";
   1007   request.url = GURL("http://www.foo.com/");
   1008   request.upload_data_stream = &upload_data_stream;
   1009   request.load_flags = 0;
   1010 
   1011   scoped_ptr<HttpTransaction> trans(
   1012       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1013                                  CreateSession(&session_deps_)));
   1014 
   1015   MockRead data_reads[] = {
   1016     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   1017     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   1018     MockRead("hello world"),
   1019     MockRead(SYNCHRONOUS, OK),
   1020   };
   1021   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1022   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1023 
   1024   TestCompletionCallback callback;
   1025 
   1026   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1027   EXPECT_EQ(ERR_IO_PENDING, rv);
   1028 
   1029   rv = callback.WaitForResult();
   1030   EXPECT_EQ(OK, rv);
   1031 
   1032   const HttpResponseInfo* response = trans->GetResponseInfo();
   1033   ASSERT_TRUE(response != NULL);
   1034 
   1035   EXPECT_TRUE(response->headers.get() != NULL);
   1036   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   1037 
   1038   std::string response_data;
   1039   rv = ReadTransaction(trans.get(), &response_data);
   1040   EXPECT_EQ(OK, rv);
   1041   EXPECT_EQ("hello world", response_data);
   1042 }
   1043 
   1044 // This test is almost the same as Ignores100 above, but the response contains
   1045 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
   1046 // HTTP/1.1 and the two status headers are read in one read.
   1047 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
   1048   HttpRequestInfo request;
   1049   request.method = "GET";
   1050   request.url = GURL("http://www.foo.com/");
   1051   request.load_flags = 0;
   1052 
   1053   scoped_ptr<HttpTransaction> trans(
   1054       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1055                                  CreateSession(&session_deps_)));
   1056 
   1057   MockRead data_reads[] = {
   1058     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
   1059              "HTTP/1.1 200 OK\r\n\r\n"),
   1060     MockRead("hello world"),
   1061     MockRead(SYNCHRONOUS, OK),
   1062   };
   1063   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1064   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1065 
   1066   TestCompletionCallback callback;
   1067 
   1068   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1069   EXPECT_EQ(ERR_IO_PENDING, rv);
   1070 
   1071   rv = callback.WaitForResult();
   1072   EXPECT_EQ(OK, rv);
   1073 
   1074   const HttpResponseInfo* response = trans->GetResponseInfo();
   1075   ASSERT_TRUE(response != NULL);
   1076 
   1077   EXPECT_TRUE(response->headers.get() != NULL);
   1078   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1079 
   1080   std::string response_data;
   1081   rv = ReadTransaction(trans.get(), &response_data);
   1082   EXPECT_EQ(OK, rv);
   1083   EXPECT_EQ("hello world", response_data);
   1084 }
   1085 
   1086 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
   1087   HttpRequestInfo request;
   1088   request.method = "POST";
   1089   request.url = GURL("http://www.foo.com/");
   1090   request.load_flags = 0;
   1091 
   1092   scoped_ptr<HttpTransaction> trans(
   1093       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1094                                  CreateSession(&session_deps_)));
   1095 
   1096   MockRead data_reads[] = {
   1097     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
   1098     MockRead(ASYNC, 0),
   1099   };
   1100   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1101   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1102 
   1103   TestCompletionCallback callback;
   1104 
   1105   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1106   EXPECT_EQ(ERR_IO_PENDING, rv);
   1107 
   1108   rv = callback.WaitForResult();
   1109   EXPECT_EQ(OK, rv);
   1110 
   1111   std::string response_data;
   1112   rv = ReadTransaction(trans.get(), &response_data);
   1113   EXPECT_EQ(OK, rv);
   1114   EXPECT_EQ("", response_data);
   1115 }
   1116 
   1117 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
   1118   HttpRequestInfo request;
   1119   request.method = "POST";
   1120   request.url = GURL("http://www.foo.com/");
   1121   request.load_flags = 0;
   1122 
   1123   scoped_ptr<HttpTransaction> trans(
   1124       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1125                                  CreateSession(&session_deps_)));
   1126 
   1127   MockRead data_reads[] = {
   1128     MockRead(ASYNC, 0),
   1129   };
   1130   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1131   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1132 
   1133   TestCompletionCallback callback;
   1134 
   1135   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1136   EXPECT_EQ(ERR_IO_PENDING, rv);
   1137 
   1138   rv = callback.WaitForResult();
   1139   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   1140 }
   1141 
   1142 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
   1143     const MockWrite* write_failure,
   1144     const MockRead* read_failure) {
   1145   HttpRequestInfo request;
   1146   request.method = "GET";
   1147   request.url = GURL("http://www.foo.com/");
   1148   request.load_flags = 0;
   1149 
   1150   CapturingNetLog net_log;
   1151   session_deps_.net_log = &net_log;
   1152   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1153 
   1154   // Written data for successfully sending both requests.
   1155   MockWrite data1_writes[] = {
   1156     MockWrite("GET / HTTP/1.1\r\n"
   1157               "Host: www.foo.com\r\n"
   1158               "Connection: keep-alive\r\n\r\n"),
   1159     MockWrite("GET / HTTP/1.1\r\n"
   1160               "Host: www.foo.com\r\n"
   1161               "Connection: keep-alive\r\n\r\n")
   1162   };
   1163 
   1164   // Read results for the first request.
   1165   MockRead data1_reads[] = {
   1166     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1167     MockRead("hello"),
   1168     MockRead(ASYNC, OK),
   1169   };
   1170 
   1171   if (write_failure) {
   1172     ASSERT_TRUE(!read_failure);
   1173     data1_writes[1] = *write_failure;
   1174   } else {
   1175     ASSERT_TRUE(read_failure);
   1176     data1_reads[2] = *read_failure;
   1177   }
   1178 
   1179   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
   1180                                  data1_writes, arraysize(data1_writes));
   1181   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1182 
   1183   MockRead data2_reads[] = {
   1184     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1185     MockRead("world"),
   1186     MockRead(ASYNC, OK),
   1187   };
   1188   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1189   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1190 
   1191   const char* kExpectedResponseData[] = {
   1192     "hello", "world"
   1193   };
   1194 
   1195   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1196   for (int i = 0; i < 2; ++i) {
   1197     TestCompletionCallback callback;
   1198 
   1199     scoped_ptr<HttpTransaction> trans(
   1200         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1201 
   1202     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1203     EXPECT_EQ(ERR_IO_PENDING, rv);
   1204 
   1205     rv = callback.WaitForResult();
   1206     EXPECT_EQ(OK, rv);
   1207 
   1208     LoadTimingInfo load_timing_info;
   1209     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1210     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1211     if (i == 0) {
   1212       first_socket_log_id = load_timing_info.socket_log_id;
   1213     } else {
   1214       // The second request should be using a new socket.
   1215       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
   1216     }
   1217 
   1218     const HttpResponseInfo* response = trans->GetResponseInfo();
   1219     ASSERT_TRUE(response != NULL);
   1220 
   1221     EXPECT_TRUE(response->headers.get() != NULL);
   1222     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1223 
   1224     std::string response_data;
   1225     rv = ReadTransaction(trans.get(), &response_data);
   1226     EXPECT_EQ(OK, rv);
   1227     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1228   }
   1229 }
   1230 
   1231 TEST_P(HttpNetworkTransactionTest,
   1232        KeepAliveConnectionNotConnectedOnWrite) {
   1233   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1234   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
   1235 }
   1236 
   1237 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
   1238   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1239   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1240 }
   1241 
   1242 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
   1243   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1244   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1245 }
   1246 
   1247 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
   1248   HttpRequestInfo request;
   1249   request.method = "GET";
   1250   request.url = GURL("http://www.google.com/");
   1251   request.load_flags = 0;
   1252 
   1253   scoped_ptr<HttpTransaction> trans(
   1254       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1255                                  CreateSession(&session_deps_)));
   1256 
   1257   MockRead data_reads[] = {
   1258     MockRead(ASYNC, ERR_CONNECTION_RESET),
   1259     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1260     MockRead("hello world"),
   1261     MockRead(SYNCHRONOUS, OK),
   1262   };
   1263   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1264   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1265 
   1266   TestCompletionCallback callback;
   1267 
   1268   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1269   EXPECT_EQ(ERR_IO_PENDING, rv);
   1270 
   1271   rv = callback.WaitForResult();
   1272   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   1273 
   1274   const HttpResponseInfo* response = trans->GetResponseInfo();
   1275   EXPECT_TRUE(response == NULL);
   1276 }
   1277 
   1278 // What do various browsers do when the server closes a non-keepalive
   1279 // connection without sending any response header or body?
   1280 //
   1281 // IE7: error page
   1282 // Safari 3.1.2 (Windows): error page
   1283 // Firefox 3.0.1: blank page
   1284 // Opera 9.52: after five attempts, blank page
   1285 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
   1286 // Us: error page (EMPTY_RESPONSE)
   1287 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
   1288   MockRead data_reads[] = {
   1289     MockRead(SYNCHRONOUS, OK),  // EOF
   1290     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1291     MockRead("hello world"),
   1292     MockRead(SYNCHRONOUS, OK),
   1293   };
   1294   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
   1295                                               arraysize(data_reads));
   1296   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
   1297 }
   1298 
   1299 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
   1300 // tests. There was a bug causing HttpNetworkTransaction to hang in the
   1301 // destructor in such situations.
   1302 // See http://crbug.com/154712 and http://crbug.com/156609.
   1303 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
   1304   HttpRequestInfo request;
   1305   request.method = "GET";
   1306   request.url = GURL("http://www.google.com/");
   1307   request.load_flags = 0;
   1308 
   1309   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1310   scoped_ptr<HttpTransaction> trans(
   1311       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1312 
   1313   MockRead data_reads[] = {
   1314     MockRead("HTTP/1.0 200 OK\r\n"),
   1315     MockRead("Connection: keep-alive\r\n"),
   1316     MockRead("Content-Length: 100\r\n\r\n"),
   1317     MockRead("hello"),
   1318     MockRead(SYNCHRONOUS, 0),
   1319   };
   1320   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1321   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1322 
   1323   TestCompletionCallback callback;
   1324 
   1325   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1326   EXPECT_EQ(ERR_IO_PENDING, rv);
   1327 
   1328   rv = callback.WaitForResult();
   1329   EXPECT_EQ(OK, rv);
   1330 
   1331   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1332   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1333   if (rv == ERR_IO_PENDING)
   1334     rv = callback.WaitForResult();
   1335   EXPECT_EQ(5, rv);
   1336   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1337   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1338 
   1339   trans.reset();
   1340   base::MessageLoop::current()->RunUntilIdle();
   1341   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1342 }
   1343 
   1344 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
   1345   HttpRequestInfo request;
   1346   request.method = "GET";
   1347   request.url = GURL("http://www.google.com/");
   1348   request.load_flags = 0;
   1349 
   1350   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1351   scoped_ptr<HttpTransaction> trans(
   1352       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1353 
   1354   MockRead data_reads[] = {
   1355     MockRead("HTTP/1.0 200 OK\r\n"),
   1356     MockRead("Connection: keep-alive\r\n"),
   1357     MockRead("Content-Length: 100\r\n\r\n"),
   1358     MockRead(SYNCHRONOUS, 0),
   1359   };
   1360   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1361   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1362 
   1363   TestCompletionCallback callback;
   1364 
   1365   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1366   EXPECT_EQ(ERR_IO_PENDING, rv);
   1367 
   1368   rv = callback.WaitForResult();
   1369   EXPECT_EQ(OK, rv);
   1370 
   1371   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1372   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1373   if (rv == ERR_IO_PENDING)
   1374     rv = callback.WaitForResult();
   1375   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1376 
   1377   trans.reset();
   1378   base::MessageLoop::current()->RunUntilIdle();
   1379   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1380 }
   1381 
   1382 // Test that we correctly reuse a keep-alive connection after not explicitly
   1383 // reading the body.
   1384 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
   1385   HttpRequestInfo request;
   1386   request.method = "GET";
   1387   request.url = GURL("http://www.foo.com/");
   1388   request.load_flags = 0;
   1389 
   1390   CapturingNetLog net_log;
   1391   session_deps_.net_log = &net_log;
   1392   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1393 
   1394   // Note that because all these reads happen in the same
   1395   // StaticSocketDataProvider, it shows that the same socket is being reused for
   1396   // all transactions.
   1397   MockRead data1_reads[] = {
   1398     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
   1399     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
   1400     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
   1401     MockRead("HTTP/1.1 302 Found\r\n"
   1402              "Content-Length: 0\r\n\r\n"),
   1403     MockRead("HTTP/1.1 302 Found\r\n"
   1404              "Content-Length: 5\r\n\r\n"
   1405              "hello"),
   1406     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1407              "Content-Length: 0\r\n\r\n"),
   1408     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1409              "Content-Length: 5\r\n\r\n"
   1410              "hello"),
   1411     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1412     MockRead("hello"),
   1413   };
   1414   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
   1415   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1416 
   1417   MockRead data2_reads[] = {
   1418     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   1419   };
   1420   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1421   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1422 
   1423   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
   1424   std::string response_lines[kNumUnreadBodies];
   1425 
   1426   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1427   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
   1428     TestCompletionCallback callback;
   1429 
   1430     scoped_ptr<HttpTransaction> trans(
   1431         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1432 
   1433     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1434     EXPECT_EQ(ERR_IO_PENDING, rv);
   1435 
   1436     rv = callback.WaitForResult();
   1437     EXPECT_EQ(OK, rv);
   1438 
   1439     LoadTimingInfo load_timing_info;
   1440     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1441     if (i == 0) {
   1442       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1443       first_socket_log_id = load_timing_info.socket_log_id;
   1444     } else {
   1445       TestLoadTimingReused(load_timing_info);
   1446       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
   1447     }
   1448 
   1449     const HttpResponseInfo* response = trans->GetResponseInfo();
   1450     ASSERT_TRUE(response != NULL);
   1451 
   1452     ASSERT_TRUE(response->headers.get() != NULL);
   1453     response_lines[i] = response->headers->GetStatusLine();
   1454 
   1455     // We intentionally don't read the response bodies.
   1456   }
   1457 
   1458   const char* const kStatusLines[] = {
   1459     "HTTP/1.1 204 No Content",
   1460     "HTTP/1.1 205 Reset Content",
   1461     "HTTP/1.1 304 Not Modified",
   1462     "HTTP/1.1 302 Found",
   1463     "HTTP/1.1 302 Found",
   1464     "HTTP/1.1 301 Moved Permanently",
   1465     "HTTP/1.1 301 Moved Permanently",
   1466   };
   1467 
   1468   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
   1469                  forgot_to_update_kStatusLines);
   1470 
   1471   for (int i = 0; i < kNumUnreadBodies; ++i)
   1472     EXPECT_EQ(kStatusLines[i], response_lines[i]);
   1473 
   1474   TestCompletionCallback callback;
   1475   scoped_ptr<HttpTransaction> trans(
   1476       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1477   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1478   EXPECT_EQ(ERR_IO_PENDING, rv);
   1479   rv = callback.WaitForResult();
   1480   EXPECT_EQ(OK, rv);
   1481   const HttpResponseInfo* response = trans->GetResponseInfo();
   1482   ASSERT_TRUE(response != NULL);
   1483   ASSERT_TRUE(response->headers.get() != NULL);
   1484   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1485   std::string response_data;
   1486   rv = ReadTransaction(trans.get(), &response_data);
   1487   EXPECT_EQ(OK, rv);
   1488   EXPECT_EQ("hello", response_data);
   1489 }
   1490 
   1491 // Test the request-challenge-retry sequence for basic auth.
   1492 // (basic auth is the easiest to mock, because it has no randomness).
   1493 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
   1494   HttpRequestInfo request;
   1495   request.method = "GET";
   1496   request.url = GURL("http://www.google.com/");
   1497   request.load_flags = 0;
   1498 
   1499   CapturingNetLog log;
   1500   session_deps_.net_log = &log;
   1501   scoped_ptr<HttpTransaction> trans(
   1502       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1503                                  CreateSession(&session_deps_)));
   1504 
   1505   MockWrite data_writes1[] = {
   1506     MockWrite("GET / HTTP/1.1\r\n"
   1507               "Host: www.google.com\r\n"
   1508               "Connection: keep-alive\r\n\r\n"),
   1509   };
   1510 
   1511   MockRead data_reads1[] = {
   1512     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1513     // Give a couple authenticate options (only the middle one is actually
   1514     // supported).
   1515     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
   1516     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1517     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1518     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1519     // Large content-length -- won't matter, as connection will be reset.
   1520     MockRead("Content-Length: 10000\r\n\r\n"),
   1521     MockRead(SYNCHRONOUS, ERR_FAILED),
   1522   };
   1523 
   1524   // After calling trans->RestartWithAuth(), this is the request we should
   1525   // be issuing -- the final header line contains the credentials.
   1526   MockWrite data_writes2[] = {
   1527     MockWrite("GET / HTTP/1.1\r\n"
   1528               "Host: www.google.com\r\n"
   1529               "Connection: keep-alive\r\n"
   1530               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1531   };
   1532 
   1533   // Lastly, the server responds with the actual content.
   1534   MockRead data_reads2[] = {
   1535     MockRead("HTTP/1.0 200 OK\r\n"),
   1536     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1537     MockRead("Content-Length: 100\r\n\r\n"),
   1538     MockRead(SYNCHRONOUS, OK),
   1539   };
   1540 
   1541   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1542                                  data_writes1, arraysize(data_writes1));
   1543   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1544                                  data_writes2, arraysize(data_writes2));
   1545   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1546   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1547 
   1548   TestCompletionCallback callback1;
   1549 
   1550   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1551   EXPECT_EQ(ERR_IO_PENDING, rv);
   1552 
   1553   rv = callback1.WaitForResult();
   1554   EXPECT_EQ(OK, rv);
   1555 
   1556   LoadTimingInfo load_timing_info1;
   1557   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1558   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1559 
   1560   const HttpResponseInfo* response = trans->GetResponseInfo();
   1561   ASSERT_TRUE(response != NULL);
   1562   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1563 
   1564   TestCompletionCallback callback2;
   1565 
   1566   rv = trans->RestartWithAuth(
   1567       AuthCredentials(kFoo, kBar), callback2.callback());
   1568   EXPECT_EQ(ERR_IO_PENDING, rv);
   1569 
   1570   rv = callback2.WaitForResult();
   1571   EXPECT_EQ(OK, rv);
   1572 
   1573   LoadTimingInfo load_timing_info2;
   1574   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1575   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
   1576   // The load timing after restart should have a new socket ID, and times after
   1577   // those of the first load timing.
   1578   EXPECT_LE(load_timing_info1.receive_headers_end,
   1579             load_timing_info2.connect_timing.connect_start);
   1580   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1581 
   1582   response = trans->GetResponseInfo();
   1583   ASSERT_TRUE(response != NULL);
   1584   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1585   EXPECT_EQ(100, response->headers->GetContentLength());
   1586 }
   1587 
   1588 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
   1589   HttpRequestInfo request;
   1590   request.method = "GET";
   1591   request.url = GURL("http://www.google.com/");
   1592   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1593 
   1594   scoped_ptr<HttpTransaction> trans(
   1595       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   1596                                  CreateSession(&session_deps_)));
   1597 
   1598   MockWrite data_writes[] = {
   1599     MockWrite("GET / HTTP/1.1\r\n"
   1600               "Host: www.google.com\r\n"
   1601               "Connection: keep-alive\r\n\r\n"),
   1602   };
   1603 
   1604   MockRead data_reads[] = {
   1605     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1606     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1607     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1608     // Large content-length -- won't matter, as connection will be reset.
   1609     MockRead("Content-Length: 10000\r\n\r\n"),
   1610     MockRead(SYNCHRONOUS, ERR_FAILED),
   1611   };
   1612 
   1613   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1614                                 data_writes, arraysize(data_writes));
   1615   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1616   TestCompletionCallback callback;
   1617 
   1618   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1619   EXPECT_EQ(ERR_IO_PENDING, rv);
   1620 
   1621   rv = callback.WaitForResult();
   1622   EXPECT_EQ(0, rv);
   1623 
   1624   const HttpResponseInfo* response = trans->GetResponseInfo();
   1625   ASSERT_TRUE(response != NULL);
   1626   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1627 }
   1628 
   1629 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1630 // connection.
   1631 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   1632   HttpRequestInfo request;
   1633   request.method = "GET";
   1634   request.url = GURL("http://www.google.com/");
   1635   request.load_flags = 0;
   1636 
   1637   CapturingNetLog log;
   1638   session_deps_.net_log = &log;
   1639   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1640 
   1641   MockWrite data_writes1[] = {
   1642     MockWrite("GET / HTTP/1.1\r\n"
   1643               "Host: www.google.com\r\n"
   1644               "Connection: keep-alive\r\n\r\n"),
   1645 
   1646     // After calling trans->RestartWithAuth(), this is the request we should
   1647     // be issuing -- the final header line contains the credentials.
   1648     MockWrite("GET / HTTP/1.1\r\n"
   1649               "Host: www.google.com\r\n"
   1650               "Connection: keep-alive\r\n"
   1651               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1652   };
   1653 
   1654   MockRead data_reads1[] = {
   1655     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1656     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1657     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1658     MockRead("Content-Length: 14\r\n\r\n"),
   1659     MockRead("Unauthorized\r\n"),
   1660 
   1661     // Lastly, the server responds with the actual content.
   1662     MockRead("HTTP/1.1 200 OK\r\n"),
   1663     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1664     MockRead("Content-Length: 5\r\n\r\n"),
   1665     MockRead("Hello"),
   1666   };
   1667 
   1668   // If there is a regression where we disconnect a Keep-Alive
   1669   // connection during an auth roundtrip, we'll end up reading this.
   1670   MockRead data_reads2[] = {
   1671     MockRead(SYNCHRONOUS, ERR_FAILED),
   1672   };
   1673 
   1674   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1675                                  data_writes1, arraysize(data_writes1));
   1676   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1677                                  NULL, 0);
   1678   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1679   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1680 
   1681   TestCompletionCallback callback1;
   1682 
   1683   scoped_ptr<HttpTransaction> trans(
   1684       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1685   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1686   EXPECT_EQ(ERR_IO_PENDING, rv);
   1687 
   1688   rv = callback1.WaitForResult();
   1689   EXPECT_EQ(OK, rv);
   1690 
   1691   LoadTimingInfo load_timing_info1;
   1692   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1693   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1694 
   1695   const HttpResponseInfo* response = trans->GetResponseInfo();
   1696   ASSERT_TRUE(response != NULL);
   1697   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1698 
   1699   TestCompletionCallback callback2;
   1700 
   1701   rv = trans->RestartWithAuth(
   1702       AuthCredentials(kFoo, kBar), callback2.callback());
   1703   EXPECT_EQ(ERR_IO_PENDING, rv);
   1704 
   1705   rv = callback2.WaitForResult();
   1706   EXPECT_EQ(OK, rv);
   1707 
   1708   LoadTimingInfo load_timing_info2;
   1709   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1710   TestLoadTimingReused(load_timing_info2);
   1711   // The load timing after restart should have the same socket ID, and times
   1712   // those of the first load timing.
   1713   EXPECT_LE(load_timing_info1.receive_headers_end,
   1714             load_timing_info2.send_start);
   1715   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1716 
   1717   response = trans->GetResponseInfo();
   1718   ASSERT_TRUE(response != NULL);
   1719   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1720   EXPECT_EQ(5, response->headers->GetContentLength());
   1721 }
   1722 
   1723 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1724 // connection and with no response body to drain.
   1725 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   1726   HttpRequestInfo request;
   1727   request.method = "GET";
   1728   request.url = GURL("http://www.google.com/");
   1729   request.load_flags = 0;
   1730 
   1731   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1732 
   1733   MockWrite data_writes1[] = {
   1734     MockWrite("GET / HTTP/1.1\r\n"
   1735               "Host: www.google.com\r\n"
   1736               "Connection: keep-alive\r\n\r\n"),
   1737 
   1738     // After calling trans->RestartWithAuth(), this is the request we should
   1739     // be issuing -- the final header line contains the credentials.
   1740     MockWrite("GET / HTTP/1.1\r\n"
   1741               "Host: www.google.com\r\n"
   1742               "Connection: keep-alive\r\n"
   1743               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1744   };
   1745 
   1746   MockRead data_reads1[] = {
   1747     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1748     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1749     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   1750 
   1751     // Lastly, the server responds with the actual content.
   1752     MockRead("HTTP/1.1 200 OK\r\n"),
   1753     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1754     MockRead("Content-Length: 5\r\n\r\n"),
   1755     MockRead("hello"),
   1756   };
   1757 
   1758   // An incorrect reconnect would cause this to be read.
   1759   MockRead data_reads2[] = {
   1760     MockRead(SYNCHRONOUS, ERR_FAILED),
   1761   };
   1762 
   1763   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1764                                  data_writes1, arraysize(data_writes1));
   1765   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1766                                  NULL, 0);
   1767   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1768   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1769 
   1770   TestCompletionCallback callback1;
   1771 
   1772   scoped_ptr<HttpTransaction> trans(
   1773       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1774   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1775   EXPECT_EQ(ERR_IO_PENDING, rv);
   1776 
   1777   rv = callback1.WaitForResult();
   1778   EXPECT_EQ(OK, rv);
   1779 
   1780   const HttpResponseInfo* response = trans->GetResponseInfo();
   1781   ASSERT_TRUE(response != NULL);
   1782   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1783 
   1784   TestCompletionCallback callback2;
   1785 
   1786   rv = trans->RestartWithAuth(
   1787       AuthCredentials(kFoo, kBar), callback2.callback());
   1788   EXPECT_EQ(ERR_IO_PENDING, rv);
   1789 
   1790   rv = callback2.WaitForResult();
   1791   EXPECT_EQ(OK, rv);
   1792 
   1793   response = trans->GetResponseInfo();
   1794   ASSERT_TRUE(response != NULL);
   1795   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1796   EXPECT_EQ(5, response->headers->GetContentLength());
   1797 }
   1798 
   1799 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1800 // connection and with a large response body to drain.
   1801 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   1802   HttpRequestInfo request;
   1803   request.method = "GET";
   1804   request.url = GURL("http://www.google.com/");
   1805   request.load_flags = 0;
   1806 
   1807   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1808 
   1809   MockWrite data_writes1[] = {
   1810     MockWrite("GET / HTTP/1.1\r\n"
   1811               "Host: www.google.com\r\n"
   1812               "Connection: keep-alive\r\n\r\n"),
   1813 
   1814     // After calling trans->RestartWithAuth(), this is the request we should
   1815     // be issuing -- the final header line contains the credentials.
   1816     MockWrite("GET / HTTP/1.1\r\n"
   1817               "Host: www.google.com\r\n"
   1818               "Connection: keep-alive\r\n"
   1819               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1820   };
   1821 
   1822   // Respond with 5 kb of response body.
   1823   std::string large_body_string("Unauthorized");
   1824   large_body_string.append(5 * 1024, ' ');
   1825   large_body_string.append("\r\n");
   1826 
   1827   MockRead data_reads1[] = {
   1828     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1829     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1830     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1831     // 5134 = 12 + 5 * 1024 + 2
   1832     MockRead("Content-Length: 5134\r\n\r\n"),
   1833     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
   1834 
   1835     // Lastly, the server responds with the actual content.
   1836     MockRead("HTTP/1.1 200 OK\r\n"),
   1837     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1838     MockRead("Content-Length: 5\r\n\r\n"),
   1839     MockRead("hello"),
   1840   };
   1841 
   1842   // An incorrect reconnect would cause this to be read.
   1843   MockRead data_reads2[] = {
   1844     MockRead(SYNCHRONOUS, ERR_FAILED),
   1845   };
   1846 
   1847   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1848                                  data_writes1, arraysize(data_writes1));
   1849   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1850                                  NULL, 0);
   1851   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1852   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1853 
   1854   TestCompletionCallback callback1;
   1855 
   1856   scoped_ptr<HttpTransaction> trans(
   1857       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1858   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1859   EXPECT_EQ(ERR_IO_PENDING, rv);
   1860 
   1861   rv = callback1.WaitForResult();
   1862   EXPECT_EQ(OK, rv);
   1863 
   1864   const HttpResponseInfo* response = trans->GetResponseInfo();
   1865   ASSERT_TRUE(response != NULL);
   1866   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1867 
   1868   TestCompletionCallback callback2;
   1869 
   1870   rv = trans->RestartWithAuth(
   1871       AuthCredentials(kFoo, kBar), callback2.callback());
   1872   EXPECT_EQ(ERR_IO_PENDING, rv);
   1873 
   1874   rv = callback2.WaitForResult();
   1875   EXPECT_EQ(OK, rv);
   1876 
   1877   response = trans->GetResponseInfo();
   1878   ASSERT_TRUE(response != NULL);
   1879   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1880   EXPECT_EQ(5, response->headers->GetContentLength());
   1881 }
   1882 
   1883 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1884 // connection, but the server gets impatient and closes the connection.
   1885 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   1886   HttpRequestInfo request;
   1887   request.method = "GET";
   1888   request.url = GURL("http://www.google.com/");
   1889   request.load_flags = 0;
   1890 
   1891   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1892 
   1893   MockWrite data_writes1[] = {
   1894     MockWrite("GET / HTTP/1.1\r\n"
   1895               "Host: www.google.com\r\n"
   1896               "Connection: keep-alive\r\n\r\n"),
   1897     // This simulates the seemingly successful write to a closed connection
   1898     // if the bug is not fixed.
   1899     MockWrite("GET / HTTP/1.1\r\n"
   1900               "Host: www.google.com\r\n"
   1901               "Connection: keep-alive\r\n"
   1902               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1903   };
   1904 
   1905   MockRead data_reads1[] = {
   1906     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1907     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1908     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1909     MockRead("Content-Length: 14\r\n\r\n"),
   1910     // Tell MockTCPClientSocket to simulate the server closing the connection.
   1911     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   1912     MockRead("Unauthorized\r\n"),
   1913     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
   1914   };
   1915 
   1916   // After calling trans->RestartWithAuth(), this is the request we should
   1917   // be issuing -- the final header line contains the credentials.
   1918   MockWrite data_writes2[] = {
   1919     MockWrite("GET / HTTP/1.1\r\n"
   1920               "Host: www.google.com\r\n"
   1921               "Connection: keep-alive\r\n"
   1922               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1923   };
   1924 
   1925   // Lastly, the server responds with the actual content.
   1926   MockRead data_reads2[] = {
   1927     MockRead("HTTP/1.1 200 OK\r\n"),
   1928     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1929     MockRead("Content-Length: 5\r\n\r\n"),
   1930     MockRead("hello"),
   1931   };
   1932 
   1933   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1934                                  data_writes1, arraysize(data_writes1));
   1935   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1936                                  data_writes2, arraysize(data_writes2));
   1937   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1938   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1939 
   1940   TestCompletionCallback callback1;
   1941 
   1942   scoped_ptr<HttpTransaction> trans(
   1943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1944   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1945   EXPECT_EQ(ERR_IO_PENDING, rv);
   1946 
   1947   rv = callback1.WaitForResult();
   1948   EXPECT_EQ(OK, rv);
   1949 
   1950   const HttpResponseInfo* response = trans->GetResponseInfo();
   1951   ASSERT_TRUE(response != NULL);
   1952   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1953 
   1954   TestCompletionCallback callback2;
   1955 
   1956   rv = trans->RestartWithAuth(
   1957       AuthCredentials(kFoo, kBar), callback2.callback());
   1958   EXPECT_EQ(ERR_IO_PENDING, rv);
   1959 
   1960   rv = callback2.WaitForResult();
   1961   EXPECT_EQ(OK, rv);
   1962 
   1963   response = trans->GetResponseInfo();
   1964   ASSERT_TRUE(response != NULL);
   1965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1966   EXPECT_EQ(5, response->headers->GetContentLength());
   1967 }
   1968 
   1969 // Test the request-challenge-retry sequence for basic auth, over a connection
   1970 // that requires a restart when setting up an SSL tunnel.
   1971 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
   1972   HttpRequestInfo request;
   1973   request.method = "GET";
   1974   request.url = GURL("https://www.google.com/");
   1975   // when the no authentication data flag is set.
   1976   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1977 
   1978   // Configure against proxy server "myproxy:70".
   1979   session_deps_.proxy_service.reset(
   1980       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   1981   CapturingBoundNetLog log;
   1982   session_deps_.net_log = log.bound().net_log();
   1983   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1984 
   1985   // Since we have proxy, should try to establish tunnel.
   1986   MockWrite data_writes1[] = {
   1987     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1988               "Host: www.google.com\r\n"
   1989               "Proxy-Connection: keep-alive\r\n\r\n"),
   1990 
   1991     // After calling trans->RestartWithAuth(), this is the request we should
   1992     // be issuing -- the final header line contains the credentials.
   1993     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1994               "Host: www.google.com\r\n"
   1995               "Proxy-Connection: keep-alive\r\n"
   1996               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1997 
   1998     MockWrite("GET / HTTP/1.1\r\n"
   1999               "Host: www.google.com\r\n"
   2000               "Connection: keep-alive\r\n\r\n"),
   2001   };
   2002 
   2003   // The proxy responds to the connect with a 407, using a persistent
   2004   // connection.
   2005   MockRead data_reads1[] = {
   2006     // No credentials.
   2007     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2008     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2009     MockRead("Proxy-Connection: close\r\n\r\n"),
   2010 
   2011     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2012 
   2013     MockRead("HTTP/1.1 200 OK\r\n"),
   2014     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2015     MockRead("Content-Length: 5\r\n\r\n"),
   2016     MockRead(SYNCHRONOUS, "hello"),
   2017   };
   2018 
   2019   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2020                                  data_writes1, arraysize(data_writes1));
   2021   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2022   SSLSocketDataProvider ssl(ASYNC, OK);
   2023   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2024 
   2025   TestCompletionCallback callback1;
   2026 
   2027   scoped_ptr<HttpTransaction> trans(
   2028       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2029 
   2030   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2031   EXPECT_EQ(ERR_IO_PENDING, rv);
   2032 
   2033   rv = callback1.WaitForResult();
   2034   EXPECT_EQ(OK, rv);
   2035   net::CapturingNetLog::CapturedEntryList entries;
   2036   log.GetEntries(&entries);
   2037   size_t pos = ExpectLogContainsSomewhere(
   2038       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2039       NetLog::PHASE_NONE);
   2040   ExpectLogContainsSomewhere(
   2041       entries, pos,
   2042       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2043       NetLog::PHASE_NONE);
   2044 
   2045   const HttpResponseInfo* response = trans->GetResponseInfo();
   2046   ASSERT_TRUE(response != NULL);
   2047   ASSERT_FALSE(response->headers.get() == NULL);
   2048   EXPECT_EQ(407, response->headers->response_code());
   2049   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2050   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2051 
   2052   LoadTimingInfo load_timing_info;
   2053   // CONNECT requests and responses are handled at the connect job level, so
   2054   // the transaction does not yet have a connection.
   2055   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
   2056 
   2057   TestCompletionCallback callback2;
   2058 
   2059   rv = trans->RestartWithAuth(
   2060       AuthCredentials(kFoo, kBar), callback2.callback());
   2061   EXPECT_EQ(ERR_IO_PENDING, rv);
   2062 
   2063   rv = callback2.WaitForResult();
   2064   EXPECT_EQ(OK, rv);
   2065 
   2066   response = trans->GetResponseInfo();
   2067   ASSERT_TRUE(response != NULL);
   2068 
   2069   EXPECT_TRUE(response->headers->IsKeepAlive());
   2070   EXPECT_EQ(200, response->headers->response_code());
   2071   EXPECT_EQ(5, response->headers->GetContentLength());
   2072   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2073 
   2074   // The password prompt info should not be set.
   2075   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2076 
   2077   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2078   TestLoadTimingNotReusedWithPac(load_timing_info,
   2079                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2080 
   2081   trans.reset();
   2082   session->CloseAllConnections();
   2083 }
   2084 
   2085 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2086 // proxy connection, when setting up an SSL tunnel.
   2087 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   2088   HttpRequestInfo request;
   2089   request.method = "GET";
   2090   request.url = GURL("https://www.google.com/");
   2091   // Ensure that proxy authentication is attempted even
   2092   // when the no authentication data flag is set.
   2093   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2094 
   2095   // Configure against proxy server "myproxy:70".
   2096   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2097   CapturingBoundNetLog log;
   2098   session_deps_.net_log = log.bound().net_log();
   2099   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2100 
   2101   scoped_ptr<HttpTransaction> trans(
   2102       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2103 
   2104   // Since we have proxy, should try to establish tunnel.
   2105   MockWrite data_writes1[] = {
   2106     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2107               "Host: www.google.com\r\n"
   2108               "Proxy-Connection: keep-alive\r\n\r\n"),
   2109 
   2110     // After calling trans->RestartWithAuth(), this is the request we should
   2111     // be issuing -- the final header line contains the credentials.
   2112     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2113               "Host: www.google.com\r\n"
   2114               "Proxy-Connection: keep-alive\r\n"
   2115               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   2116   };
   2117 
   2118   // The proxy responds to the connect with a 407, using a persistent
   2119   // connection.
   2120   MockRead data_reads1[] = {
   2121     // No credentials.
   2122     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2123     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2124     MockRead("Content-Length: 10\r\n\r\n"),
   2125     MockRead("0123456789"),
   2126 
   2127     // Wrong credentials (wrong password).
   2128     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2129     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2130     MockRead("Content-Length: 10\r\n\r\n"),
   2131     // No response body because the test stops reading here.
   2132     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2133   };
   2134 
   2135   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2136                                  data_writes1, arraysize(data_writes1));
   2137   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2138 
   2139   TestCompletionCallback callback1;
   2140 
   2141   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2142   EXPECT_EQ(ERR_IO_PENDING, rv);
   2143 
   2144   rv = callback1.WaitForResult();
   2145   EXPECT_EQ(OK, rv);
   2146   net::CapturingNetLog::CapturedEntryList entries;
   2147   log.GetEntries(&entries);
   2148   size_t pos = ExpectLogContainsSomewhere(
   2149       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2150       NetLog::PHASE_NONE);
   2151   ExpectLogContainsSomewhere(
   2152       entries, pos,
   2153       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2154       NetLog::PHASE_NONE);
   2155 
   2156   const HttpResponseInfo* response = trans->GetResponseInfo();
   2157   ASSERT_TRUE(response != NULL);
   2158   ASSERT_FALSE(response->headers.get() == NULL);
   2159   EXPECT_TRUE(response->headers->IsKeepAlive());
   2160   EXPECT_EQ(407, response->headers->response_code());
   2161   EXPECT_EQ(10, response->headers->GetContentLength());
   2162   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2163   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2164 
   2165   TestCompletionCallback callback2;
   2166 
   2167   // Wrong password (should be "bar").
   2168   rv = trans->RestartWithAuth(
   2169       AuthCredentials(kFoo, kBaz), callback2.callback());
   2170   EXPECT_EQ(ERR_IO_PENDING, rv);
   2171 
   2172   rv = callback2.WaitForResult();
   2173   EXPECT_EQ(OK, rv);
   2174 
   2175   response = trans->GetResponseInfo();
   2176   ASSERT_TRUE(response != NULL);
   2177   ASSERT_FALSE(response->headers.get() == NULL);
   2178   EXPECT_TRUE(response->headers->IsKeepAlive());
   2179   EXPECT_EQ(407, response->headers->response_code());
   2180   EXPECT_EQ(10, response->headers->GetContentLength());
   2181   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2182   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2183 
   2184   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
   2185   // out of scope.
   2186   session->CloseAllConnections();
   2187 }
   2188 
   2189 // Test that we don't read the response body when we fail to establish a tunnel,
   2190 // even if the user cancels the proxy's auth attempt.
   2191 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   2192   HttpRequestInfo request;
   2193   request.method = "GET";
   2194   request.url = GURL("https://www.google.com/");
   2195   request.load_flags = 0;
   2196 
   2197   // Configure against proxy server "myproxy:70".
   2198   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2199 
   2200   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2201 
   2202   scoped_ptr<HttpTransaction> trans(
   2203       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2204 
   2205   // Since we have proxy, should try to establish tunnel.
   2206   MockWrite data_writes[] = {
   2207     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2208               "Host: www.google.com\r\n"
   2209               "Proxy-Connection: keep-alive\r\n\r\n"),
   2210   };
   2211 
   2212   // The proxy responds to the connect with a 407.
   2213   MockRead data_reads[] = {
   2214     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2215     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2216     MockRead("Content-Length: 10\r\n\r\n"),
   2217     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2218   };
   2219 
   2220   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   2221                                 data_writes, arraysize(data_writes));
   2222   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2223 
   2224   TestCompletionCallback callback;
   2225 
   2226   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2227   EXPECT_EQ(ERR_IO_PENDING, rv);
   2228 
   2229   rv = callback.WaitForResult();
   2230   EXPECT_EQ(OK, rv);
   2231 
   2232   const HttpResponseInfo* response = trans->GetResponseInfo();
   2233   ASSERT_TRUE(response != NULL);
   2234 
   2235   EXPECT_TRUE(response->headers->IsKeepAlive());
   2236   EXPECT_EQ(407, response->headers->response_code());
   2237   EXPECT_EQ(10, response->headers->GetContentLength());
   2238   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2239 
   2240   std::string response_data;
   2241   rv = ReadTransaction(trans.get(), &response_data);
   2242   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   2243 
   2244   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
   2245   session->CloseAllConnections();
   2246 }
   2247 
   2248 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
   2249 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
   2250 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   2251   HttpRequestInfo request;
   2252   request.method = "GET";
   2253   request.url = GURL("http://www.google.com/");
   2254   request.load_flags = 0;
   2255 
   2256   // We are using a DIRECT connection (i.e. no proxy) for this session.
   2257   scoped_ptr<HttpTransaction> trans(
   2258       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   2259                                  CreateSession(&session_deps_)));
   2260 
   2261   MockWrite data_writes1[] = {
   2262     MockWrite("GET / HTTP/1.1\r\n"
   2263               "Host: www.google.com\r\n"
   2264               "Connection: keep-alive\r\n\r\n"),
   2265   };
   2266 
   2267   MockRead data_reads1[] = {
   2268     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
   2269     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2270     // Large content-length -- won't matter, as connection will be reset.
   2271     MockRead("Content-Length: 10000\r\n\r\n"),
   2272     MockRead(SYNCHRONOUS, ERR_FAILED),
   2273   };
   2274 
   2275   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2276                                  data_writes1, arraysize(data_writes1));
   2277   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2278 
   2279   TestCompletionCallback callback;
   2280 
   2281   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2282   EXPECT_EQ(ERR_IO_PENDING, rv);
   2283 
   2284   rv = callback.WaitForResult();
   2285   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2286 }
   2287 
   2288 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
   2289 // through a non-authenticating proxy. The request should fail with
   2290 // ERR_UNEXPECTED_PROXY_AUTH.
   2291 // Note that it is impossible to detect if an HTTP server returns a 407 through
   2292 // a non-authenticating proxy - there is nothing to indicate whether the
   2293 // response came from the proxy or the server, so it is treated as if the proxy
   2294 // issued the challenge.
   2295 TEST_P(HttpNetworkTransactionTest,
   2296        HttpsServerRequestsProxyAuthThroughProxy) {
   2297   HttpRequestInfo request;
   2298   request.method = "GET";
   2299   request.url = GURL("https://www.google.com/");
   2300 
   2301   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2302   CapturingBoundNetLog log;
   2303   session_deps_.net_log = log.bound().net_log();
   2304   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2305 
   2306   // Since we have proxy, should try to establish tunnel.
   2307   MockWrite data_writes1[] = {
   2308     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2309               "Host: www.google.com\r\n"
   2310               "Proxy-Connection: keep-alive\r\n\r\n"),
   2311 
   2312     MockWrite("GET / HTTP/1.1\r\n"
   2313               "Host: www.google.com\r\n"
   2314               "Connection: keep-alive\r\n\r\n"),
   2315   };
   2316 
   2317   MockRead data_reads1[] = {
   2318     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2319 
   2320     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
   2321     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2322     MockRead("\r\n"),
   2323     MockRead(SYNCHRONOUS, OK),
   2324   };
   2325 
   2326   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2327                                  data_writes1, arraysize(data_writes1));
   2328   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2329   SSLSocketDataProvider ssl(ASYNC, OK);
   2330   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2331 
   2332   TestCompletionCallback callback1;
   2333 
   2334   scoped_ptr<HttpTransaction> trans(
   2335       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2336 
   2337   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2338   EXPECT_EQ(ERR_IO_PENDING, rv);
   2339 
   2340   rv = callback1.WaitForResult();
   2341   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2342   net::CapturingNetLog::CapturedEntryList entries;
   2343   log.GetEntries(&entries);
   2344   size_t pos = ExpectLogContainsSomewhere(
   2345       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2346       NetLog::PHASE_NONE);
   2347   ExpectLogContainsSomewhere(
   2348       entries, pos,
   2349       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2350       NetLog::PHASE_NONE);
   2351 }
   2352 
   2353 // Test the load timing for HTTPS requests with an HTTP proxy.
   2354 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
   2355   HttpRequestInfo request1;
   2356   request1.method = "GET";
   2357   request1.url = GURL("https://www.google.com/1");
   2358 
   2359   HttpRequestInfo request2;
   2360   request2.method = "GET";
   2361   request2.url = GURL("https://www.google.com/2");
   2362 
   2363   // Configure against proxy server "myproxy:70".
   2364   session_deps_.proxy_service.reset(
   2365       ProxyService::CreateFixed("PROXY myproxy:70"));
   2366   CapturingBoundNetLog log;
   2367   session_deps_.net_log = log.bound().net_log();
   2368   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2369 
   2370   // Since we have proxy, should try to establish tunnel.
   2371   MockWrite data_writes1[] = {
   2372     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2373               "Host: www.google.com\r\n"
   2374               "Proxy-Connection: keep-alive\r\n\r\n"),
   2375 
   2376     MockWrite("GET /1 HTTP/1.1\r\n"
   2377               "Host: www.google.com\r\n"
   2378               "Connection: keep-alive\r\n\r\n"),
   2379 
   2380     MockWrite("GET /2 HTTP/1.1\r\n"
   2381               "Host: www.google.com\r\n"
   2382               "Connection: keep-alive\r\n\r\n"),
   2383   };
   2384 
   2385   // The proxy responds to the connect with a 407, using a persistent
   2386   // connection.
   2387   MockRead data_reads1[] = {
   2388     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2389 
   2390     MockRead("HTTP/1.1 200 OK\r\n"),
   2391     MockRead("Content-Length: 1\r\n\r\n"),
   2392     MockRead(SYNCHRONOUS, "1"),
   2393 
   2394     MockRead("HTTP/1.1 200 OK\r\n"),
   2395     MockRead("Content-Length: 2\r\n\r\n"),
   2396     MockRead(SYNCHRONOUS, "22"),
   2397   };
   2398 
   2399   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2400                                  data_writes1, arraysize(data_writes1));
   2401   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2402   SSLSocketDataProvider ssl(ASYNC, OK);
   2403   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2404 
   2405   TestCompletionCallback callback1;
   2406   scoped_ptr<HttpTransaction> trans1(
   2407       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2408 
   2409   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2410   EXPECT_EQ(ERR_IO_PENDING, rv);
   2411 
   2412   rv = callback1.WaitForResult();
   2413   EXPECT_EQ(OK, rv);
   2414 
   2415   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2416   ASSERT_TRUE(response1 != NULL);
   2417   ASSERT_TRUE(response1->headers.get() != NULL);
   2418   EXPECT_EQ(1, response1->headers->GetContentLength());
   2419 
   2420   LoadTimingInfo load_timing_info1;
   2421   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2422   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
   2423 
   2424   trans1.reset();
   2425 
   2426   TestCompletionCallback callback2;
   2427   scoped_ptr<HttpTransaction> trans2(
   2428       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2429 
   2430   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2431   EXPECT_EQ(ERR_IO_PENDING, rv);
   2432 
   2433   rv = callback2.WaitForResult();
   2434   EXPECT_EQ(OK, rv);
   2435 
   2436   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2437   ASSERT_TRUE(response2 != NULL);
   2438   ASSERT_TRUE(response2->headers.get() != NULL);
   2439   EXPECT_EQ(2, response2->headers->GetContentLength());
   2440 
   2441   LoadTimingInfo load_timing_info2;
   2442   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2443   TestLoadTimingReused(load_timing_info2);
   2444 
   2445   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2446 
   2447   trans2.reset();
   2448   session->CloseAllConnections();
   2449 }
   2450 
   2451 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
   2452 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
   2453   HttpRequestInfo request1;
   2454   request1.method = "GET";
   2455   request1.url = GURL("https://www.google.com/1");
   2456 
   2457   HttpRequestInfo request2;
   2458   request2.method = "GET";
   2459   request2.url = GURL("https://www.google.com/2");
   2460 
   2461   // Configure against proxy server "myproxy:70".
   2462   session_deps_.proxy_service.reset(
   2463       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2464   CapturingBoundNetLog log;
   2465   session_deps_.net_log = log.bound().net_log();
   2466   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2467 
   2468   // Since we have proxy, should try to establish tunnel.
   2469   MockWrite data_writes1[] = {
   2470     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2471               "Host: www.google.com\r\n"
   2472               "Proxy-Connection: keep-alive\r\n\r\n"),
   2473 
   2474     MockWrite("GET /1 HTTP/1.1\r\n"
   2475               "Host: www.google.com\r\n"
   2476               "Connection: keep-alive\r\n\r\n"),
   2477 
   2478     MockWrite("GET /2 HTTP/1.1\r\n"
   2479               "Host: www.google.com\r\n"
   2480               "Connection: keep-alive\r\n\r\n"),
   2481   };
   2482 
   2483   // The proxy responds to the connect with a 407, using a persistent
   2484   // connection.
   2485   MockRead data_reads1[] = {
   2486     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2487 
   2488     MockRead("HTTP/1.1 200 OK\r\n"),
   2489     MockRead("Content-Length: 1\r\n\r\n"),
   2490     MockRead(SYNCHRONOUS, "1"),
   2491 
   2492     MockRead("HTTP/1.1 200 OK\r\n"),
   2493     MockRead("Content-Length: 2\r\n\r\n"),
   2494     MockRead(SYNCHRONOUS, "22"),
   2495   };
   2496 
   2497   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2498                                  data_writes1, arraysize(data_writes1));
   2499   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2500   SSLSocketDataProvider ssl(ASYNC, OK);
   2501   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2502 
   2503   TestCompletionCallback callback1;
   2504   scoped_ptr<HttpTransaction> trans1(
   2505       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2506 
   2507   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2508   EXPECT_EQ(ERR_IO_PENDING, rv);
   2509 
   2510   rv = callback1.WaitForResult();
   2511   EXPECT_EQ(OK, rv);
   2512 
   2513   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2514   ASSERT_TRUE(response1 != NULL);
   2515   ASSERT_TRUE(response1->headers.get() != NULL);
   2516   EXPECT_EQ(1, response1->headers->GetContentLength());
   2517 
   2518   LoadTimingInfo load_timing_info1;
   2519   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2520   TestLoadTimingNotReusedWithPac(load_timing_info1,
   2521                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2522 
   2523   trans1.reset();
   2524 
   2525   TestCompletionCallback callback2;
   2526   scoped_ptr<HttpTransaction> trans2(
   2527       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2528 
   2529   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2530   EXPECT_EQ(ERR_IO_PENDING, rv);
   2531 
   2532   rv = callback2.WaitForResult();
   2533   EXPECT_EQ(OK, rv);
   2534 
   2535   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2536   ASSERT_TRUE(response2 != NULL);
   2537   ASSERT_TRUE(response2->headers.get() != NULL);
   2538   EXPECT_EQ(2, response2->headers->GetContentLength());
   2539 
   2540   LoadTimingInfo load_timing_info2;
   2541   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2542   TestLoadTimingReusedWithPac(load_timing_info2);
   2543 
   2544   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2545 
   2546   trans2.reset();
   2547   session->CloseAllConnections();
   2548 }
   2549 
   2550 // Test a simple get through an HTTPS Proxy.
   2551 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
   2552   HttpRequestInfo request;
   2553   request.method = "GET";
   2554   request.url = GURL("http://www.google.com/");
   2555 
   2556   // Configure against https proxy server "proxy:70".
   2557   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2558       "https://proxy:70"));
   2559   CapturingBoundNetLog log;
   2560   session_deps_.net_log = log.bound().net_log();
   2561   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2562 
   2563   // Since we have proxy, should use full url
   2564   MockWrite data_writes1[] = {
   2565     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2566               "Host: www.google.com\r\n"
   2567               "Proxy-Connection: keep-alive\r\n\r\n"),
   2568   };
   2569 
   2570   MockRead data_reads1[] = {
   2571     MockRead("HTTP/1.1 200 OK\r\n"),
   2572     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2573     MockRead("Content-Length: 100\r\n\r\n"),
   2574     MockRead(SYNCHRONOUS, OK),
   2575   };
   2576 
   2577   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2578                                  data_writes1, arraysize(data_writes1));
   2579   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2580   SSLSocketDataProvider ssl(ASYNC, OK);
   2581   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2582 
   2583   TestCompletionCallback callback1;
   2584 
   2585   scoped_ptr<HttpTransaction> trans(
   2586       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2587 
   2588   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2589   EXPECT_EQ(ERR_IO_PENDING, rv);
   2590 
   2591   rv = callback1.WaitForResult();
   2592   EXPECT_EQ(OK, rv);
   2593 
   2594   LoadTimingInfo load_timing_info;
   2595   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2596   TestLoadTimingNotReused(load_timing_info,
   2597                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2598 
   2599   const HttpResponseInfo* response = trans->GetResponseInfo();
   2600   ASSERT_TRUE(response != NULL);
   2601 
   2602   EXPECT_TRUE(response->headers->IsKeepAlive());
   2603   EXPECT_EQ(200, response->headers->response_code());
   2604   EXPECT_EQ(100, response->headers->GetContentLength());
   2605   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2606 
   2607   // The password prompt info should not be set.
   2608   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2609 }
   2610 
   2611 // Test a SPDY get through an HTTPS Proxy.
   2612 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   2613   HttpRequestInfo request;
   2614   request.method = "GET";
   2615   request.url = GURL("http://www.google.com/");
   2616   request.load_flags = 0;
   2617 
   2618   // Configure against https proxy server "proxy:70".
   2619   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2620       "https://proxy:70"));
   2621   CapturingBoundNetLog log;
   2622   session_deps_.net_log = log.bound().net_log();
   2623   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2624 
   2625   // fetch http://www.google.com/ via SPDY
   2626   scoped_ptr<SpdyFrame> req(
   2627       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2628   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   2629 
   2630   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2631   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2632   MockRead spdy_reads[] = {
   2633     CreateMockRead(*resp),
   2634     CreateMockRead(*data),
   2635     MockRead(ASYNC, 0, 0),
   2636   };
   2637 
   2638   DelayedSocketData spdy_data(
   2639       1,  // wait for one write to finish before reading.
   2640       spdy_reads, arraysize(spdy_reads),
   2641       spdy_writes, arraysize(spdy_writes));
   2642   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2643 
   2644   SSLSocketDataProvider ssl(ASYNC, OK);
   2645   ssl.SetNextProto(GetParam());
   2646   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2647 
   2648   TestCompletionCallback callback1;
   2649 
   2650   scoped_ptr<HttpTransaction> trans(
   2651       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2652 
   2653   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2654   EXPECT_EQ(ERR_IO_PENDING, rv);
   2655 
   2656   rv = callback1.WaitForResult();
   2657   EXPECT_EQ(OK, rv);
   2658 
   2659   LoadTimingInfo load_timing_info;
   2660   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2661   TestLoadTimingNotReused(load_timing_info,
   2662                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2663 
   2664   const HttpResponseInfo* response = trans->GetResponseInfo();
   2665   ASSERT_TRUE(response != NULL);
   2666   ASSERT_TRUE(response->headers.get() != NULL);
   2667   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2668 
   2669   std::string response_data;
   2670   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2671   EXPECT_EQ(kUploadData, response_data);
   2672 }
   2673 
   2674 // Test a SPDY get through an HTTPS Proxy.
   2675 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   2676   HttpRequestInfo request;
   2677   request.method = "GET";
   2678   request.url = GURL("http://www.google.com/");
   2679   request.load_flags = 0;
   2680 
   2681   // Configure against https proxy server "myproxy:70".
   2682   session_deps_.proxy_service.reset(
   2683       ProxyService::CreateFixed("https://myproxy:70"));
   2684   CapturingBoundNetLog log;
   2685   session_deps_.net_log = log.bound().net_log();
   2686   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2687 
   2688   // The first request will be a bare GET, the second request will be a
   2689   // GET with a Proxy-Authorization header.
   2690   scoped_ptr<SpdyFrame> req_get(
   2691       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2692   const char* const kExtraAuthorizationHeaders[] = {
   2693     "proxy-authorization", "Basic Zm9vOmJhcg=="
   2694   };
   2695   scoped_ptr<SpdyFrame> req_get_authorization(
   2696       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
   2697                                   arraysize(kExtraAuthorizationHeaders) / 2,
   2698                                   false,
   2699                                   3,
   2700                                   LOWEST,
   2701                                   false));
   2702   MockWrite spdy_writes[] = {
   2703     CreateMockWrite(*req_get, 1),
   2704     CreateMockWrite(*req_get_authorization, 4),
   2705   };
   2706 
   2707   // The first response is a 407 proxy authentication challenge, and the second
   2708   // response will be a 200 response since the second request includes a valid
   2709   // Authorization header.
   2710   const char* const kExtraAuthenticationHeaders[] = {
   2711     "proxy-authenticate", "Basic realm=\"MyRealm1\""
   2712   };
   2713   scoped_ptr<SpdyFrame> resp_authentication(
   2714       spdy_util_.ConstructSpdySynReplyError(
   2715           "407 Proxy Authentication Required",
   2716           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
   2717           1));
   2718   scoped_ptr<SpdyFrame> body_authentication(
   2719       spdy_util_.ConstructSpdyBodyFrame(1, true));
   2720   scoped_ptr<SpdyFrame> resp_data(
   2721       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   2722   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
   2723   MockRead spdy_reads[] = {
   2724     CreateMockRead(*resp_authentication, 2),
   2725     CreateMockRead(*body_authentication, 3),
   2726     CreateMockRead(*resp_data, 5),
   2727     CreateMockRead(*body_data, 6),
   2728     MockRead(ASYNC, 0, 7),
   2729   };
   2730 
   2731   OrderedSocketData data(
   2732       spdy_reads, arraysize(spdy_reads),
   2733       spdy_writes, arraysize(spdy_writes));
   2734   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2735 
   2736   SSLSocketDataProvider ssl(ASYNC, OK);
   2737   ssl.SetNextProto(GetParam());
   2738   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2739 
   2740   TestCompletionCallback callback1;
   2741 
   2742   scoped_ptr<HttpTransaction> trans(
   2743       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2744 
   2745   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2746   EXPECT_EQ(ERR_IO_PENDING, rv);
   2747 
   2748   rv = callback1.WaitForResult();
   2749   EXPECT_EQ(OK, rv);
   2750 
   2751   const HttpResponseInfo* const response = trans->GetResponseInfo();
   2752 
   2753   ASSERT_TRUE(response != NULL);
   2754   ASSERT_TRUE(response->headers.get() != NULL);
   2755   EXPECT_EQ(407, response->headers->response_code());
   2756   EXPECT_TRUE(response->was_fetched_via_spdy);
   2757   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2758 
   2759   TestCompletionCallback callback2;
   2760 
   2761   rv = trans->RestartWithAuth(
   2762       AuthCredentials(kFoo, kBar), callback2.callback());
   2763   EXPECT_EQ(ERR_IO_PENDING, rv);
   2764 
   2765   rv = callback2.WaitForResult();
   2766   EXPECT_EQ(OK, rv);
   2767 
   2768   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   2769 
   2770   ASSERT_TRUE(response_restart != NULL);
   2771   ASSERT_TRUE(response_restart->headers.get() != NULL);
   2772   EXPECT_EQ(200, response_restart->headers->response_code());
   2773   // The password prompt info should not be set.
   2774   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   2775 }
   2776 
   2777 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
   2778 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   2779   HttpRequestInfo request;
   2780   request.method = "GET";
   2781   request.url = GURL("https://www.google.com/");
   2782   request.load_flags = 0;
   2783 
   2784   // Configure against https proxy server "proxy:70".
   2785   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2786       "https://proxy:70"));
   2787   CapturingBoundNetLog log;
   2788   session_deps_.net_log = log.bound().net_log();
   2789   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2790 
   2791   scoped_ptr<HttpTransaction> trans(
   2792       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2793 
   2794   // CONNECT to www.google.com:443 via SPDY
   2795   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   2796   // fetch https://www.google.com/ via HTTP
   2797 
   2798   const char get[] = "GET / HTTP/1.1\r\n"
   2799     "Host: www.google.com\r\n"
   2800     "Connection: keep-alive\r\n\r\n";
   2801   scoped_ptr<SpdyFrame> wrapped_get(
   2802       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
   2803   scoped_ptr<SpdyFrame> conn_resp(
   2804       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2805   const char resp[] = "HTTP/1.1 200 OK\r\n"
   2806       "Content-Length: 10\r\n\r\n";
   2807   scoped_ptr<SpdyFrame> wrapped_get_resp(
   2808       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
   2809   scoped_ptr<SpdyFrame> wrapped_body(
   2810       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
   2811   scoped_ptr<SpdyFrame> window_update(
   2812       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   2813 
   2814   MockWrite spdy_writes[] = {
   2815       CreateMockWrite(*connect, 1),
   2816       CreateMockWrite(*wrapped_get, 3),
   2817       CreateMockWrite(*window_update, 5),
   2818   };
   2819 
   2820   MockRead spdy_reads[] = {
   2821     CreateMockRead(*conn_resp, 2, ASYNC),
   2822     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   2823     CreateMockRead(*wrapped_body, 6, ASYNC),
   2824     CreateMockRead(*wrapped_body, 7, ASYNC),
   2825     MockRead(ASYNC, 0, 8),
   2826   };
   2827 
   2828   OrderedSocketData spdy_data(
   2829       spdy_reads, arraysize(spdy_reads),
   2830       spdy_writes, arraysize(spdy_writes));
   2831   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2832 
   2833   SSLSocketDataProvider ssl(ASYNC, OK);
   2834   ssl.SetNextProto(GetParam());
   2835   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2836   SSLSocketDataProvider ssl2(ASYNC, OK);
   2837   ssl2.was_npn_negotiated = false;
   2838   ssl2.protocol_negotiated = kProtoUnknown;
   2839   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   2840 
   2841   TestCompletionCallback callback1;
   2842 
   2843   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2844   EXPECT_EQ(ERR_IO_PENDING, rv);
   2845 
   2846   rv = callback1.WaitForResult();
   2847   EXPECT_EQ(OK, rv);
   2848 
   2849   LoadTimingInfo load_timing_info;
   2850   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2851   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   2852 
   2853   const HttpResponseInfo* response = trans->GetResponseInfo();
   2854   ASSERT_TRUE(response != NULL);
   2855   ASSERT_TRUE(response->headers.get() != NULL);
   2856   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2857 
   2858   std::string response_data;
   2859   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2860   EXPECT_EQ("1234567890", response_data);
   2861 }
   2862 
   2863 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
   2864 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   2865   HttpRequestInfo request;
   2866   request.method = "GET";
   2867   request.url = GURL("https://www.google.com/");
   2868   request.load_flags = 0;
   2869 
   2870   // Configure against https proxy server "proxy:70".
   2871   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2872       "https://proxy:70"));
   2873   CapturingBoundNetLog log;
   2874   session_deps_.net_log = log.bound().net_log();
   2875   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2876 
   2877   scoped_ptr<HttpTransaction> trans(
   2878       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2879 
   2880   // CONNECT to www.google.com:443 via SPDY
   2881   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   2882   // fetch https://www.google.com/ via SPDY
   2883   const char* const kMyUrl = "https://www.google.com/";
   2884   scoped_ptr<SpdyFrame> get(
   2885       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   2886   scoped_ptr<SpdyFrame> wrapped_get(
   2887       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
   2888   scoped_ptr<SpdyFrame> conn_resp(
   2889       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2890   scoped_ptr<SpdyFrame> get_resp(
   2891       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2892   scoped_ptr<SpdyFrame> wrapped_get_resp(
   2893       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
   2894   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2895   scoped_ptr<SpdyFrame> wrapped_body(
   2896       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
   2897   scoped_ptr<SpdyFrame> window_update_get_resp(
   2898       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   2899   scoped_ptr<SpdyFrame> window_update_body(
   2900       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
   2901 
   2902   MockWrite spdy_writes[] = {
   2903       CreateMockWrite(*connect, 1),
   2904       CreateMockWrite(*wrapped_get, 3),
   2905       CreateMockWrite(*window_update_get_resp, 5),
   2906       CreateMockWrite(*window_update_body, 7),
   2907   };
   2908 
   2909   MockRead spdy_reads[] = {
   2910     CreateMockRead(*conn_resp, 2, ASYNC),
   2911     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   2912     CreateMockRead(*wrapped_body, 6, ASYNC),
   2913     MockRead(ASYNC, 0, 8),
   2914   };
   2915 
   2916   OrderedSocketData spdy_data(
   2917       spdy_reads, arraysize(spdy_reads),
   2918       spdy_writes, arraysize(spdy_writes));
   2919   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2920 
   2921   SSLSocketDataProvider ssl(ASYNC, OK);
   2922   ssl.SetNextProto(GetParam());
   2923   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2924   SSLSocketDataProvider ssl2(ASYNC, OK);
   2925   ssl2.SetNextProto(GetParam());
   2926   ssl2.protocol_negotiated = GetParam();
   2927   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   2928 
   2929   TestCompletionCallback callback1;
   2930 
   2931   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2932   EXPECT_EQ(ERR_IO_PENDING, rv);
   2933 
   2934   rv = callback1.WaitForResult();
   2935   EXPECT_EQ(OK, rv);
   2936 
   2937   LoadTimingInfo load_timing_info;
   2938   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2939   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   2940 
   2941   const HttpResponseInfo* response = trans->GetResponseInfo();
   2942   ASSERT_TRUE(response != NULL);
   2943   ASSERT_TRUE(response->headers.get() != NULL);
   2944   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2945 
   2946   std::string response_data;
   2947   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2948   EXPECT_EQ(kUploadData, response_data);
   2949 }
   2950 
   2951 // Test a SPDY CONNECT failure through an HTTPS Proxy.
   2952 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   2953   HttpRequestInfo request;
   2954   request.method = "GET";
   2955   request.url = GURL("https://www.google.com/");
   2956   request.load_flags = 0;
   2957 
   2958   // Configure against https proxy server "proxy:70".
   2959   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2960       "https://proxy:70"));
   2961   CapturingBoundNetLog log;
   2962   session_deps_.net_log = log.bound().net_log();
   2963   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2964 
   2965   scoped_ptr<HttpTransaction> trans(
   2966       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2967 
   2968   // CONNECT to www.google.com:443 via SPDY
   2969   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   2970   scoped_ptr<SpdyFrame> get(
   2971       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   2972 
   2973   MockWrite spdy_writes[] = {
   2974       CreateMockWrite(*connect, 1),
   2975       CreateMockWrite(*get, 3),
   2976   };
   2977 
   2978   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
   2979   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2980   MockRead spdy_reads[] = {
   2981     CreateMockRead(*resp, 2, ASYNC),
   2982     MockRead(ASYNC, 0, 4),
   2983   };
   2984 
   2985   OrderedSocketData spdy_data(
   2986       spdy_reads, arraysize(spdy_reads),
   2987       spdy_writes, arraysize(spdy_writes));
   2988   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2989 
   2990   SSLSocketDataProvider ssl(ASYNC, OK);
   2991   ssl.SetNextProto(GetParam());
   2992   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2993   SSLSocketDataProvider ssl2(ASYNC, OK);
   2994   ssl2.SetNextProto(GetParam());
   2995   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   2996 
   2997   TestCompletionCallback callback1;
   2998 
   2999   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3000   EXPECT_EQ(ERR_IO_PENDING, rv);
   3001 
   3002   rv = callback1.WaitForResult();
   3003   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3004 
   3005   // TODO(ttuttle): Anything else to check here?
   3006 }
   3007 
   3008 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3009 // HTTPS Proxy to different servers.
   3010 TEST_P(HttpNetworkTransactionTest,
   3011        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
   3012   // Configure against https proxy server "proxy:70".
   3013   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3014       "https://proxy:70"));
   3015   CapturingBoundNetLog log;
   3016   session_deps_.net_log = log.bound().net_log();
   3017   scoped_refptr<HttpNetworkSession> session(
   3018       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3019 
   3020   HttpRequestInfo request1;
   3021   request1.method = "GET";
   3022   request1.url = GURL("https://www.google.com/");
   3023   request1.load_flags = 0;
   3024 
   3025   HttpRequestInfo request2;
   3026   request2.method = "GET";
   3027   request2.url = GURL("https://news.google.com/");
   3028   request2.load_flags = 0;
   3029 
   3030   // CONNECT to www.google.com:443 via SPDY.
   3031   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   3032   scoped_ptr<SpdyFrame> conn_resp1(
   3033       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3034 
   3035   // Fetch https://www.google.com/ via HTTP.
   3036   const char get1[] = "GET / HTTP/1.1\r\n"
   3037       "Host: www.google.com\r\n"
   3038       "Connection: keep-alive\r\n\r\n";
   3039   scoped_ptr<SpdyFrame> wrapped_get1(
   3040       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3041   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3042       "Content-Length: 1\r\n\r\n";
   3043   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3044       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3045   scoped_ptr<SpdyFrame> wrapped_body1(
   3046       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3047   scoped_ptr<SpdyFrame> window_update(
   3048       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3049 
   3050   // CONNECT to news.google.com:443 via SPDY.
   3051   const char* const kConnectHeaders2[] = {
   3052     spdy_util_.GetMethodKey(), "CONNECT",
   3053     spdy_util_.GetPathKey(), "news.google.com:443",
   3054     spdy_util_.GetHostKey(), "news.google.com",
   3055     spdy_util_.GetVersionKey(), "HTTP/1.1",
   3056   };
   3057   scoped_ptr<SpdyFrame> connect2(
   3058       spdy_util_.ConstructSpdyControlFrame(NULL,
   3059                                            0,
   3060                                            /*compressed*/ false,
   3061                                            3,
   3062                                            LOWEST,
   3063                                            SYN_STREAM,
   3064                                            CONTROL_FLAG_NONE,
   3065                                            kConnectHeaders2,
   3066                                            arraysize(kConnectHeaders2),
   3067                                            0));
   3068   scoped_ptr<SpdyFrame> conn_resp2(
   3069       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3070 
   3071   // Fetch https://news.google.com/ via HTTP.
   3072   const char get2[] = "GET / HTTP/1.1\r\n"
   3073       "Host: news.google.com\r\n"
   3074       "Connection: keep-alive\r\n\r\n";
   3075   scoped_ptr<SpdyFrame> wrapped_get2(
   3076       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
   3077   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3078       "Content-Length: 2\r\n\r\n";
   3079   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3080       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
   3081   scoped_ptr<SpdyFrame> wrapped_body2(
   3082       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
   3083 
   3084   MockWrite spdy_writes[] = {
   3085       CreateMockWrite(*connect1, 0),
   3086       CreateMockWrite(*wrapped_get1, 2),
   3087       CreateMockWrite(*connect2, 5),
   3088       CreateMockWrite(*wrapped_get2, 7),
   3089   };
   3090 
   3091   MockRead spdy_reads[] = {
   3092     CreateMockRead(*conn_resp1, 1, ASYNC),
   3093     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3094     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3095     CreateMockRead(*conn_resp2, 6, ASYNC),
   3096     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
   3097     CreateMockRead(*wrapped_body2, 9, ASYNC),
   3098     MockRead(ASYNC, 0, 10),
   3099   };
   3100 
   3101   DeterministicSocketData spdy_data(
   3102       spdy_reads, arraysize(spdy_reads),
   3103       spdy_writes, arraysize(spdy_writes));
   3104   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3105 
   3106   SSLSocketDataProvider ssl(ASYNC, OK);
   3107   ssl.SetNextProto(GetParam());
   3108   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3109   SSLSocketDataProvider ssl2(ASYNC, OK);
   3110   ssl2.was_npn_negotiated = false;
   3111   ssl2.protocol_negotiated = kProtoUnknown;
   3112   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3113   SSLSocketDataProvider ssl3(ASYNC, OK);
   3114   ssl3.was_npn_negotiated = false;
   3115   ssl3.protocol_negotiated = kProtoUnknown;
   3116   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
   3117 
   3118   TestCompletionCallback callback;
   3119 
   3120   scoped_ptr<HttpTransaction> trans(
   3121       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3122   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3123   EXPECT_EQ(ERR_IO_PENDING, rv);
   3124   // The first connect and request, each of their responses, and the body.
   3125   spdy_data.RunFor(5);
   3126 
   3127   rv = callback.WaitForResult();
   3128   EXPECT_EQ(OK, rv);
   3129 
   3130   LoadTimingInfo load_timing_info;
   3131   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3132   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3133 
   3134   const HttpResponseInfo* response = trans->GetResponseInfo();
   3135   ASSERT_TRUE(response != NULL);
   3136   ASSERT_TRUE(response->headers.get() != NULL);
   3137   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3138 
   3139   std::string response_data;
   3140   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3141   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3142 
   3143   scoped_ptr<HttpTransaction> trans2(
   3144       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3145   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3146   EXPECT_EQ(ERR_IO_PENDING, rv);
   3147 
   3148   // The second connect and request, each of their responses, and the body.
   3149   spdy_data.RunFor(5);
   3150   rv = callback.WaitForResult();
   3151   EXPECT_EQ(OK, rv);
   3152 
   3153   LoadTimingInfo load_timing_info2;
   3154   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3155   // Even though the SPDY connection is reused, a new tunnelled connection has
   3156   // to be created, so the socket's load timing looks like a fresh connection.
   3157   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
   3158 
   3159   // The requests should have different IDs, since they each are using their own
   3160   // separate stream.
   3161   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3162 
   3163   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3164 }
   3165 
   3166 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3167 // HTTPS Proxy to the same server.
   3168 TEST_P(HttpNetworkTransactionTest,
   3169        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
   3170   // Configure against https proxy server "proxy:70".
   3171   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3172       "https://proxy:70"));
   3173   CapturingBoundNetLog log;
   3174   session_deps_.net_log = log.bound().net_log();
   3175   scoped_refptr<HttpNetworkSession> session(
   3176       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3177 
   3178   HttpRequestInfo request1;
   3179   request1.method = "GET";
   3180   request1.url = GURL("https://www.google.com/");
   3181   request1.load_flags = 0;
   3182 
   3183   HttpRequestInfo request2;
   3184   request2.method = "GET";
   3185   request2.url = GURL("https://www.google.com/2");
   3186   request2.load_flags = 0;
   3187 
   3188   // CONNECT to www.google.com:443 via SPDY.
   3189   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   3190   scoped_ptr<SpdyFrame> conn_resp1(
   3191       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3192 
   3193   // Fetch https://www.google.com/ via HTTP.
   3194   const char get1[] = "GET / HTTP/1.1\r\n"
   3195       "Host: www.google.com\r\n"
   3196       "Connection: keep-alive\r\n\r\n";
   3197   scoped_ptr<SpdyFrame> wrapped_get1(
   3198       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3199   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3200       "Content-Length: 1\r\n\r\n";
   3201   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3202       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3203   scoped_ptr<SpdyFrame> wrapped_body1(
   3204       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3205   scoped_ptr<SpdyFrame> window_update(
   3206       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3207 
   3208   // Fetch https://www.google.com/2 via HTTP.
   3209   const char get2[] = "GET /2 HTTP/1.1\r\n"
   3210       "Host: www.google.com\r\n"
   3211       "Connection: keep-alive\r\n\r\n";
   3212   scoped_ptr<SpdyFrame> wrapped_get2(
   3213       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
   3214   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3215       "Content-Length: 2\r\n\r\n";
   3216   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3217       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
   3218   scoped_ptr<SpdyFrame> wrapped_body2(
   3219       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
   3220 
   3221   MockWrite spdy_writes[] = {
   3222       CreateMockWrite(*connect1, 0),
   3223       CreateMockWrite(*wrapped_get1, 2),
   3224       CreateMockWrite(*wrapped_get2, 5),
   3225   };
   3226 
   3227   MockRead spdy_reads[] = {
   3228     CreateMockRead(*conn_resp1, 1, ASYNC),
   3229     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3230     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3231     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
   3232     CreateMockRead(*wrapped_body2, 7, ASYNC),
   3233     MockRead(ASYNC, 0, 8),
   3234   };
   3235 
   3236   DeterministicSocketData spdy_data(
   3237       spdy_reads, arraysize(spdy_reads),
   3238       spdy_writes, arraysize(spdy_writes));
   3239   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3240 
   3241   SSLSocketDataProvider ssl(ASYNC, OK);
   3242   ssl.SetNextProto(GetParam());
   3243   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3244   SSLSocketDataProvider ssl2(ASYNC, OK);
   3245   ssl2.was_npn_negotiated = false;
   3246   ssl2.protocol_negotiated = kProtoUnknown;
   3247   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3248 
   3249   TestCompletionCallback callback;
   3250 
   3251   scoped_ptr<HttpTransaction> trans(
   3252       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3253   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3254   EXPECT_EQ(ERR_IO_PENDING, rv);
   3255   // The first connect and request, each of their responses, and the body.
   3256   spdy_data.RunFor(5);
   3257 
   3258   rv = callback.WaitForResult();
   3259   EXPECT_EQ(OK, rv);
   3260 
   3261   LoadTimingInfo load_timing_info;
   3262   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3263   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3264 
   3265   const HttpResponseInfo* response = trans->GetResponseInfo();
   3266   ASSERT_TRUE(response != NULL);
   3267   ASSERT_TRUE(response->headers.get() != NULL);
   3268   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3269 
   3270   std::string response_data;
   3271   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3272   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3273   trans.reset();
   3274 
   3275   scoped_ptr<HttpTransaction> trans2(
   3276       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3277   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3278   EXPECT_EQ(ERR_IO_PENDING, rv);
   3279 
   3280   // The second request, response, and body.  There should not be a second
   3281   // connect.
   3282   spdy_data.RunFor(3);
   3283   rv = callback.WaitForResult();
   3284   EXPECT_EQ(OK, rv);
   3285 
   3286   LoadTimingInfo load_timing_info2;
   3287   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3288   TestLoadTimingReused(load_timing_info2);
   3289 
   3290   // The requests should have the same ID.
   3291   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3292 
   3293   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3294 }
   3295 
   3296 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
   3297 // Proxy to different servers.
   3298 TEST_P(HttpNetworkTransactionTest,
   3299        HttpsProxySpdyLoadTimingTwoHttpRequests) {
   3300   // Configure against https proxy server "proxy:70".
   3301   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3302       "https://proxy:70"));
   3303   CapturingBoundNetLog log;
   3304   session_deps_.net_log = log.bound().net_log();
   3305   scoped_refptr<HttpNetworkSession> session(
   3306       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3307 
   3308   HttpRequestInfo request1;
   3309   request1.method = "GET";
   3310   request1.url = GURL("http://www.google.com/");
   3311   request1.load_flags = 0;
   3312 
   3313   HttpRequestInfo request2;
   3314   request2.method = "GET";
   3315   request2.url = GURL("http://news.google.com/");
   3316   request2.load_flags = 0;
   3317 
   3318   // http://www.google.com/
   3319   scoped_ptr<SpdyHeaderBlock> headers(
   3320       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   3321   scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
   3322       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3323   scoped_ptr<SpdyFrame> get_resp1(
   3324       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3325   scoped_ptr<SpdyFrame> body1(
   3326       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
   3327 
   3328   // http://news.google.com/
   3329   scoped_ptr<SpdyHeaderBlock> headers2(
   3330       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
   3331   scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
   3332       headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3333   scoped_ptr<SpdyFrame> get_resp2(
   3334       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3335   scoped_ptr<SpdyFrame> body2(
   3336       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
   3337 
   3338   MockWrite spdy_writes[] = {
   3339       CreateMockWrite(*get1, 0),
   3340       CreateMockWrite(*get2, 3),
   3341   };
   3342 
   3343   MockRead spdy_reads[] = {
   3344     CreateMockRead(*get_resp1, 1, ASYNC),
   3345     CreateMockRead(*body1, 2, ASYNC),
   3346     CreateMockRead(*get_resp2, 4, ASYNC),
   3347     CreateMockRead(*body2, 5, ASYNC),
   3348     MockRead(ASYNC, 0, 6),
   3349   };
   3350 
   3351   DeterministicSocketData spdy_data(
   3352       spdy_reads, arraysize(spdy_reads),
   3353       spdy_writes, arraysize(spdy_writes));
   3354   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3355 
   3356   SSLSocketDataProvider ssl(ASYNC, OK);
   3357   ssl.SetNextProto(GetParam());
   3358   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3359 
   3360   TestCompletionCallback callback;
   3361 
   3362   scoped_ptr<HttpTransaction> trans(
   3363       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3364   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3365   EXPECT_EQ(ERR_IO_PENDING, rv);
   3366   spdy_data.RunFor(2);
   3367 
   3368   rv = callback.WaitForResult();
   3369   EXPECT_EQ(OK, rv);
   3370 
   3371   LoadTimingInfo load_timing_info;
   3372   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3373   TestLoadTimingNotReused(load_timing_info,
   3374                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3375 
   3376   const HttpResponseInfo* response = trans->GetResponseInfo();
   3377   ASSERT_TRUE(response != NULL);
   3378   ASSERT_TRUE(response->headers.get() != NULL);
   3379   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3380 
   3381   std::string response_data;
   3382   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3383   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
   3384   spdy_data.RunFor(1);
   3385   EXPECT_EQ(1, callback.WaitForResult());
   3386   // Delete the first request, so the second one can reuse the socket.
   3387   trans.reset();
   3388 
   3389   scoped_ptr<HttpTransaction> trans2(
   3390       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3391   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3392   EXPECT_EQ(ERR_IO_PENDING, rv);
   3393 
   3394   spdy_data.RunFor(2);
   3395   rv = callback.WaitForResult();
   3396   EXPECT_EQ(OK, rv);
   3397 
   3398   LoadTimingInfo load_timing_info2;
   3399   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3400   TestLoadTimingReused(load_timing_info2);
   3401 
   3402   // The requests should have the same ID.
   3403   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3404 
   3405   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
   3406   spdy_data.RunFor(1);
   3407   EXPECT_EQ(2, callback.WaitForResult());
   3408 }
   3409 
   3410 // Test the challenge-response-retry sequence through an HTTPS Proxy
   3411 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   3412   HttpRequestInfo request;
   3413   request.method = "GET";
   3414   request.url = GURL("http://www.google.com/");
   3415   // when the no authentication data flag is set.
   3416   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   3417 
   3418   // Configure against https proxy server "myproxy:70".
   3419   session_deps_.proxy_service.reset(
   3420       ProxyService::CreateFixed("https://myproxy:70"));
   3421   CapturingBoundNetLog log;
   3422   session_deps_.net_log = log.bound().net_log();
   3423   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3424 
   3425   // Since we have proxy, should use full url
   3426   MockWrite data_writes1[] = {
   3427     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3428               "Host: www.google.com\r\n"
   3429               "Proxy-Connection: keep-alive\r\n\r\n"),
   3430 
   3431     // After calling trans->RestartWithAuth(), this is the request we should
   3432     // be issuing -- the final header line contains the credentials.
   3433     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3434               "Host: www.google.com\r\n"
   3435               "Proxy-Connection: keep-alive\r\n"
   3436               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3437   };
   3438 
   3439   // The proxy responds to the GET with a 407, using a persistent
   3440   // connection.
   3441   MockRead data_reads1[] = {
   3442     // No credentials.
   3443     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3444     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3445     MockRead("Proxy-Connection: keep-alive\r\n"),
   3446     MockRead("Content-Length: 0\r\n\r\n"),
   3447 
   3448     MockRead("HTTP/1.1 200 OK\r\n"),
   3449     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3450     MockRead("Content-Length: 100\r\n\r\n"),
   3451     MockRead(SYNCHRONOUS, OK),
   3452   };
   3453 
   3454   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3455                                  data_writes1, arraysize(data_writes1));
   3456   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3457   SSLSocketDataProvider ssl(ASYNC, OK);
   3458   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3459 
   3460   TestCompletionCallback callback1;
   3461 
   3462   scoped_ptr<HttpTransaction> trans(
   3463       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3464 
   3465   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3466   EXPECT_EQ(ERR_IO_PENDING, rv);
   3467 
   3468   rv = callback1.WaitForResult();
   3469   EXPECT_EQ(OK, rv);
   3470 
   3471   LoadTimingInfo load_timing_info;
   3472   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3473   TestLoadTimingNotReused(load_timing_info,
   3474                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3475 
   3476   const HttpResponseInfo* response = trans->GetResponseInfo();
   3477   ASSERT_TRUE(response != NULL);
   3478   ASSERT_FALSE(response->headers.get() == NULL);
   3479   EXPECT_EQ(407, response->headers->response_code());
   3480   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3481   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3482 
   3483   TestCompletionCallback callback2;
   3484 
   3485   rv = trans->RestartWithAuth(
   3486       AuthCredentials(kFoo, kBar), callback2.callback());
   3487   EXPECT_EQ(ERR_IO_PENDING, rv);
   3488 
   3489   rv = callback2.WaitForResult();
   3490   EXPECT_EQ(OK, rv);
   3491 
   3492   load_timing_info = LoadTimingInfo();
   3493   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3494   // Retrying with HTTP AUTH is considered to be reusing a socket.
   3495   TestLoadTimingReused(load_timing_info);
   3496 
   3497   response = trans->GetResponseInfo();
   3498   ASSERT_TRUE(response != NULL);
   3499 
   3500   EXPECT_TRUE(response->headers->IsKeepAlive());
   3501   EXPECT_EQ(200, response->headers->response_code());
   3502   EXPECT_EQ(100, response->headers->GetContentLength());
   3503   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3504 
   3505   // The password prompt info should not be set.
   3506   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3507 }
   3508 
   3509 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   3510     const MockRead& status, int expected_status) {
   3511   HttpRequestInfo request;
   3512   request.method = "GET";
   3513   request.url = GURL("https://www.google.com/");
   3514   request.load_flags = 0;
   3515 
   3516   // Configure against proxy server "myproxy:70".
   3517   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3518 
   3519   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3520 
   3521   // Since we have proxy, should try to establish tunnel.
   3522   MockWrite data_writes[] = {
   3523     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   3524               "Host: www.google.com\r\n"
   3525               "Proxy-Connection: keep-alive\r\n\r\n"),
   3526   };
   3527 
   3528   MockRead data_reads[] = {
   3529     status,
   3530     MockRead("Content-Length: 10\r\n\r\n"),
   3531     // No response body because the test stops reading here.
   3532     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   3533   };
   3534 
   3535   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3536                                 data_writes, arraysize(data_writes));
   3537   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3538 
   3539   TestCompletionCallback callback;
   3540 
   3541   scoped_ptr<HttpTransaction> trans(
   3542       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3543 
   3544   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   3545   EXPECT_EQ(ERR_IO_PENDING, rv);
   3546 
   3547   rv = callback.WaitForResult();
   3548   EXPECT_EQ(expected_status, rv);
   3549 }
   3550 
   3551 void HttpNetworkTransactionTest::ConnectStatusHelper(
   3552     const MockRead& status) {
   3553   ConnectStatusHelperWithExpectedStatus(
   3554       status, ERR_TUNNEL_CONNECTION_FAILED);
   3555 }
   3556 
   3557 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
   3558   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   3559 }
   3560 
   3561 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
   3562   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   3563 }
   3564 
   3565 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
   3566   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   3567 }
   3568 
   3569 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
   3570   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   3571 }
   3572 
   3573 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
   3574   ConnectStatusHelper(
   3575       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   3576 }
   3577 
   3578 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
   3579   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   3580 }
   3581 
   3582 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
   3583   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   3584 }
   3585 
   3586 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
   3587   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   3588 }
   3589 
   3590 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
   3591   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   3592 }
   3593 
   3594 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
   3595   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   3596 }
   3597 
   3598 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
   3599   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   3600 }
   3601 
   3602 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
   3603   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   3604 }
   3605 
   3606 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
   3607   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   3608 }
   3609 
   3610 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
   3611   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   3612 }
   3613 
   3614 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
   3615   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   3616 }
   3617 
   3618 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
   3619   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   3620 }
   3621 
   3622 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
   3623   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   3624 }
   3625 
   3626 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
   3627   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   3628 }
   3629 
   3630 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
   3631   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   3632 }
   3633 
   3634 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
   3635   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   3636 }
   3637 
   3638 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
   3639   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   3640 }
   3641 
   3642 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
   3643   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   3644 }
   3645 
   3646 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
   3647   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   3648 }
   3649 
   3650 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
   3651   ConnectStatusHelperWithExpectedStatus(
   3652       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3653       ERR_PROXY_AUTH_UNSUPPORTED);
   3654 }
   3655 
   3656 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
   3657   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   3658 }
   3659 
   3660 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
   3661   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   3662 }
   3663 
   3664 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
   3665   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   3666 }
   3667 
   3668 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
   3669   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   3670 }
   3671 
   3672 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
   3673   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   3674 }
   3675 
   3676 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
   3677   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   3678 }
   3679 
   3680 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
   3681   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   3682 }
   3683 
   3684 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
   3685   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   3686 }
   3687 
   3688 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
   3689   ConnectStatusHelper(
   3690       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   3691 }
   3692 
   3693 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
   3694   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   3695 }
   3696 
   3697 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
   3698   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   3699 }
   3700 
   3701 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
   3702   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   3703 }
   3704 
   3705 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
   3706   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   3707 }
   3708 
   3709 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
   3710   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   3711 }
   3712 
   3713 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
   3714   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   3715 }
   3716 
   3717 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
   3718   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   3719 }
   3720 
   3721 // Test the flow when both the proxy server AND origin server require
   3722 // authentication. Again, this uses basic auth for both since that is
   3723 // the simplest to mock.
   3724 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   3725   HttpRequestInfo request;
   3726   request.method = "GET";
   3727   request.url = GURL("http://www.google.com/");
   3728   request.load_flags = 0;
   3729 
   3730   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3731 
   3732   // Configure against proxy server "myproxy:70".
   3733   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
   3734       CreateSession(&session_deps_)));
   3735 
   3736   MockWrite data_writes1[] = {
   3737     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3738               "Host: www.google.com\r\n"
   3739               "Proxy-Connection: keep-alive\r\n\r\n"),
   3740   };
   3741 
   3742   MockRead data_reads1[] = {
   3743     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   3744     // Give a couple authenticate options (only the middle one is actually
   3745     // supported).
   3746     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   3747     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3748     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   3749     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3750     // Large content-length -- won't matter, as connection will be reset.
   3751     MockRead("Content-Length: 10000\r\n\r\n"),
   3752     MockRead(SYNCHRONOUS, ERR_FAILED),
   3753   };
   3754 
   3755   // After calling trans->RestartWithAuth() the first time, this is the
   3756   // request we should be issuing -- the final header line contains the
   3757   // proxy's credentials.
   3758   MockWrite data_writes2[] = {
   3759     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3760               "Host: www.google.com\r\n"
   3761               "Proxy-Connection: keep-alive\r\n"
   3762               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3763   };
   3764 
   3765   // Now the proxy server lets the request pass through to origin server.
   3766   // The origin server responds with a 401.
   3767   MockRead data_reads2[] = {
   3768     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3769     // Note: We are using the same realm-name as the proxy server. This is
   3770     // completely valid, as realms are unique across hosts.
   3771     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3772     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3773     MockRead("Content-Length: 2000\r\n\r\n"),
   3774     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
   3775   };
   3776 
   3777   // After calling trans->RestartWithAuth() the second time, we should send
   3778   // the credentials for both the proxy and origin server.
   3779   MockWrite data_writes3[] = {
   3780     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3781               "Host: www.google.com\r\n"
   3782               "Proxy-Connection: keep-alive\r\n"
   3783               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   3784               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   3785   };
   3786 
   3787   // Lastly we get the desired content.
   3788   MockRead data_reads3[] = {
   3789     MockRead("HTTP/1.0 200 OK\r\n"),
   3790     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3791     MockRead("Content-Length: 100\r\n\r\n"),
   3792     MockRead(SYNCHRONOUS, OK),
   3793   };
   3794 
   3795   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3796                                  data_writes1, arraysize(data_writes1));
   3797   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3798                                  data_writes2, arraysize(data_writes2));
   3799   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   3800                                  data_writes3, arraysize(data_writes3));
   3801   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3802   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   3803   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   3804 
   3805   TestCompletionCallback callback1;
   3806 
   3807   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   3808   EXPECT_EQ(ERR_IO_PENDING, rv);
   3809 
   3810   rv = callback1.WaitForResult();
   3811   EXPECT_EQ(OK, rv);
   3812 
   3813   const HttpResponseInfo* response = trans->GetResponseInfo();
   3814   ASSERT_TRUE(response != NULL);
   3815   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3816 
   3817   TestCompletionCallback callback2;
   3818 
   3819   rv = trans->RestartWithAuth(
   3820       AuthCredentials(kFoo, kBar), callback2.callback());
   3821   EXPECT_EQ(ERR_IO_PENDING, rv);
   3822 
   3823   rv = callback2.WaitForResult();
   3824   EXPECT_EQ(OK, rv);
   3825 
   3826   response = trans->GetResponseInfo();
   3827   ASSERT_TRUE(response != NULL);
   3828   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   3829 
   3830   TestCompletionCallback callback3;
   3831 
   3832   rv = trans->RestartWithAuth(
   3833       AuthCredentials(kFoo2, kBar2), callback3.callback());
   3834   EXPECT_EQ(ERR_IO_PENDING, rv);
   3835 
   3836   rv = callback3.WaitForResult();
   3837   EXPECT_EQ(OK, rv);
   3838 
   3839   response = trans->GetResponseInfo();
   3840   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3841   EXPECT_EQ(100, response->headers->GetContentLength());
   3842 }
   3843 
   3844 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   3845 // can't hook into its internals to cause it to generate predictable NTLM
   3846 // authorization headers.
   3847 #if defined(NTLM_PORTABLE)
   3848 // The NTLM authentication unit tests were generated by capturing the HTTP
   3849 // requests and responses using Fiddler 2 and inspecting the generated random
   3850 // bytes in the debugger.
   3851 
   3852 // Enter the correct password and authenticate successfully.
   3853 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
   3854   HttpRequestInfo request;
   3855   request.method = "GET";
   3856   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   3857   request.load_flags = 0;
   3858 
   3859   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   3860                                                     MockGetHostName);
   3861   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3862 
   3863   MockWrite data_writes1[] = {
   3864     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3865               "Host: 172.22.68.17\r\n"
   3866               "Connection: keep-alive\r\n\r\n"),
   3867   };
   3868 
   3869   MockRead data_reads1[] = {
   3870     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   3871     // Negotiate and NTLM are often requested together.  However, we only want
   3872     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   3873     // the header that requests Negotiate for this test.
   3874     MockRead("WWW-Authenticate: NTLM\r\n"),
   3875     MockRead("Connection: close\r\n"),
   3876     MockRead("Content-Length: 42\r\n"),
   3877     MockRead("Content-Type: text/html\r\n\r\n"),
   3878     // Missing content -- won't matter, as connection will be reset.
   3879     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   3880   };
   3881 
   3882   MockWrite data_writes2[] = {
   3883     // After restarting with a null identity, this is the
   3884     // request we should be issuing -- the final header line contains a Type
   3885     // 1 message.
   3886     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3887               "Host: 172.22.68.17\r\n"
   3888               "Connection: keep-alive\r\n"
   3889               "Authorization: NTLM "
   3890               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   3891 
   3892     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   3893     // (the credentials for the origin server).  The second request continues
   3894     // on the same connection.
   3895     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3896               "Host: 172.22.68.17\r\n"
   3897               "Connection: keep-alive\r\n"
   3898               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   3899               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   3900               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   3901               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   3902               "ahlhx5I=\r\n\r\n"),
   3903   };
   3904 
   3905   MockRead data_reads2[] = {
   3906     // The origin server responds with a Type 2 message.
   3907     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   3908     MockRead("WWW-Authenticate: NTLM "
   3909              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   3910              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   3911              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   3912              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   3913              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   3914              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   3915              "BtAAAAAAA=\r\n"),
   3916     MockRead("Content-Length: 42\r\n"),
   3917     MockRead("Content-Type: text/html\r\n\r\n"),
   3918     MockRead("You are not authorized to view this page\r\n"),
   3919 
   3920     // Lastly we get the desired content.
   3921     MockRead("HTTP/1.1 200 OK\r\n"),
   3922     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   3923     MockRead("Content-Length: 13\r\n\r\n"),
   3924     MockRead("Please Login\r\n"),
   3925     MockRead(SYNCHRONOUS, OK),
   3926   };
   3927 
   3928   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3929                                  data_writes1, arraysize(data_writes1));
   3930   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3931                                  data_writes2, arraysize(data_writes2));
   3932   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3933   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   3934 
   3935   TestCompletionCallback callback1;
   3936 
   3937   scoped_ptr<HttpTransaction> trans(
   3938       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3939 
   3940   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   3941   EXPECT_EQ(ERR_IO_PENDING, rv);
   3942 
   3943   rv = callback1.WaitForResult();
   3944   EXPECT_EQ(OK, rv);
   3945 
   3946   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3947 
   3948   const HttpResponseInfo* response = trans->GetResponseInfo();
   3949   ASSERT_FALSE(response == NULL);
   3950   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   3951 
   3952   TestCompletionCallback callback2;
   3953 
   3954   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   3955                               callback2.callback());
   3956   EXPECT_EQ(ERR_IO_PENDING, rv);
   3957 
   3958   rv = callback2.WaitForResult();
   3959   EXPECT_EQ(OK, rv);
   3960 
   3961   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3962 
   3963   response = trans->GetResponseInfo();
   3964   ASSERT_TRUE(response != NULL);
   3965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3966 
   3967   TestCompletionCallback callback3;
   3968 
   3969   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   3970   EXPECT_EQ(ERR_IO_PENDING, rv);
   3971 
   3972   rv = callback3.WaitForResult();
   3973   EXPECT_EQ(OK, rv);
   3974 
   3975   response = trans->GetResponseInfo();
   3976   ASSERT_TRUE(response != NULL);
   3977   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3978   EXPECT_EQ(13, response->headers->GetContentLength());
   3979 }
   3980 
   3981 // Enter a wrong password, and then the correct one.
   3982 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
   3983   HttpRequestInfo request;
   3984   request.method = "GET";
   3985   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   3986   request.load_flags = 0;
   3987 
   3988   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   3989                                                     MockGetHostName);
   3990   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3991 
   3992   MockWrite data_writes1[] = {
   3993     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3994               "Host: 172.22.68.17\r\n"
   3995               "Connection: keep-alive\r\n\r\n"),
   3996   };
   3997 
   3998   MockRead data_reads1[] = {
   3999     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4000     // Negotiate and NTLM are often requested together.  However, we only want
   4001     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4002     // the header that requests Negotiate for this test.
   4003     MockRead("WWW-Authenticate: NTLM\r\n"),
   4004     MockRead("Connection: close\r\n"),
   4005     MockRead("Content-Length: 42\r\n"),
   4006     MockRead("Content-Type: text/html\r\n\r\n"),
   4007     // Missing content -- won't matter, as connection will be reset.
   4008     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4009   };
   4010 
   4011   MockWrite data_writes2[] = {
   4012     // After restarting with a null identity, this is the
   4013     // request we should be issuing -- the final header line contains a Type
   4014     // 1 message.
   4015     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4016               "Host: 172.22.68.17\r\n"
   4017               "Connection: keep-alive\r\n"
   4018               "Authorization: NTLM "
   4019               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4020 
   4021     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4022     // (the credentials for the origin server).  The second request continues
   4023     // on the same connection.
   4024     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4025               "Host: 172.22.68.17\r\n"
   4026               "Connection: keep-alive\r\n"
   4027               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4028               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4029               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   4030               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   4031               "4Ww7b7E=\r\n\r\n"),
   4032   };
   4033 
   4034   MockRead data_reads2[] = {
   4035     // The origin server responds with a Type 2 message.
   4036     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4037     MockRead("WWW-Authenticate: NTLM "
   4038              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   4039              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4040              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4041              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4042              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4043              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4044              "BtAAAAAAA=\r\n"),
   4045     MockRead("Content-Length: 42\r\n"),
   4046     MockRead("Content-Type: text/html\r\n\r\n"),
   4047     MockRead("You are not authorized to view this page\r\n"),
   4048 
   4049     // Wrong password.
   4050     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4051     MockRead("WWW-Authenticate: NTLM\r\n"),
   4052     MockRead("Connection: close\r\n"),
   4053     MockRead("Content-Length: 42\r\n"),
   4054     MockRead("Content-Type: text/html\r\n\r\n"),
   4055     // Missing content -- won't matter, as connection will be reset.
   4056     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4057   };
   4058 
   4059   MockWrite data_writes3[] = {
   4060     // After restarting with a null identity, this is the
   4061     // request we should be issuing -- the final header line contains a Type
   4062     // 1 message.
   4063     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4064               "Host: 172.22.68.17\r\n"
   4065               "Connection: keep-alive\r\n"
   4066               "Authorization: NTLM "
   4067               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4068 
   4069     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4070     // (the credentials for the origin server).  The second request continues
   4071     // on the same connection.
   4072     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4073               "Host: 172.22.68.17\r\n"
   4074               "Connection: keep-alive\r\n"
   4075               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4076               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4077               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   4078               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   4079               "+4MUm7c=\r\n\r\n"),
   4080   };
   4081 
   4082   MockRead data_reads3[] = {
   4083     // The origin server responds with a Type 2 message.
   4084     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4085     MockRead("WWW-Authenticate: NTLM "
   4086              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   4087              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4088              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4089              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4090              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4091              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4092              "BtAAAAAAA=\r\n"),
   4093     MockRead("Content-Length: 42\r\n"),
   4094     MockRead("Content-Type: text/html\r\n\r\n"),
   4095     MockRead("You are not authorized to view this page\r\n"),
   4096 
   4097     // Lastly we get the desired content.
   4098     MockRead("HTTP/1.1 200 OK\r\n"),
   4099     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4100     MockRead("Content-Length: 13\r\n\r\n"),
   4101     MockRead("Please Login\r\n"),
   4102     MockRead(SYNCHRONOUS, OK),
   4103   };
   4104 
   4105   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4106                                  data_writes1, arraysize(data_writes1));
   4107   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4108                                  data_writes2, arraysize(data_writes2));
   4109   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4110                                  data_writes3, arraysize(data_writes3));
   4111   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4112   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4113   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4114 
   4115   TestCompletionCallback callback1;
   4116 
   4117   scoped_ptr<HttpTransaction> trans(
   4118       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4119 
   4120   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4121   EXPECT_EQ(ERR_IO_PENDING, rv);
   4122 
   4123   rv = callback1.WaitForResult();
   4124   EXPECT_EQ(OK, rv);
   4125 
   4126   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4127 
   4128   const HttpResponseInfo* response = trans->GetResponseInfo();
   4129   ASSERT_TRUE(response != NULL);
   4130   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4131 
   4132   TestCompletionCallback callback2;
   4133 
   4134   // Enter the wrong password.
   4135   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
   4136                               callback2.callback());
   4137   EXPECT_EQ(ERR_IO_PENDING, rv);
   4138 
   4139   rv = callback2.WaitForResult();
   4140   EXPECT_EQ(OK, rv);
   4141 
   4142   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4143   TestCompletionCallback callback3;
   4144   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4145   EXPECT_EQ(ERR_IO_PENDING, rv);
   4146   rv = callback3.WaitForResult();
   4147   EXPECT_EQ(OK, rv);
   4148   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4149 
   4150   response = trans->GetResponseInfo();
   4151   ASSERT_FALSE(response == NULL);
   4152   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4153 
   4154   TestCompletionCallback callback4;
   4155 
   4156   // Now enter the right password.
   4157   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4158                               callback4.callback());
   4159   EXPECT_EQ(ERR_IO_PENDING, rv);
   4160 
   4161   rv = callback4.WaitForResult();
   4162   EXPECT_EQ(OK, rv);
   4163 
   4164   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4165 
   4166   TestCompletionCallback callback5;
   4167 
   4168   // One more roundtrip
   4169   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
   4170   EXPECT_EQ(ERR_IO_PENDING, rv);
   4171 
   4172   rv = callback5.WaitForResult();
   4173   EXPECT_EQ(OK, rv);
   4174 
   4175   response = trans->GetResponseInfo();
   4176   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4177   EXPECT_EQ(13, response->headers->GetContentLength());
   4178 }
   4179 #endif  // NTLM_PORTABLE
   4180 
   4181 // Test reading a server response which has only headers, and no body.
   4182 // After some maximum number of bytes is consumed, the transaction should
   4183 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   4184 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   4185   HttpRequestInfo request;
   4186   request.method = "GET";
   4187   request.url = GURL("http://www.google.com/");
   4188   request.load_flags = 0;
   4189 
   4190   scoped_ptr<HttpTransaction> trans(
   4191       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   4192                                  CreateSession(&session_deps_)));
   4193 
   4194   // Respond with 300 kb of headers (we should fail after 256 kb).
   4195   std::string large_headers_string;
   4196   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   4197 
   4198   MockRead data_reads[] = {
   4199     MockRead("HTTP/1.0 200 OK\r\n"),
   4200     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
   4201     MockRead("\r\nBODY"),
   4202     MockRead(SYNCHRONOUS, OK),
   4203   };
   4204   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4205   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4206 
   4207   TestCompletionCallback callback;
   4208 
   4209   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4210   EXPECT_EQ(ERR_IO_PENDING, rv);
   4211 
   4212   rv = callback.WaitForResult();
   4213   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   4214 
   4215   const HttpResponseInfo* response = trans->GetResponseInfo();
   4216   EXPECT_TRUE(response == NULL);
   4217 }
   4218 
   4219 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   4220 // establish tunnel.
   4221 // http://code.google.com/p/chromium/issues/detail?id=3772
   4222 TEST_P(HttpNetworkTransactionTest,
   4223        DontRecycleTransportSocketForSSLTunnel) {
   4224   HttpRequestInfo request;
   4225   request.method = "GET";
   4226   request.url = GURL("https://www.google.com/");
   4227   request.load_flags = 0;
   4228 
   4229   // Configure against proxy server "myproxy:70".
   4230   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4231 
   4232   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4233 
   4234   scoped_ptr<HttpTransaction> trans(
   4235       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4236 
   4237   // Since we have proxy, should try to establish tunnel.
   4238   MockWrite data_writes1[] = {
   4239     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4240               "Host: www.google.com\r\n"
   4241               "Proxy-Connection: keep-alive\r\n\r\n"),
   4242   };
   4243 
   4244   // The proxy responds to the connect with a 404, using a persistent
   4245   // connection. Usually a proxy would return 501 (not implemented),
   4246   // or 200 (tunnel established).
   4247   MockRead data_reads1[] = {
   4248     MockRead("HTTP/1.1 404 Not Found\r\n"),
   4249     MockRead("Content-Length: 10\r\n\r\n"),
   4250     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   4251   };
   4252 
   4253   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4254                                  data_writes1, arraysize(data_writes1));
   4255   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4256 
   4257   TestCompletionCallback callback1;
   4258 
   4259   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4260   EXPECT_EQ(ERR_IO_PENDING, rv);
   4261 
   4262   rv = callback1.WaitForResult();
   4263   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   4264 
   4265   const HttpResponseInfo* response = trans->GetResponseInfo();
   4266   EXPECT_TRUE(response == NULL);
   4267 
   4268   // Empty the current queue.  This is necessary because idle sockets are
   4269   // added to the connection pool asynchronously with a PostTask.
   4270   base::MessageLoop::current()->RunUntilIdle();
   4271 
   4272   // We now check to make sure the TCPClientSocket was not added back to
   4273   // the pool.
   4274   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4275   trans.reset();
   4276   base::MessageLoop::current()->RunUntilIdle();
   4277   // Make sure that the socket didn't get recycled after calling the destructor.
   4278   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4279 }
   4280 
   4281 // Make sure that we recycle a socket after reading all of the response body.
   4282 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
   4283   HttpRequestInfo request;
   4284   request.method = "GET";
   4285   request.url = GURL("http://www.google.com/");
   4286   request.load_flags = 0;
   4287 
   4288   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4289 
   4290   scoped_ptr<HttpTransaction> trans(
   4291       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4292 
   4293   MockRead data_reads[] = {
   4294     // A part of the response body is received with the response headers.
   4295     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   4296     // The rest of the response body is received in two parts.
   4297     MockRead("lo"),
   4298     MockRead(" world"),
   4299     MockRead("junk"),  // Should not be read!!
   4300     MockRead(SYNCHRONOUS, OK),
   4301   };
   4302 
   4303   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4304   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4305 
   4306   TestCompletionCallback callback;
   4307 
   4308   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4309   EXPECT_EQ(ERR_IO_PENDING, rv);
   4310 
   4311   rv = callback.WaitForResult();
   4312   EXPECT_EQ(OK, rv);
   4313 
   4314   const HttpResponseInfo* response = trans->GetResponseInfo();
   4315   ASSERT_TRUE(response != NULL);
   4316 
   4317   EXPECT_TRUE(response->headers.get() != NULL);
   4318   std::string status_line = response->headers->GetStatusLine();
   4319   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   4320 
   4321   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4322 
   4323   std::string response_data;
   4324   rv = ReadTransaction(trans.get(), &response_data);
   4325   EXPECT_EQ(OK, rv);
   4326   EXPECT_EQ("hello world", response_data);
   4327 
   4328   // Empty the current queue.  This is necessary because idle sockets are
   4329   // added to the connection pool asynchronously with a PostTask.
   4330   base::MessageLoop::current()->RunUntilIdle();
   4331 
   4332   // We now check to make sure the socket was added back to the pool.
   4333   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4334 }
   4335 
   4336 // Make sure that we recycle a SSL socket after reading all of the response
   4337 // body.
   4338 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
   4339   HttpRequestInfo request;
   4340   request.method = "GET";
   4341   request.url = GURL("https://www.google.com/");
   4342   request.load_flags = 0;
   4343 
   4344   MockWrite data_writes[] = {
   4345     MockWrite("GET / HTTP/1.1\r\n"
   4346               "Host: www.google.com\r\n"
   4347               "Connection: keep-alive\r\n\r\n"),
   4348   };
   4349 
   4350   MockRead data_reads[] = {
   4351     MockRead("HTTP/1.1 200 OK\r\n"),
   4352     MockRead("Content-Length: 11\r\n\r\n"),
   4353     MockRead("hello world"),
   4354     MockRead(SYNCHRONOUS, OK),
   4355   };
   4356 
   4357   SSLSocketDataProvider ssl(ASYNC, OK);
   4358   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4359 
   4360   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4361                                 data_writes, arraysize(data_writes));
   4362   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4363 
   4364   TestCompletionCallback callback;
   4365 
   4366   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4367   scoped_ptr<HttpTransaction> trans(
   4368       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4369 
   4370   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4371 
   4372   EXPECT_EQ(ERR_IO_PENDING, rv);
   4373   EXPECT_EQ(OK, callback.WaitForResult());
   4374 
   4375   const HttpResponseInfo* response = trans->GetResponseInfo();
   4376   ASSERT_TRUE(response != NULL);
   4377   ASSERT_TRUE(response->headers.get() != NULL);
   4378   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4379 
   4380   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4381 
   4382   std::string response_data;
   4383   rv = ReadTransaction(trans.get(), &response_data);
   4384   EXPECT_EQ(OK, rv);
   4385   EXPECT_EQ("hello world", response_data);
   4386 
   4387   // Empty the current queue.  This is necessary because idle sockets are
   4388   // added to the connection pool asynchronously with a PostTask.
   4389   base::MessageLoop::current()->RunUntilIdle();
   4390 
   4391   // We now check to make sure the socket was added back to the pool.
   4392   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4393 }
   4394 
   4395 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
   4396 // from the pool and make sure that we recover okay.
   4397 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   4398   HttpRequestInfo request;
   4399   request.method = "GET";
   4400   request.url = GURL("https://www.google.com/");
   4401   request.load_flags = 0;
   4402 
   4403   MockWrite data_writes[] = {
   4404     MockWrite("GET / HTTP/1.1\r\n"
   4405               "Host: www.google.com\r\n"
   4406               "Connection: keep-alive\r\n\r\n"),
   4407     MockWrite("GET / HTTP/1.1\r\n"
   4408               "Host: www.google.com\r\n"
   4409               "Connection: keep-alive\r\n\r\n"),
   4410   };
   4411 
   4412   MockRead data_reads[] = {
   4413     MockRead("HTTP/1.1 200 OK\r\n"),
   4414     MockRead("Content-Length: 11\r\n\r\n"),
   4415     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   4416     MockRead("hello world"),
   4417     MockRead(ASYNC, 0, 0)   // EOF
   4418   };
   4419 
   4420   SSLSocketDataProvider ssl(ASYNC, OK);
   4421   SSLSocketDataProvider ssl2(ASYNC, OK);
   4422   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4423   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   4424 
   4425   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4426                                 data_writes, arraysize(data_writes));
   4427   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
   4428                                 data_writes, arraysize(data_writes));
   4429   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4430   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4431 
   4432   TestCompletionCallback callback;
   4433 
   4434   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4435   scoped_ptr<HttpTransaction> trans(
   4436       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4437 
   4438   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4439 
   4440   EXPECT_EQ(ERR_IO_PENDING, rv);
   4441   EXPECT_EQ(OK, callback.WaitForResult());
   4442 
   4443   const HttpResponseInfo* response = trans->GetResponseInfo();
   4444   ASSERT_TRUE(response != NULL);
   4445   ASSERT_TRUE(response->headers.get() != NULL);
   4446   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4447 
   4448   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4449 
   4450   std::string response_data;
   4451   rv = ReadTransaction(trans.get(), &response_data);
   4452   EXPECT_EQ(OK, rv);
   4453   EXPECT_EQ("hello world", response_data);
   4454 
   4455   // Empty the current queue.  This is necessary because idle sockets are
   4456   // added to the connection pool asynchronously with a PostTask.
   4457   base::MessageLoop::current()->RunUntilIdle();
   4458 
   4459   // We now check to make sure the socket was added back to the pool.
   4460   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4461 
   4462   // Now start the second transaction, which should reuse the previous socket.
   4463 
   4464   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4465 
   4466   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4467 
   4468   EXPECT_EQ(ERR_IO_PENDING, rv);
   4469   EXPECT_EQ(OK, callback.WaitForResult());
   4470 
   4471   response = trans->GetResponseInfo();
   4472   ASSERT_TRUE(response != NULL);
   4473   ASSERT_TRUE(response->headers.get() != NULL);
   4474   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4475 
   4476   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4477 
   4478   rv = ReadTransaction(trans.get(), &response_data);
   4479   EXPECT_EQ(OK, rv);
   4480   EXPECT_EQ("hello world", response_data);
   4481 
   4482   // Empty the current queue.  This is necessary because idle sockets are
   4483   // added to the connection pool asynchronously with a PostTask.
   4484   base::MessageLoop::current()->RunUntilIdle();
   4485 
   4486   // We now check to make sure the socket was added back to the pool.
   4487   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4488 }
   4489 
   4490 // Make sure that we recycle a socket after a zero-length response.
   4491 // http://crbug.com/9880
   4492 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   4493   HttpRequestInfo request;
   4494   request.method = "GET";
   4495   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   4496                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   4497                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   4498                      "rt=prt.2642,ol.2649,xjs.2951");
   4499   request.load_flags = 0;
   4500 
   4501   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4502 
   4503   scoped_ptr<HttpTransaction> trans(
   4504       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4505 
   4506   MockRead data_reads[] = {
   4507     MockRead("HTTP/1.1 204 No Content\r\n"
   4508              "Content-Length: 0\r\n"
   4509              "Content-Type: text/html\r\n\r\n"),
   4510     MockRead("junk"),  // Should not be read!!
   4511     MockRead(SYNCHRONOUS, OK),
   4512   };
   4513 
   4514   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4515   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4516 
   4517   TestCompletionCallback callback;
   4518 
   4519   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4520   EXPECT_EQ(ERR_IO_PENDING, rv);
   4521 
   4522   rv = callback.WaitForResult();
   4523   EXPECT_EQ(OK, rv);
   4524 
   4525   const HttpResponseInfo* response = trans->GetResponseInfo();
   4526   ASSERT_TRUE(response != NULL);
   4527 
   4528   EXPECT_TRUE(response->headers.get() != NULL);
   4529   std::string status_line = response->headers->GetStatusLine();
   4530   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   4531 
   4532   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4533 
   4534   std::string response_data;
   4535   rv = ReadTransaction(trans.get(), &response_data);
   4536   EXPECT_EQ(OK, rv);
   4537   EXPECT_EQ("", response_data);
   4538 
   4539   // Empty the current queue.  This is necessary because idle sockets are
   4540   // added to the connection pool asynchronously with a PostTask.
   4541   base::MessageLoop::current()->RunUntilIdle();
   4542 
   4543   // We now check to make sure the socket was added back to the pool.
   4544   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4545 }
   4546 
   4547 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   4548   ScopedVector<UploadElementReader> element_readers;
   4549   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   4550   UploadDataStream upload_data_stream(&element_readers, 0);
   4551 
   4552   HttpRequestInfo request[2];
   4553   // Transaction 1: a GET request that succeeds.  The socket is recycled
   4554   // after use.
   4555   request[0].method = "GET";
   4556   request[0].url = GURL("http://www.google.com/");
   4557   request[0].load_flags = 0;
   4558   // Transaction 2: a POST request.  Reuses the socket kept alive from
   4559   // transaction 1.  The first attempts fails when writing the POST data.
   4560   // This causes the transaction to retry with a new socket.  The second
   4561   // attempt succeeds.
   4562   request[1].method = "POST";
   4563   request[1].url = GURL("http://www.google.com/login.cgi");
   4564   request[1].upload_data_stream = &upload_data_stream;
   4565   request[1].load_flags = 0;
   4566 
   4567   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4568 
   4569   // The first socket is used for transaction 1 and the first attempt of
   4570   // transaction 2.
   4571 
   4572   // The response of transaction 1.
   4573   MockRead data_reads1[] = {
   4574     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   4575     MockRead("hello world"),
   4576     MockRead(SYNCHRONOUS, OK),
   4577   };
   4578   // The mock write results of transaction 1 and the first attempt of
   4579   // transaction 2.
   4580   MockWrite data_writes1[] = {
   4581     MockWrite(SYNCHRONOUS, 64),  // GET
   4582     MockWrite(SYNCHRONOUS, 93),  // POST
   4583     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
   4584   };
   4585   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4586                                  data_writes1, arraysize(data_writes1));
   4587 
   4588   // The second socket is used for the second attempt of transaction 2.
   4589 
   4590   // The response of transaction 2.
   4591   MockRead data_reads2[] = {
   4592     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   4593     MockRead("welcome"),
   4594     MockRead(SYNCHRONOUS, OK),
   4595   };
   4596   // The mock write results of the second attempt of transaction 2.
   4597   MockWrite data_writes2[] = {
   4598     MockWrite(SYNCHRONOUS, 93),  // POST
   4599     MockWrite(SYNCHRONOUS, 3),  // POST data
   4600   };
   4601   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4602                                  data_writes2, arraysize(data_writes2));
   4603 
   4604   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4605   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4606 
   4607   const char* kExpectedResponseData[] = {
   4608     "hello world", "welcome"
   4609   };
   4610 
   4611   for (int i = 0; i < 2; ++i) {
   4612     scoped_ptr<HttpTransaction> trans(
   4613         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4614 
   4615     TestCompletionCallback callback;
   4616 
   4617     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
   4618     EXPECT_EQ(ERR_IO_PENDING, rv);
   4619 
   4620     rv = callback.WaitForResult();
   4621     EXPECT_EQ(OK, rv);
   4622 
   4623     const HttpResponseInfo* response = trans->GetResponseInfo();
   4624     ASSERT_TRUE(response != NULL);
   4625 
   4626     EXPECT_TRUE(response->headers.get() != NULL);
   4627     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4628 
   4629     std::string response_data;
   4630     rv = ReadTransaction(trans.get(), &response_data);
   4631     EXPECT_EQ(OK, rv);
   4632     EXPECT_EQ(kExpectedResponseData[i], response_data);
   4633   }
   4634 }
   4635 
   4636 // Test the request-challenge-retry sequence for basic auth when there is
   4637 // an identity in the URL. The request should be sent as normal, but when
   4638 // it fails the identity from the URL is used to answer the challenge.
   4639 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
   4640   HttpRequestInfo request;
   4641   request.method = "GET";
   4642   request.url = GURL("http://foo:b@r@www.google.com/");
   4643   request.load_flags = LOAD_NORMAL;
   4644 
   4645   scoped_ptr<HttpTransaction> trans(
   4646       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   4647                                  CreateSession(&session_deps_)));
   4648 
   4649   // The password contains an escaped character -- for this test to pass it
   4650   // will need to be unescaped by HttpNetworkTransaction.
   4651   EXPECT_EQ("b%40r", request.url.password());
   4652 
   4653   MockWrite data_writes1[] = {
   4654     MockWrite("GET / HTTP/1.1\r\n"
   4655               "Host: www.google.com\r\n"
   4656               "Connection: keep-alive\r\n\r\n"),
   4657   };
   4658 
   4659   MockRead data_reads1[] = {
   4660     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4661     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4662     MockRead("Content-Length: 10\r\n\r\n"),
   4663     MockRead(SYNCHRONOUS, ERR_FAILED),
   4664   };
   4665 
   4666   // After the challenge above, the transaction will be restarted using the
   4667   // identity from the url (foo, b@r) to answer the challenge.
   4668   MockWrite data_writes2[] = {
   4669     MockWrite("GET / HTTP/1.1\r\n"
   4670               "Host: www.google.com\r\n"
   4671               "Connection: keep-alive\r\n"
   4672               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   4673   };
   4674 
   4675   MockRead data_reads2[] = {
   4676     MockRead("HTTP/1.0 200 OK\r\n"),
   4677     MockRead("Content-Length: 100\r\n\r\n"),
   4678     MockRead(SYNCHRONOUS, OK),
   4679   };
   4680 
   4681   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4682                                  data_writes1, arraysize(data_writes1));
   4683   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4684                                  data_writes2, arraysize(data_writes2));
   4685   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4686   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4687 
   4688   TestCompletionCallback callback1;
   4689   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4690   EXPECT_EQ(ERR_IO_PENDING, rv);
   4691   rv = callback1.WaitForResult();
   4692   EXPECT_EQ(OK, rv);
   4693   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4694 
   4695   TestCompletionCallback callback2;
   4696   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   4697   EXPECT_EQ(ERR_IO_PENDING, rv);
   4698   rv = callback2.WaitForResult();
   4699   EXPECT_EQ(OK, rv);
   4700   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4701 
   4702   const HttpResponseInfo* response = trans->GetResponseInfo();
   4703   ASSERT_TRUE(response != NULL);
   4704 
   4705   // There is no challenge info, since the identity in URL worked.
   4706   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4707 
   4708   EXPECT_EQ(100, response->headers->GetContentLength());
   4709 
   4710   // Empty the current queue.
   4711   base::MessageLoop::current()->RunUntilIdle();
   4712 }
   4713 
   4714 // Test the request-challenge-retry sequence for basic auth when there is an
   4715 // incorrect identity in the URL. The identity from the URL should be used only
   4716 // once.
   4717 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   4718   HttpRequestInfo request;
   4719   request.method = "GET";
   4720   // Note: the URL has a username:password in it.  The password "baz" is
   4721   // wrong (should be "bar").
   4722   request.url = GURL("http://foo:baz@www.google.com/");
   4723 
   4724   request.load_flags = LOAD_NORMAL;
   4725 
   4726   scoped_ptr<HttpTransaction> trans(
   4727       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   4728                                  CreateSession(&session_deps_)));
   4729 
   4730   MockWrite data_writes1[] = {
   4731     MockWrite("GET / HTTP/1.1\r\n"
   4732               "Host: www.google.com\r\n"
   4733               "Connection: keep-alive\r\n\r\n"),
   4734   };
   4735 
   4736   MockRead data_reads1[] = {
   4737     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4738     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4739     MockRead("Content-Length: 10\r\n\r\n"),
   4740     MockRead(SYNCHRONOUS, ERR_FAILED),
   4741   };
   4742 
   4743   // After the challenge above, the transaction will be restarted using the
   4744   // identity from the url (foo, baz) to answer the challenge.
   4745   MockWrite data_writes2[] = {
   4746     MockWrite("GET / HTTP/1.1\r\n"
   4747               "Host: www.google.com\r\n"
   4748               "Connection: keep-alive\r\n"
   4749               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   4750   };
   4751 
   4752   MockRead data_reads2[] = {
   4753     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4754     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4755     MockRead("Content-Length: 10\r\n\r\n"),
   4756     MockRead(SYNCHRONOUS, ERR_FAILED),
   4757   };
   4758 
   4759   // After the challenge above, the transaction will be restarted using the
   4760   // identity supplied by the user (foo, bar) to answer the challenge.
   4761   MockWrite data_writes3[] = {
   4762     MockWrite("GET / HTTP/1.1\r\n"
   4763               "Host: www.google.com\r\n"
   4764               "Connection: keep-alive\r\n"
   4765               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4766   };
   4767 
   4768   MockRead data_reads3[] = {
   4769     MockRead("HTTP/1.0 200 OK\r\n"),
   4770     MockRead("Content-Length: 100\r\n\r\n"),
   4771     MockRead(SYNCHRONOUS, OK),
   4772   };
   4773 
   4774   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4775                                  data_writes1, arraysize(data_writes1));
   4776   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4777                                  data_writes2, arraysize(data_writes2));
   4778   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4779                                  data_writes3, arraysize(data_writes3));
   4780   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4781   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4782   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4783 
   4784   TestCompletionCallback callback1;
   4785 
   4786   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4787   EXPECT_EQ(ERR_IO_PENDING, rv);
   4788 
   4789   rv = callback1.WaitForResult();
   4790   EXPECT_EQ(OK, rv);
   4791 
   4792   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4793   TestCompletionCallback callback2;
   4794   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   4795   EXPECT_EQ(ERR_IO_PENDING, rv);
   4796   rv = callback2.WaitForResult();
   4797   EXPECT_EQ(OK, rv);
   4798   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4799 
   4800   const HttpResponseInfo* response = trans->GetResponseInfo();
   4801   ASSERT_TRUE(response != NULL);
   4802   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4803 
   4804   TestCompletionCallback callback3;
   4805   rv = trans->RestartWithAuth(
   4806       AuthCredentials(kFoo, kBar), callback3.callback());
   4807   EXPECT_EQ(ERR_IO_PENDING, rv);
   4808   rv = callback3.WaitForResult();
   4809   EXPECT_EQ(OK, rv);
   4810   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4811 
   4812   response = trans->GetResponseInfo();
   4813   ASSERT_TRUE(response != NULL);
   4814 
   4815   // There is no challenge info, since the identity worked.
   4816   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4817 
   4818   EXPECT_EQ(100, response->headers->GetContentLength());
   4819 
   4820   // Empty the current queue.
   4821   base::MessageLoop::current()->RunUntilIdle();
   4822 }
   4823 
   4824 // Test that previously tried username/passwords for a realm get re-used.
   4825 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   4826   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4827 
   4828   // Transaction 1: authenticate (foo, bar) on MyRealm1
   4829   {
   4830     HttpRequestInfo request;
   4831     request.method = "GET";
   4832     request.url = GURL("http://www.google.com/x/y/z");
   4833     request.load_flags = 0;
   4834 
   4835     scoped_ptr<HttpTransaction> trans(
   4836         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4837 
   4838     MockWrite data_writes1[] = {
   4839       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4840                 "Host: www.google.com\r\n"
   4841                 "Connection: keep-alive\r\n\r\n"),
   4842     };
   4843 
   4844     MockRead data_reads1[] = {
   4845       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4846       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4847       MockRead("Content-Length: 10000\r\n\r\n"),
   4848       MockRead(SYNCHRONOUS, ERR_FAILED),
   4849     };
   4850 
   4851     // Resend with authorization (username=foo, password=bar)
   4852     MockWrite data_writes2[] = {
   4853       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4854                 "Host: www.google.com\r\n"
   4855                 "Connection: keep-alive\r\n"
   4856                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4857     };
   4858 
   4859     // Sever accepts the authorization.
   4860     MockRead data_reads2[] = {
   4861       MockRead("HTTP/1.0 200 OK\r\n"),
   4862       MockRead("Content-Length: 100\r\n\r\n"),
   4863       MockRead(SYNCHRONOUS, OK),
   4864     };
   4865 
   4866     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4867                                    data_writes1, arraysize(data_writes1));
   4868     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4869                                    data_writes2, arraysize(data_writes2));
   4870     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4871     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4872 
   4873     TestCompletionCallback callback1;
   4874 
   4875     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4876     EXPECT_EQ(ERR_IO_PENDING, rv);
   4877 
   4878     rv = callback1.WaitForResult();
   4879     EXPECT_EQ(OK, rv);
   4880 
   4881     const HttpResponseInfo* response = trans->GetResponseInfo();
   4882     ASSERT_TRUE(response != NULL);
   4883     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4884 
   4885     TestCompletionCallback callback2;
   4886 
   4887     rv = trans->RestartWithAuth(
   4888         AuthCredentials(kFoo, kBar), callback2.callback());
   4889     EXPECT_EQ(ERR_IO_PENDING, rv);
   4890 
   4891     rv = callback2.WaitForResult();
   4892     EXPECT_EQ(OK, rv);
   4893 
   4894     response = trans->GetResponseInfo();
   4895     ASSERT_TRUE(response != NULL);
   4896     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4897     EXPECT_EQ(100, response->headers->GetContentLength());
   4898   }
   4899 
   4900   // ------------------------------------------------------------------------
   4901 
   4902   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   4903   {
   4904     HttpRequestInfo request;
   4905     request.method = "GET";
   4906     // Note that Transaction 1 was at /x/y/z, so this is in the same
   4907     // protection space as MyRealm1.
   4908     request.url = GURL("http://www.google.com/x/y/a/b");
   4909     request.load_flags = 0;
   4910 
   4911     scoped_ptr<HttpTransaction> trans(
   4912         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4913 
   4914     MockWrite data_writes1[] = {
   4915       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   4916                 "Host: www.google.com\r\n"
   4917                 "Connection: keep-alive\r\n"
   4918                 // Send preemptive authorization for MyRealm1
   4919                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4920     };
   4921 
   4922     // The server didn't like the preemptive authorization, and
   4923     // challenges us for a different realm (MyRealm2).
   4924     MockRead data_reads1[] = {
   4925       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4926       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   4927       MockRead("Content-Length: 10000\r\n\r\n"),
   4928       MockRead(SYNCHRONOUS, ERR_FAILED),
   4929     };
   4930 
   4931     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   4932     MockWrite data_writes2[] = {
   4933       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   4934                 "Host: www.google.com\r\n"
   4935                 "Connection: keep-alive\r\n"
   4936                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   4937     };
   4938 
   4939     // Sever accepts the authorization.
   4940     MockRead data_reads2[] = {
   4941       MockRead("HTTP/1.0 200 OK\r\n"),
   4942       MockRead("Content-Length: 100\r\n\r\n"),
   4943       MockRead(SYNCHRONOUS, OK),
   4944     };
   4945 
   4946     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4947                                    data_writes1, arraysize(data_writes1));
   4948     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4949                                    data_writes2, arraysize(data_writes2));
   4950     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4951     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4952 
   4953     TestCompletionCallback callback1;
   4954 
   4955     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4956     EXPECT_EQ(ERR_IO_PENDING, rv);
   4957 
   4958     rv = callback1.WaitForResult();
   4959     EXPECT_EQ(OK, rv);
   4960 
   4961     const HttpResponseInfo* response = trans->GetResponseInfo();
   4962     ASSERT_TRUE(response != NULL);
   4963     ASSERT_TRUE(response->auth_challenge.get());
   4964     EXPECT_FALSE(response->auth_challenge->is_proxy);
   4965     EXPECT_EQ("www.google.com:80",
   4966               response->auth_challenge->challenger.ToString());
   4967     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
   4968     EXPECT_EQ("basic", response->auth_challenge->scheme);
   4969 
   4970     TestCompletionCallback callback2;
   4971 
   4972     rv = trans->RestartWithAuth(
   4973         AuthCredentials(kFoo2, kBar2), callback2.callback());
   4974     EXPECT_EQ(ERR_IO_PENDING, rv);
   4975 
   4976     rv = callback2.WaitForResult();
   4977     EXPECT_EQ(OK, rv);
   4978 
   4979     response = trans->GetResponseInfo();
   4980     ASSERT_TRUE(response != NULL);
   4981     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4982     EXPECT_EQ(100, response->headers->GetContentLength());
   4983   }
   4984 
   4985   // ------------------------------------------------------------------------
   4986 
   4987   // Transaction 3: Resend a request in MyRealm's protection space --
   4988   // succeed with preemptive authorization.
   4989   {
   4990     HttpRequestInfo request;
   4991     request.method = "GET";
   4992     request.url = GURL("http://www.google.com/x/y/z2");
   4993     request.load_flags = 0;
   4994 
   4995     scoped_ptr<HttpTransaction> trans(
   4996         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4997 
   4998     MockWrite data_writes1[] = {
   4999       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   5000                 "Host: www.google.com\r\n"
   5001                 "Connection: keep-alive\r\n"
   5002                 // The authorization for MyRealm1 gets sent preemptively
   5003                 // (since the url is in the same protection space)
   5004                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5005     };
   5006 
   5007     // Sever accepts the preemptive authorization
   5008     MockRead data_reads1[] = {
   5009       MockRead("HTTP/1.0 200 OK\r\n"),
   5010       MockRead("Content-Length: 100\r\n\r\n"),
   5011       MockRead(SYNCHRONOUS, OK),
   5012     };
   5013 
   5014     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5015                                    data_writes1, arraysize(data_writes1));
   5016     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5017 
   5018     TestCompletionCallback callback1;
   5019 
   5020     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5021     EXPECT_EQ(ERR_IO_PENDING, rv);
   5022 
   5023     rv = callback1.WaitForResult();
   5024     EXPECT_EQ(OK, rv);
   5025 
   5026     const HttpResponseInfo* response = trans->GetResponseInfo();
   5027     ASSERT_TRUE(response != NULL);
   5028 
   5029     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5030     EXPECT_EQ(100, response->headers->GetContentLength());
   5031   }
   5032 
   5033   // ------------------------------------------------------------------------
   5034 
   5035   // Transaction 4: request another URL in MyRealm (however the
   5036   // url is not known to belong to the protection space, so no pre-auth).
   5037   {
   5038     HttpRequestInfo request;
   5039     request.method = "GET";
   5040     request.url = GURL("http://www.google.com/x/1");
   5041     request.load_flags = 0;
   5042 
   5043     scoped_ptr<HttpTransaction> trans(
   5044         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5045 
   5046     MockWrite data_writes1[] = {
   5047       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5048                 "Host: www.google.com\r\n"
   5049                 "Connection: keep-alive\r\n\r\n"),
   5050     };
   5051 
   5052     MockRead data_reads1[] = {
   5053       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5054       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5055       MockRead("Content-Length: 10000\r\n\r\n"),
   5056       MockRead(SYNCHRONOUS, ERR_FAILED),
   5057     };
   5058 
   5059     // Resend with authorization from MyRealm's cache.
   5060     MockWrite data_writes2[] = {
   5061       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5062                 "Host: www.google.com\r\n"
   5063                 "Connection: keep-alive\r\n"
   5064                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5065     };
   5066 
   5067     // Sever accepts the authorization.
   5068     MockRead data_reads2[] = {
   5069       MockRead("HTTP/1.0 200 OK\r\n"),
   5070       MockRead("Content-Length: 100\r\n\r\n"),
   5071       MockRead(SYNCHRONOUS, OK),
   5072     };
   5073 
   5074     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5075                                    data_writes1, arraysize(data_writes1));
   5076     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5077                                    data_writes2, arraysize(data_writes2));
   5078     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5079     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5080 
   5081     TestCompletionCallback callback1;
   5082 
   5083     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5084     EXPECT_EQ(ERR_IO_PENDING, rv);
   5085 
   5086     rv = callback1.WaitForResult();
   5087     EXPECT_EQ(OK, rv);
   5088 
   5089     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5090     TestCompletionCallback callback2;
   5091     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5092     EXPECT_EQ(ERR_IO_PENDING, rv);
   5093     rv = callback2.WaitForResult();
   5094     EXPECT_EQ(OK, rv);
   5095     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5096 
   5097     const HttpResponseInfo* response = trans->GetResponseInfo();
   5098     ASSERT_TRUE(response != NULL);
   5099     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5100     EXPECT_EQ(100, response->headers->GetContentLength());
   5101   }
   5102 
   5103   // ------------------------------------------------------------------------
   5104 
   5105   // Transaction 5: request a URL in MyRealm, but the server rejects the
   5106   // cached identity. Should invalidate and re-prompt.
   5107   {
   5108     HttpRequestInfo request;
   5109     request.method = "GET";
   5110     request.url = GURL("http://www.google.com/p/q/t");
   5111     request.load_flags = 0;
   5112 
   5113     scoped_ptr<HttpTransaction> trans(
   5114         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5115 
   5116     MockWrite data_writes1[] = {
   5117       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5118                 "Host: www.google.com\r\n"
   5119                 "Connection: keep-alive\r\n\r\n"),
   5120     };
   5121 
   5122     MockRead data_reads1[] = {
   5123       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5124       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5125       MockRead("Content-Length: 10000\r\n\r\n"),
   5126       MockRead(SYNCHRONOUS, ERR_FAILED),
   5127     };
   5128 
   5129     // Resend with authorization from cache for MyRealm.
   5130     MockWrite data_writes2[] = {
   5131       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5132                 "Host: www.google.com\r\n"
   5133                 "Connection: keep-alive\r\n"
   5134                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5135     };
   5136 
   5137     // Sever rejects the authorization.
   5138     MockRead data_reads2[] = {
   5139       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5140       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5141       MockRead("Content-Length: 10000\r\n\r\n"),
   5142       MockRead(SYNCHRONOUS, ERR_FAILED),
   5143     };
   5144 
   5145     // At this point we should prompt for new credentials for MyRealm.
   5146     // Restart with username=foo3, password=foo4.
   5147     MockWrite data_writes3[] = {
   5148       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5149                 "Host: www.google.com\r\n"
   5150                 "Connection: keep-alive\r\n"
   5151                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   5152     };
   5153 
   5154     // Sever accepts the authorization.
   5155     MockRead data_reads3[] = {
   5156       MockRead("HTTP/1.0 200 OK\r\n"),
   5157       MockRead("Content-Length: 100\r\n\r\n"),
   5158       MockRead(SYNCHRONOUS, OK),
   5159     };
   5160 
   5161     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5162                                    data_writes1, arraysize(data_writes1));
   5163     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5164                                    data_writes2, arraysize(data_writes2));
   5165     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5166                                    data_writes3, arraysize(data_writes3));
   5167     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5168     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5169     session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5170 
   5171     TestCompletionCallback callback1;
   5172 
   5173     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5174     EXPECT_EQ(ERR_IO_PENDING, rv);
   5175 
   5176     rv = callback1.WaitForResult();
   5177     EXPECT_EQ(OK, rv);
   5178 
   5179     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5180     TestCompletionCallback callback2;
   5181     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5182     EXPECT_EQ(ERR_IO_PENDING, rv);
   5183     rv = callback2.WaitForResult();
   5184     EXPECT_EQ(OK, rv);
   5185     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5186 
   5187     const HttpResponseInfo* response = trans->GetResponseInfo();
   5188     ASSERT_TRUE(response != NULL);
   5189     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5190 
   5191     TestCompletionCallback callback3;
   5192 
   5193     rv = trans->RestartWithAuth(
   5194         AuthCredentials(kFoo3, kBar3), callback3.callback());
   5195     EXPECT_EQ(ERR_IO_PENDING, rv);
   5196 
   5197     rv = callback3.WaitForResult();
   5198     EXPECT_EQ(OK, rv);
   5199 
   5200     response = trans->GetResponseInfo();
   5201     ASSERT_TRUE(response != NULL);
   5202     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5203     EXPECT_EQ(100, response->headers->GetContentLength());
   5204   }
   5205 }
   5206 
   5207 // Tests that nonce count increments when multiple auth attempts
   5208 // are started with the same nonce.
   5209 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
   5210   HttpAuthHandlerDigest::Factory* digest_factory =
   5211       new HttpAuthHandlerDigest::Factory();
   5212   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
   5213       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
   5214   digest_factory->set_nonce_generator(nonce_generator);
   5215   session_deps_.http_auth_handler_factory.reset(digest_factory);
   5216   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5217 
   5218   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5219   {
   5220     HttpRequestInfo request;
   5221     request.method = "GET";
   5222     request.url = GURL("http://www.google.com/x/y/z");
   5223     request.load_flags = 0;
   5224 
   5225     scoped_ptr<HttpTransaction> trans(
   5226         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5227 
   5228     MockWrite data_writes1[] = {
   5229       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5230                 "Host: www.google.com\r\n"
   5231                 "Connection: keep-alive\r\n\r\n"),
   5232     };
   5233 
   5234     MockRead data_reads1[] = {
   5235       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5236       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
   5237                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
   5238       MockRead(SYNCHRONOUS, OK),
   5239     };
   5240 
   5241     // Resend with authorization (username=foo, password=bar)
   5242     MockWrite data_writes2[] = {
   5243       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5244                 "Host: www.google.com\r\n"
   5245                 "Connection: keep-alive\r\n"
   5246                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5247                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
   5248                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
   5249                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5250     };
   5251 
   5252     // Sever accepts the authorization.
   5253     MockRead data_reads2[] = {
   5254       MockRead("HTTP/1.0 200 OK\r\n"),
   5255       MockRead(SYNCHRONOUS, OK),
   5256     };
   5257 
   5258     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5259                                    data_writes1, arraysize(data_writes1));
   5260     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5261                                    data_writes2, arraysize(data_writes2));
   5262     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5263     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5264 
   5265     TestCompletionCallback callback1;
   5266 
   5267     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5268     EXPECT_EQ(ERR_IO_PENDING, rv);
   5269 
   5270     rv = callback1.WaitForResult();
   5271     EXPECT_EQ(OK, rv);
   5272 
   5273     const HttpResponseInfo* response = trans->GetResponseInfo();
   5274     ASSERT_TRUE(response != NULL);
   5275     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
   5276 
   5277     TestCompletionCallback callback2;
   5278 
   5279     rv = trans->RestartWithAuth(
   5280         AuthCredentials(kFoo, kBar), callback2.callback());
   5281     EXPECT_EQ(ERR_IO_PENDING, rv);
   5282 
   5283     rv = callback2.WaitForResult();
   5284     EXPECT_EQ(OK, rv);
   5285 
   5286     response = trans->GetResponseInfo();
   5287     ASSERT_TRUE(response != NULL);
   5288     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5289   }
   5290 
   5291   // ------------------------------------------------------------------------
   5292 
   5293   // Transaction 2: Request another resource in digestive's protection space.
   5294   // This will preemptively add an Authorization header which should have an
   5295   // "nc" value of 2 (as compared to 1 in the first use.
   5296   {
   5297     HttpRequestInfo request;
   5298     request.method = "GET";
   5299     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5300     // protection space as digest.
   5301     request.url = GURL("http://www.google.com/x/y/a/b");
   5302     request.load_flags = 0;
   5303 
   5304     scoped_ptr<HttpTransaction> trans(
   5305         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5306 
   5307     MockWrite data_writes1[] = {
   5308       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5309                 "Host: www.google.com\r\n"
   5310                 "Connection: keep-alive\r\n"
   5311                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5312                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
   5313                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
   5314                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5315     };
   5316 
   5317     // Sever accepts the authorization.
   5318     MockRead data_reads1[] = {
   5319       MockRead("HTTP/1.0 200 OK\r\n"),
   5320       MockRead("Content-Length: 100\r\n\r\n"),
   5321       MockRead(SYNCHRONOUS, OK),
   5322     };
   5323 
   5324     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5325                                    data_writes1, arraysize(data_writes1));
   5326     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5327 
   5328     TestCompletionCallback callback1;
   5329 
   5330     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5331     EXPECT_EQ(ERR_IO_PENDING, rv);
   5332 
   5333     rv = callback1.WaitForResult();
   5334     EXPECT_EQ(OK, rv);
   5335 
   5336     const HttpResponseInfo* response = trans->GetResponseInfo();
   5337     ASSERT_TRUE(response != NULL);
   5338     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5339   }
   5340 }
   5341 
   5342 // Test the ResetStateForRestart() private method.
   5343 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
   5344   // Create a transaction (the dependencies aren't important).
   5345   scoped_ptr<HttpNetworkTransaction> trans(
   5346       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5347                                  CreateSession(&session_deps_)));
   5348 
   5349   // Setup some state (which we expect ResetStateForRestart() will clear).
   5350   trans->read_buf_ = new IOBuffer(15);
   5351   trans->read_buf_len_ = 15;
   5352   trans->request_headers_.SetHeader("Authorization", "NTLM");
   5353 
   5354   // Setup state in response_
   5355   HttpResponseInfo* response = &trans->response_;
   5356   response->auth_challenge = new AuthChallengeInfo();
   5357   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
   5358   response->response_time = base::Time::Now();
   5359   response->was_cached = true;  // (Wouldn't ever actually be true...)
   5360 
   5361   { // Setup state for response_.vary_data
   5362     HttpRequestInfo request;
   5363     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   5364     std::replace(temp.begin(), temp.end(), '\n', '\0');
   5365     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
   5366     request.extra_headers.SetHeader("Foo", "1");
   5367     request.extra_headers.SetHeader("bar", "23");
   5368     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
   5369   }
   5370 
   5371   // Cause the above state to be reset.
   5372   trans->ResetStateForRestart();
   5373 
   5374   // Verify that the state that needed to be reset, has been reset.
   5375   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   5376   EXPECT_EQ(0, trans->read_buf_len_);
   5377   EXPECT_TRUE(trans->request_headers_.IsEmpty());
   5378   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5379   EXPECT_TRUE(response->headers.get() == NULL);
   5380   EXPECT_FALSE(response->was_cached);
   5381   EXPECT_EQ(0U, response->ssl_info.cert_status);
   5382   EXPECT_FALSE(response->vary_data.is_valid());
   5383 }
   5384 
   5385 // Test HTTPS connections to a site with a bad certificate
   5386 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   5387   HttpRequestInfo request;
   5388   request.method = "GET";
   5389   request.url = GURL("https://www.google.com/");
   5390   request.load_flags = 0;
   5391 
   5392   scoped_ptr<HttpTransaction> trans(
   5393       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5394                                  CreateSession(&session_deps_)));
   5395 
   5396   MockWrite data_writes[] = {
   5397     MockWrite("GET / HTTP/1.1\r\n"
   5398               "Host: www.google.com\r\n"
   5399               "Connection: keep-alive\r\n\r\n"),
   5400   };
   5401 
   5402   MockRead data_reads[] = {
   5403     MockRead("HTTP/1.0 200 OK\r\n"),
   5404     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5405     MockRead("Content-Length: 100\r\n\r\n"),
   5406     MockRead(SYNCHRONOUS, OK),
   5407   };
   5408 
   5409   StaticSocketDataProvider ssl_bad_certificate;
   5410   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5411                                 data_writes, arraysize(data_writes));
   5412   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5413   SSLSocketDataProvider ssl(ASYNC, OK);
   5414 
   5415   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5416   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5417   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5418   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5419 
   5420   TestCompletionCallback callback;
   5421 
   5422   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5423   EXPECT_EQ(ERR_IO_PENDING, rv);
   5424 
   5425   rv = callback.WaitForResult();
   5426   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5427 
   5428   rv = trans->RestartIgnoringLastError(callback.callback());
   5429   EXPECT_EQ(ERR_IO_PENDING, rv);
   5430 
   5431   rv = callback.WaitForResult();
   5432   EXPECT_EQ(OK, rv);
   5433 
   5434   const HttpResponseInfo* response = trans->GetResponseInfo();
   5435 
   5436   ASSERT_TRUE(response != NULL);
   5437   EXPECT_EQ(100, response->headers->GetContentLength());
   5438 }
   5439 
   5440 // Test HTTPS connections to a site with a bad certificate, going through a
   5441 // proxy
   5442 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   5443   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   5444 
   5445   HttpRequestInfo request;
   5446   request.method = "GET";
   5447   request.url = GURL("https://www.google.com/");
   5448   request.load_flags = 0;
   5449 
   5450   MockWrite proxy_writes[] = {
   5451     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5452               "Host: www.google.com\r\n"
   5453               "Proxy-Connection: keep-alive\r\n\r\n"),
   5454   };
   5455 
   5456   MockRead proxy_reads[] = {
   5457     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5458     MockRead(SYNCHRONOUS, OK)
   5459   };
   5460 
   5461   MockWrite data_writes[] = {
   5462     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5463               "Host: www.google.com\r\n"
   5464               "Proxy-Connection: keep-alive\r\n\r\n"),
   5465     MockWrite("GET / HTTP/1.1\r\n"
   5466               "Host: www.google.com\r\n"
   5467               "Connection: keep-alive\r\n\r\n"),
   5468   };
   5469 
   5470   MockRead data_reads[] = {
   5471     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5472     MockRead("HTTP/1.0 200 OK\r\n"),
   5473     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5474     MockRead("Content-Length: 100\r\n\r\n"),
   5475     MockRead(SYNCHRONOUS, OK),
   5476   };
   5477 
   5478   StaticSocketDataProvider ssl_bad_certificate(
   5479       proxy_reads, arraysize(proxy_reads),
   5480       proxy_writes, arraysize(proxy_writes));
   5481   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5482                                 data_writes, arraysize(data_writes));
   5483   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5484   SSLSocketDataProvider ssl(ASYNC, OK);
   5485 
   5486   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5487   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5488   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5489   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5490 
   5491   TestCompletionCallback callback;
   5492 
   5493   for (int i = 0; i < 2; i++) {
   5494     session_deps_.socket_factory->ResetNextMockIndexes();
   5495 
   5496     scoped_ptr<HttpTransaction> trans(
   5497         new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5498                                    CreateSession(&session_deps_)));
   5499 
   5500     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5501     EXPECT_EQ(ERR_IO_PENDING, rv);
   5502 
   5503     rv = callback.WaitForResult();
   5504     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5505 
   5506     rv = trans->RestartIgnoringLastError(callback.callback());
   5507     EXPECT_EQ(ERR_IO_PENDING, rv);
   5508 
   5509     rv = callback.WaitForResult();
   5510     EXPECT_EQ(OK, rv);
   5511 
   5512     const HttpResponseInfo* response = trans->GetResponseInfo();
   5513 
   5514     ASSERT_TRUE(response != NULL);
   5515     EXPECT_EQ(100, response->headers->GetContentLength());
   5516   }
   5517 }
   5518 
   5519 
   5520 // Test HTTPS connections to a site, going through an HTTPS proxy
   5521 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
   5522   session_deps_.proxy_service.reset(
   5523       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   5524   CapturingNetLog net_log;
   5525   session_deps_.net_log = &net_log;
   5526 
   5527   HttpRequestInfo request;
   5528   request.method = "GET";
   5529   request.url = GURL("https://www.google.com/");
   5530   request.load_flags = 0;
   5531 
   5532   MockWrite data_writes[] = {
   5533     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5534               "Host: www.google.com\r\n"
   5535               "Proxy-Connection: keep-alive\r\n\r\n"),
   5536     MockWrite("GET / HTTP/1.1\r\n"
   5537               "Host: www.google.com\r\n"
   5538               "Connection: keep-alive\r\n\r\n"),
   5539   };
   5540 
   5541   MockRead data_reads[] = {
   5542     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5543     MockRead("HTTP/1.1 200 OK\r\n"),
   5544     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5545     MockRead("Content-Length: 100\r\n\r\n"),
   5546     MockRead(SYNCHRONOUS, OK),
   5547   };
   5548 
   5549   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5550                                 data_writes, arraysize(data_writes));
   5551   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5552   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
   5553 
   5554   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5555   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5556   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
   5557 
   5558   TestCompletionCallback callback;
   5559 
   5560   scoped_ptr<HttpTransaction> trans(
   5561       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5562                                  CreateSession(&session_deps_)));
   5563 
   5564   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5565   EXPECT_EQ(ERR_IO_PENDING, rv);
   5566 
   5567   rv = callback.WaitForResult();
   5568   EXPECT_EQ(OK, rv);
   5569   const HttpResponseInfo* response = trans->GetResponseInfo();
   5570 
   5571   ASSERT_TRUE(response != NULL);
   5572 
   5573   EXPECT_TRUE(response->headers->IsKeepAlive());
   5574   EXPECT_EQ(200, response->headers->response_code());
   5575   EXPECT_EQ(100, response->headers->GetContentLength());
   5576   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   5577 
   5578   LoadTimingInfo load_timing_info;
   5579   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   5580   TestLoadTimingNotReusedWithPac(load_timing_info,
   5581                                  CONNECT_TIMING_HAS_SSL_TIMES);
   5582 }
   5583 
   5584 // Test an HTTPS Proxy's ability to redirect a CONNECT request
   5585 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
   5586   session_deps_.proxy_service.reset(
   5587       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   5588   CapturingNetLog net_log;
   5589   session_deps_.net_log = &net_log;
   5590 
   5591   HttpRequestInfo request;
   5592   request.method = "GET";
   5593   request.url = GURL("https://www.google.com/");
   5594   request.load_flags = 0;
   5595 
   5596   MockWrite data_writes[] = {
   5597     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5598               "Host: www.google.com\r\n"
   5599               "Proxy-Connection: keep-alive\r\n\r\n"),
   5600   };
   5601 
   5602   MockRead data_reads[] = {
   5603     MockRead("HTTP/1.1 302 Redirect\r\n"),
   5604     MockRead("Location: http://login.example.com/\r\n"),
   5605     MockRead("Content-Length: 0\r\n\r\n"),
   5606     MockRead(SYNCHRONOUS, OK),
   5607   };
   5608 
   5609   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5610                                 data_writes, arraysize(data_writes));
   5611   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5612 
   5613   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5614   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5615 
   5616   TestCompletionCallback callback;
   5617 
   5618   scoped_ptr<HttpTransaction> trans(
   5619       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5620                                  CreateSession(&session_deps_)));
   5621 
   5622   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5623   EXPECT_EQ(ERR_IO_PENDING, rv);
   5624 
   5625   rv = callback.WaitForResult();
   5626   EXPECT_EQ(OK, rv);
   5627   const HttpResponseInfo* response = trans->GetResponseInfo();
   5628 
   5629   ASSERT_TRUE(response != NULL);
   5630 
   5631   EXPECT_EQ(302, response->headers->response_code());
   5632   std::string url;
   5633   EXPECT_TRUE(response->headers->IsRedirect(&url));
   5634   EXPECT_EQ("http://login.example.com/", url);
   5635 
   5636   // In the case of redirects from proxies, HttpNetworkTransaction returns
   5637   // timing for the proxy connection instead of the connection to the host,
   5638   // and no send / receive times.
   5639   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
   5640   LoadTimingInfo load_timing_info;
   5641   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   5642 
   5643   EXPECT_FALSE(load_timing_info.socket_reused);
   5644   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
   5645 
   5646   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
   5647   EXPECT_LE(load_timing_info.proxy_resolve_start,
   5648             load_timing_info.proxy_resolve_end);
   5649   EXPECT_LE(load_timing_info.proxy_resolve_end,
   5650             load_timing_info.connect_timing.connect_start);
   5651   ExpectConnectTimingHasTimes(
   5652       load_timing_info.connect_timing,
   5653       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
   5654 
   5655   EXPECT_TRUE(load_timing_info.send_start.is_null());
   5656   EXPECT_TRUE(load_timing_info.send_end.is_null());
   5657   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
   5658 }
   5659 
   5660 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
   5661 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
   5662   session_deps_.proxy_service.reset(
   5663       ProxyService::CreateFixed("https://proxy:70"));
   5664 
   5665   HttpRequestInfo request;
   5666   request.method = "GET";
   5667   request.url = GURL("https://www.google.com/");
   5668   request.load_flags = 0;
   5669 
   5670   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   5671   scoped_ptr<SpdyFrame> goaway(
   5672       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5673   MockWrite data_writes[] = {
   5674     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   5675     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
   5676   };
   5677 
   5678   static const char* const kExtraHeaders[] = {
   5679     "location",
   5680     "http://login.example.com/",
   5681   };
   5682   scoped_ptr<SpdyFrame> resp(
   5683       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
   5684                                  arraysize(kExtraHeaders)/2, 1));
   5685   MockRead data_reads[] = {
   5686     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   5687     MockRead(ASYNC, 0, 2),  // EOF
   5688   };
   5689 
   5690   DelayedSocketData data(
   5691       1,  // wait for one write to finish before reading.
   5692       data_reads, arraysize(data_reads),
   5693       data_writes, arraysize(data_writes));
   5694   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5695   proxy_ssl.SetNextProto(GetParam());
   5696 
   5697   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5698   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5699 
   5700   TestCompletionCallback callback;
   5701 
   5702   scoped_ptr<HttpTransaction> trans(
   5703       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5704                                  CreateSession(&session_deps_)));
   5705 
   5706   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5707   EXPECT_EQ(ERR_IO_PENDING, rv);
   5708 
   5709   rv = callback.WaitForResult();
   5710   EXPECT_EQ(OK, rv);
   5711   const HttpResponseInfo* response = trans->GetResponseInfo();
   5712 
   5713   ASSERT_TRUE(response != NULL);
   5714 
   5715   EXPECT_EQ(302, response->headers->response_code());
   5716   std::string url;
   5717   EXPECT_TRUE(response->headers->IsRedirect(&url));
   5718   EXPECT_EQ("http://login.example.com/", url);
   5719 }
   5720 
   5721 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
   5722 TEST_P(HttpNetworkTransactionTest,
   5723        ErrorResponseToHttpsConnectViaHttpsProxy) {
   5724   session_deps_.proxy_service.reset(
   5725       ProxyService::CreateFixed("https://proxy:70"));
   5726 
   5727   HttpRequestInfo request;
   5728   request.method = "GET";
   5729   request.url = GURL("https://www.google.com/");
   5730   request.load_flags = 0;
   5731 
   5732   MockWrite data_writes[] = {
   5733     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5734               "Host: www.google.com\r\n"
   5735               "Proxy-Connection: keep-alive\r\n\r\n"),
   5736   };
   5737 
   5738   MockRead data_reads[] = {
   5739     MockRead("HTTP/1.1 404 Not Found\r\n"),
   5740     MockRead("Content-Length: 23\r\n\r\n"),
   5741     MockRead("The host does not exist"),
   5742     MockRead(SYNCHRONOUS, OK),
   5743   };
   5744 
   5745   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5746                                 data_writes, arraysize(data_writes));
   5747   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5748 
   5749   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5750   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5751 
   5752   TestCompletionCallback callback;
   5753 
   5754   scoped_ptr<HttpTransaction> trans(
   5755       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5756                                  CreateSession(&session_deps_)));
   5757 
   5758   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5759   EXPECT_EQ(ERR_IO_PENDING, rv);
   5760 
   5761   rv = callback.WaitForResult();
   5762   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   5763 
   5764   // TODO(ttuttle): Anything else to check here?
   5765 }
   5766 
   5767 // Test that a SPDY proxy's response to a CONNECT request is filtered.
   5768 TEST_P(HttpNetworkTransactionTest,
   5769        ErrorResponseToHttpsConnectViaSpdyProxy) {
   5770   session_deps_.proxy_service.reset(
   5771      ProxyService::CreateFixed("https://proxy:70"));
   5772 
   5773   HttpRequestInfo request;
   5774   request.method = "GET";
   5775   request.url = GURL("https://www.google.com/");
   5776   request.load_flags = 0;
   5777 
   5778   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   5779   scoped_ptr<SpdyFrame> rst(
   5780       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5781   MockWrite data_writes[] = {
   5782     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   5783     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
   5784   };
   5785 
   5786   static const char* const kExtraHeaders[] = {
   5787     "location",
   5788     "http://login.example.com/",
   5789   };
   5790   scoped_ptr<SpdyFrame> resp(
   5791       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
   5792                                  arraysize(kExtraHeaders)/2, 1));
   5793   scoped_ptr<SpdyFrame> body(
   5794       spdy_util_.ConstructSpdyBodyFrame(
   5795           1, "The host does not exist", 23, true));
   5796   MockRead data_reads[] = {
   5797     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   5798     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
   5799     MockRead(ASYNC, 0, 4),  // EOF
   5800   };
   5801 
   5802   DelayedSocketData data(
   5803       1,  // wait for one write to finish before reading.
   5804       data_reads, arraysize(data_reads),
   5805       data_writes, arraysize(data_writes));
   5806   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5807   proxy_ssl.SetNextProto(GetParam());
   5808 
   5809   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5810   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5811 
   5812   TestCompletionCallback callback;
   5813 
   5814   scoped_ptr<HttpTransaction> trans(
   5815       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   5816                                  CreateSession(&session_deps_)));
   5817 
   5818   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5819   EXPECT_EQ(ERR_IO_PENDING, rv);
   5820 
   5821   rv = callback.WaitForResult();
   5822   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   5823 
   5824   // TODO(ttuttle): Anything else to check here?
   5825 }
   5826 
   5827 // Test the request-challenge-retry sequence for basic auth, through
   5828 // a SPDY proxy over a single SPDY session.
   5829 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
   5830   HttpRequestInfo request;
   5831   request.method = "GET";
   5832   request.url = GURL("https://www.google.com/");
   5833   // when the no authentication data flag is set.
   5834   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   5835 
   5836   // Configure against https proxy server "myproxy:70".
   5837   session_deps_.proxy_service.reset(
   5838       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   5839   CapturingBoundNetLog log;
   5840   session_deps_.net_log = log.bound().net_log();
   5841   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5842 
   5843   // Since we have proxy, should try to establish tunnel.
   5844   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   5845   scoped_ptr<SpdyFrame> rst(
   5846       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5847 
   5848   // After calling trans->RestartWithAuth(), this is the request we should
   5849   // be issuing -- the final header line contains the credentials.
   5850   const char* const kAuthCredentials[] = {
   5851       "proxy-authorization", "Basic Zm9vOmJhcg==",
   5852   };
   5853   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
   5854       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3));
   5855   // fetch https://www.google.com/ via HTTP
   5856   const char get[] = "GET / HTTP/1.1\r\n"
   5857     "Host: www.google.com\r\n"
   5858     "Connection: keep-alive\r\n\r\n";
   5859   scoped_ptr<SpdyFrame> wrapped_get(
   5860       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
   5861 
   5862   MockWrite spdy_writes[] = {
   5863     CreateMockWrite(*req, 1, ASYNC),
   5864     CreateMockWrite(*rst, 4, ASYNC),
   5865     CreateMockWrite(*connect2, 5),
   5866     CreateMockWrite(*wrapped_get, 8),
   5867   };
   5868 
   5869   // The proxy responds to the connect with a 407, using a persistent
   5870   // connection.
   5871   const char* const kAuthChallenge[] = {
   5872     spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
   5873     spdy_util_.GetVersionKey(), "HTTP/1.1",
   5874     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
   5875   };
   5876 
   5877   scoped_ptr<SpdyFrame> conn_auth_resp(
   5878       spdy_util_.ConstructSpdyControlFrame(NULL,
   5879                                            0,
   5880                                            false,
   5881                                            1,
   5882                                            LOWEST,
   5883                                            SYN_REPLY,
   5884                                            CONTROL_FLAG_NONE,
   5885                                            kAuthChallenge,
   5886                                            arraysize(kAuthChallenge),
   5887                                            0));
   5888 
   5889   scoped_ptr<SpdyFrame> conn_resp(
   5890       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   5891   const char resp[] = "HTTP/1.1 200 OK\r\n"
   5892       "Content-Length: 5\r\n\r\n";
   5893 
   5894   scoped_ptr<SpdyFrame> wrapped_get_resp(
   5895       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
   5896   scoped_ptr<SpdyFrame> wrapped_body(
   5897       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
   5898   MockRead spdy_reads[] = {
   5899     CreateMockRead(*conn_auth_resp, 2, ASYNC),
   5900     CreateMockRead(*conn_resp, 6, ASYNC),
   5901     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
   5902     CreateMockRead(*wrapped_body, 10, ASYNC),
   5903     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
   5904   };
   5905 
   5906   OrderedSocketData spdy_data(
   5907       spdy_reads, arraysize(spdy_reads),
   5908       spdy_writes, arraysize(spdy_writes));
   5909   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   5910   // Negotiate SPDY to the proxy
   5911   SSLSocketDataProvider proxy(ASYNC, OK);
   5912   proxy.SetNextProto(GetParam());
   5913   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   5914   // Vanilla SSL to the server
   5915   SSLSocketDataProvider server(ASYNC, OK);
   5916   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
   5917 
   5918   TestCompletionCallback callback1;
   5919 
   5920   scoped_ptr<HttpTransaction> trans(
   5921       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5922 
   5923   int rv = trans->Start(&request, callback1.callback(), log.bound());
   5924   EXPECT_EQ(ERR_IO_PENDING, rv);
   5925 
   5926   rv = callback1.WaitForResult();
   5927   EXPECT_EQ(OK, rv);
   5928   net::CapturingNetLog::CapturedEntryList entries;
   5929   log.GetEntries(&entries);
   5930   size_t pos = ExpectLogContainsSomewhere(
   5931       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   5932       NetLog::PHASE_NONE);
   5933   ExpectLogContainsSomewhere(
   5934       entries, pos,
   5935       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   5936       NetLog::PHASE_NONE);
   5937 
   5938   const HttpResponseInfo* response = trans->GetResponseInfo();
   5939   ASSERT_TRUE(response != NULL);
   5940   ASSERT_FALSE(response->headers.get() == NULL);
   5941   EXPECT_EQ(407, response->headers->response_code());
   5942   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   5943   EXPECT_TRUE(response->auth_challenge.get() != NULL);
   5944   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   5945 
   5946   TestCompletionCallback callback2;
   5947 
   5948   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
   5949                               callback2.callback());
   5950   EXPECT_EQ(ERR_IO_PENDING, rv);
   5951 
   5952   rv = callback2.WaitForResult();
   5953   EXPECT_EQ(OK, rv);
   5954 
   5955   response = trans->GetResponseInfo();
   5956   ASSERT_TRUE(response != NULL);
   5957 
   5958   EXPECT_TRUE(response->headers->IsKeepAlive());
   5959   EXPECT_EQ(200, response->headers->response_code());
   5960   EXPECT_EQ(5, response->headers->GetContentLength());
   5961   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   5962 
   5963   // The password prompt info should not be set.
   5964   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5965 
   5966   LoadTimingInfo load_timing_info;
   5967   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   5968   TestLoadTimingNotReusedWithPac(load_timing_info,
   5969                                  CONNECT_TIMING_HAS_SSL_TIMES);
   5970 
   5971   trans.reset();
   5972   session->CloseAllConnections();
   5973 }
   5974 
   5975 // Test that an explicitly trusted SPDY proxy can push a resource from an
   5976 // origin that is different from that of its associated resource.
   5977 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
   5978   HttpRequestInfo request;
   5979   HttpRequestInfo push_request;
   5980 
   5981   request.method = "GET";
   5982   request.url = GURL("http://www.google.com/");
   5983   push_request.method = "GET";
   5984   push_request.url = GURL("http://www.another-origin.com/foo.dat");
   5985 
   5986   // Configure against https proxy server "myproxy:70".
   5987   session_deps_.proxy_service.reset(
   5988       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   5989   CapturingBoundNetLog log;
   5990   session_deps_.net_log = log.bound().net_log();
   5991 
   5992   // Enable cross-origin push.
   5993   session_deps_.trusted_spdy_proxy = "myproxy:70";
   5994 
   5995   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5996 
   5997   scoped_ptr<SpdyFrame> stream1_syn(
   5998       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   5999 
   6000   MockWrite spdy_writes[] = {
   6001     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6002   };
   6003 
   6004   scoped_ptr<SpdyFrame>
   6005       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6006 
   6007   scoped_ptr<SpdyFrame>
   6008       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6009 
   6010   scoped_ptr<SpdyFrame>
   6011       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6012                                     0,
   6013                                     2,
   6014                                     1,
   6015                                     "http://www.another-origin.com/foo.dat"));
   6016   const char kPushedData[] = "pushed";
   6017   scoped_ptr<SpdyFrame> stream2_body(
   6018       spdy_util_.ConstructSpdyBodyFrame(
   6019           2, kPushedData, strlen(kPushedData), true));
   6020 
   6021   MockRead spdy_reads[] = {
   6022     CreateMockRead(*stream1_reply, 2, ASYNC),
   6023     CreateMockRead(*stream2_syn, 3, ASYNC),
   6024     CreateMockRead(*stream1_body, 4, ASYNC),
   6025     CreateMockRead(*stream2_body, 5, ASYNC),
   6026     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6027   };
   6028 
   6029   OrderedSocketData spdy_data(
   6030       spdy_reads, arraysize(spdy_reads),
   6031       spdy_writes, arraysize(spdy_writes));
   6032   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6033   // Negotiate SPDY to the proxy
   6034   SSLSocketDataProvider proxy(ASYNC, OK);
   6035   proxy.SetNextProto(GetParam());
   6036   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6037 
   6038   scoped_ptr<HttpTransaction> trans(
   6039       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6040   TestCompletionCallback callback;
   6041   int rv = trans->Start(&request, callback.callback(), log.bound());
   6042   EXPECT_EQ(ERR_IO_PENDING, rv);
   6043 
   6044   rv = callback.WaitForResult();
   6045   EXPECT_EQ(OK, rv);
   6046   const HttpResponseInfo* response = trans->GetResponseInfo();
   6047 
   6048   scoped_ptr<HttpTransaction> push_trans(
   6049       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6050   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
   6051   EXPECT_EQ(ERR_IO_PENDING, rv);
   6052 
   6053   rv = callback.WaitForResult();
   6054   EXPECT_EQ(OK, rv);
   6055   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
   6056 
   6057   ASSERT_TRUE(response != NULL);
   6058   EXPECT_TRUE(response->headers->IsKeepAlive());
   6059 
   6060   EXPECT_EQ(200, response->headers->response_code());
   6061   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6062 
   6063   std::string response_data;
   6064   rv = ReadTransaction(trans.get(), &response_data);
   6065   EXPECT_EQ(OK, rv);
   6066   EXPECT_EQ("hello!", response_data);
   6067 
   6068   LoadTimingInfo load_timing_info;
   6069   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6070   TestLoadTimingNotReusedWithPac(load_timing_info,
   6071                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6072 
   6073   // Verify the pushed stream.
   6074   EXPECT_TRUE(push_response->headers.get() != NULL);
   6075   EXPECT_EQ(200, push_response->headers->response_code());
   6076 
   6077   rv = ReadTransaction(push_trans.get(), &response_data);
   6078   EXPECT_EQ(OK, rv);
   6079   EXPECT_EQ("pushed", response_data);
   6080 
   6081   LoadTimingInfo push_load_timing_info;
   6082   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
   6083   TestLoadTimingReusedWithPac(push_load_timing_info);
   6084   // The transactions should share a socket ID, despite being for different
   6085   // origins.
   6086   EXPECT_EQ(load_timing_info.socket_log_id,
   6087             push_load_timing_info.socket_log_id);
   6088 
   6089   trans.reset();
   6090   push_trans.reset();
   6091   session->CloseAllConnections();
   6092 }
   6093 
   6094 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
   6095 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
   6096   HttpRequestInfo request;
   6097 
   6098   request.method = "GET";
   6099   request.url = GURL("http://www.google.com/");
   6100 
   6101   // Configure against https proxy server "myproxy:70".
   6102   session_deps_.proxy_service.reset(
   6103       ProxyService::CreateFixed("https://myproxy:70"));
   6104   CapturingBoundNetLog log;
   6105   session_deps_.net_log = log.bound().net_log();
   6106 
   6107   // Enable cross-origin push.
   6108   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6109 
   6110   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6111 
   6112   scoped_ptr<SpdyFrame> stream1_syn(
   6113       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6114 
   6115   scoped_ptr<SpdyFrame> push_rst(
   6116       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   6117 
   6118   MockWrite spdy_writes[] = {
   6119     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6120     CreateMockWrite(*push_rst, 4),
   6121   };
   6122 
   6123   scoped_ptr<SpdyFrame>
   6124       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6125 
   6126   scoped_ptr<SpdyFrame>
   6127       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6128 
   6129   scoped_ptr<SpdyFrame>
   6130       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6131                                     0,
   6132                                     2,
   6133                                     1,
   6134                                     "https://www.another-origin.com/foo.dat"));
   6135 
   6136   MockRead spdy_reads[] = {
   6137     CreateMockRead(*stream1_reply, 2, ASYNC),
   6138     CreateMockRead(*stream2_syn, 3, ASYNC),
   6139     CreateMockRead(*stream1_body, 5, ASYNC),
   6140     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6141   };
   6142 
   6143   OrderedSocketData spdy_data(
   6144       spdy_reads, arraysize(spdy_reads),
   6145       spdy_writes, arraysize(spdy_writes));
   6146   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6147   // Negotiate SPDY to the proxy
   6148   SSLSocketDataProvider proxy(ASYNC, OK);
   6149   proxy.SetNextProto(GetParam());
   6150   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6151 
   6152   scoped_ptr<HttpTransaction> trans(
   6153       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6154   TestCompletionCallback callback;
   6155   int rv = trans->Start(&request, callback.callback(), log.bound());
   6156   EXPECT_EQ(ERR_IO_PENDING, rv);
   6157 
   6158   rv = callback.WaitForResult();
   6159   EXPECT_EQ(OK, rv);
   6160   const HttpResponseInfo* response = trans->GetResponseInfo();
   6161 
   6162   ASSERT_TRUE(response != NULL);
   6163   EXPECT_TRUE(response->headers->IsKeepAlive());
   6164 
   6165   EXPECT_EQ(200, response->headers->response_code());
   6166   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6167 
   6168   std::string response_data;
   6169   rv = ReadTransaction(trans.get(), &response_data);
   6170   EXPECT_EQ(OK, rv);
   6171   EXPECT_EQ("hello!", response_data);
   6172 
   6173   trans.reset();
   6174   session->CloseAllConnections();
   6175 }
   6176 
   6177 // Test HTTPS connections to a site with a bad certificate, going through an
   6178 // HTTPS proxy
   6179 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
   6180   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   6181       "https://proxy:70"));
   6182 
   6183   HttpRequestInfo request;
   6184   request.method = "GET";
   6185   request.url = GURL("https://www.google.com/");
   6186   request.load_flags = 0;
   6187 
   6188   // Attempt to fetch the URL from a server with a bad cert
   6189   MockWrite bad_cert_writes[] = {
   6190     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6191               "Host: www.google.com\r\n"
   6192               "Proxy-Connection: keep-alive\r\n\r\n"),
   6193   };
   6194 
   6195   MockRead bad_cert_reads[] = {
   6196     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6197     MockRead(SYNCHRONOUS, OK)
   6198   };
   6199 
   6200   // Attempt to fetch the URL with a good cert
   6201   MockWrite good_data_writes[] = {
   6202     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6203               "Host: www.google.com\r\n"
   6204               "Proxy-Connection: keep-alive\r\n\r\n"),
   6205     MockWrite("GET / HTTP/1.1\r\n"
   6206               "Host: www.google.com\r\n"
   6207               "Connection: keep-alive\r\n\r\n"),
   6208   };
   6209 
   6210   MockRead good_cert_reads[] = {
   6211     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6212     MockRead("HTTP/1.0 200 OK\r\n"),
   6213     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6214     MockRead("Content-Length: 100\r\n\r\n"),
   6215     MockRead(SYNCHRONOUS, OK),
   6216   };
   6217 
   6218   StaticSocketDataProvider ssl_bad_certificate(
   6219       bad_cert_reads, arraysize(bad_cert_reads),
   6220       bad_cert_writes, arraysize(bad_cert_writes));
   6221   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
   6222                                 good_data_writes, arraysize(good_data_writes));
   6223   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6224   SSLSocketDataProvider ssl(ASYNC, OK);
   6225 
   6226   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
   6227   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6228   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6229   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6230 
   6231   // SSL to the proxy, then CONNECT request, then valid SSL certificate
   6232   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6233   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6234   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6235 
   6236   TestCompletionCallback callback;
   6237 
   6238   scoped_ptr<HttpTransaction> trans(
   6239       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6240                                  CreateSession(&session_deps_)));
   6241 
   6242   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6243   EXPECT_EQ(ERR_IO_PENDING, rv);
   6244 
   6245   rv = callback.WaitForResult();
   6246   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6247 
   6248   rv = trans->RestartIgnoringLastError(callback.callback());
   6249   EXPECT_EQ(ERR_IO_PENDING, rv);
   6250 
   6251   rv = callback.WaitForResult();
   6252   EXPECT_EQ(OK, rv);
   6253 
   6254   const HttpResponseInfo* response = trans->GetResponseInfo();
   6255 
   6256   ASSERT_TRUE(response != NULL);
   6257   EXPECT_EQ(100, response->headers->GetContentLength());
   6258 }
   6259 
   6260 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   6261   HttpRequestInfo request;
   6262   request.method = "GET";
   6263   request.url = GURL("http://www.google.com/");
   6264   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6265                                   "Chromium Ultra Awesome X Edition");
   6266 
   6267   scoped_ptr<HttpTransaction> trans(
   6268       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6269                                  CreateSession(&session_deps_)));
   6270 
   6271   MockWrite data_writes[] = {
   6272     MockWrite("GET / HTTP/1.1\r\n"
   6273               "Host: www.google.com\r\n"
   6274               "Connection: keep-alive\r\n"
   6275               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6276   };
   6277 
   6278   // Lastly, the server responds with the actual content.
   6279   MockRead data_reads[] = {
   6280     MockRead("HTTP/1.0 200 OK\r\n"),
   6281     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6282     MockRead("Content-Length: 100\r\n\r\n"),
   6283     MockRead(SYNCHRONOUS, OK),
   6284   };
   6285 
   6286   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6287                                 data_writes, arraysize(data_writes));
   6288   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6289 
   6290   TestCompletionCallback callback;
   6291 
   6292   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6293   EXPECT_EQ(ERR_IO_PENDING, rv);
   6294 
   6295   rv = callback.WaitForResult();
   6296   EXPECT_EQ(OK, rv);
   6297 }
   6298 
   6299 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   6300   HttpRequestInfo request;
   6301   request.method = "GET";
   6302   request.url = GURL("https://www.google.com/");
   6303   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6304                                   "Chromium Ultra Awesome X Edition");
   6305 
   6306   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   6307   scoped_ptr<HttpTransaction> trans(
   6308       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6309                                  CreateSession(&session_deps_)));
   6310 
   6311   MockWrite data_writes[] = {
   6312     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6313               "Host: www.google.com\r\n"
   6314               "Proxy-Connection: keep-alive\r\n"
   6315               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6316   };
   6317   MockRead data_reads[] = {
   6318     // Return an error, so the transaction stops here (this test isn't
   6319     // interested in the rest).
   6320     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   6321     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   6322     MockRead("Proxy-Connection: close\r\n\r\n"),
   6323   };
   6324 
   6325   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6326                                 data_writes, arraysize(data_writes));
   6327   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6328 
   6329   TestCompletionCallback callback;
   6330 
   6331   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6332   EXPECT_EQ(ERR_IO_PENDING, rv);
   6333 
   6334   rv = callback.WaitForResult();
   6335   EXPECT_EQ(OK, rv);
   6336 }
   6337 
   6338 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
   6339   HttpRequestInfo request;
   6340   request.method = "GET";
   6341   request.url = GURL("http://www.google.com/");
   6342   request.load_flags = 0;
   6343   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
   6344                                   "http://the.previous.site.com/");
   6345 
   6346   scoped_ptr<HttpTransaction> trans(
   6347       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6348                                  CreateSession(&session_deps_)));
   6349 
   6350   MockWrite data_writes[] = {
   6351     MockWrite("GET / HTTP/1.1\r\n"
   6352               "Host: www.google.com\r\n"
   6353               "Connection: keep-alive\r\n"
   6354               "Referer: http://the.previous.site.com/\r\n\r\n"),
   6355   };
   6356 
   6357   // Lastly, the server responds with the actual content.
   6358   MockRead data_reads[] = {
   6359     MockRead("HTTP/1.0 200 OK\r\n"),
   6360     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6361     MockRead("Content-Length: 100\r\n\r\n"),
   6362     MockRead(SYNCHRONOUS, OK),
   6363   };
   6364 
   6365   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6366                                 data_writes, arraysize(data_writes));
   6367   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6368 
   6369   TestCompletionCallback callback;
   6370 
   6371   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6372   EXPECT_EQ(ERR_IO_PENDING, rv);
   6373 
   6374   rv = callback.WaitForResult();
   6375   EXPECT_EQ(OK, rv);
   6376 }
   6377 
   6378 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   6379   HttpRequestInfo request;
   6380   request.method = "POST";
   6381   request.url = GURL("http://www.google.com/");
   6382 
   6383   scoped_ptr<HttpTransaction> trans(
   6384       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6385                                  CreateSession(&session_deps_)));
   6386 
   6387   MockWrite data_writes[] = {
   6388     MockWrite("POST / HTTP/1.1\r\n"
   6389               "Host: www.google.com\r\n"
   6390               "Connection: keep-alive\r\n"
   6391               "Content-Length: 0\r\n\r\n"),
   6392   };
   6393 
   6394   // Lastly, the server responds with the actual content.
   6395   MockRead data_reads[] = {
   6396     MockRead("HTTP/1.0 200 OK\r\n"),
   6397     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6398     MockRead("Content-Length: 100\r\n\r\n"),
   6399     MockRead(SYNCHRONOUS, OK),
   6400   };
   6401 
   6402   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6403                                 data_writes, arraysize(data_writes));
   6404   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6405 
   6406   TestCompletionCallback callback;
   6407 
   6408   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6409   EXPECT_EQ(ERR_IO_PENDING, rv);
   6410 
   6411   rv = callback.WaitForResult();
   6412   EXPECT_EQ(OK, rv);
   6413 }
   6414 
   6415 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   6416   HttpRequestInfo request;
   6417   request.method = "PUT";
   6418   request.url = GURL("http://www.google.com/");
   6419 
   6420   scoped_ptr<HttpTransaction> trans(
   6421       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6422                                  CreateSession(&session_deps_)));
   6423 
   6424   MockWrite data_writes[] = {
   6425     MockWrite("PUT / HTTP/1.1\r\n"
   6426               "Host: www.google.com\r\n"
   6427               "Connection: keep-alive\r\n"
   6428               "Content-Length: 0\r\n\r\n"),
   6429   };
   6430 
   6431   // Lastly, the server responds with the actual content.
   6432   MockRead data_reads[] = {
   6433     MockRead("HTTP/1.0 200 OK\r\n"),
   6434     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6435     MockRead("Content-Length: 100\r\n\r\n"),
   6436     MockRead(SYNCHRONOUS, OK),
   6437   };
   6438 
   6439   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6440                                 data_writes, arraysize(data_writes));
   6441   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6442 
   6443   TestCompletionCallback callback;
   6444 
   6445   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6446   EXPECT_EQ(ERR_IO_PENDING, rv);
   6447 
   6448   rv = callback.WaitForResult();
   6449   EXPECT_EQ(OK, rv);
   6450 }
   6451 
   6452 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   6453   HttpRequestInfo request;
   6454   request.method = "HEAD";
   6455   request.url = GURL("http://www.google.com/");
   6456 
   6457   scoped_ptr<HttpTransaction> trans(
   6458       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6459                                  CreateSession(&session_deps_)));
   6460 
   6461   MockWrite data_writes[] = {
   6462     MockWrite("HEAD / HTTP/1.1\r\n"
   6463               "Host: www.google.com\r\n"
   6464               "Connection: keep-alive\r\n"
   6465               "Content-Length: 0\r\n\r\n"),
   6466   };
   6467 
   6468   // Lastly, the server responds with the actual content.
   6469   MockRead data_reads[] = {
   6470     MockRead("HTTP/1.0 200 OK\r\n"),
   6471     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6472     MockRead("Content-Length: 100\r\n\r\n"),
   6473     MockRead(SYNCHRONOUS, OK),
   6474   };
   6475 
   6476   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6477                                 data_writes, arraysize(data_writes));
   6478   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6479 
   6480   TestCompletionCallback callback;
   6481 
   6482   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6483   EXPECT_EQ(ERR_IO_PENDING, rv);
   6484 
   6485   rv = callback.WaitForResult();
   6486   EXPECT_EQ(OK, rv);
   6487 }
   6488 
   6489 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   6490   HttpRequestInfo request;
   6491   request.method = "GET";
   6492   request.url = GURL("http://www.google.com/");
   6493   request.load_flags = LOAD_BYPASS_CACHE;
   6494 
   6495   scoped_ptr<HttpTransaction> trans(
   6496       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6497                                  CreateSession(&session_deps_)));
   6498 
   6499   MockWrite data_writes[] = {
   6500     MockWrite("GET / HTTP/1.1\r\n"
   6501               "Host: www.google.com\r\n"
   6502               "Connection: keep-alive\r\n"
   6503               "Pragma: no-cache\r\n"
   6504               "Cache-Control: no-cache\r\n\r\n"),
   6505   };
   6506 
   6507   // Lastly, the server responds with the actual content.
   6508   MockRead data_reads[] = {
   6509     MockRead("HTTP/1.0 200 OK\r\n"),
   6510     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6511     MockRead("Content-Length: 100\r\n\r\n"),
   6512     MockRead(SYNCHRONOUS, OK),
   6513   };
   6514 
   6515   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6516                                 data_writes, arraysize(data_writes));
   6517   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6518 
   6519   TestCompletionCallback callback;
   6520 
   6521   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6522   EXPECT_EQ(ERR_IO_PENDING, rv);
   6523 
   6524   rv = callback.WaitForResult();
   6525   EXPECT_EQ(OK, rv);
   6526 }
   6527 
   6528 TEST_P(HttpNetworkTransactionTest,
   6529        BuildRequest_CacheControlValidateCache) {
   6530   HttpRequestInfo request;
   6531   request.method = "GET";
   6532   request.url = GURL("http://www.google.com/");
   6533   request.load_flags = LOAD_VALIDATE_CACHE;
   6534 
   6535   scoped_ptr<HttpTransaction> trans(
   6536       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6537                                  CreateSession(&session_deps_)));
   6538 
   6539   MockWrite data_writes[] = {
   6540     MockWrite("GET / HTTP/1.1\r\n"
   6541               "Host: www.google.com\r\n"
   6542               "Connection: keep-alive\r\n"
   6543               "Cache-Control: max-age=0\r\n\r\n"),
   6544   };
   6545 
   6546   // Lastly, the server responds with the actual content.
   6547   MockRead data_reads[] = {
   6548     MockRead("HTTP/1.0 200 OK\r\n"),
   6549     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6550     MockRead("Content-Length: 100\r\n\r\n"),
   6551     MockRead(SYNCHRONOUS, OK),
   6552   };
   6553 
   6554   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6555                                 data_writes, arraysize(data_writes));
   6556   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6557 
   6558   TestCompletionCallback callback;
   6559 
   6560   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6561   EXPECT_EQ(ERR_IO_PENDING, rv);
   6562 
   6563   rv = callback.WaitForResult();
   6564   EXPECT_EQ(OK, rv);
   6565 }
   6566 
   6567 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   6568   HttpRequestInfo request;
   6569   request.method = "GET";
   6570   request.url = GURL("http://www.google.com/");
   6571   request.extra_headers.SetHeader("FooHeader", "Bar");
   6572 
   6573   scoped_ptr<HttpTransaction> trans(
   6574       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6575                                  CreateSession(&session_deps_)));
   6576 
   6577   MockWrite data_writes[] = {
   6578     MockWrite("GET / HTTP/1.1\r\n"
   6579               "Host: www.google.com\r\n"
   6580               "Connection: keep-alive\r\n"
   6581               "FooHeader: Bar\r\n\r\n"),
   6582   };
   6583 
   6584   // Lastly, the server responds with the actual content.
   6585   MockRead data_reads[] = {
   6586     MockRead("HTTP/1.0 200 OK\r\n"),
   6587     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6588     MockRead("Content-Length: 100\r\n\r\n"),
   6589     MockRead(SYNCHRONOUS, OK),
   6590   };
   6591 
   6592   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6593                                 data_writes, arraysize(data_writes));
   6594   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6595 
   6596   TestCompletionCallback callback;
   6597 
   6598   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6599   EXPECT_EQ(ERR_IO_PENDING, rv);
   6600 
   6601   rv = callback.WaitForResult();
   6602   EXPECT_EQ(OK, rv);
   6603 }
   6604 
   6605 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   6606   HttpRequestInfo request;
   6607   request.method = "GET";
   6608   request.url = GURL("http://www.google.com/");
   6609   request.extra_headers.SetHeader("referer", "www.foo.com");
   6610   request.extra_headers.SetHeader("hEllo", "Kitty");
   6611   request.extra_headers.SetHeader("FoO", "bar");
   6612 
   6613   scoped_ptr<HttpTransaction> trans(
   6614       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6615                                  CreateSession(&session_deps_)));
   6616 
   6617   MockWrite data_writes[] = {
   6618     MockWrite("GET / HTTP/1.1\r\n"
   6619               "Host: www.google.com\r\n"
   6620               "Connection: keep-alive\r\n"
   6621               "referer: www.foo.com\r\n"
   6622               "hEllo: Kitty\r\n"
   6623               "FoO: bar\r\n\r\n"),
   6624   };
   6625 
   6626   // Lastly, the server responds with the actual content.
   6627   MockRead data_reads[] = {
   6628     MockRead("HTTP/1.0 200 OK\r\n"),
   6629     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6630     MockRead("Content-Length: 100\r\n\r\n"),
   6631     MockRead(SYNCHRONOUS, OK),
   6632   };
   6633 
   6634   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6635                                 data_writes, arraysize(data_writes));
   6636   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6637 
   6638   TestCompletionCallback callback;
   6639 
   6640   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6641   EXPECT_EQ(ERR_IO_PENDING, rv);
   6642 
   6643   rv = callback.WaitForResult();
   6644   EXPECT_EQ(OK, rv);
   6645 }
   6646 
   6647 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   6648   HttpRequestInfo request;
   6649   request.method = "GET";
   6650   request.url = GURL("http://www.google.com/");
   6651   request.load_flags = 0;
   6652 
   6653   session_deps_.proxy_service.reset(
   6654       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   6655   CapturingNetLog net_log;
   6656   session_deps_.net_log = &net_log;
   6657 
   6658   scoped_ptr<HttpTransaction> trans(
   6659       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6660                                  CreateSession(&session_deps_)));
   6661 
   6662   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   6663   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6664 
   6665   MockWrite data_writes[] = {
   6666     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   6667     MockWrite("GET / HTTP/1.1\r\n"
   6668               "Host: www.google.com\r\n"
   6669               "Connection: keep-alive\r\n\r\n")
   6670   };
   6671 
   6672   MockRead data_reads[] = {
   6673     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   6674     MockRead("HTTP/1.0 200 OK\r\n"),
   6675     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6676     MockRead("Payload"),
   6677     MockRead(SYNCHRONOUS, OK)
   6678   };
   6679 
   6680   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6681                                 data_writes, arraysize(data_writes));
   6682   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6683 
   6684   TestCompletionCallback callback;
   6685 
   6686   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6687   EXPECT_EQ(ERR_IO_PENDING, rv);
   6688 
   6689   rv = callback.WaitForResult();
   6690   EXPECT_EQ(OK, rv);
   6691 
   6692   const HttpResponseInfo* response = trans->GetResponseInfo();
   6693   ASSERT_TRUE(response != NULL);
   6694 
   6695   LoadTimingInfo load_timing_info;
   6696   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6697   TestLoadTimingNotReusedWithPac(load_timing_info,
   6698                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6699 
   6700   std::string response_text;
   6701   rv = ReadTransaction(trans.get(), &response_text);
   6702   EXPECT_EQ(OK, rv);
   6703   EXPECT_EQ("Payload", response_text);
   6704 }
   6705 
   6706 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   6707   HttpRequestInfo request;
   6708   request.method = "GET";
   6709   request.url = GURL("https://www.google.com/");
   6710   request.load_flags = 0;
   6711 
   6712   session_deps_.proxy_service.reset(
   6713       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   6714   CapturingNetLog net_log;
   6715   session_deps_.net_log = &net_log;
   6716 
   6717   scoped_ptr<HttpTransaction> trans(
   6718       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6719                                  CreateSession(&session_deps_)));
   6720 
   6721   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
   6722   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6723 
   6724   MockWrite data_writes[] = {
   6725     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
   6726               arraysize(write_buffer)),
   6727     MockWrite("GET / HTTP/1.1\r\n"
   6728               "Host: www.google.com\r\n"
   6729               "Connection: keep-alive\r\n\r\n")
   6730   };
   6731 
   6732   MockRead data_reads[] = {
   6733     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
   6734              arraysize(read_buffer)),
   6735     MockRead("HTTP/1.0 200 OK\r\n"),
   6736     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6737     MockRead("Payload"),
   6738     MockRead(SYNCHRONOUS, OK)
   6739   };
   6740 
   6741   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6742                                 data_writes, arraysize(data_writes));
   6743   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6744 
   6745   SSLSocketDataProvider ssl(ASYNC, OK);
   6746   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6747 
   6748   TestCompletionCallback callback;
   6749 
   6750   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6751   EXPECT_EQ(ERR_IO_PENDING, rv);
   6752 
   6753   rv = callback.WaitForResult();
   6754   EXPECT_EQ(OK, rv);
   6755 
   6756   LoadTimingInfo load_timing_info;
   6757   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6758   TestLoadTimingNotReusedWithPac(load_timing_info,
   6759                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6760 
   6761   const HttpResponseInfo* response = trans->GetResponseInfo();
   6762   ASSERT_TRUE(response != NULL);
   6763 
   6764   std::string response_text;
   6765   rv = ReadTransaction(trans.get(), &response_text);
   6766   EXPECT_EQ(OK, rv);
   6767   EXPECT_EQ("Payload", response_text);
   6768 }
   6769 
   6770 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
   6771   HttpRequestInfo request;
   6772   request.method = "GET";
   6773   request.url = GURL("http://www.google.com/");
   6774   request.load_flags = 0;
   6775 
   6776   session_deps_.proxy_service.reset(
   6777       ProxyService::CreateFixed("socks4://myproxy:1080"));
   6778   CapturingNetLog net_log;
   6779   session_deps_.net_log = &net_log;
   6780 
   6781   scoped_ptr<HttpTransaction> trans(
   6782       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6783                                  CreateSession(&session_deps_)));
   6784 
   6785   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   6786   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6787 
   6788   MockWrite data_writes[] = {
   6789     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   6790     MockWrite("GET / HTTP/1.1\r\n"
   6791               "Host: www.google.com\r\n"
   6792               "Connection: keep-alive\r\n\r\n")
   6793   };
   6794 
   6795   MockRead data_reads[] = {
   6796     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   6797     MockRead("HTTP/1.0 200 OK\r\n"),
   6798     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6799     MockRead("Payload"),
   6800     MockRead(SYNCHRONOUS, OK)
   6801   };
   6802 
   6803   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6804                                 data_writes, arraysize(data_writes));
   6805   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6806 
   6807   TestCompletionCallback callback;
   6808 
   6809   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6810   EXPECT_EQ(ERR_IO_PENDING, rv);
   6811 
   6812   rv = callback.WaitForResult();
   6813   EXPECT_EQ(OK, rv);
   6814 
   6815   const HttpResponseInfo* response = trans->GetResponseInfo();
   6816   ASSERT_TRUE(response != NULL);
   6817 
   6818   LoadTimingInfo load_timing_info;
   6819   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6820   TestLoadTimingNotReused(load_timing_info,
   6821                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6822 
   6823   std::string response_text;
   6824   rv = ReadTransaction(trans.get(), &response_text);
   6825   EXPECT_EQ(OK, rv);
   6826   EXPECT_EQ("Payload", response_text);
   6827 }
   6828 
   6829 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   6830   HttpRequestInfo request;
   6831   request.method = "GET";
   6832   request.url = GURL("http://www.google.com/");
   6833   request.load_flags = 0;
   6834 
   6835   session_deps_.proxy_service.reset(
   6836       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   6837   CapturingNetLog net_log;
   6838   session_deps_.net_log = &net_log;
   6839 
   6840   scoped_ptr<HttpTransaction> trans(
   6841       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6842                                  CreateSession(&session_deps_)));
   6843 
   6844   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   6845   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   6846   const char kSOCKS5OkRequest[] = {
   6847     0x05,  // Version
   6848     0x01,  // Command (CONNECT)
   6849     0x00,  // Reserved.
   6850     0x03,  // Address type (DOMAINNAME).
   6851     0x0E,  // Length of domain (14)
   6852     // Domain string:
   6853     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   6854     0x00, 0x50,  // 16-bit port (80)
   6855   };
   6856   const char kSOCKS5OkResponse[] =
   6857       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
   6858 
   6859   MockWrite data_writes[] = {
   6860     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   6861     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
   6862     MockWrite("GET / HTTP/1.1\r\n"
   6863               "Host: www.google.com\r\n"
   6864               "Connection: keep-alive\r\n\r\n")
   6865   };
   6866 
   6867   MockRead data_reads[] = {
   6868     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   6869     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   6870     MockRead("HTTP/1.0 200 OK\r\n"),
   6871     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6872     MockRead("Payload"),
   6873     MockRead(SYNCHRONOUS, OK)
   6874   };
   6875 
   6876   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6877                                 data_writes, arraysize(data_writes));
   6878   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6879 
   6880   TestCompletionCallback callback;
   6881 
   6882   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6883   EXPECT_EQ(ERR_IO_PENDING, rv);
   6884 
   6885   rv = callback.WaitForResult();
   6886   EXPECT_EQ(OK, rv);
   6887 
   6888   const HttpResponseInfo* response = trans->GetResponseInfo();
   6889   ASSERT_TRUE(response != NULL);
   6890 
   6891   LoadTimingInfo load_timing_info;
   6892   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6893   TestLoadTimingNotReusedWithPac(load_timing_info,
   6894                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6895 
   6896   std::string response_text;
   6897   rv = ReadTransaction(trans.get(), &response_text);
   6898   EXPECT_EQ(OK, rv);
   6899   EXPECT_EQ("Payload", response_text);
   6900 }
   6901 
   6902 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   6903   HttpRequestInfo request;
   6904   request.method = "GET";
   6905   request.url = GURL("https://www.google.com/");
   6906   request.load_flags = 0;
   6907 
   6908   session_deps_.proxy_service.reset(
   6909       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   6910   CapturingNetLog net_log;
   6911   session_deps_.net_log = &net_log;
   6912 
   6913   scoped_ptr<HttpTransaction> trans(
   6914       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   6915                                  CreateSession(&session_deps_)));
   6916 
   6917   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   6918   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   6919   const unsigned char kSOCKS5OkRequest[] = {
   6920     0x05,  // Version
   6921     0x01,  // Command (CONNECT)
   6922     0x00,  // Reserved.
   6923     0x03,  // Address type (DOMAINNAME).
   6924     0x0E,  // Length of domain (14)
   6925     // Domain string:
   6926     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   6927     0x01, 0xBB,  // 16-bit port (443)
   6928   };
   6929 
   6930   const char kSOCKS5OkResponse[] =
   6931       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
   6932 
   6933   MockWrite data_writes[] = {
   6934     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   6935     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
   6936               arraysize(kSOCKS5OkRequest)),
   6937     MockWrite("GET / HTTP/1.1\r\n"
   6938               "Host: www.google.com\r\n"
   6939               "Connection: keep-alive\r\n\r\n")
   6940   };
   6941 
   6942   MockRead data_reads[] = {
   6943     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   6944     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   6945     MockRead("HTTP/1.0 200 OK\r\n"),
   6946     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6947     MockRead("Payload"),
   6948     MockRead(SYNCHRONOUS, OK)
   6949   };
   6950 
   6951   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6952                                 data_writes, arraysize(data_writes));
   6953   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6954 
   6955   SSLSocketDataProvider ssl(ASYNC, OK);
   6956   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6957 
   6958   TestCompletionCallback callback;
   6959 
   6960   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6961   EXPECT_EQ(ERR_IO_PENDING, rv);
   6962 
   6963   rv = callback.WaitForResult();
   6964   EXPECT_EQ(OK, rv);
   6965 
   6966   const HttpResponseInfo* response = trans->GetResponseInfo();
   6967   ASSERT_TRUE(response != NULL);
   6968 
   6969   LoadTimingInfo load_timing_info;
   6970   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6971   TestLoadTimingNotReusedWithPac(load_timing_info,
   6972                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6973 
   6974   std::string response_text;
   6975   rv = ReadTransaction(trans.get(), &response_text);
   6976   EXPECT_EQ(OK, rv);
   6977   EXPECT_EQ("Payload", response_text);
   6978 }
   6979 
   6980 namespace {
   6981 
   6982 // Tests that for connection endpoints the group names are correctly set.
   6983 
   6984 struct GroupNameTest {
   6985   std::string proxy_server;
   6986   std::string url;
   6987   std::string expected_group_name;
   6988   bool ssl;
   6989 };
   6990 
   6991 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
   6992     NextProto next_proto,
   6993     SpdySessionDependencies* session_deps_) {
   6994   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
   6995 
   6996   base::WeakPtr<HttpServerProperties> http_server_properties =
   6997       session->http_server_properties();
   6998   http_server_properties->SetAlternateProtocol(
   6999       HostPortPair("host.with.alternate", 80), 443,
   7000       AlternateProtocolFromNextProto(next_proto));
   7001 
   7002   return session;
   7003 }
   7004 
   7005 int GroupNameTransactionHelper(
   7006     const std::string& url,
   7007     const scoped_refptr<HttpNetworkSession>& session) {
   7008   HttpRequestInfo request;
   7009   request.method = "GET";
   7010   request.url = GURL(url);
   7011   request.load_flags = 0;
   7012 
   7013   scoped_ptr<HttpTransaction> trans(
   7014       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7015 
   7016   TestCompletionCallback callback;
   7017 
   7018   // We do not complete this request, the dtor will clean the transaction up.
   7019   return trans->Start(&request, callback.callback(), BoundNetLog());
   7020 }
   7021 
   7022 }  // namespace
   7023 
   7024 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
   7025   const GroupNameTest tests[] = {
   7026     {
   7027       "",  // unused
   7028       "http://www.google.com/direct",
   7029       "www.google.com:80",
   7030       false,
   7031     },
   7032     {
   7033       "",  // unused
   7034       "http://[2001:1418:13:1::25]/direct",
   7035       "[2001:1418:13:1::25]:80",
   7036       false,
   7037     },
   7038 
   7039     // SSL Tests
   7040     {
   7041       "",  // unused
   7042       "https://www.google.com/direct_ssl",
   7043       "ssl/www.google.com:443",
   7044       true,
   7045     },
   7046     {
   7047       "",  // unused
   7048       "https://[2001:1418:13:1::25]/direct",
   7049       "ssl/[2001:1418:13:1::25]:443",
   7050       true,
   7051     },
   7052     {
   7053       "",  // unused
   7054       "http://host.with.alternate/direct",
   7055       "ssl/host.with.alternate:443",
   7056       true,
   7057     },
   7058   };
   7059 
   7060   HttpStreamFactory::set_use_alternate_protocols(true);
   7061 
   7062   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7063     session_deps_.proxy_service.reset(
   7064         ProxyService::CreateFixed(tests[i].proxy_server));
   7065     scoped_refptr<HttpNetworkSession> session(
   7066         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7067 
   7068     HttpNetworkSessionPeer peer(session);
   7069     CaptureGroupNameTransportSocketPool* transport_conn_pool =
   7070         new CaptureGroupNameTransportSocketPool(NULL, NULL);
   7071     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7072         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7073     MockClientSocketPoolManager* mock_pool_manager =
   7074         new MockClientSocketPoolManager;
   7075     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
   7076     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
   7077     peer.SetClientSocketPoolManager(mock_pool_manager);
   7078 
   7079     EXPECT_EQ(ERR_IO_PENDING,
   7080               GroupNameTransactionHelper(tests[i].url, session));
   7081     if (tests[i].ssl)
   7082       EXPECT_EQ(tests[i].expected_group_name,
   7083                 ssl_conn_pool->last_group_name_received());
   7084     else
   7085       EXPECT_EQ(tests[i].expected_group_name,
   7086                 transport_conn_pool->last_group_name_received());
   7087   }
   7088 
   7089 }
   7090 
   7091 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
   7092   const GroupNameTest tests[] = {
   7093     {
   7094       "http_proxy",
   7095       "http://www.google.com/http_proxy_normal",
   7096       "www.google.com:80",
   7097       false,
   7098     },
   7099 
   7100     // SSL Tests
   7101     {
   7102       "http_proxy",
   7103       "https://www.google.com/http_connect_ssl",
   7104       "ssl/www.google.com:443",
   7105       true,
   7106     },
   7107 
   7108     {
   7109       "http_proxy",
   7110       "http://host.with.alternate/direct",
   7111       "ssl/host.with.alternate:443",
   7112       true,
   7113     },
   7114 
   7115     {
   7116       "http_proxy",
   7117       "ftp://ftp.google.com/http_proxy_normal",
   7118       "ftp/ftp.google.com:21",
   7119       false,
   7120     },
   7121   };
   7122 
   7123   HttpStreamFactory::set_use_alternate_protocols(true);
   7124 
   7125   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7126     session_deps_.proxy_service.reset(
   7127         ProxyService::CreateFixed(tests[i].proxy_server));
   7128     scoped_refptr<HttpNetworkSession> session(
   7129         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7130 
   7131     HttpNetworkSessionPeer peer(session);
   7132 
   7133     HostPortPair proxy_host("http_proxy", 80);
   7134     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
   7135         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
   7136     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7137         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7138 
   7139     MockClientSocketPoolManager* mock_pool_manager =
   7140         new MockClientSocketPoolManager;
   7141     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
   7142     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7143     peer.SetClientSocketPoolManager(mock_pool_manager);
   7144 
   7145     EXPECT_EQ(ERR_IO_PENDING,
   7146               GroupNameTransactionHelper(tests[i].url, session));
   7147     if (tests[i].ssl)
   7148       EXPECT_EQ(tests[i].expected_group_name,
   7149                 ssl_conn_pool->last_group_name_received());
   7150     else
   7151       EXPECT_EQ(tests[i].expected_group_name,
   7152                 http_proxy_pool->last_group_name_received());
   7153   }
   7154 }
   7155 
   7156 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
   7157   const GroupNameTest tests[] = {
   7158     {
   7159       "socks4://socks_proxy:1080",
   7160       "http://www.google.com/socks4_direct",
   7161       "socks4/www.google.com:80",
   7162       false,
   7163     },
   7164     {
   7165       "socks5://socks_proxy:1080",
   7166       "http://www.google.com/socks5_direct",
   7167       "socks5/www.google.com:80",
   7168       false,
   7169     },
   7170 
   7171     // SSL Tests
   7172     {
   7173       "socks4://socks_proxy:1080",
   7174       "https://www.google.com/socks4_ssl",
   7175       "socks4/ssl/www.google.com:443",
   7176       true,
   7177     },
   7178     {
   7179       "socks5://socks_proxy:1080",
   7180       "https://www.google.com/socks5_ssl",
   7181       "socks5/ssl/www.google.com:443",
   7182       true,
   7183     },
   7184 
   7185     {
   7186       "socks4://socks_proxy:1080",
   7187       "http://host.with.alternate/direct",
   7188       "socks4/ssl/host.with.alternate:443",
   7189       true,
   7190     },
   7191   };
   7192 
   7193   HttpStreamFactory::set_use_alternate_protocols(true);
   7194 
   7195   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7196     session_deps_.proxy_service.reset(
   7197         ProxyService::CreateFixed(tests[i].proxy_server));
   7198     scoped_refptr<HttpNetworkSession> session(
   7199         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7200 
   7201     HttpNetworkSessionPeer peer(session);
   7202 
   7203     HostPortPair proxy_host("socks_proxy", 1080);
   7204     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
   7205         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
   7206     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7207         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7208 
   7209     MockClientSocketPoolManager* mock_pool_manager =
   7210         new MockClientSocketPoolManager;
   7211     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
   7212     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7213     peer.SetClientSocketPoolManager(mock_pool_manager);
   7214 
   7215     scoped_ptr<HttpTransaction> trans(
   7216         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7217 
   7218     EXPECT_EQ(ERR_IO_PENDING,
   7219               GroupNameTransactionHelper(tests[i].url, session));
   7220     if (tests[i].ssl)
   7221       EXPECT_EQ(tests[i].expected_group_name,
   7222                 ssl_conn_pool->last_group_name_received());
   7223     else
   7224       EXPECT_EQ(tests[i].expected_group_name,
   7225                 socks_conn_pool->last_group_name_received());
   7226   }
   7227 }
   7228 
   7229 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   7230   HttpRequestInfo request;
   7231   request.method = "GET";
   7232   request.url = GURL("http://www.google.com/");
   7233 
   7234   session_deps_.proxy_service.reset(
   7235       ProxyService::CreateFixed("myproxy:70;foobar:80"));
   7236 
   7237   // This simulates failure resolving all hostnames; that means we will fail
   7238   // connecting to both proxies (myproxy:70 and foobar:80).
   7239   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
   7240 
   7241   scoped_ptr<HttpTransaction> trans(
   7242       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7243                                  CreateSession(&session_deps_)));
   7244 
   7245   TestCompletionCallback callback;
   7246 
   7247   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7248   EXPECT_EQ(ERR_IO_PENDING, rv);
   7249 
   7250   rv = callback.WaitForResult();
   7251   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
   7252 }
   7253 
   7254 // Base test to make sure that when the load flags for a request specify to
   7255 // bypass the cache, the DNS cache is not used.
   7256 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
   7257     int load_flags) {
   7258   // Issue a request, asking to bypass the cache(s).
   7259   HttpRequestInfo request;
   7260   request.method = "GET";
   7261   request.load_flags = load_flags;
   7262   request.url = GURL("http://www.google.com/");
   7263 
   7264   // Select a host resolver that does caching.
   7265   session_deps_.host_resolver.reset(new MockCachingHostResolver);
   7266 
   7267   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7268       CreateSession(&session_deps_)));
   7269 
   7270   // Warm up the host cache so it has an entry for "www.google.com".
   7271   AddressList addrlist;
   7272   TestCompletionCallback callback;
   7273   int rv = session_deps_.host_resolver->Resolve(
   7274       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
   7275       callback.callback(), NULL, BoundNetLog());
   7276   EXPECT_EQ(ERR_IO_PENDING, rv);
   7277   rv = callback.WaitForResult();
   7278   EXPECT_EQ(OK, rv);
   7279 
   7280   // Verify that it was added to host cache, by doing a subsequent async lookup
   7281   // and confirming it completes synchronously.
   7282   rv = session_deps_.host_resolver->Resolve(
   7283       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
   7284       callback.callback(), NULL, BoundNetLog());
   7285   ASSERT_EQ(OK, rv);
   7286 
   7287   // Inject a failure the next time that "www.google.com" is resolved. This way
   7288   // we can tell if the next lookup hit the cache, or the "network".
   7289   // (cache --> success, "network" --> failure).
   7290   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
   7291 
   7292   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   7293   // first read -- this won't be reached as the host resolution will fail first.
   7294   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
   7295   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7296   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7297 
   7298   // Run the request.
   7299   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7300   ASSERT_EQ(ERR_IO_PENDING, rv);
   7301   rv = callback.WaitForResult();
   7302 
   7303   // If we bypassed the cache, we would have gotten a failure while resolving
   7304   // "www.google.com".
   7305   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   7306 }
   7307 
   7308 // There are multiple load flags that should trigger the host cache bypass.
   7309 // Test each in isolation:
   7310 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
   7311   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
   7312 }
   7313 
   7314 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
   7315   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
   7316 }
   7317 
   7318 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
   7319   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
   7320 }
   7321 
   7322 // Make sure we can handle an error when writing the request.
   7323 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
   7324   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7325 
   7326   HttpRequestInfo request;
   7327   request.method = "GET";
   7328   request.url = GURL("http://www.foo.com/");
   7329   request.load_flags = 0;
   7330 
   7331   MockWrite write_failure[] = {
   7332     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   7333   };
   7334   StaticSocketDataProvider data(NULL, 0,
   7335                                 write_failure, arraysize(write_failure));
   7336   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7337 
   7338   TestCompletionCallback callback;
   7339 
   7340   scoped_ptr<HttpTransaction> trans(
   7341       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7342                                  CreateSession(&session_deps_)));
   7343 
   7344   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7345   EXPECT_EQ(ERR_IO_PENDING, rv);
   7346 
   7347   rv = callback.WaitForResult();
   7348   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   7349 }
   7350 
   7351 // Check that a connection closed after the start of the headers finishes ok.
   7352 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
   7353   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7354 
   7355   HttpRequestInfo request;
   7356   request.method = "GET";
   7357   request.url = GURL("http://www.foo.com/");
   7358   request.load_flags = 0;
   7359 
   7360   MockRead data_reads[] = {
   7361     MockRead("HTTP/1."),
   7362     MockRead(SYNCHRONOUS, OK),
   7363   };
   7364 
   7365   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7366   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7367 
   7368   TestCompletionCallback callback;
   7369 
   7370   scoped_ptr<HttpTransaction> trans(
   7371       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7372                                  CreateSession(&session_deps_)));
   7373 
   7374   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7375   EXPECT_EQ(ERR_IO_PENDING, rv);
   7376 
   7377   rv = callback.WaitForResult();
   7378   EXPECT_EQ(OK, rv);
   7379 
   7380   const HttpResponseInfo* response = trans->GetResponseInfo();
   7381   ASSERT_TRUE(response != NULL);
   7382 
   7383   EXPECT_TRUE(response->headers.get() != NULL);
   7384   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7385 
   7386   std::string response_data;
   7387   rv = ReadTransaction(trans.get(), &response_data);
   7388   EXPECT_EQ(OK, rv);
   7389   EXPECT_EQ("", response_data);
   7390 }
   7391 
   7392 // Make sure that a dropped connection while draining the body for auth
   7393 // restart does the right thing.
   7394 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
   7395   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7396 
   7397   HttpRequestInfo request;
   7398   request.method = "GET";
   7399   request.url = GURL("http://www.google.com/");
   7400   request.load_flags = 0;
   7401 
   7402   MockWrite data_writes1[] = {
   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_reads1[] = {
   7409     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   7410     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   7411     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7412     MockRead("Content-Length: 14\r\n\r\n"),
   7413     MockRead("Unauth"),
   7414     MockRead(ASYNC, ERR_CONNECTION_RESET),
   7415   };
   7416 
   7417   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   7418                                  data_writes1, arraysize(data_writes1));
   7419   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   7420 
   7421   // After calling trans->RestartWithAuth(), this is the request we should
   7422   // be issuing -- the final header line contains the credentials.
   7423   MockWrite data_writes2[] = {
   7424     MockWrite("GET / HTTP/1.1\r\n"
   7425               "Host: www.google.com\r\n"
   7426               "Connection: keep-alive\r\n"
   7427               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   7428   };
   7429 
   7430   // Lastly, the server responds with the actual content.
   7431   MockRead data_reads2[] = {
   7432     MockRead("HTTP/1.1 200 OK\r\n"),
   7433     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7434     MockRead("Content-Length: 100\r\n\r\n"),
   7435     MockRead(SYNCHRONOUS, OK),
   7436   };
   7437 
   7438   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   7439                                  data_writes2, arraysize(data_writes2));
   7440   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   7441 
   7442   TestCompletionCallback callback1;
   7443 
   7444   scoped_ptr<HttpTransaction> trans(
   7445       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7446 
   7447   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7448   EXPECT_EQ(ERR_IO_PENDING, rv);
   7449 
   7450   rv = callback1.WaitForResult();
   7451   EXPECT_EQ(OK, rv);
   7452 
   7453   const HttpResponseInfo* response = trans->GetResponseInfo();
   7454   ASSERT_TRUE(response != NULL);
   7455   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   7456 
   7457   TestCompletionCallback callback2;
   7458 
   7459   rv = trans->RestartWithAuth(
   7460       AuthCredentials(kFoo, kBar), callback2.callback());
   7461   EXPECT_EQ(ERR_IO_PENDING, rv);
   7462 
   7463   rv = callback2.WaitForResult();
   7464   EXPECT_EQ(OK, rv);
   7465 
   7466   response = trans->GetResponseInfo();
   7467   ASSERT_TRUE(response != NULL);
   7468   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7469   EXPECT_EQ(100, response->headers->GetContentLength());
   7470 }
   7471 
   7472 // Test HTTPS connections going through a proxy that sends extra data.
   7473 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
   7474   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   7475 
   7476   HttpRequestInfo request;
   7477   request.method = "GET";
   7478   request.url = GURL("https://www.google.com/");
   7479   request.load_flags = 0;
   7480 
   7481   MockRead proxy_reads[] = {
   7482     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
   7483     MockRead(SYNCHRONOUS, OK)
   7484   };
   7485 
   7486   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
   7487   SSLSocketDataProvider ssl(ASYNC, OK);
   7488 
   7489   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7490   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   7491 
   7492   TestCompletionCallback callback;
   7493 
   7494   session_deps_.socket_factory->ResetNextMockIndexes();
   7495 
   7496   scoped_ptr<HttpTransaction> trans(
   7497       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7498                                  CreateSession(&session_deps_)));
   7499 
   7500   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7501   EXPECT_EQ(ERR_IO_PENDING, rv);
   7502 
   7503   rv = callback.WaitForResult();
   7504   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   7505 }
   7506 
   7507 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   7508   HttpRequestInfo request;
   7509   request.method = "GET";
   7510   request.url = GURL("http://www.google.com/");
   7511   request.load_flags = 0;
   7512 
   7513   scoped_ptr<HttpTransaction> trans(
   7514       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7515                                  CreateSession(&session_deps_)));
   7516 
   7517   MockRead data_reads[] = {
   7518     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
   7519     MockRead(SYNCHRONOUS, OK),
   7520   };
   7521 
   7522   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7523   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7524 
   7525   TestCompletionCallback callback;
   7526 
   7527   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7528   EXPECT_EQ(ERR_IO_PENDING, rv);
   7529 
   7530   EXPECT_EQ(OK, callback.WaitForResult());
   7531 
   7532   const HttpResponseInfo* response = trans->GetResponseInfo();
   7533   ASSERT_TRUE(response != NULL);
   7534 
   7535   EXPECT_TRUE(response->headers.get() != NULL);
   7536   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7537 
   7538   std::string response_data;
   7539   rv = ReadTransaction(trans.get(), &response_data);
   7540   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   7541 }
   7542 
   7543 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
   7544   base::FilePath temp_file_path;
   7545   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
   7546   const uint64 kFakeSize = 100000;  // file is actually blank
   7547   UploadFileElementReader::ScopedOverridingContentLengthForTests
   7548       overriding_content_length(kFakeSize);
   7549 
   7550   ScopedVector<UploadElementReader> element_readers;
   7551   element_readers.push_back(
   7552       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   7553                                   temp_file_path,
   7554                                   0,
   7555                                   kuint64max,
   7556                                   base::Time()));
   7557   UploadDataStream upload_data_stream(&element_readers, 0);
   7558 
   7559   HttpRequestInfo request;
   7560   request.method = "POST";
   7561   request.url = GURL("http://www.google.com/upload");
   7562   request.upload_data_stream = &upload_data_stream;
   7563   request.load_flags = 0;
   7564 
   7565   scoped_ptr<HttpTransaction> trans(
   7566       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7567                                  CreateSession(&session_deps_)));
   7568 
   7569   MockRead data_reads[] = {
   7570     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   7571     MockRead("hello world"),
   7572     MockRead(SYNCHRONOUS, OK),
   7573   };
   7574   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7575   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7576 
   7577   TestCompletionCallback callback;
   7578 
   7579   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7580   EXPECT_EQ(ERR_IO_PENDING, rv);
   7581 
   7582   rv = callback.WaitForResult();
   7583   EXPECT_EQ(OK, rv);
   7584 
   7585   const HttpResponseInfo* response = trans->GetResponseInfo();
   7586   ASSERT_TRUE(response != NULL);
   7587 
   7588   EXPECT_TRUE(response->headers.get() != NULL);
   7589   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7590 
   7591   std::string response_data;
   7592   rv = ReadTransaction(trans.get(), &response_data);
   7593   EXPECT_EQ(OK, rv);
   7594   EXPECT_EQ("hello world", response_data);
   7595 
   7596   base::DeleteFile(temp_file_path, false);
   7597 }
   7598 
   7599 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
   7600   base::FilePath temp_file;
   7601   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
   7602   std::string temp_file_content("Unreadable file.");
   7603   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
   7604                                    temp_file_content.length()));
   7605   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
   7606 
   7607   ScopedVector<UploadElementReader> element_readers;
   7608   element_readers.push_back(
   7609       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   7610                                   temp_file,
   7611                                   0,
   7612                                   kuint64max,
   7613                                   base::Time()));
   7614   UploadDataStream upload_data_stream(&element_readers, 0);
   7615 
   7616   HttpRequestInfo request;
   7617   request.method = "POST";
   7618   request.url = GURL("http://www.google.com/upload");
   7619   request.upload_data_stream = &upload_data_stream;
   7620   request.load_flags = 0;
   7621 
   7622   // If we try to upload an unreadable file, the network stack should report
   7623   // the file size as zero and upload zero bytes for that file.
   7624   scoped_ptr<HttpTransaction> trans(
   7625       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7626                                  CreateSession(&session_deps_)));
   7627 
   7628   MockRead data_reads[] = {
   7629     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   7630     MockRead(SYNCHRONOUS, OK),
   7631   };
   7632   MockWrite data_writes[] = {
   7633     MockWrite("POST /upload HTTP/1.1\r\n"
   7634               "Host: www.google.com\r\n"
   7635               "Connection: keep-alive\r\n"
   7636               "Content-Length: 0\r\n\r\n"),
   7637     MockWrite(SYNCHRONOUS, OK),
   7638   };
   7639   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   7640                                 arraysize(data_writes));
   7641   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7642 
   7643   TestCompletionCallback callback;
   7644 
   7645   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7646   EXPECT_EQ(ERR_IO_PENDING, rv);
   7647 
   7648   rv = callback.WaitForResult();
   7649   EXPECT_EQ(OK, rv);
   7650 
   7651   const HttpResponseInfo* response = trans->GetResponseInfo();
   7652   ASSERT_TRUE(response != NULL);
   7653   EXPECT_TRUE(response->headers.get() != NULL);
   7654   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7655 
   7656   base::DeleteFile(temp_file, false);
   7657 }
   7658 
   7659 TEST_P(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
   7660   base::FilePath temp_file;
   7661   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
   7662   std::string temp_file_contents("Unreadable file.");
   7663   std::string unreadable_contents(temp_file_contents.length(), '\0');
   7664   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
   7665                                    temp_file_contents.length()));
   7666 
   7667   ScopedVector<UploadElementReader> element_readers;
   7668   element_readers.push_back(
   7669       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   7670                                   temp_file,
   7671                                   0,
   7672                                   kuint64max,
   7673                                   base::Time()));
   7674   UploadDataStream upload_data_stream(&element_readers, 0);
   7675 
   7676   HttpRequestInfo request;
   7677   request.method = "POST";
   7678   request.url = GURL("http://www.google.com/upload");
   7679   request.upload_data_stream = &upload_data_stream;
   7680   request.load_flags = 0;
   7681 
   7682   scoped_ptr<HttpTransaction> trans(
   7683       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7684                                  CreateSession(&session_deps_)));
   7685 
   7686   MockRead data_reads[] = {
   7687     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   7688     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   7689     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   7690 
   7691     MockRead("HTTP/1.1 200 OK\r\n"),
   7692     MockRead("Content-Length: 0\r\n\r\n"),
   7693     MockRead(SYNCHRONOUS, OK),
   7694   };
   7695   MockWrite data_writes[] = {
   7696     MockWrite("POST /upload HTTP/1.1\r\n"
   7697               "Host: www.google.com\r\n"
   7698               "Connection: keep-alive\r\n"
   7699               "Content-Length: 16\r\n\r\n"),
   7700     MockWrite(SYNCHRONOUS, temp_file_contents.c_str()),
   7701 
   7702     MockWrite("POST /upload HTTP/1.1\r\n"
   7703               "Host: www.google.com\r\n"
   7704               "Connection: keep-alive\r\n"
   7705               "Content-Length: 0\r\n"
   7706               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   7707     MockWrite(SYNCHRONOUS, unreadable_contents.c_str(),
   7708               temp_file_contents.length()),
   7709     MockWrite(SYNCHRONOUS, OK),
   7710   };
   7711   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   7712                                 arraysize(data_writes));
   7713   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7714 
   7715   TestCompletionCallback callback1;
   7716 
   7717   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7718   EXPECT_EQ(ERR_IO_PENDING, rv);
   7719 
   7720   rv = callback1.WaitForResult();
   7721   EXPECT_EQ(OK, rv);
   7722 
   7723   const HttpResponseInfo* response = trans->GetResponseInfo();
   7724   ASSERT_TRUE(response != NULL);
   7725   ASSERT_TRUE(response->headers.get() != NULL);
   7726   EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
   7727   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   7728 
   7729   // Now make the file unreadable and try again.
   7730   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
   7731 
   7732   TestCompletionCallback callback2;
   7733 
   7734   rv = trans->RestartWithAuth(
   7735       AuthCredentials(kFoo, kBar), callback2.callback());
   7736   EXPECT_EQ(ERR_IO_PENDING, rv);
   7737 
   7738   rv = callback2.WaitForResult();
   7739   EXPECT_EQ(OK, rv);
   7740 
   7741   response = trans->GetResponseInfo();
   7742   ASSERT_TRUE(response != NULL);
   7743   EXPECT_TRUE(response->headers.get() != NULL);
   7744   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7745   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7746 
   7747   base::DeleteFile(temp_file, false);
   7748 }
   7749 
   7750 // Tests that changes to Auth realms are treated like auth rejections.
   7751 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
   7752 
   7753   HttpRequestInfo request;
   7754   request.method = "GET";
   7755   request.url = GURL("http://www.google.com/");
   7756   request.load_flags = 0;
   7757 
   7758   // First transaction will request a resource and receive a Basic challenge
   7759   // with realm="first_realm".
   7760   MockWrite data_writes1[] = {
   7761     MockWrite("GET / HTTP/1.1\r\n"
   7762               "Host: www.google.com\r\n"
   7763               "Connection: keep-alive\r\n"
   7764               "\r\n"),
   7765   };
   7766   MockRead data_reads1[] = {
   7767     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7768              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   7769              "\r\n"),
   7770   };
   7771 
   7772   // After calling trans->RestartWithAuth(), provide an Authentication header
   7773   // for first_realm. The server will reject and provide a challenge with
   7774   // second_realm.
   7775   MockWrite data_writes2[] = {
   7776     MockWrite("GET / HTTP/1.1\r\n"
   7777               "Host: www.google.com\r\n"
   7778               "Connection: keep-alive\r\n"
   7779               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
   7780               "\r\n"),
   7781   };
   7782   MockRead data_reads2[] = {
   7783     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7784              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
   7785              "\r\n"),
   7786   };
   7787 
   7788   // This again fails, and goes back to first_realm. Make sure that the
   7789   // entry is removed from cache.
   7790   MockWrite data_writes3[] = {
   7791     MockWrite("GET / HTTP/1.1\r\n"
   7792               "Host: www.google.com\r\n"
   7793               "Connection: keep-alive\r\n"
   7794               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
   7795               "\r\n"),
   7796   };
   7797   MockRead data_reads3[] = {
   7798     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7799              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   7800              "\r\n"),
   7801   };
   7802 
   7803   // Try one last time (with the correct password) and get the resource.
   7804   MockWrite data_writes4[] = {
   7805     MockWrite("GET / HTTP/1.1\r\n"
   7806               "Host: www.google.com\r\n"
   7807               "Connection: keep-alive\r\n"
   7808               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
   7809               "\r\n"),
   7810   };
   7811   MockRead data_reads4[] = {
   7812     MockRead("HTTP/1.1 200 OK\r\n"
   7813              "Content-Type: text/html; charset=iso-8859-1\r\n"
   7814              "Content-Length: 5\r\n"
   7815              "\r\n"
   7816              "hello"),
   7817   };
   7818 
   7819   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   7820                                  data_writes1, arraysize(data_writes1));
   7821   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   7822                                  data_writes2, arraysize(data_writes2));
   7823   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   7824                                  data_writes3, arraysize(data_writes3));
   7825   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
   7826                                  data_writes4, arraysize(data_writes4));
   7827   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   7828   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   7829   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   7830   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   7831 
   7832   TestCompletionCallback callback1;
   7833 
   7834   scoped_ptr<HttpTransaction> trans(
   7835       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   7836                                  CreateSession(&session_deps_)));
   7837 
   7838   // Issue the first request with Authorize headers. There should be a
   7839   // password prompt for first_realm waiting to be filled in after the
   7840   // transaction completes.
   7841   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7842   EXPECT_EQ(ERR_IO_PENDING, rv);
   7843   rv = callback1.WaitForResult();
   7844   EXPECT_EQ(OK, rv);
   7845   const HttpResponseInfo* response = trans->GetResponseInfo();
   7846   ASSERT_TRUE(response != NULL);
   7847   const AuthChallengeInfo* challenge = response->auth_challenge.get();
   7848   ASSERT_FALSE(challenge == NULL);
   7849   EXPECT_FALSE(challenge->is_proxy);
   7850   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7851   EXPECT_EQ("first_realm", challenge->realm);
   7852   EXPECT_EQ("basic", challenge->scheme);
   7853 
   7854   // Issue the second request with an incorrect password. There should be a
   7855   // password prompt for second_realm waiting to be filled in after the
   7856   // transaction completes.
   7857   TestCompletionCallback callback2;
   7858   rv = trans->RestartWithAuth(
   7859       AuthCredentials(kFirst, kBaz), callback2.callback());
   7860   EXPECT_EQ(ERR_IO_PENDING, rv);
   7861   rv = callback2.WaitForResult();
   7862   EXPECT_EQ(OK, rv);
   7863   response = trans->GetResponseInfo();
   7864   ASSERT_TRUE(response != NULL);
   7865   challenge = response->auth_challenge.get();
   7866   ASSERT_FALSE(challenge == NULL);
   7867   EXPECT_FALSE(challenge->is_proxy);
   7868   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7869   EXPECT_EQ("second_realm", challenge->realm);
   7870   EXPECT_EQ("basic", challenge->scheme);
   7871 
   7872   // Issue the third request with another incorrect password. There should be
   7873   // a password prompt for first_realm waiting to be filled in. If the password
   7874   // prompt is not present, it indicates that the HttpAuthCacheEntry for
   7875   // first_realm was not correctly removed.
   7876   TestCompletionCallback callback3;
   7877   rv = trans->RestartWithAuth(
   7878       AuthCredentials(kSecond, kFou), callback3.callback());
   7879   EXPECT_EQ(ERR_IO_PENDING, rv);
   7880   rv = callback3.WaitForResult();
   7881   EXPECT_EQ(OK, rv);
   7882   response = trans->GetResponseInfo();
   7883   ASSERT_TRUE(response != NULL);
   7884   challenge = response->auth_challenge.get();
   7885   ASSERT_FALSE(challenge == NULL);
   7886   EXPECT_FALSE(challenge->is_proxy);
   7887   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7888   EXPECT_EQ("first_realm", challenge->realm);
   7889   EXPECT_EQ("basic", challenge->scheme);
   7890 
   7891   // Issue the fourth request with the correct password and username.
   7892   TestCompletionCallback callback4;
   7893   rv = trans->RestartWithAuth(
   7894       AuthCredentials(kFirst, kBar), callback4.callback());
   7895   EXPECT_EQ(ERR_IO_PENDING, rv);
   7896   rv = callback4.WaitForResult();
   7897   EXPECT_EQ(OK, rv);
   7898   response = trans->GetResponseInfo();
   7899   ASSERT_TRUE(response != NULL);
   7900   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7901 }
   7902 
   7903 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
   7904   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   7905   HttpStreamFactory::set_use_alternate_protocols(true);
   7906 
   7907   std::string alternate_protocol_http_header =
   7908       GetAlternateProtocolHttpHeader();
   7909 
   7910   MockRead data_reads[] = {
   7911     MockRead("HTTP/1.1 200 OK\r\n"),
   7912     MockRead(alternate_protocol_http_header.c_str()),
   7913     MockRead("hello world"),
   7914     MockRead(SYNCHRONOUS, OK),
   7915   };
   7916 
   7917   HttpRequestInfo request;
   7918   request.method = "GET";
   7919   request.url = GURL("http://www.google.com/");
   7920   request.load_flags = 0;
   7921 
   7922   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7923 
   7924   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7925 
   7926   TestCompletionCallback callback;
   7927 
   7928   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7929   scoped_ptr<HttpTransaction> trans(
   7930       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7931 
   7932   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7933   EXPECT_EQ(ERR_IO_PENDING, rv);
   7934 
   7935   HostPortPair http_host_port_pair("www.google.com", 80);
   7936   const HttpServerProperties& http_server_properties =
   7937       *session->http_server_properties();
   7938   EXPECT_FALSE(
   7939       http_server_properties.HasAlternateProtocol(http_host_port_pair));
   7940 
   7941   EXPECT_EQ(OK, callback.WaitForResult());
   7942 
   7943   const HttpResponseInfo* response = trans->GetResponseInfo();
   7944   ASSERT_TRUE(response != NULL);
   7945   ASSERT_TRUE(response->headers.get() != NULL);
   7946   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7947   EXPECT_FALSE(response->was_fetched_via_spdy);
   7948   EXPECT_FALSE(response->was_npn_negotiated);
   7949 
   7950   std::string response_data;
   7951   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7952   EXPECT_EQ("hello world", response_data);
   7953 
   7954   ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair));
   7955   const PortAlternateProtocolPair alternate =
   7956       http_server_properties.GetAlternateProtocol(http_host_port_pair);
   7957   PortAlternateProtocolPair expected_alternate;
   7958   expected_alternate.port = 443;
   7959   expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
   7960   EXPECT_TRUE(expected_alternate.Equals(alternate));
   7961 }
   7962 
   7963 TEST_P(HttpNetworkTransactionTest,
   7964        MarkBrokenAlternateProtocolAndFallback) {
   7965   HttpStreamFactory::set_use_alternate_protocols(true);
   7966 
   7967   HttpRequestInfo request;
   7968   request.method = "GET";
   7969   request.url = GURL("http://www.google.com/");
   7970   request.load_flags = 0;
   7971 
   7972   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   7973   StaticSocketDataProvider first_data;
   7974   first_data.set_connect_data(mock_connect);
   7975   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   7976 
   7977   MockRead data_reads[] = {
   7978     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   7979     MockRead("hello world"),
   7980     MockRead(ASYNC, OK),
   7981   };
   7982   StaticSocketDataProvider second_data(
   7983       data_reads, arraysize(data_reads), NULL, 0);
   7984   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   7985 
   7986   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7987 
   7988   base::WeakPtr<HttpServerProperties> http_server_properties =
   7989       session->http_server_properties();
   7990   // Port must be < 1024, or the header will be ignored (since initial port was
   7991   // port 80 (another restricted port).
   7992   http_server_properties->SetAlternateProtocol(
   7993       HostPortPair::FromURL(request.url),
   7994       666 /* port is ignored by MockConnect anyway */,
   7995       AlternateProtocolFromNextProto(GetParam()));
   7996 
   7997   scoped_ptr<HttpTransaction> trans(
   7998       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7999   TestCompletionCallback callback;
   8000 
   8001   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8002   EXPECT_EQ(ERR_IO_PENDING, rv);
   8003   EXPECT_EQ(OK, callback.WaitForResult());
   8004 
   8005   const HttpResponseInfo* response = trans->GetResponseInfo();
   8006   ASSERT_TRUE(response != NULL);
   8007   ASSERT_TRUE(response->headers.get() != NULL);
   8008   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8009 
   8010   std::string response_data;
   8011   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8012   EXPECT_EQ("hello world", response_data);
   8013 
   8014   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
   8015       HostPortPair::FromURL(request.url)));
   8016   const PortAlternateProtocolPair alternate =
   8017       http_server_properties->GetAlternateProtocol(
   8018           HostPortPair::FromURL(request.url));
   8019   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
   8020 }
   8021 
   8022 TEST_P(HttpNetworkTransactionTest,
   8023        AlternateProtocolPortRestrictedBlocked) {
   8024   // Ensure that we're not allowed to redirect traffic via an alternate
   8025   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8026   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8027   // other cases.
   8028   HttpStreamFactory::set_use_alternate_protocols(true);
   8029 
   8030   HttpRequestInfo restricted_port_request;
   8031   restricted_port_request.method = "GET";
   8032   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8033   restricted_port_request.load_flags = 0;
   8034 
   8035   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8036   StaticSocketDataProvider first_data;
   8037   first_data.set_connect_data(mock_connect);
   8038   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8039 
   8040   MockRead data_reads[] = {
   8041     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8042     MockRead("hello world"),
   8043     MockRead(ASYNC, OK),
   8044   };
   8045   StaticSocketDataProvider second_data(
   8046       data_reads, arraysize(data_reads), NULL, 0);
   8047   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8048 
   8049   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8050 
   8051   base::WeakPtr<HttpServerProperties> http_server_properties =
   8052       session->http_server_properties();
   8053   const int kUnrestrictedAlternatePort = 1024;
   8054   http_server_properties->SetAlternateProtocol(
   8055       HostPortPair::FromURL(restricted_port_request.url),
   8056       kUnrestrictedAlternatePort,
   8057       AlternateProtocolFromNextProto(GetParam()));
   8058 
   8059   scoped_ptr<HttpTransaction> trans(
   8060       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8061   TestCompletionCallback callback;
   8062 
   8063   int rv = trans->Start(
   8064       &restricted_port_request,
   8065       callback.callback(), BoundNetLog());
   8066   EXPECT_EQ(ERR_IO_PENDING, rv);
   8067   // Invalid change to unrestricted port should fail.
   8068   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
   8069 }
   8070 
   8071 TEST_P(HttpNetworkTransactionTest,
   8072        AlternateProtocolPortRestrictedPermitted) {
   8073   // Ensure that we're allowed to redirect traffic via an alternate
   8074   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8075   // on a restricted port (port < 1024) if we set
   8076   // enable_user_alternate_protocol_ports.
   8077 
   8078   HttpStreamFactory::set_use_alternate_protocols(true);
   8079   session_deps_.enable_user_alternate_protocol_ports = true;
   8080 
   8081   HttpRequestInfo restricted_port_request;
   8082   restricted_port_request.method = "GET";
   8083   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8084   restricted_port_request.load_flags = 0;
   8085 
   8086   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8087   StaticSocketDataProvider first_data;
   8088   first_data.set_connect_data(mock_connect);
   8089   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8090 
   8091   MockRead data_reads[] = {
   8092     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8093     MockRead("hello world"),
   8094     MockRead(ASYNC, OK),
   8095   };
   8096   StaticSocketDataProvider second_data(
   8097       data_reads, arraysize(data_reads), NULL, 0);
   8098   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8099 
   8100   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8101 
   8102   base::WeakPtr<HttpServerProperties> http_server_properties =
   8103       session->http_server_properties();
   8104   const int kUnrestrictedAlternatePort = 1024;
   8105   http_server_properties->SetAlternateProtocol(
   8106       HostPortPair::FromURL(restricted_port_request.url),
   8107       kUnrestrictedAlternatePort,
   8108       AlternateProtocolFromNextProto(GetParam()));
   8109 
   8110   scoped_ptr<HttpTransaction> trans(
   8111       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8112   TestCompletionCallback callback;
   8113 
   8114   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
   8115       &restricted_port_request,
   8116       callback.callback(), BoundNetLog()));
   8117   // Change to unrestricted port should succeed.
   8118   EXPECT_EQ(OK, callback.WaitForResult());
   8119 }
   8120 
   8121 TEST_P(HttpNetworkTransactionTest,
   8122        AlternateProtocolPortRestrictedAllowed) {
   8123   // Ensure that we're not allowed to redirect traffic via an alternate
   8124   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8125   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8126   // other cases.
   8127   HttpStreamFactory::set_use_alternate_protocols(true);
   8128 
   8129   HttpRequestInfo restricted_port_request;
   8130   restricted_port_request.method = "GET";
   8131   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8132   restricted_port_request.load_flags = 0;
   8133 
   8134   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8135   StaticSocketDataProvider first_data;
   8136   first_data.set_connect_data(mock_connect);
   8137   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8138 
   8139   MockRead data_reads[] = {
   8140     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8141     MockRead("hello world"),
   8142     MockRead(ASYNC, OK),
   8143   };
   8144   StaticSocketDataProvider second_data(
   8145       data_reads, arraysize(data_reads), NULL, 0);
   8146   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8147 
   8148   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8149 
   8150   base::WeakPtr<HttpServerProperties> http_server_properties =
   8151       session->http_server_properties();
   8152   const int kRestrictedAlternatePort = 80;
   8153   http_server_properties->SetAlternateProtocol(
   8154       HostPortPair::FromURL(restricted_port_request.url),
   8155       kRestrictedAlternatePort,
   8156       AlternateProtocolFromNextProto(GetParam()));
   8157 
   8158   scoped_ptr<HttpTransaction> trans(
   8159       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8160   TestCompletionCallback callback;
   8161 
   8162   int rv = trans->Start(
   8163       &restricted_port_request,
   8164       callback.callback(), BoundNetLog());
   8165   EXPECT_EQ(ERR_IO_PENDING, rv);
   8166   // Valid change to restricted port should pass.
   8167   EXPECT_EQ(OK, callback.WaitForResult());
   8168 }
   8169 
   8170 TEST_P(HttpNetworkTransactionTest,
   8171        AlternateProtocolPortUnrestrictedAllowed1) {
   8172   // Ensure that we're not allowed to redirect traffic via an alternate
   8173   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8174   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8175   // other cases.
   8176   HttpStreamFactory::set_use_alternate_protocols(true);
   8177 
   8178   HttpRequestInfo unrestricted_port_request;
   8179   unrestricted_port_request.method = "GET";
   8180   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8181   unrestricted_port_request.load_flags = 0;
   8182 
   8183   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8184   StaticSocketDataProvider first_data;
   8185   first_data.set_connect_data(mock_connect);
   8186   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8187 
   8188   MockRead data_reads[] = {
   8189     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8190     MockRead("hello world"),
   8191     MockRead(ASYNC, OK),
   8192   };
   8193   StaticSocketDataProvider second_data(
   8194       data_reads, arraysize(data_reads), NULL, 0);
   8195   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8196 
   8197   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8198 
   8199   base::WeakPtr<HttpServerProperties> http_server_properties =
   8200       session->http_server_properties();
   8201   const int kRestrictedAlternatePort = 80;
   8202   http_server_properties->SetAlternateProtocol(
   8203       HostPortPair::FromURL(unrestricted_port_request.url),
   8204       kRestrictedAlternatePort,
   8205       AlternateProtocolFromNextProto(GetParam()));
   8206 
   8207   scoped_ptr<HttpTransaction> trans(
   8208       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8209   TestCompletionCallback callback;
   8210 
   8211   int rv = trans->Start(
   8212       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8213   EXPECT_EQ(ERR_IO_PENDING, rv);
   8214   // Valid change to restricted port should pass.
   8215   EXPECT_EQ(OK, callback.WaitForResult());
   8216 }
   8217 
   8218 TEST_P(HttpNetworkTransactionTest,
   8219        AlternateProtocolPortUnrestrictedAllowed2) {
   8220   // Ensure that we're not allowed to redirect traffic via an alternate
   8221   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8222   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8223   // other cases.
   8224   HttpStreamFactory::set_use_alternate_protocols(true);
   8225 
   8226   HttpRequestInfo unrestricted_port_request;
   8227   unrestricted_port_request.method = "GET";
   8228   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8229   unrestricted_port_request.load_flags = 0;
   8230 
   8231   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8232   StaticSocketDataProvider first_data;
   8233   first_data.set_connect_data(mock_connect);
   8234   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8235 
   8236   MockRead data_reads[] = {
   8237     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8238     MockRead("hello world"),
   8239     MockRead(ASYNC, OK),
   8240   };
   8241   StaticSocketDataProvider second_data(
   8242       data_reads, arraysize(data_reads), NULL, 0);
   8243   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8244 
   8245   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8246 
   8247   base::WeakPtr<HttpServerProperties> http_server_properties =
   8248       session->http_server_properties();
   8249   const int kUnrestrictedAlternatePort = 1024;
   8250   http_server_properties->SetAlternateProtocol(
   8251       HostPortPair::FromURL(unrestricted_port_request.url),
   8252       kUnrestrictedAlternatePort,
   8253       AlternateProtocolFromNextProto(GetParam()));
   8254 
   8255   scoped_ptr<HttpTransaction> trans(
   8256       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8257   TestCompletionCallback callback;
   8258 
   8259   int rv = trans->Start(
   8260       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8261   EXPECT_EQ(ERR_IO_PENDING, rv);
   8262   // Valid change to an unrestricted port should pass.
   8263   EXPECT_EQ(OK, callback.WaitForResult());
   8264 }
   8265 
   8266 TEST_P(HttpNetworkTransactionTest,
   8267        AlternateProtocolUnsafeBlocked) {
   8268   // Ensure that we're not allowed to redirect traffic via an alternate
   8269   // protocol to an unsafe port, and that we resume the second
   8270   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
   8271   HttpStreamFactory::set_use_alternate_protocols(true);
   8272 
   8273   HttpRequestInfo request;
   8274   request.method = "GET";
   8275   request.url = GURL("http://www.google.com/");
   8276   request.load_flags = 0;
   8277 
   8278   // The alternate protocol request will error out before we attempt to connect,
   8279   // so only the standard HTTP request will try to connect.
   8280   MockRead data_reads[] = {
   8281     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8282     MockRead("hello world"),
   8283     MockRead(ASYNC, OK),
   8284   };
   8285   StaticSocketDataProvider data(
   8286       data_reads, arraysize(data_reads), NULL, 0);
   8287   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8288 
   8289   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8290 
   8291   base::WeakPtr<HttpServerProperties> http_server_properties =
   8292       session->http_server_properties();
   8293   const int kUnsafePort = 7;
   8294   http_server_properties->SetAlternateProtocol(
   8295       HostPortPair::FromURL(request.url),
   8296       kUnsafePort,
   8297       AlternateProtocolFromNextProto(GetParam()));
   8298 
   8299   scoped_ptr<HttpTransaction> trans(
   8300       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8301   TestCompletionCallback callback;
   8302 
   8303   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8304   EXPECT_EQ(ERR_IO_PENDING, rv);
   8305   // The HTTP request should succeed.
   8306   EXPECT_EQ(OK, callback.WaitForResult());
   8307 
   8308   // Disable alternate protocol before the asserts.
   8309   HttpStreamFactory::set_use_alternate_protocols(false);
   8310 
   8311   const HttpResponseInfo* response = trans->GetResponseInfo();
   8312   ASSERT_TRUE(response != NULL);
   8313   ASSERT_TRUE(response->headers.get() != NULL);
   8314   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8315 
   8316   std::string response_data;
   8317   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8318   EXPECT_EQ("hello world", response_data);
   8319 }
   8320 
   8321 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
   8322   HttpStreamFactory::set_use_alternate_protocols(true);
   8323   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8324 
   8325   HttpRequestInfo request;
   8326   request.method = "GET";
   8327   request.url = GURL("http://www.google.com/");
   8328   request.load_flags = 0;
   8329 
   8330   std::string alternate_protocol_http_header =
   8331       GetAlternateProtocolHttpHeader();
   8332 
   8333   MockRead data_reads[] = {
   8334     MockRead("HTTP/1.1 200 OK\r\n"),
   8335     MockRead(alternate_protocol_http_header.c_str()),
   8336     MockRead("hello world"),
   8337     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8338     MockRead(ASYNC, OK)
   8339   };
   8340 
   8341   StaticSocketDataProvider first_transaction(
   8342       data_reads, arraysize(data_reads), NULL, 0);
   8343   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8344 
   8345   SSLSocketDataProvider ssl(ASYNC, OK);
   8346   ssl.SetNextProto(GetParam());
   8347   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8348 
   8349   scoped_ptr<SpdyFrame> req(
   8350       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8351   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8352 
   8353   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8354   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8355   MockRead spdy_reads[] = {
   8356     CreateMockRead(*resp),
   8357     CreateMockRead(*data),
   8358     MockRead(ASYNC, 0, 0),
   8359   };
   8360 
   8361   DelayedSocketData spdy_data(
   8362       1,  // wait for one write to finish before reading.
   8363       spdy_reads, arraysize(spdy_reads),
   8364       spdy_writes, arraysize(spdy_writes));
   8365   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8366 
   8367   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8368   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8369       NULL, 0, NULL, 0);
   8370   hanging_non_alternate_protocol_socket.set_connect_data(
   8371       never_finishing_connect);
   8372   session_deps_.socket_factory->AddSocketDataProvider(
   8373       &hanging_non_alternate_protocol_socket);
   8374 
   8375   TestCompletionCallback callback;
   8376 
   8377   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8378   scoped_ptr<HttpTransaction> trans(
   8379       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8380 
   8381   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8382   EXPECT_EQ(ERR_IO_PENDING, rv);
   8383   EXPECT_EQ(OK, callback.WaitForResult());
   8384 
   8385   const HttpResponseInfo* response = trans->GetResponseInfo();
   8386   ASSERT_TRUE(response != NULL);
   8387   ASSERT_TRUE(response->headers.get() != NULL);
   8388   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8389 
   8390   std::string response_data;
   8391   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8392   EXPECT_EQ("hello world", response_data);
   8393 
   8394   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8395 
   8396   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8397   EXPECT_EQ(ERR_IO_PENDING, rv);
   8398   EXPECT_EQ(OK, callback.WaitForResult());
   8399 
   8400   response = trans->GetResponseInfo();
   8401   ASSERT_TRUE(response != NULL);
   8402   ASSERT_TRUE(response->headers.get() != NULL);
   8403   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8404   EXPECT_TRUE(response->was_fetched_via_spdy);
   8405   EXPECT_TRUE(response->was_npn_negotiated);
   8406 
   8407   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8408   EXPECT_EQ("hello!", response_data);
   8409 }
   8410 
   8411 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
   8412   HttpStreamFactory::set_use_alternate_protocols(true);
   8413   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8414 
   8415   HttpRequestInfo request;
   8416   request.method = "GET";
   8417   request.url = GURL("http://www.google.com/");
   8418   request.load_flags = 0;
   8419 
   8420   std::string alternate_protocol_http_header =
   8421       GetAlternateProtocolHttpHeader();
   8422 
   8423   MockRead data_reads[] = {
   8424     MockRead("HTTP/1.1 200 OK\r\n"),
   8425     MockRead(alternate_protocol_http_header.c_str()),
   8426     MockRead("hello world"),
   8427     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8428     MockRead(ASYNC, OK),
   8429   };
   8430 
   8431   StaticSocketDataProvider first_transaction(
   8432       data_reads, arraysize(data_reads), NULL, 0);
   8433   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
   8434   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8435 
   8436   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8437   StaticSocketDataProvider hanging_socket(
   8438       NULL, 0, NULL, 0);
   8439   hanging_socket.set_connect_data(never_finishing_connect);
   8440   // Socket 2 and 3 are the hanging Alternate-Protocol and
   8441   // non-Alternate-Protocol jobs from the 2nd transaction.
   8442   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8443   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8444 
   8445   SSLSocketDataProvider ssl(ASYNC, OK);
   8446   ssl.SetNextProto(GetParam());
   8447   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8448 
   8449   scoped_ptr<SpdyFrame> req1(
   8450       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8451   scoped_ptr<SpdyFrame> req2(
   8452       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   8453   MockWrite spdy_writes[] = {
   8454     CreateMockWrite(*req1),
   8455     CreateMockWrite(*req2),
   8456   };
   8457   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8458   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8459   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   8460   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   8461   MockRead spdy_reads[] = {
   8462     CreateMockRead(*resp1),
   8463     CreateMockRead(*data1),
   8464     CreateMockRead(*resp2),
   8465     CreateMockRead(*data2),
   8466     MockRead(ASYNC, 0, 0),
   8467   };
   8468 
   8469   DelayedSocketData spdy_data(
   8470       2,  // wait for writes to finish before reading.
   8471       spdy_reads, arraysize(spdy_reads),
   8472       spdy_writes, arraysize(spdy_writes));
   8473   // Socket 4 is the successful Alternate-Protocol for transaction 3.
   8474   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8475 
   8476   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
   8477   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8478 
   8479   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8480   TestCompletionCallback callback1;
   8481   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   8482 
   8483   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
   8484   EXPECT_EQ(ERR_IO_PENDING, rv);
   8485   EXPECT_EQ(OK, callback1.WaitForResult());
   8486 
   8487   const HttpResponseInfo* response = trans1.GetResponseInfo();
   8488   ASSERT_TRUE(response != NULL);
   8489   ASSERT_TRUE(response->headers.get() != NULL);
   8490   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8491 
   8492   std::string response_data;
   8493   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   8494   EXPECT_EQ("hello world", response_data);
   8495 
   8496   TestCompletionCallback callback2;
   8497   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   8498   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
   8499   EXPECT_EQ(ERR_IO_PENDING, rv);
   8500 
   8501   TestCompletionCallback callback3;
   8502   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
   8503   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
   8504   EXPECT_EQ(ERR_IO_PENDING, rv);
   8505 
   8506   EXPECT_EQ(OK, callback2.WaitForResult());
   8507   EXPECT_EQ(OK, callback3.WaitForResult());
   8508 
   8509   response = trans2.GetResponseInfo();
   8510   ASSERT_TRUE(response != NULL);
   8511   ASSERT_TRUE(response->headers.get() != NULL);
   8512   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8513   EXPECT_TRUE(response->was_fetched_via_spdy);
   8514   EXPECT_TRUE(response->was_npn_negotiated);
   8515   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   8516   EXPECT_EQ("hello!", response_data);
   8517 
   8518   response = trans3.GetResponseInfo();
   8519   ASSERT_TRUE(response != NULL);
   8520   ASSERT_TRUE(response->headers.get() != NULL);
   8521   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8522   EXPECT_TRUE(response->was_fetched_via_spdy);
   8523   EXPECT_TRUE(response->was_npn_negotiated);
   8524   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
   8525   EXPECT_EQ("hello!", response_data);
   8526 }
   8527 
   8528 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
   8529   HttpStreamFactory::set_use_alternate_protocols(true);
   8530   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8531 
   8532   HttpRequestInfo request;
   8533   request.method = "GET";
   8534   request.url = GURL("http://www.google.com/");
   8535   request.load_flags = 0;
   8536 
   8537   std::string alternate_protocol_http_header =
   8538       GetAlternateProtocolHttpHeader();
   8539 
   8540   MockRead data_reads[] = {
   8541     MockRead("HTTP/1.1 200 OK\r\n"),
   8542     MockRead(alternate_protocol_http_header.c_str()),
   8543     MockRead("hello world"),
   8544     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8545     MockRead(ASYNC, OK),
   8546   };
   8547 
   8548   StaticSocketDataProvider first_transaction(
   8549       data_reads, arraysize(data_reads), NULL, 0);
   8550   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8551 
   8552   SSLSocketDataProvider ssl(ASYNC, OK);
   8553   ssl.SetNextProto(GetParam());
   8554   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8555 
   8556   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8557   StaticSocketDataProvider hanging_alternate_protocol_socket(
   8558       NULL, 0, NULL, 0);
   8559   hanging_alternate_protocol_socket.set_connect_data(
   8560       never_finishing_connect);
   8561   session_deps_.socket_factory->AddSocketDataProvider(
   8562       &hanging_alternate_protocol_socket);
   8563 
   8564   // 2nd request is just a copy of the first one, over HTTP again.
   8565   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8566 
   8567   TestCompletionCallback callback;
   8568 
   8569   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8570   scoped_ptr<HttpTransaction> trans(
   8571       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8572 
   8573   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8574   EXPECT_EQ(ERR_IO_PENDING, rv);
   8575   EXPECT_EQ(OK, callback.WaitForResult());
   8576 
   8577   const HttpResponseInfo* response = trans->GetResponseInfo();
   8578   ASSERT_TRUE(response != NULL);
   8579   ASSERT_TRUE(response->headers.get() != NULL);
   8580   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8581 
   8582   std::string response_data;
   8583   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8584   EXPECT_EQ("hello world", response_data);
   8585 
   8586   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8587 
   8588   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8589   EXPECT_EQ(ERR_IO_PENDING, rv);
   8590   EXPECT_EQ(OK, callback.WaitForResult());
   8591 
   8592   response = trans->GetResponseInfo();
   8593   ASSERT_TRUE(response != NULL);
   8594   ASSERT_TRUE(response->headers.get() != NULL);
   8595   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8596   EXPECT_FALSE(response->was_fetched_via_spdy);
   8597   EXPECT_FALSE(response->was_npn_negotiated);
   8598 
   8599   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8600   EXPECT_EQ("hello world", response_data);
   8601 }
   8602 
   8603 class CapturingProxyResolver : public ProxyResolver {
   8604  public:
   8605   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
   8606   virtual ~CapturingProxyResolver() {}
   8607 
   8608   virtual int GetProxyForURL(const GURL& url,
   8609                              ProxyInfo* results,
   8610                              const CompletionCallback& callback,
   8611                              RequestHandle* request,
   8612                              const BoundNetLog& net_log) OVERRIDE {
   8613     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
   8614                              HostPortPair("myproxy", 80));
   8615     results->UseProxyServer(proxy_server);
   8616     resolved_.push_back(url);
   8617     return OK;
   8618   }
   8619 
   8620   virtual void CancelRequest(RequestHandle request) OVERRIDE {
   8621     NOTREACHED();
   8622   }
   8623 
   8624   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
   8625     NOTREACHED();
   8626     return LOAD_STATE_IDLE;
   8627   }
   8628 
   8629   virtual void CancelSetPacScript() OVERRIDE {
   8630     NOTREACHED();
   8631   }
   8632 
   8633   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
   8634                            const CompletionCallback& /*callback*/) OVERRIDE {
   8635     return OK;
   8636   }
   8637 
   8638   const std::vector<GURL>& resolved() const { return resolved_; }
   8639 
   8640  private:
   8641   std::vector<GURL> resolved_;
   8642 
   8643   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
   8644 };
   8645 
   8646 TEST_P(HttpNetworkTransactionTest,
   8647        UseAlternateProtocolForTunneledNpnSpdy) {
   8648   HttpStreamFactory::set_use_alternate_protocols(true);
   8649   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8650 
   8651   ProxyConfig proxy_config;
   8652   proxy_config.set_auto_detect(true);
   8653   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
   8654 
   8655   CapturingProxyResolver* capturing_proxy_resolver =
   8656       new CapturingProxyResolver();
   8657   session_deps_.proxy_service.reset(new ProxyService(
   8658       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   8659       NULL));
   8660   CapturingNetLog net_log;
   8661   session_deps_.net_log = &net_log;
   8662 
   8663   HttpRequestInfo request;
   8664   request.method = "GET";
   8665   request.url = GURL("http://www.google.com/");
   8666   request.load_flags = 0;
   8667 
   8668   std::string alternate_protocol_http_header =
   8669       GetAlternateProtocolHttpHeader();
   8670 
   8671   MockRead data_reads[] = {
   8672     MockRead("HTTP/1.1 200 OK\r\n"),
   8673     MockRead(alternate_protocol_http_header.c_str()),
   8674     MockRead("hello world"),
   8675     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8676     MockRead(ASYNC, OK),
   8677   };
   8678 
   8679   StaticSocketDataProvider first_transaction(
   8680       data_reads, arraysize(data_reads), NULL, 0);
   8681   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8682 
   8683   SSLSocketDataProvider ssl(ASYNC, OK);
   8684   ssl.SetNextProto(GetParam());
   8685   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8686 
   8687   scoped_ptr<SpdyFrame> req(
   8688       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8689   MockWrite spdy_writes[] = {
   8690     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   8691               "Host: www.google.com\r\n"
   8692               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
   8693     CreateMockWrite(*req),                              // 3
   8694   };
   8695 
   8696   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   8697 
   8698   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8699   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8700   MockRead spdy_reads[] = {
   8701     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
   8702     CreateMockRead(*resp.get(), 4),  // 2, 4
   8703     CreateMockRead(*data.get(), 4),  // 5
   8704     MockRead(ASYNC, 0, 0, 4),  // 6
   8705   };
   8706 
   8707   OrderedSocketData spdy_data(
   8708       spdy_reads, arraysize(spdy_reads),
   8709       spdy_writes, arraysize(spdy_writes));
   8710   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8711 
   8712   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8713   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8714       NULL, 0, NULL, 0);
   8715   hanging_non_alternate_protocol_socket.set_connect_data(
   8716       never_finishing_connect);
   8717   session_deps_.socket_factory->AddSocketDataProvider(
   8718       &hanging_non_alternate_protocol_socket);
   8719 
   8720   TestCompletionCallback callback;
   8721 
   8722   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8723   scoped_ptr<HttpTransaction> trans(
   8724       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8725 
   8726   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8727   EXPECT_EQ(ERR_IO_PENDING, rv);
   8728   EXPECT_EQ(OK, callback.WaitForResult());
   8729 
   8730   const HttpResponseInfo* response = trans->GetResponseInfo();
   8731   ASSERT_TRUE(response != NULL);
   8732   ASSERT_TRUE(response->headers.get() != NULL);
   8733   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8734   EXPECT_FALSE(response->was_fetched_via_spdy);
   8735   EXPECT_FALSE(response->was_npn_negotiated);
   8736 
   8737   std::string response_data;
   8738   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8739   EXPECT_EQ("hello world", response_data);
   8740 
   8741   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8742 
   8743   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8744   EXPECT_EQ(ERR_IO_PENDING, rv);
   8745   EXPECT_EQ(OK, callback.WaitForResult());
   8746 
   8747   response = trans->GetResponseInfo();
   8748   ASSERT_TRUE(response != NULL);
   8749   ASSERT_TRUE(response->headers.get() != NULL);
   8750   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8751   EXPECT_TRUE(response->was_fetched_via_spdy);
   8752   EXPECT_TRUE(response->was_npn_negotiated);
   8753 
   8754   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8755   EXPECT_EQ("hello!", response_data);
   8756   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
   8757   EXPECT_EQ("http://www.google.com/",
   8758             capturing_proxy_resolver->resolved()[0].spec());
   8759   EXPECT_EQ("https://www.google.com/",
   8760             capturing_proxy_resolver->resolved()[1].spec());
   8761 
   8762   LoadTimingInfo load_timing_info;
   8763   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   8764   TestLoadTimingNotReusedWithPac(load_timing_info,
   8765                                  CONNECT_TIMING_HAS_SSL_TIMES);
   8766 }
   8767 
   8768 TEST_P(HttpNetworkTransactionTest,
   8769        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
   8770   HttpStreamFactory::set_use_alternate_protocols(true);
   8771   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8772 
   8773   HttpRequestInfo request;
   8774   request.method = "GET";
   8775   request.url = GURL("http://www.google.com/");
   8776   request.load_flags = 0;
   8777 
   8778   std::string alternate_protocol_http_header =
   8779       GetAlternateProtocolHttpHeader();
   8780 
   8781   MockRead data_reads[] = {
   8782     MockRead("HTTP/1.1 200 OK\r\n"),
   8783     MockRead(alternate_protocol_http_header.c_str()),
   8784     MockRead("hello world"),
   8785     MockRead(ASYNC, OK),
   8786   };
   8787 
   8788   StaticSocketDataProvider first_transaction(
   8789       data_reads, arraysize(data_reads), NULL, 0);
   8790   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8791 
   8792   SSLSocketDataProvider ssl(ASYNC, OK);
   8793   ssl.SetNextProto(GetParam());
   8794   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8795 
   8796   scoped_ptr<SpdyFrame> req(
   8797       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8798   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8799 
   8800   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8801   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8802   MockRead spdy_reads[] = {
   8803     CreateMockRead(*resp),
   8804     CreateMockRead(*data),
   8805     MockRead(ASYNC, 0, 0),
   8806   };
   8807 
   8808   DelayedSocketData spdy_data(
   8809       1,  // wait for one write to finish before reading.
   8810       spdy_reads, arraysize(spdy_reads),
   8811       spdy_writes, arraysize(spdy_writes));
   8812   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8813 
   8814   TestCompletionCallback callback;
   8815 
   8816   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8817 
   8818   scoped_ptr<HttpTransaction> trans(
   8819       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8820 
   8821   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8822   EXPECT_EQ(ERR_IO_PENDING, rv);
   8823   EXPECT_EQ(OK, callback.WaitForResult());
   8824 
   8825   const HttpResponseInfo* response = trans->GetResponseInfo();
   8826   ASSERT_TRUE(response != NULL);
   8827   ASSERT_TRUE(response->headers.get() != NULL);
   8828   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8829 
   8830   std::string response_data;
   8831   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8832   EXPECT_EQ("hello world", response_data);
   8833 
   8834   // Set up an initial SpdySession in the pool to reuse.
   8835   HostPortPair host_port_pair("www.google.com", 443);
   8836   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   8837                      kPrivacyModeDisabled);
   8838   base::WeakPtr<SpdySession> spdy_session =
   8839       CreateSecureSpdySession(session, key, BoundNetLog());
   8840 
   8841   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8842 
   8843   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8844   EXPECT_EQ(ERR_IO_PENDING, rv);
   8845   EXPECT_EQ(OK, callback.WaitForResult());
   8846 
   8847   response = trans->GetResponseInfo();
   8848   ASSERT_TRUE(response != NULL);
   8849   ASSERT_TRUE(response->headers.get() != NULL);
   8850   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8851   EXPECT_TRUE(response->was_fetched_via_spdy);
   8852   EXPECT_TRUE(response->was_npn_negotiated);
   8853 
   8854   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8855   EXPECT_EQ("hello!", response_data);
   8856 }
   8857 
   8858 // GenerateAuthToken is a mighty big test.
   8859 // It tests all permutation of GenerateAuthToken behavior:
   8860 //   - Synchronous and Asynchronous completion.
   8861 //   - OK or error on completion.
   8862 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
   8863 //   - HTTP or HTTPS backend (to include proxy tunneling).
   8864 //   - Non-authenticating and authenticating backend.
   8865 //
   8866 // In all, there are 44 reasonable permuations (for example, if there are
   8867 // problems generating an auth token for an authenticating proxy, we don't
   8868 // need to test all permutations of the backend server).
   8869 //
   8870 // The test proceeds by going over each of the configuration cases, and
   8871 // potentially running up to three rounds in each of the tests. The TestConfig
   8872 // specifies both the configuration for the test as well as the expectations
   8873 // for the results.
   8874 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
   8875   static const char kServer[] = "http://www.example.com";
   8876   static const char kSecureServer[] = "https://www.example.com";
   8877   static const char kProxy[] = "myproxy:70";
   8878   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
   8879 
   8880   enum AuthTiming {
   8881     AUTH_NONE,
   8882     AUTH_SYNC,
   8883     AUTH_ASYNC,
   8884   };
   8885 
   8886   const MockWrite kGet(
   8887       "GET / HTTP/1.1\r\n"
   8888       "Host: www.example.com\r\n"
   8889       "Connection: keep-alive\r\n\r\n");
   8890   const MockWrite kGetProxy(
   8891       "GET http://www.example.com/ HTTP/1.1\r\n"
   8892       "Host: www.example.com\r\n"
   8893       "Proxy-Connection: keep-alive\r\n\r\n");
   8894   const MockWrite kGetAuth(
   8895       "GET / HTTP/1.1\r\n"
   8896       "Host: www.example.com\r\n"
   8897       "Connection: keep-alive\r\n"
   8898       "Authorization: auth_token\r\n\r\n");
   8899   const MockWrite kGetProxyAuth(
   8900       "GET http://www.example.com/ HTTP/1.1\r\n"
   8901       "Host: www.example.com\r\n"
   8902       "Proxy-Connection: keep-alive\r\n"
   8903       "Proxy-Authorization: auth_token\r\n\r\n");
   8904   const MockWrite kGetAuthThroughProxy(
   8905       "GET http://www.example.com/ HTTP/1.1\r\n"
   8906       "Host: www.example.com\r\n"
   8907       "Proxy-Connection: keep-alive\r\n"
   8908       "Authorization: auth_token\r\n\r\n");
   8909   const MockWrite kGetAuthWithProxyAuth(
   8910       "GET http://www.example.com/ HTTP/1.1\r\n"
   8911       "Host: www.example.com\r\n"
   8912       "Proxy-Connection: keep-alive\r\n"
   8913       "Proxy-Authorization: auth_token\r\n"
   8914       "Authorization: auth_token\r\n\r\n");
   8915   const MockWrite kConnect(
   8916       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   8917       "Host: www.example.com\r\n"
   8918       "Proxy-Connection: keep-alive\r\n\r\n");
   8919   const MockWrite kConnectProxyAuth(
   8920       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   8921       "Host: www.example.com\r\n"
   8922       "Proxy-Connection: keep-alive\r\n"
   8923       "Proxy-Authorization: auth_token\r\n\r\n");
   8924 
   8925   const MockRead kSuccess(
   8926       "HTTP/1.1 200 OK\r\n"
   8927       "Content-Type: text/html; charset=iso-8859-1\r\n"
   8928       "Content-Length: 3\r\n\r\n"
   8929       "Yes");
   8930   const MockRead kFailure(
   8931       "Should not be called.");
   8932   const MockRead kServerChallenge(
   8933       "HTTP/1.1 401 Unauthorized\r\n"
   8934       "WWW-Authenticate: Mock realm=server\r\n"
   8935       "Content-Type: text/html; charset=iso-8859-1\r\n"
   8936       "Content-Length: 14\r\n\r\n"
   8937       "Unauthorized\r\n");
   8938   const MockRead kProxyChallenge(
   8939       "HTTP/1.1 407 Unauthorized\r\n"
   8940       "Proxy-Authenticate: Mock realm=proxy\r\n"
   8941       "Proxy-Connection: close\r\n"
   8942       "Content-Type: text/html; charset=iso-8859-1\r\n"
   8943       "Content-Length: 14\r\n\r\n"
   8944       "Unauthorized\r\n");
   8945   const MockRead kProxyConnected(
   8946       "HTTP/1.1 200 Connection Established\r\n\r\n");
   8947 
   8948   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
   8949   // no constructors, but the C++ compiler on Windows warns about
   8950   // unspecified data in compound literals. So, moved to using constructors,
   8951   // and TestRound's created with the default constructor should not be used.
   8952   struct TestRound {
   8953     TestRound()
   8954         : expected_rv(ERR_UNEXPECTED),
   8955           extra_write(NULL),
   8956           extra_read(NULL) {
   8957     }
   8958     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   8959               int expected_rv_arg)
   8960         : write(write_arg),
   8961           read(read_arg),
   8962           expected_rv(expected_rv_arg),
   8963           extra_write(NULL),
   8964           extra_read(NULL) {
   8965     }
   8966     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   8967               int expected_rv_arg, const MockWrite* extra_write_arg,
   8968               const MockRead* extra_read_arg)
   8969         : write(write_arg),
   8970           read(read_arg),
   8971           expected_rv(expected_rv_arg),
   8972           extra_write(extra_write_arg),
   8973           extra_read(extra_read_arg) {
   8974     }
   8975     MockWrite write;
   8976     MockRead read;
   8977     int expected_rv;
   8978     const MockWrite* extra_write;
   8979     const MockRead* extra_read;
   8980   };
   8981 
   8982   static const int kNoSSL = 500;
   8983 
   8984   struct TestConfig {
   8985     const char* proxy_url;
   8986     AuthTiming proxy_auth_timing;
   8987     int proxy_auth_rv;
   8988     const char* server_url;
   8989     AuthTiming server_auth_timing;
   8990     int server_auth_rv;
   8991     int num_auth_rounds;
   8992     int first_ssl_round;
   8993     TestRound rounds[3];
   8994   } test_configs[] = {
   8995     // Non-authenticating HTTP server with a direct connection.
   8996     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   8997       { TestRound(kGet, kSuccess, OK)}},
   8998     // Authenticating HTTP server with a direct connection.
   8999     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9000       { TestRound(kGet, kServerChallenge, OK),
   9001         TestRound(kGetAuth, kSuccess, OK)}},
   9002     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9003       { TestRound(kGet, kServerChallenge, OK),
   9004         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9005     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9006       { TestRound(kGet, kServerChallenge, OK),
   9007         TestRound(kGetAuth, kSuccess, OK)}},
   9008     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9009       { TestRound(kGet, kServerChallenge, OK),
   9010         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9011     // Non-authenticating HTTP server through a non-authenticating proxy.
   9012     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   9013       { TestRound(kGetProxy, kSuccess, OK)}},
   9014     // Authenticating HTTP server through a non-authenticating proxy.
   9015     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9016       { TestRound(kGetProxy, kServerChallenge, OK),
   9017         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9018     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9019       { TestRound(kGetProxy, kServerChallenge, OK),
   9020         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9021     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9022       { TestRound(kGetProxy, kServerChallenge, OK),
   9023         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9024     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9025       { TestRound(kGetProxy, kServerChallenge, OK),
   9026         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9027     // Non-authenticating HTTP server through an authenticating proxy.
   9028     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9029       { TestRound(kGetProxy, kProxyChallenge, OK),
   9030         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9031     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9032       { TestRound(kGetProxy, kProxyChallenge, OK),
   9033         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9034     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9035       { TestRound(kGetProxy, kProxyChallenge, OK),
   9036         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9037     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9038       { TestRound(kGetProxy, kProxyChallenge, OK),
   9039         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9040     // Authenticating HTTP server through an authenticating proxy.
   9041     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9042       { TestRound(kGetProxy, kProxyChallenge, OK),
   9043         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9044         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9045     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9046       { TestRound(kGetProxy, kProxyChallenge, OK),
   9047         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9048         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9049     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9050       { TestRound(kGetProxy, kProxyChallenge, OK),
   9051         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9052         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9053     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9054       { TestRound(kGetProxy, kProxyChallenge, OK),
   9055         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9056         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9057     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9058       { TestRound(kGetProxy, kProxyChallenge, OK),
   9059         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9060         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9061     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9062       { TestRound(kGetProxy, kProxyChallenge, OK),
   9063         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9064         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9065     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9066       { TestRound(kGetProxy, kProxyChallenge, OK),
   9067         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9068         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9069     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9070       { TestRound(kGetProxy, kProxyChallenge, OK),
   9071         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9072         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9073     // Non-authenticating HTTPS server with a direct connection.
   9074     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9075       { TestRound(kGet, kSuccess, OK)}},
   9076     // Authenticating HTTPS server with a direct connection.
   9077     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9078       { TestRound(kGet, kServerChallenge, OK),
   9079         TestRound(kGetAuth, kSuccess, OK)}},
   9080     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9081       { TestRound(kGet, kServerChallenge, OK),
   9082         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9083     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9084       { TestRound(kGet, kServerChallenge, OK),
   9085         TestRound(kGetAuth, kSuccess, OK)}},
   9086     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9087       { TestRound(kGet, kServerChallenge, OK),
   9088         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9089     // Non-authenticating HTTPS server with a non-authenticating proxy.
   9090     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9091       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
   9092     // Authenticating HTTPS server through a non-authenticating proxy.
   9093     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9094       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9095         TestRound(kGetAuth, kSuccess, OK)}},
   9096     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9097       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9098         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9099     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9100       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9101         TestRound(kGetAuth, kSuccess, OK)}},
   9102     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9103       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9104         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9105     // Non-Authenticating HTTPS server through an authenticating proxy.
   9106     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9107       { TestRound(kConnect, kProxyChallenge, OK),
   9108         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9109     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9110       { TestRound(kConnect, kProxyChallenge, OK),
   9111         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9112     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9113       { TestRound(kConnect, kProxyChallenge, OK),
   9114         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9115     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9116       { TestRound(kConnect, kProxyChallenge, OK),
   9117         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9118     // Authenticating HTTPS server through an authenticating proxy.
   9119     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9120       { TestRound(kConnect, kProxyChallenge, OK),
   9121         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9122                   &kGet, &kServerChallenge),
   9123         TestRound(kGetAuth, kSuccess, OK)}},
   9124     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9125       { TestRound(kConnect, kProxyChallenge, OK),
   9126         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9127                   &kGet, &kServerChallenge),
   9128         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9129     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9130       { TestRound(kConnect, kProxyChallenge, OK),
   9131         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9132                   &kGet, &kServerChallenge),
   9133         TestRound(kGetAuth, kSuccess, OK)}},
   9134     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9135       { TestRound(kConnect, kProxyChallenge, OK),
   9136         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9137                   &kGet, &kServerChallenge),
   9138         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9139     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9140       { TestRound(kConnect, kProxyChallenge, OK),
   9141         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9142                   &kGet, &kServerChallenge),
   9143         TestRound(kGetAuth, kSuccess, OK)}},
   9144     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9145       { TestRound(kConnect, kProxyChallenge, OK),
   9146         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9147                   &kGet, &kServerChallenge),
   9148         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9149     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9150       { TestRound(kConnect, kProxyChallenge, OK),
   9151         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9152                   &kGet, &kServerChallenge),
   9153         TestRound(kGetAuth, kSuccess, OK)}},
   9154     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9155       { TestRound(kConnect, kProxyChallenge, OK),
   9156         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9157                   &kGet, &kServerChallenge),
   9158         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9159   };
   9160 
   9161   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
   9162     HttpAuthHandlerMock::Factory* auth_factory(
   9163         new HttpAuthHandlerMock::Factory());
   9164     session_deps_.http_auth_handler_factory.reset(auth_factory);
   9165     const TestConfig& test_config = test_configs[i];
   9166 
   9167     // Set up authentication handlers as necessary.
   9168     if (test_config.proxy_auth_timing != AUTH_NONE) {
   9169       for (int n = 0; n < 2; n++) {
   9170         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9171         std::string auth_challenge = "Mock realm=proxy";
   9172         GURL origin(test_config.proxy_url);
   9173         HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9174                                                auth_challenge.end());
   9175         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
   9176                                         origin, BoundNetLog());
   9177         auth_handler->SetGenerateExpectation(
   9178             test_config.proxy_auth_timing == AUTH_ASYNC,
   9179             test_config.proxy_auth_rv);
   9180         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   9181       }
   9182     }
   9183     if (test_config.server_auth_timing != AUTH_NONE) {
   9184       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9185       std::string auth_challenge = "Mock realm=server";
   9186       GURL origin(test_config.server_url);
   9187       HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9188                                              auth_challenge.end());
   9189       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9190                                       origin, BoundNetLog());
   9191       auth_handler->SetGenerateExpectation(
   9192           test_config.server_auth_timing == AUTH_ASYNC,
   9193           test_config.server_auth_rv);
   9194       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9195     }
   9196     if (test_config.proxy_url) {
   9197       session_deps_.proxy_service.reset(
   9198           ProxyService::CreateFixed(test_config.proxy_url));
   9199     } else {
   9200       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9201     }
   9202 
   9203     HttpRequestInfo request;
   9204     request.method = "GET";
   9205     request.url = GURL(test_config.server_url);
   9206     request.load_flags = 0;
   9207 
   9208     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9209     HttpNetworkTransaction trans(
   9210         DEFAULT_PRIORITY, CreateSession(&session_deps_));
   9211 
   9212     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
   9213       const TestRound& read_write_round = test_config.rounds[round];
   9214 
   9215       // Set up expected reads and writes.
   9216       MockRead reads[2];
   9217       reads[0] = read_write_round.read;
   9218       size_t length_reads = 1;
   9219       if (read_write_round.extra_read) {
   9220         reads[1] = *read_write_round.extra_read;
   9221         length_reads = 2;
   9222       }
   9223 
   9224       MockWrite writes[2];
   9225       writes[0] = read_write_round.write;
   9226       size_t length_writes = 1;
   9227       if (read_write_round.extra_write) {
   9228         writes[1] = *read_write_round.extra_write;
   9229         length_writes = 2;
   9230       }
   9231       StaticSocketDataProvider data_provider(
   9232           reads, length_reads, writes, length_writes);
   9233       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9234 
   9235       // Add an SSL sequence if necessary.
   9236       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
   9237       if (round >= test_config.first_ssl_round)
   9238         session_deps_.socket_factory->AddSSLSocketDataProvider(
   9239             &ssl_socket_data_provider);
   9240 
   9241       // Start or restart the transaction.
   9242       TestCompletionCallback callback;
   9243       int rv;
   9244       if (round == 0) {
   9245         rv = trans.Start(&request, callback.callback(), BoundNetLog());
   9246       } else {
   9247         rv = trans.RestartWithAuth(
   9248             AuthCredentials(kFoo, kBar), callback.callback());
   9249       }
   9250       if (rv == ERR_IO_PENDING)
   9251         rv = callback.WaitForResult();
   9252 
   9253       // Compare results with expected data.
   9254       EXPECT_EQ(read_write_round.expected_rv, rv);
   9255       const HttpResponseInfo* response = trans.GetResponseInfo();
   9256       if (read_write_round.expected_rv == OK) {
   9257         ASSERT_TRUE(response != NULL);
   9258       } else {
   9259         EXPECT_TRUE(response == NULL);
   9260         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
   9261         continue;
   9262       }
   9263       if (round + 1 < test_config.num_auth_rounds) {
   9264         EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9265       } else {
   9266         EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9267       }
   9268     }
   9269   }
   9270 }
   9271 
   9272 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
   9273   // Do multi-round authentication and make sure it works correctly.
   9274   HttpAuthHandlerMock::Factory* auth_factory(
   9275       new HttpAuthHandlerMock::Factory());
   9276   session_deps_.http_auth_handler_factory.reset(auth_factory);
   9277   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9278   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
   9279   session_deps_.host_resolver->set_synchronous_mode(true);
   9280 
   9281   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9282   auth_handler->set_connection_based(true);
   9283   std::string auth_challenge = "Mock realm=server";
   9284   GURL origin("http://www.example.com");
   9285   HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9286                                          auth_challenge.end());
   9287   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9288                                   origin, BoundNetLog());
   9289   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9290 
   9291   int rv = OK;
   9292   const HttpResponseInfo* response = NULL;
   9293   HttpRequestInfo request;
   9294   request.method = "GET";
   9295   request.url = origin;
   9296   request.load_flags = 0;
   9297 
   9298   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9299 
   9300   // Use a TCP Socket Pool with only one connection per group. This is used
   9301   // to validate that the TCP socket is not released to the pool between
   9302   // each round of multi-round authentication.
   9303   HttpNetworkSessionPeer session_peer(session);
   9304   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
   9305   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
   9306       50,  // Max sockets for pool
   9307       1,   // Max sockets per group
   9308       &transport_pool_histograms,
   9309       session_deps_.host_resolver.get(),
   9310       session_deps_.socket_factory.get(),
   9311       session_deps_.net_log);
   9312   MockClientSocketPoolManager* mock_pool_manager =
   9313       new MockClientSocketPoolManager;
   9314   mock_pool_manager->SetTransportSocketPool(transport_pool);
   9315   session_peer.SetClientSocketPoolManager(mock_pool_manager);
   9316 
   9317   scoped_ptr<HttpTransaction> trans(
   9318       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9319   TestCompletionCallback callback;
   9320 
   9321   const MockWrite kGet(
   9322       "GET / HTTP/1.1\r\n"
   9323       "Host: www.example.com\r\n"
   9324       "Connection: keep-alive\r\n\r\n");
   9325   const MockWrite kGetAuth(
   9326       "GET / HTTP/1.1\r\n"
   9327       "Host: www.example.com\r\n"
   9328       "Connection: keep-alive\r\n"
   9329       "Authorization: auth_token\r\n\r\n");
   9330 
   9331   const MockRead kServerChallenge(
   9332       "HTTP/1.1 401 Unauthorized\r\n"
   9333       "WWW-Authenticate: Mock realm=server\r\n"
   9334       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9335       "Content-Length: 14\r\n\r\n"
   9336       "Unauthorized\r\n");
   9337   const MockRead kSuccess(
   9338       "HTTP/1.1 200 OK\r\n"
   9339       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9340       "Content-Length: 3\r\n\r\n"
   9341       "Yes");
   9342 
   9343   MockWrite writes[] = {
   9344     // First round
   9345     kGet,
   9346     // Second round
   9347     kGetAuth,
   9348     // Third round
   9349     kGetAuth,
   9350     // Fourth round
   9351     kGetAuth,
   9352     // Competing request
   9353     kGet,
   9354   };
   9355   MockRead reads[] = {
   9356     // First round
   9357     kServerChallenge,
   9358     // Second round
   9359     kServerChallenge,
   9360     // Third round
   9361     kServerChallenge,
   9362     // Fourth round
   9363     kSuccess,
   9364     // Competing response
   9365     kSuccess,
   9366   };
   9367   StaticSocketDataProvider data_provider(reads, arraysize(reads),
   9368                                          writes, arraysize(writes));
   9369   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9370 
   9371   const char* const kSocketGroup = "www.example.com:80";
   9372 
   9373   // First round of authentication.
   9374   auth_handler->SetGenerateExpectation(false, OK);
   9375   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9376   if (rv == ERR_IO_PENDING)
   9377     rv = callback.WaitForResult();
   9378   EXPECT_EQ(OK, rv);
   9379   response = trans->GetResponseInfo();
   9380   ASSERT_TRUE(response != NULL);
   9381   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9382   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9383 
   9384   // In between rounds, another request comes in for the same domain.
   9385   // It should not be able to grab the TCP socket that trans has already
   9386   // claimed.
   9387   scoped_ptr<HttpTransaction> trans_compete(
   9388       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9389   TestCompletionCallback callback_compete;
   9390   rv = trans_compete->Start(
   9391       &request, callback_compete.callback(), BoundNetLog());
   9392   EXPECT_EQ(ERR_IO_PENDING, rv);
   9393   // callback_compete.WaitForResult at this point would stall forever,
   9394   // since the HttpNetworkTransaction does not release the request back to
   9395   // the pool until after authentication completes.
   9396 
   9397   // Second round of authentication.
   9398   auth_handler->SetGenerateExpectation(false, OK);
   9399   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
   9400   if (rv == ERR_IO_PENDING)
   9401     rv = callback.WaitForResult();
   9402   EXPECT_EQ(OK, rv);
   9403   response = trans->GetResponseInfo();
   9404   ASSERT_TRUE(response != NULL);
   9405   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9406   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9407 
   9408   // Third round of authentication.
   9409   auth_handler->SetGenerateExpectation(false, OK);
   9410   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9411   if (rv == ERR_IO_PENDING)
   9412     rv = callback.WaitForResult();
   9413   EXPECT_EQ(OK, rv);
   9414   response = trans->GetResponseInfo();
   9415   ASSERT_TRUE(response != NULL);
   9416   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9417   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9418 
   9419   // Fourth round of authentication, which completes successfully.
   9420   auth_handler->SetGenerateExpectation(false, OK);
   9421   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9422   if (rv == ERR_IO_PENDING)
   9423     rv = callback.WaitForResult();
   9424   EXPECT_EQ(OK, rv);
   9425   response = trans->GetResponseInfo();
   9426   ASSERT_TRUE(response != NULL);
   9427   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9428   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9429 
   9430   // Read the body since the fourth round was successful. This will also
   9431   // release the socket back to the pool.
   9432   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
   9433   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9434   if (rv == ERR_IO_PENDING)
   9435     rv = callback.WaitForResult();
   9436   EXPECT_EQ(3, rv);
   9437   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9438   EXPECT_EQ(0, rv);
   9439   // There are still 0 idle sockets, since the trans_compete transaction
   9440   // will be handed it immediately after trans releases it to the group.
   9441   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9442 
   9443   // The competing request can now finish. Wait for the headers and then
   9444   // read the body.
   9445   rv = callback_compete.WaitForResult();
   9446   EXPECT_EQ(OK, rv);
   9447   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9448   if (rv == ERR_IO_PENDING)
   9449     rv = callback.WaitForResult();
   9450   EXPECT_EQ(3, rv);
   9451   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9452   EXPECT_EQ(0, rv);
   9453 
   9454   // Finally, the socket is released to the group.
   9455   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9456 }
   9457 
   9458 // This tests the case that a request is issued via http instead of spdy after
   9459 // npn is negotiated.
   9460 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
   9461   HttpStreamFactory::set_use_alternate_protocols(true);
   9462   std::vector<NextProto> next_protos;
   9463   next_protos.push_back(kProtoHTTP11);
   9464   HttpStreamFactory::SetNextProtos(next_protos);
   9465   HttpRequestInfo request;
   9466   request.method = "GET";
   9467   request.url = GURL("https://www.google.com/");
   9468   request.load_flags = 0;
   9469 
   9470   MockWrite data_writes[] = {
   9471     MockWrite("GET / HTTP/1.1\r\n"
   9472               "Host: www.google.com\r\n"
   9473               "Connection: keep-alive\r\n\r\n"),
   9474   };
   9475 
   9476   std::string alternate_protocol_http_header =
   9477       GetAlternateProtocolHttpHeader();
   9478 
   9479   MockRead data_reads[] = {
   9480     MockRead("HTTP/1.1 200 OK\r\n"),
   9481     MockRead(alternate_protocol_http_header.c_str()),
   9482     MockRead("hello world"),
   9483     MockRead(SYNCHRONOUS, OK),
   9484   };
   9485 
   9486   SSLSocketDataProvider ssl(ASYNC, OK);
   9487   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   9488   ssl.next_proto = "http/1.1";
   9489   ssl.protocol_negotiated = kProtoHTTP11;
   9490 
   9491   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9492 
   9493   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   9494                                 data_writes, arraysize(data_writes));
   9495   session_deps_.socket_factory->AddSocketDataProvider(&data);
   9496 
   9497   TestCompletionCallback callback;
   9498 
   9499   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9500   scoped_ptr<HttpTransaction> trans(
   9501       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9502 
   9503   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9504 
   9505   EXPECT_EQ(ERR_IO_PENDING, rv);
   9506   EXPECT_EQ(OK, callback.WaitForResult());
   9507 
   9508   const HttpResponseInfo* response = trans->GetResponseInfo();
   9509   ASSERT_TRUE(response != NULL);
   9510   ASSERT_TRUE(response->headers.get() != NULL);
   9511   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9512 
   9513   std::string response_data;
   9514   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9515   EXPECT_EQ("hello world", response_data);
   9516 
   9517   EXPECT_FALSE(response->was_fetched_via_spdy);
   9518   EXPECT_TRUE(response->was_npn_negotiated);
   9519 }
   9520 
   9521 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
   9522   // Simulate the SSL handshake completing with an NPN negotiation
   9523   // followed by an immediate server closing of the socket.
   9524   // Fix crash:  http://crbug.com/46369
   9525   HttpStreamFactory::set_use_alternate_protocols(true);
   9526   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   9527 
   9528   HttpRequestInfo request;
   9529   request.method = "GET";
   9530   request.url = GURL("https://www.google.com/");
   9531   request.load_flags = 0;
   9532 
   9533   SSLSocketDataProvider ssl(ASYNC, OK);
   9534   ssl.SetNextProto(GetParam());
   9535   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9536 
   9537   scoped_ptr<SpdyFrame> req(
   9538       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9539   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   9540 
   9541   MockRead spdy_reads[] = {
   9542     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
   9543   };
   9544 
   9545   DelayedSocketData spdy_data(
   9546       0,  // don't wait in this case, immediate hangup.
   9547       spdy_reads, arraysize(spdy_reads),
   9548       spdy_writes, arraysize(spdy_writes));
   9549   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   9550 
   9551   TestCompletionCallback callback;
   9552 
   9553   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9554   scoped_ptr<HttpTransaction> trans(
   9555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9556 
   9557   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9558   EXPECT_EQ(ERR_IO_PENDING, rv);
   9559   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
   9560 }
   9561 
   9562 // A subclass of HttpAuthHandlerMock that records the request URL when
   9563 // it gets it. This is needed since the auth handler may get destroyed
   9564 // before we get a chance to query it.
   9565 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
   9566  public:
   9567   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
   9568 
   9569   virtual ~UrlRecordingHttpAuthHandlerMock() {}
   9570 
   9571  protected:
   9572   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
   9573                                     const HttpRequestInfo* request,
   9574                                     const CompletionCallback& callback,
   9575                                     std::string* auth_token) OVERRIDE {
   9576     *url_ = request->url;
   9577     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
   9578         credentials, request, callback, auth_token);
   9579   }
   9580 
   9581  private:
   9582   GURL* url_;
   9583 };
   9584 
   9585 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
   9586   // This test ensures that the URL passed into the proxy is upgraded
   9587   // to https when doing an Alternate Protocol upgrade.
   9588   HttpStreamFactory::set_use_alternate_protocols(true);
   9589   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   9590 
   9591   session_deps_.proxy_service.reset(
   9592       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9593   CapturingNetLog net_log;
   9594   session_deps_.net_log = &net_log;
   9595   GURL request_url;
   9596   {
   9597     HttpAuthHandlerMock::Factory* auth_factory =
   9598         new HttpAuthHandlerMock::Factory();
   9599     UrlRecordingHttpAuthHandlerMock* auth_handler =
   9600         new UrlRecordingHttpAuthHandlerMock(&request_url);
   9601     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   9602     auth_factory->set_do_init_from_challenge(true);
   9603     session_deps_.http_auth_handler_factory.reset(auth_factory);
   9604   }
   9605 
   9606   HttpRequestInfo request;
   9607   request.method = "GET";
   9608   request.url = GURL("http://www.google.com");
   9609   request.load_flags = 0;
   9610 
   9611   // First round goes unauthenticated through the proxy.
   9612   MockWrite data_writes_1[] = {
   9613     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   9614               "Host: www.google.com\r\n"
   9615               "Proxy-Connection: keep-alive\r\n"
   9616               "\r\n"),
   9617   };
   9618   MockRead data_reads_1[] = {
   9619     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9620     MockRead("HTTP/1.1 200 OK\r\n"
   9621              "Alternate-Protocol: 443:npn-spdy/2\r\n"
   9622              "Proxy-Connection: close\r\n"
   9623              "\r\n"),
   9624   };
   9625   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
   9626                                   data_writes_1, arraysize(data_writes_1));
   9627 
   9628   // Second round tries to tunnel to www.google.com due to the
   9629   // Alternate-Protocol announcement in the first round. It fails due
   9630   // to a proxy authentication challenge.
   9631   // After the failure, a tunnel is established to www.google.com using
   9632   // Proxy-Authorization headers. There is then a SPDY request round.
   9633   //
   9634   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
   9635   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
   9636   // does a Disconnect and Connect on the same socket, rather than trying
   9637   // to obtain a new one.
   9638   //
   9639   // NOTE: Originally, the proxy response to the second CONNECT request
   9640   // simply returned another 407 so the unit test could skip the SSL connection
   9641   // establishment and SPDY framing issues. Alas, the
   9642   // retry-http-when-alternate-protocol fails logic kicks in, which was more
   9643   // complicated to set up expectations for than the SPDY session.
   9644 
   9645   scoped_ptr<SpdyFrame> req(
   9646       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9647   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   9648   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   9649 
   9650   MockWrite data_writes_2[] = {
   9651     // First connection attempt without Proxy-Authorization.
   9652     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9653               "Host: www.google.com\r\n"
   9654               "Proxy-Connection: keep-alive\r\n"
   9655               "\r\n"),
   9656 
   9657     // Second connection attempt with Proxy-Authorization.
   9658     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9659               "Host: www.google.com\r\n"
   9660               "Proxy-Connection: keep-alive\r\n"
   9661               "Proxy-Authorization: auth_token\r\n"
   9662               "\r\n"),
   9663 
   9664     // SPDY request
   9665     CreateMockWrite(*req),
   9666   };
   9667   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
   9668                                          "Proxy-Authenticate: Mock\r\n"
   9669                                          "Proxy-Connection: close\r\n"
   9670                                          "\r\n");
   9671   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   9672   MockRead data_reads_2[] = {
   9673     // First connection attempt fails
   9674     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
   9675     MockRead(ASYNC, kRejectConnectResponse,
   9676              arraysize(kRejectConnectResponse) - 1, 1),
   9677 
   9678     // Second connection attempt passes
   9679     MockRead(ASYNC, kAcceptConnectResponse,
   9680              arraysize(kAcceptConnectResponse) -1, 4),
   9681 
   9682     // SPDY response
   9683     CreateMockRead(*resp.get(), 6),
   9684     CreateMockRead(*data.get(), 6),
   9685     MockRead(ASYNC, 0, 0, 6),
   9686   };
   9687   OrderedSocketData data_2(
   9688       data_reads_2, arraysize(data_reads_2),
   9689       data_writes_2, arraysize(data_writes_2));
   9690 
   9691   SSLSocketDataProvider ssl(ASYNC, OK);
   9692   ssl.SetNextProto(GetParam());
   9693 
   9694   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   9695   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   9696       NULL, 0, NULL, 0);
   9697   hanging_non_alternate_protocol_socket.set_connect_data(
   9698       never_finishing_connect);
   9699 
   9700   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
   9701   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
   9702   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9703   session_deps_.socket_factory->AddSocketDataProvider(
   9704       &hanging_non_alternate_protocol_socket);
   9705   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9706 
   9707   // First round should work and provide the Alternate-Protocol state.
   9708   TestCompletionCallback callback_1;
   9709   scoped_ptr<HttpTransaction> trans_1(
   9710       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9711   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
   9712   EXPECT_EQ(ERR_IO_PENDING, rv);
   9713   EXPECT_EQ(OK, callback_1.WaitForResult());
   9714 
   9715   // Second round should attempt a tunnel connect and get an auth challenge.
   9716   TestCompletionCallback callback_2;
   9717   scoped_ptr<HttpTransaction> trans_2(
   9718       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9719   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
   9720   EXPECT_EQ(ERR_IO_PENDING, rv);
   9721   EXPECT_EQ(OK, callback_2.WaitForResult());
   9722   const HttpResponseInfo* response = trans_2->GetResponseInfo();
   9723   ASSERT_TRUE(response != NULL);
   9724   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   9725 
   9726   // Restart with auth. Tunnel should work and response received.
   9727   TestCompletionCallback callback_3;
   9728   rv = trans_2->RestartWithAuth(
   9729       AuthCredentials(kFoo, kBar), callback_3.callback());
   9730   EXPECT_EQ(ERR_IO_PENDING, rv);
   9731   EXPECT_EQ(OK, callback_3.WaitForResult());
   9732 
   9733   // After all that work, these two lines (or actually, just the scheme) are
   9734   // what this test is all about. Make sure it happens correctly.
   9735   EXPECT_EQ("https", request_url.scheme());
   9736   EXPECT_EQ("www.google.com", request_url.host());
   9737 
   9738   LoadTimingInfo load_timing_info;
   9739   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
   9740   TestLoadTimingNotReusedWithPac(load_timing_info,
   9741                                  CONNECT_TIMING_HAS_SSL_TIMES);
   9742 }
   9743 
   9744 // Test that if we cancel the transaction as the connection is completing, that
   9745 // everything tears down correctly.
   9746 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
   9747   // Setup everything about the connection to complete synchronously, so that
   9748   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
   9749   // for is the callback from the HttpStreamRequest.
   9750   // Then cancel the transaction.
   9751   // Verify that we don't crash.
   9752   MockConnect mock_connect(SYNCHRONOUS, OK);
   9753   MockRead data_reads[] = {
   9754     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
   9755     MockRead(SYNCHRONOUS, "hello world"),
   9756     MockRead(SYNCHRONOUS, OK),
   9757   };
   9758 
   9759   HttpRequestInfo request;
   9760   request.method = "GET";
   9761   request.url = GURL("http://www.google.com/");
   9762   request.load_flags = 0;
   9763 
   9764   session_deps_.host_resolver->set_synchronous_mode(true);
   9765   scoped_ptr<HttpTransaction> trans(
   9766       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   9767                                  CreateSession(&session_deps_)));
   9768 
   9769   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   9770   data.set_connect_data(mock_connect);
   9771   session_deps_.socket_factory->AddSocketDataProvider(&data);
   9772 
   9773   TestCompletionCallback callback;
   9774 
   9775   CapturingBoundNetLog log;
   9776   int rv = trans->Start(&request, callback.callback(), log.bound());
   9777   EXPECT_EQ(ERR_IO_PENDING, rv);
   9778   trans.reset();  // Cancel the transaction here.
   9779 
   9780   base::MessageLoop::current()->RunUntilIdle();
   9781 }
   9782 
   9783 // Test a basic GET request through a proxy.
   9784 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
   9785   session_deps_.proxy_service.reset(
   9786       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9787   CapturingBoundNetLog log;
   9788   session_deps_.net_log = log.bound().net_log();
   9789   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9790 
   9791   HttpRequestInfo request;
   9792   request.method = "GET";
   9793   request.url = GURL("http://www.google.com/");
   9794 
   9795   MockWrite data_writes1[] = {
   9796     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   9797               "Host: www.google.com\r\n"
   9798               "Proxy-Connection: keep-alive\r\n\r\n"),
   9799   };
   9800 
   9801   MockRead data_reads1[] = {
   9802     MockRead("HTTP/1.1 200 OK\r\n"),
   9803     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   9804     MockRead("Content-Length: 100\r\n\r\n"),
   9805     MockRead(SYNCHRONOUS, OK),
   9806   };
   9807 
   9808   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   9809                                  data_writes1, arraysize(data_writes1));
   9810   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   9811 
   9812   TestCompletionCallback callback1;
   9813 
   9814   scoped_ptr<HttpTransaction> trans(
   9815       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9816 
   9817   int rv = trans->Start(&request, callback1.callback(), log.bound());
   9818   EXPECT_EQ(ERR_IO_PENDING, rv);
   9819 
   9820   rv = callback1.WaitForResult();
   9821   EXPECT_EQ(OK, rv);
   9822 
   9823   const HttpResponseInfo* response = trans->GetResponseInfo();
   9824   ASSERT_TRUE(response != NULL);
   9825 
   9826   EXPECT_TRUE(response->headers->IsKeepAlive());
   9827   EXPECT_EQ(200, response->headers->response_code());
   9828   EXPECT_EQ(100, response->headers->GetContentLength());
   9829   EXPECT_TRUE(response->was_fetched_via_proxy);
   9830   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   9831 
   9832   LoadTimingInfo load_timing_info;
   9833   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   9834   TestLoadTimingNotReusedWithPac(load_timing_info,
   9835                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   9836 }
   9837 
   9838 // Test a basic HTTPS GET request through a proxy.
   9839 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
   9840   session_deps_.proxy_service.reset(
   9841       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9842   CapturingBoundNetLog log;
   9843   session_deps_.net_log = log.bound().net_log();
   9844   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9845 
   9846   HttpRequestInfo request;
   9847   request.method = "GET";
   9848   request.url = GURL("https://www.google.com/");
   9849 
   9850   // Since we have proxy, should try to establish tunnel.
   9851   MockWrite data_writes1[] = {
   9852     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9853               "Host: www.google.com\r\n"
   9854               "Proxy-Connection: keep-alive\r\n\r\n"),
   9855 
   9856     MockWrite("GET / HTTP/1.1\r\n"
   9857               "Host: www.google.com\r\n"
   9858               "Connection: keep-alive\r\n\r\n"),
   9859   };
   9860 
   9861   MockRead data_reads1[] = {
   9862     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   9863 
   9864     MockRead("HTTP/1.1 200 OK\r\n"),
   9865     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   9866     MockRead("Content-Length: 100\r\n\r\n"),
   9867     MockRead(SYNCHRONOUS, OK),
   9868   };
   9869 
   9870   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   9871                                  data_writes1, arraysize(data_writes1));
   9872   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   9873   SSLSocketDataProvider ssl(ASYNC, OK);
   9874   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9875 
   9876   TestCompletionCallback callback1;
   9877 
   9878   scoped_ptr<HttpTransaction> trans(
   9879       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9880 
   9881   int rv = trans->Start(&request, callback1.callback(), log.bound());
   9882   EXPECT_EQ(ERR_IO_PENDING, rv);
   9883 
   9884   rv = callback1.WaitForResult();
   9885   EXPECT_EQ(OK, rv);
   9886   net::CapturingNetLog::CapturedEntryList entries;
   9887   log.GetEntries(&entries);
   9888   size_t pos = ExpectLogContainsSomewhere(
   9889       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   9890       NetLog::PHASE_NONE);
   9891   ExpectLogContainsSomewhere(
   9892       entries, pos,
   9893       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   9894       NetLog::PHASE_NONE);
   9895 
   9896   const HttpResponseInfo* response = trans->GetResponseInfo();
   9897   ASSERT_TRUE(response != NULL);
   9898 
   9899   EXPECT_TRUE(response->headers->IsKeepAlive());
   9900   EXPECT_EQ(200, response->headers->response_code());
   9901   EXPECT_EQ(100, response->headers->GetContentLength());
   9902   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   9903   EXPECT_TRUE(response->was_fetched_via_proxy);
   9904 
   9905   LoadTimingInfo load_timing_info;
   9906   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   9907   TestLoadTimingNotReusedWithPac(load_timing_info,
   9908                                  CONNECT_TIMING_HAS_SSL_TIMES);
   9909 }
   9910 
   9911 // Test a basic HTTPS GET request through a proxy, but the server hangs up
   9912 // while establishing the tunnel.
   9913 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
   9914   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   9915   CapturingBoundNetLog log;
   9916   session_deps_.net_log = log.bound().net_log();
   9917   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9918 
   9919   HttpRequestInfo request;
   9920   request.method = "GET";
   9921   request.url = GURL("https://www.google.com/");
   9922 
   9923   // Since we have proxy, should try to establish tunnel.
   9924   MockWrite data_writes1[] = {
   9925     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9926               "Host: www.google.com\r\n"
   9927               "Proxy-Connection: keep-alive\r\n\r\n"),
   9928 
   9929     MockWrite("GET / HTTP/1.1\r\n"
   9930               "Host: www.google.com\r\n"
   9931               "Connection: keep-alive\r\n\r\n"),
   9932   };
   9933 
   9934   MockRead data_reads1[] = {
   9935     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9936     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   9937     MockRead(ASYNC, 0, 0),  // EOF
   9938   };
   9939 
   9940   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   9941                                  data_writes1, arraysize(data_writes1));
   9942   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   9943   SSLSocketDataProvider ssl(ASYNC, OK);
   9944   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9945 
   9946   TestCompletionCallback callback1;
   9947 
   9948   scoped_ptr<HttpTransaction> trans(
   9949       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9950 
   9951   int rv = trans->Start(&request, callback1.callback(), log.bound());
   9952   EXPECT_EQ(ERR_IO_PENDING, rv);
   9953 
   9954   rv = callback1.WaitForResult();
   9955   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   9956   net::CapturingNetLog::CapturedEntryList entries;
   9957   log.GetEntries(&entries);
   9958   size_t pos = ExpectLogContainsSomewhere(
   9959       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   9960       NetLog::PHASE_NONE);
   9961   ExpectLogContainsSomewhere(
   9962       entries, pos,
   9963       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   9964       NetLog::PHASE_NONE);
   9965 }
   9966 
   9967 // Test for crbug.com/55424.
   9968 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
   9969   scoped_ptr<SpdyFrame> req(
   9970       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   9971   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   9972 
   9973   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   9974   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   9975   MockRead spdy_reads[] = {
   9976     CreateMockRead(*resp),
   9977     CreateMockRead(*data),
   9978     MockRead(ASYNC, 0, 0),
   9979   };
   9980 
   9981   DelayedSocketData spdy_data(
   9982       1,  // wait for one write to finish before reading.
   9983       spdy_reads, arraysize(spdy_reads),
   9984       spdy_writes, arraysize(spdy_writes));
   9985   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   9986 
   9987   SSLSocketDataProvider ssl(ASYNC, OK);
   9988   ssl.SetNextProto(GetParam());
   9989   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9990 
   9991   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9992 
   9993   // Set up an initial SpdySession in the pool to reuse.
   9994   HostPortPair host_port_pair("www.google.com", 443);
   9995   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   9996                      kPrivacyModeDisabled);
   9997   base::WeakPtr<SpdySession> spdy_session =
   9998       CreateInsecureSpdySession(session, key, BoundNetLog());
   9999 
   10000   HttpRequestInfo request;
   10001   request.method = "GET";
   10002   request.url = GURL("https://www.google.com/");
   10003   request.load_flags = 0;
   10004 
   10005   // This is the important line that marks this as a preconnect.
   10006   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
   10007 
   10008   scoped_ptr<HttpTransaction> trans(
   10009       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10010 
   10011   TestCompletionCallback callback;
   10012   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   10013   EXPECT_EQ(ERR_IO_PENDING, rv);
   10014   EXPECT_EQ(OK, callback.WaitForResult());
   10015 }
   10016 
   10017 // Given a net error, cause that error to be returned from the first Write()
   10018 // call and verify that the HttpTransaction fails with that error.
   10019 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
   10020     int error, IoMode mode) {
   10021   net::HttpRequestInfo request_info;
   10022   request_info.url = GURL("https://www.example.com/");
   10023   request_info.method = "GET";
   10024   request_info.load_flags = net::LOAD_NORMAL;
   10025 
   10026   SSLSocketDataProvider ssl_data(mode, OK);
   10027   net::MockWrite data_writes[] = {
   10028     net::MockWrite(mode, error),
   10029   };
   10030   net::StaticSocketDataProvider data(NULL, 0,
   10031                                      data_writes, arraysize(data_writes));
   10032   session_deps_.socket_factory->AddSocketDataProvider(&data);
   10033   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   10034 
   10035   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10036   scoped_ptr<HttpTransaction> trans(
   10037       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10038 
   10039   TestCompletionCallback callback;
   10040   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10041   if (rv == net::ERR_IO_PENDING)
   10042     rv = callback.WaitForResult();
   10043   ASSERT_EQ(error, rv);
   10044 }
   10045 
   10046 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
   10047   // Just check a grab bag of cert errors.
   10048   static const int kErrors[] = {
   10049     ERR_CERT_COMMON_NAME_INVALID,
   10050     ERR_CERT_AUTHORITY_INVALID,
   10051     ERR_CERT_DATE_INVALID,
   10052   };
   10053   for (size_t i = 0; i < arraysize(kErrors); i++) {
   10054     CheckErrorIsPassedBack(kErrors[i], ASYNC);
   10055     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
   10056   }
   10057 }
   10058 
   10059 // Ensure that a client certificate is removed from the SSL client auth
   10060 // cache when:
   10061 //  1) No proxy is involved.
   10062 //  2) TLS False Start is disabled.
   10063 //  3) The initial TLS handshake requests a client certificate.
   10064 //  4) The client supplies an invalid/unacceptable certificate.
   10065 TEST_P(HttpNetworkTransactionTest,
   10066        ClientAuthCertCache_Direct_NoFalseStart) {
   10067   net::HttpRequestInfo request_info;
   10068   request_info.url = GURL("https://www.example.com/");
   10069   request_info.method = "GET";
   10070   request_info.load_flags = net::LOAD_NORMAL;
   10071 
   10072   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10073   cert_request->host_and_port = "www.example.com:443";
   10074 
   10075   // [ssl_]data1 contains the data for the first SSL handshake. When a
   10076   // CertificateRequest is received for the first time, the handshake will
   10077   // be aborted to allow the caller to provide a certificate.
   10078   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10079   ssl_data1.cert_request_info = cert_request.get();
   10080   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10081   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10082   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10083 
   10084   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
   10085   // False Start is not being used, the result of the SSL handshake will be
   10086   // returned as part of the SSLClientSocket::Connect() call. This test
   10087   // matches the result of a server sending a handshake_failure alert,
   10088   // rather than a Finished message, because it requires a client
   10089   // certificate and none was supplied.
   10090   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10091   ssl_data2.cert_request_info = cert_request.get();
   10092   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10093   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10094   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10095 
   10096   // [ssl_]data3 contains the data for the third SSL handshake. When a
   10097   // connection to a server fails during an SSL handshake,
   10098   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
   10099   // connection was attempted with TLSv1.1. This is transparent to the caller
   10100   // of the HttpNetworkTransaction. Because this test failure is due to
   10101   // requiring a client certificate, this fallback handshake should also
   10102   // fail.
   10103   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10104   ssl_data3.cert_request_info = cert_request.get();
   10105   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10106   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10107   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10108 
   10109   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
   10110   // connection to a server fails during an SSL handshake,
   10111   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
   10112   // connection was attempted with TLSv1. This is transparent to the caller
   10113   // of the HttpNetworkTransaction. Because this test failure is due to
   10114   // requiring a client certificate, this fallback handshake should also
   10115   // fail.
   10116   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10117   ssl_data4.cert_request_info = cert_request.get();
   10118   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10119   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
   10120   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10121 
   10122   // Need one more if TLSv1.2 is enabled.
   10123   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10124   ssl_data5.cert_request_info = cert_request.get();
   10125   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10126   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
   10127   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10128 
   10129   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10130   scoped_ptr<HttpTransaction> trans(
   10131       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10132 
   10133   // Begin the SSL handshake with the peer. This consumes ssl_data1.
   10134   TestCompletionCallback callback;
   10135   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10136   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10137 
   10138   // Complete the SSL handshake, which should abort due to requiring a
   10139   // client certificate.
   10140   rv = callback.WaitForResult();
   10141   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10142 
   10143   // Indicate that no certificate should be supplied. From the perspective
   10144   // of SSLClientCertCache, NULL is just as meaningful as a real
   10145   // certificate, so this is the same as supply a
   10146   // legitimate-but-unacceptable certificate.
   10147   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10148   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10149 
   10150   // Ensure the certificate was added to the client auth cache before
   10151   // allowing the connection to continue restarting.
   10152   scoped_refptr<X509Certificate> client_cert;
   10153   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10154                                                        &client_cert));
   10155   ASSERT_EQ(NULL, client_cert.get());
   10156 
   10157   // Restart the handshake. This will consume ssl_data2, which fails, and
   10158   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10159   // The result code is checked against what ssl_data4 should return.
   10160   rv = callback.WaitForResult();
   10161   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10162 
   10163   // Ensure that the client certificate is removed from the cache on a
   10164   // handshake failure.
   10165   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10166                                                         &client_cert));
   10167 }
   10168 
   10169 // Ensure that a client certificate is removed from the SSL client auth
   10170 // cache when:
   10171 //  1) No proxy is involved.
   10172 //  2) TLS False Start is enabled.
   10173 //  3) The initial TLS handshake requests a client certificate.
   10174 //  4) The client supplies an invalid/unacceptable certificate.
   10175 TEST_P(HttpNetworkTransactionTest,
   10176        ClientAuthCertCache_Direct_FalseStart) {
   10177   net::HttpRequestInfo request_info;
   10178   request_info.url = GURL("https://www.example.com/");
   10179   request_info.method = "GET";
   10180   request_info.load_flags = net::LOAD_NORMAL;
   10181 
   10182   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10183   cert_request->host_and_port = "www.example.com:443";
   10184 
   10185   // When TLS False Start is used, SSLClientSocket::Connect() calls will
   10186   // return successfully after reading up to the peer's Certificate message.
   10187   // This is to allow the caller to call SSLClientSocket::Write(), which can
   10188   // enqueue application data to be sent in the same packet as the
   10189   // ChangeCipherSpec and Finished messages.
   10190   // The actual handshake will be finished when SSLClientSocket::Read() is
   10191   // called, which expects to process the peer's ChangeCipherSpec and
   10192   // Finished messages. If there was an error negotiating with the peer,
   10193   // such as due to the peer requiring a client certificate when none was
   10194   // supplied, the alert sent by the peer won't be processed until Read() is
   10195   // called.
   10196 
   10197   // Like the non-False Start case, when a client certificate is requested by
   10198   // the peer, the handshake is aborted during the Connect() call.
   10199   // [ssl_]data1 represents the initial SSL handshake with the peer.
   10200   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10201   ssl_data1.cert_request_info = cert_request.get();
   10202   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10203   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10204   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10205 
   10206   // When a client certificate is supplied, Connect() will not be aborted
   10207   // when the peer requests the certificate. Instead, the handshake will
   10208   // artificially succeed, allowing the caller to write the HTTP request to
   10209   // the socket. The handshake messages are not processed until Read() is
   10210   // called, which then detects that the handshake was aborted, due to the
   10211   // peer sending a handshake_failure because it requires a client
   10212   // certificate.
   10213   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
   10214   ssl_data2.cert_request_info = cert_request.get();
   10215   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10216   net::MockRead data2_reads[] = {
   10217     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
   10218   };
   10219   net::StaticSocketDataProvider data2(
   10220       data2_reads, arraysize(data2_reads), NULL, 0);
   10221   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10222 
   10223   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
   10224   // the data for the SSL handshake once the TLSv1.1 connection falls back to
   10225   // TLSv1. It has the same behaviour as [ssl_]data2.
   10226   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
   10227   ssl_data3.cert_request_info = cert_request.get();
   10228   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10229   net::StaticSocketDataProvider data3(
   10230       data2_reads, arraysize(data2_reads), NULL, 0);
   10231   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10232 
   10233   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
   10234   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
   10235   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
   10236   ssl_data4.cert_request_info = cert_request.get();
   10237   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10238   net::StaticSocketDataProvider data4(
   10239       data2_reads, arraysize(data2_reads), NULL, 0);
   10240   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10241 
   10242   // Need one more if TLSv1.2 is enabled.
   10243   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
   10244   ssl_data5.cert_request_info = cert_request.get();
   10245   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10246   net::StaticSocketDataProvider data5(
   10247       data2_reads, arraysize(data2_reads), NULL, 0);
   10248   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10249 
   10250   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10251   scoped_ptr<HttpTransaction> trans(
   10252       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10253 
   10254   // Begin the initial SSL handshake.
   10255   TestCompletionCallback callback;
   10256   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10257   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10258 
   10259   // Complete the SSL handshake, which should abort due to requiring a
   10260   // client certificate.
   10261   rv = callback.WaitForResult();
   10262   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10263 
   10264   // Indicate that no certificate should be supplied. From the perspective
   10265   // of SSLClientCertCache, NULL is just as meaningful as a real
   10266   // certificate, so this is the same as supply a
   10267   // legitimate-but-unacceptable certificate.
   10268   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10269   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10270 
   10271   // Ensure the certificate was added to the client auth cache before
   10272   // allowing the connection to continue restarting.
   10273   scoped_refptr<X509Certificate> client_cert;
   10274   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10275                                                        &client_cert));
   10276   ASSERT_EQ(NULL, client_cert.get());
   10277 
   10278   // Restart the handshake. This will consume ssl_data2, which fails, and
   10279   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10280   // The result code is checked against what ssl_data4 should return.
   10281   rv = callback.WaitForResult();
   10282   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10283 
   10284   // Ensure that the client certificate is removed from the cache on a
   10285   // handshake failure.
   10286   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10287                                                         &client_cert));
   10288 }
   10289 
   10290 // Ensure that a client certificate is removed from the SSL client auth
   10291 // cache when:
   10292 //  1) An HTTPS proxy is involved.
   10293 //  3) The HTTPS proxy requests a client certificate.
   10294 //  4) The client supplies an invalid/unacceptable certificate for the
   10295 //     proxy.
   10296 // The test is repeated twice, first for connecting to an HTTPS endpoint,
   10297 // then for connecting to an HTTP endpoint.
   10298 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
   10299   session_deps_.proxy_service.reset(
   10300       ProxyService::CreateFixed("https://proxy:70"));
   10301   CapturingBoundNetLog log;
   10302   session_deps_.net_log = log.bound().net_log();
   10303 
   10304   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10305   cert_request->host_and_port = "proxy:70";
   10306 
   10307   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
   10308   // [ssl_]data[1-3]. Rather than represending the endpoint
   10309   // (www.example.com:443), they represent failures with the HTTPS proxy
   10310   // (proxy:70).
   10311   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10312   ssl_data1.cert_request_info = cert_request.get();
   10313   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10314   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10315   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10316 
   10317   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10318   ssl_data2.cert_request_info = cert_request.get();
   10319   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10320   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10321   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10322 
   10323   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
   10324 #if 0
   10325   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10326   ssl_data3.cert_request_info = cert_request.get();
   10327   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10328   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10329   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10330 #endif
   10331 
   10332   net::HttpRequestInfo requests[2];
   10333   requests[0].url = GURL("https://www.example.com/");
   10334   requests[0].method = "GET";
   10335   requests[0].load_flags = net::LOAD_NORMAL;
   10336 
   10337   requests[1].url = GURL("http://www.example.com/");
   10338   requests[1].method = "GET";
   10339   requests[1].load_flags = net::LOAD_NORMAL;
   10340 
   10341   for (size_t i = 0; i < arraysize(requests); ++i) {
   10342     session_deps_.socket_factory->ResetNextMockIndexes();
   10343     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10344     scoped_ptr<HttpNetworkTransaction> trans(
   10345         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10346 
   10347     // Begin the SSL handshake with the proxy.
   10348     TestCompletionCallback callback;
   10349     int rv = trans->Start(
   10350         &requests[i], callback.callback(), net::BoundNetLog());
   10351     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10352 
   10353     // Complete the SSL handshake, which should abort due to requiring a
   10354     // client certificate.
   10355     rv = callback.WaitForResult();
   10356     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10357 
   10358     // Indicate that no certificate should be supplied. From the perspective
   10359     // of SSLClientCertCache, NULL is just as meaningful as a real
   10360     // certificate, so this is the same as supply a
   10361     // legitimate-but-unacceptable certificate.
   10362     rv = trans->RestartWithCertificate(NULL, callback.callback());
   10363     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10364 
   10365     // Ensure the certificate was added to the client auth cache before
   10366     // allowing the connection to continue restarting.
   10367     scoped_refptr<X509Certificate> client_cert;
   10368     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   10369                                                          &client_cert));
   10370     ASSERT_EQ(NULL, client_cert.get());
   10371     // Ensure the certificate was NOT cached for the endpoint. This only
   10372     // applies to HTTPS requests, but is fine to check for HTTP requests.
   10373     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10374                                                           &client_cert));
   10375 
   10376     // Restart the handshake. This will consume ssl_data2, which fails, and
   10377     // then consume ssl_data3, which should also fail. The result code is
   10378     // checked against what ssl_data3 should return.
   10379     rv = callback.WaitForResult();
   10380     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
   10381 
   10382     // Now that the new handshake has failed, ensure that the client
   10383     // certificate was removed from the client auth cache.
   10384     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   10385                                                           &client_cert));
   10386     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10387                                                           &client_cert));
   10388   }
   10389 }
   10390 
   10391 // Unlike TEST/TEST_F, which are macros that expand to further macros,
   10392 // TEST_P is a macro that expands directly to code that stringizes the
   10393 // arguments. As a result, macros passed as parameters (such as prefix
   10394 // or test_case_name) will not be expanded by the preprocessor. To
   10395 // work around this, indirect the macro for TEST_P, so that the
   10396 // pre-processor will expand macros such as MAYBE_test_name before
   10397 // instantiating the test.
   10398 #define WRAPPED_TEST_P(test_case_name, test_name) \
   10399   TEST_P(test_case_name, test_name)
   10400 
   10401 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   10402 #if defined(OS_WIN)
   10403 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
   10404 #else
   10405 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
   10406 #endif
   10407 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
   10408   HttpStreamFactory::set_use_alternate_protocols(true);
   10409   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10410 
   10411   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   10412   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   10413   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10414   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10415   pool_peer.DisableDomainAuthenticationVerification();
   10416 
   10417   SSLSocketDataProvider ssl(ASYNC, OK);
   10418   ssl.SetNextProto(GetParam());
   10419   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10420 
   10421   scoped_ptr<SpdyFrame> host1_req(
   10422       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10423   scoped_ptr<SpdyFrame> host2_req(
   10424       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10425   MockWrite spdy_writes[] = {
   10426     CreateMockWrite(*host1_req, 1),
   10427     CreateMockWrite(*host2_req, 4),
   10428   };
   10429   scoped_ptr<SpdyFrame> host1_resp(
   10430       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10431   scoped_ptr<SpdyFrame> host1_resp_body(
   10432       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10433   scoped_ptr<SpdyFrame> host2_resp(
   10434       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10435   scoped_ptr<SpdyFrame> host2_resp_body(
   10436       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10437   MockRead spdy_reads[] = {
   10438     CreateMockRead(*host1_resp, 2),
   10439     CreateMockRead(*host1_resp_body, 3),
   10440     CreateMockRead(*host2_resp, 5),
   10441     CreateMockRead(*host2_resp_body, 6),
   10442     MockRead(ASYNC, 0, 7),
   10443   };
   10444 
   10445   IPAddressNumber ip;
   10446   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10447   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10448   MockConnect connect(ASYNC, OK, peer_addr);
   10449   OrderedSocketData spdy_data(
   10450       connect,
   10451       spdy_reads, arraysize(spdy_reads),
   10452       spdy_writes, arraysize(spdy_writes));
   10453   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10454 
   10455   TestCompletionCallback callback;
   10456   HttpRequestInfo request1;
   10457   request1.method = "GET";
   10458   request1.url = GURL("https://www.google.com/");
   10459   request1.load_flags = 0;
   10460   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10461 
   10462   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10463   EXPECT_EQ(ERR_IO_PENDING, rv);
   10464   EXPECT_EQ(OK, callback.WaitForResult());
   10465 
   10466   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10467   ASSERT_TRUE(response != NULL);
   10468   ASSERT_TRUE(response->headers.get() != NULL);
   10469   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10470 
   10471   std::string response_data;
   10472   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10473   EXPECT_EQ("hello!", response_data);
   10474 
   10475   // Preload www.gmail.com into HostCache.
   10476   HostPortPair host_port("www.gmail.com", 443);
   10477   HostResolver::RequestInfo resolve_info(host_port);
   10478   AddressList ignored;
   10479   rv = session_deps_.host_resolver->Resolve(resolve_info, &ignored,
   10480                                            callback.callback(), NULL,
   10481                                            BoundNetLog());
   10482   EXPECT_EQ(ERR_IO_PENDING, rv);
   10483   rv = callback.WaitForResult();
   10484   EXPECT_EQ(OK, rv);
   10485 
   10486   HttpRequestInfo request2;
   10487   request2.method = "GET";
   10488   request2.url = GURL("https://www.gmail.com/");
   10489   request2.load_flags = 0;
   10490   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10491 
   10492   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10493   EXPECT_EQ(ERR_IO_PENDING, rv);
   10494   EXPECT_EQ(OK, callback.WaitForResult());
   10495 
   10496   response = trans2.GetResponseInfo();
   10497   ASSERT_TRUE(response != NULL);
   10498   ASSERT_TRUE(response->headers.get() != NULL);
   10499   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10500   EXPECT_TRUE(response->was_fetched_via_spdy);
   10501   EXPECT_TRUE(response->was_npn_negotiated);
   10502   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10503   EXPECT_EQ("hello!", response_data);
   10504 }
   10505 #undef MAYBE_UseIPConnectionPooling
   10506 
   10507 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
   10508   HttpStreamFactory::set_use_alternate_protocols(true);
   10509   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10510 
   10511   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   10512   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   10513   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10514   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10515   pool_peer.DisableDomainAuthenticationVerification();
   10516 
   10517   SSLSocketDataProvider ssl(ASYNC, OK);
   10518   ssl.SetNextProto(GetParam());
   10519   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10520 
   10521   scoped_ptr<SpdyFrame> host1_req(
   10522       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10523   scoped_ptr<SpdyFrame> host2_req(
   10524       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10525   MockWrite spdy_writes[] = {
   10526     CreateMockWrite(*host1_req, 1),
   10527     CreateMockWrite(*host2_req, 4),
   10528   };
   10529   scoped_ptr<SpdyFrame> host1_resp(
   10530       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10531   scoped_ptr<SpdyFrame> host1_resp_body(
   10532       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10533   scoped_ptr<SpdyFrame> host2_resp(
   10534       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10535   scoped_ptr<SpdyFrame> host2_resp_body(
   10536       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10537   MockRead spdy_reads[] = {
   10538     CreateMockRead(*host1_resp, 2),
   10539     CreateMockRead(*host1_resp_body, 3),
   10540     CreateMockRead(*host2_resp, 5),
   10541     CreateMockRead(*host2_resp_body, 6),
   10542     MockRead(ASYNC, 0, 7),
   10543   };
   10544 
   10545   IPAddressNumber ip;
   10546   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10547   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10548   MockConnect connect(ASYNC, OK, peer_addr);
   10549   OrderedSocketData spdy_data(
   10550       connect,
   10551       spdy_reads, arraysize(spdy_reads),
   10552       spdy_writes, arraysize(spdy_writes));
   10553   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10554 
   10555   TestCompletionCallback callback;
   10556   HttpRequestInfo request1;
   10557   request1.method = "GET";
   10558   request1.url = GURL("https://www.google.com/");
   10559   request1.load_flags = 0;
   10560   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10561 
   10562   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10563   EXPECT_EQ(ERR_IO_PENDING, rv);
   10564   EXPECT_EQ(OK, callback.WaitForResult());
   10565 
   10566   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10567   ASSERT_TRUE(response != NULL);
   10568   ASSERT_TRUE(response->headers.get() != NULL);
   10569   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10570 
   10571   std::string response_data;
   10572   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10573   EXPECT_EQ("hello!", response_data);
   10574 
   10575   HttpRequestInfo request2;
   10576   request2.method = "GET";
   10577   request2.url = GURL("https://www.gmail.com/");
   10578   request2.load_flags = 0;
   10579   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10580 
   10581   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10582   EXPECT_EQ(ERR_IO_PENDING, rv);
   10583   EXPECT_EQ(OK, callback.WaitForResult());
   10584 
   10585   response = trans2.GetResponseInfo();
   10586   ASSERT_TRUE(response != NULL);
   10587   ASSERT_TRUE(response->headers.get() != NULL);
   10588   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10589   EXPECT_TRUE(response->was_fetched_via_spdy);
   10590   EXPECT_TRUE(response->was_npn_negotiated);
   10591   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10592   EXPECT_EQ("hello!", response_data);
   10593 }
   10594 
   10595 class OneTimeCachingHostResolver : public net::HostResolver {
   10596  public:
   10597   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
   10598       : host_port_(host_port) {}
   10599   virtual ~OneTimeCachingHostResolver() {}
   10600 
   10601   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
   10602 
   10603   // HostResolver methods:
   10604   virtual int Resolve(const RequestInfo& info,
   10605                       AddressList* addresses,
   10606                       const CompletionCallback& callback,
   10607                       RequestHandle* out_req,
   10608                       const BoundNetLog& net_log) OVERRIDE {
   10609     return host_resolver_.Resolve(
   10610         info, addresses, callback, out_req, net_log);
   10611   }
   10612 
   10613   virtual int ResolveFromCache(const RequestInfo& info,
   10614                                AddressList* addresses,
   10615                                const BoundNetLog& net_log) OVERRIDE {
   10616     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
   10617     if (rv == OK && info.host_port_pair().Equals(host_port_))
   10618       host_resolver_.GetHostCache()->clear();
   10619     return rv;
   10620   }
   10621 
   10622   virtual void CancelRequest(RequestHandle req) OVERRIDE {
   10623     host_resolver_.CancelRequest(req);
   10624   }
   10625 
   10626   MockCachingHostResolver* GetMockHostResolver() {
   10627     return &host_resolver_;
   10628   }
   10629 
   10630  private:
   10631   MockCachingHostResolver host_resolver_;
   10632   const HostPortPair host_port_;
   10633 };
   10634 
   10635 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   10636 #if defined(OS_WIN)
   10637 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   10638     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
   10639 #else
   10640 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   10641     UseIPConnectionPoolingWithHostCacheExpiration
   10642 #endif
   10643 WRAPPED_TEST_P(HttpNetworkTransactionTest,
   10644                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
   10645 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
   10646 // prefix doesn't work with parametrized tests).
   10647 #if defined(OS_WIN)
   10648   return;
   10649 #endif
   10650 
   10651   HttpStreamFactory::set_use_alternate_protocols(true);
   10652   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10653 
   10654   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
   10655   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
   10656   HttpNetworkSession::Params params =
   10657       SpdySessionDependencies::CreateSessionParams(&session_deps_);
   10658   params.host_resolver = &host_resolver;
   10659   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10660   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10661   pool_peer.DisableDomainAuthenticationVerification();
   10662 
   10663   SSLSocketDataProvider ssl(ASYNC, OK);
   10664   ssl.SetNextProto(GetParam());
   10665   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10666 
   10667   scoped_ptr<SpdyFrame> host1_req(
   10668       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10669   scoped_ptr<SpdyFrame> host2_req(
   10670       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10671   MockWrite spdy_writes[] = {
   10672     CreateMockWrite(*host1_req, 1),
   10673     CreateMockWrite(*host2_req, 4),
   10674   };
   10675   scoped_ptr<SpdyFrame> host1_resp(
   10676       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10677   scoped_ptr<SpdyFrame> host1_resp_body(
   10678       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10679   scoped_ptr<SpdyFrame> host2_resp(
   10680       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10681   scoped_ptr<SpdyFrame> host2_resp_body(
   10682       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10683   MockRead spdy_reads[] = {
   10684     CreateMockRead(*host1_resp, 2),
   10685     CreateMockRead(*host1_resp_body, 3),
   10686     CreateMockRead(*host2_resp, 5),
   10687     CreateMockRead(*host2_resp_body, 6),
   10688     MockRead(ASYNC, 0, 7),
   10689   };
   10690 
   10691   IPAddressNumber ip;
   10692   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10693   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10694   MockConnect connect(ASYNC, OK, peer_addr);
   10695   OrderedSocketData spdy_data(
   10696       connect,
   10697       spdy_reads, arraysize(spdy_reads),
   10698       spdy_writes, arraysize(spdy_writes));
   10699   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10700 
   10701   TestCompletionCallback callback;
   10702   HttpRequestInfo request1;
   10703   request1.method = "GET";
   10704   request1.url = GURL("https://www.google.com/");
   10705   request1.load_flags = 0;
   10706   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10707 
   10708   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10709   EXPECT_EQ(ERR_IO_PENDING, rv);
   10710   EXPECT_EQ(OK, callback.WaitForResult());
   10711 
   10712   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10713   ASSERT_TRUE(response != NULL);
   10714   ASSERT_TRUE(response->headers.get() != NULL);
   10715   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10716 
   10717   std::string response_data;
   10718   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10719   EXPECT_EQ("hello!", response_data);
   10720 
   10721   // Preload cache entries into HostCache.
   10722   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
   10723   AddressList ignored;
   10724   rv = host_resolver.Resolve(resolve_info, &ignored, callback.callback(),
   10725                              NULL, BoundNetLog());
   10726   EXPECT_EQ(ERR_IO_PENDING, rv);
   10727   rv = callback.WaitForResult();
   10728   EXPECT_EQ(OK, rv);
   10729 
   10730   HttpRequestInfo request2;
   10731   request2.method = "GET";
   10732   request2.url = GURL("https://www.gmail.com/");
   10733   request2.load_flags = 0;
   10734   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10735 
   10736   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10737   EXPECT_EQ(ERR_IO_PENDING, rv);
   10738   EXPECT_EQ(OK, callback.WaitForResult());
   10739 
   10740   response = trans2.GetResponseInfo();
   10741   ASSERT_TRUE(response != NULL);
   10742   ASSERT_TRUE(response->headers.get() != NULL);
   10743   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10744   EXPECT_TRUE(response->was_fetched_via_spdy);
   10745   EXPECT_TRUE(response->was_npn_negotiated);
   10746   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10747   EXPECT_EQ("hello!", response_data);
   10748 }
   10749 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
   10750 
   10751 TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
   10752   MockRead data_reads1[] = {
   10753     MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
   10754   };
   10755   MockRead data_reads2[] = {
   10756     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   10757     MockRead("hello world"),
   10758     MockRead(SYNCHRONOUS, OK),
   10759   };
   10760   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
   10761   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
   10762   StaticSocketDataProvider* data[] = { &data1, &data2 };
   10763 
   10764   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
   10765 
   10766   EXPECT_EQ(OK, out.rv);
   10767   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
   10768   EXPECT_EQ("hello world", out.response_data);
   10769 }
   10770 
   10771 TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
   10772   MockWrite data_writes1[] = {
   10773     MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
   10774   };
   10775   MockWrite data_writes2[] = {
   10776     MockWrite("GET / HTTP/1.1\r\n"
   10777               "Host: www.google.com\r\n"
   10778               "Connection: keep-alive\r\n\r\n"),
   10779   };
   10780   MockRead data_reads2[] = {
   10781     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   10782     MockRead("hello world"),
   10783     MockRead(SYNCHRONOUS, OK),
   10784   };
   10785   StaticSocketDataProvider data1(NULL, 0,
   10786                                  data_writes1, arraysize(data_writes1));
   10787   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   10788                                  data_writes2, arraysize(data_writes2));
   10789   StaticSocketDataProvider* data[] = { &data1, &data2 };
   10790 
   10791   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
   10792 
   10793   EXPECT_EQ(OK, out.rv);
   10794   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
   10795   EXPECT_EQ("hello world", out.response_data);
   10796 }
   10797 
   10798 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
   10799   const std::string https_url = "https://www.google.com/";
   10800   const std::string http_url = "http://www.google.com:443/";
   10801 
   10802   // SPDY GET for HTTPS URL
   10803   scoped_ptr<SpdyFrame> req1(
   10804       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   10805 
   10806   MockWrite writes1[] = {
   10807     CreateMockWrite(*req1, 0),
   10808   };
   10809 
   10810   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10811   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10812   MockRead reads1[] = {
   10813     CreateMockRead(*resp1, 1),
   10814     CreateMockRead(*body1, 2),
   10815     MockRead(ASYNC, ERR_IO_PENDING, 3)
   10816   };
   10817 
   10818   DelayedSocketData data1(
   10819       1, reads1, arraysize(reads1),
   10820       writes1, arraysize(writes1));
   10821   MockConnect connect_data1(ASYNC, OK);
   10822   data1.set_connect_data(connect_data1);
   10823 
   10824   // HTTP GET for the HTTP URL
   10825   MockWrite writes2[] = {
   10826     MockWrite(ASYNC, 4,
   10827               "GET / HTTP/1.1\r\n"
   10828               "Host: www.google.com:443\r\n"
   10829               "Connection: keep-alive\r\n\r\n"),
   10830   };
   10831 
   10832   MockRead reads2[] = {
   10833     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   10834     MockRead(ASYNC, 6, "hello"),
   10835     MockRead(ASYNC, 7, OK),
   10836   };
   10837 
   10838   DelayedSocketData data2(
   10839       1, reads2, arraysize(reads2),
   10840       writes2, arraysize(writes2));
   10841 
   10842   SSLSocketDataProvider ssl(ASYNC, OK);
   10843   ssl.SetNextProto(GetParam());
   10844   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10845   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10846   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10847 
   10848   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10849 
   10850   // Start the first transaction to set up the SpdySession
   10851   HttpRequestInfo request1;
   10852   request1.method = "GET";
   10853   request1.url = GURL(https_url);
   10854   request1.load_flags = 0;
   10855   HttpNetworkTransaction trans1(LOWEST, session.get());
   10856   TestCompletionCallback callback1;
   10857   EXPECT_EQ(ERR_IO_PENDING,
   10858             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   10859   base::MessageLoop::current()->RunUntilIdle();
   10860 
   10861   EXPECT_EQ(OK, callback1.WaitForResult());
   10862   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   10863 
   10864   // Now, start the HTTP request
   10865   HttpRequestInfo request2;
   10866   request2.method = "GET";
   10867   request2.url = GURL(http_url);
   10868   request2.load_flags = 0;
   10869   HttpNetworkTransaction trans2(MEDIUM, session.get());
   10870   TestCompletionCallback callback2;
   10871   EXPECT_EQ(ERR_IO_PENDING,
   10872             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   10873   base::MessageLoop::current()->RunUntilIdle();
   10874 
   10875   EXPECT_EQ(OK, callback2.WaitForResult());
   10876   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   10877 }
   10878 
   10879 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
   10880   const std::string https_url = "https://www.google.com/";
   10881   const std::string http_url = "http://www.google.com:443/";
   10882 
   10883   // SPDY GET for HTTPS URL (through CONNECT tunnel)
   10884   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1));
   10885   scoped_ptr<SpdyFrame> req1(
   10886       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   10887 
   10888   // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
   10889   scoped_ptr<SpdyFrame> wrapped_req1(
   10890       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
   10891   const char* const headers[] = {
   10892     spdy_util_.GetMethodKey(), "GET",
   10893     spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
   10894     spdy_util_.GetHostKey(),  "www.google.com:443",
   10895     spdy_util_.GetSchemeKey(), "http",
   10896     spdy_util_.GetVersionKey(), "HTTP/1.1"
   10897   };
   10898   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
   10899       NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
   10900       headers, arraysize(headers), 0));
   10901 
   10902   MockWrite writes1[] = {
   10903     CreateMockWrite(*connect, 0),
   10904     CreateMockWrite(*wrapped_req1, 2),
   10905     CreateMockWrite(*req2, 5),
   10906   };
   10907 
   10908   scoped_ptr<SpdyFrame> conn_resp(
   10909       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10910   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10911   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10912   scoped_ptr<SpdyFrame> wrapped_resp1(
   10913       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
   10914   scoped_ptr<SpdyFrame> wrapped_body1(
   10915       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
   10916   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10917   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   10918   MockRead reads1[] = {
   10919     CreateMockRead(*conn_resp, 1),
   10920     CreateMockRead(*wrapped_resp1, 3),
   10921     CreateMockRead(*wrapped_body1, 4),
   10922     CreateMockRead(*resp2, 6),
   10923     CreateMockRead(*body2, 7),
   10924     MockRead(ASYNC, ERR_IO_PENDING, 8)
   10925   };
   10926 
   10927   DeterministicSocketData data1(reads1, arraysize(reads1),
   10928                                 writes1, arraysize(writes1));
   10929   MockConnect connect_data1(ASYNC, OK);
   10930   data1.set_connect_data(connect_data1);
   10931 
   10932   session_deps_.proxy_service.reset(
   10933       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   10934   CapturingNetLog log;
   10935   session_deps_.net_log = &log;
   10936   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   10937   ssl1.SetNextProto(GetParam());
   10938   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   10939   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   10940   ssl2.SetNextProto(GetParam());
   10941   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   10942   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
   10943 
   10944   scoped_refptr<HttpNetworkSession> session(
   10945       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   10946 
   10947   // Start the first transaction to set up the SpdySession
   10948   HttpRequestInfo request1;
   10949   request1.method = "GET";
   10950   request1.url = GURL(https_url);
   10951   request1.load_flags = 0;
   10952   HttpNetworkTransaction trans1(LOWEST, session.get());
   10953   TestCompletionCallback callback1;
   10954   EXPECT_EQ(ERR_IO_PENDING,
   10955             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   10956   base::MessageLoop::current()->RunUntilIdle();
   10957   data1.RunFor(4);
   10958 
   10959   EXPECT_EQ(OK, callback1.WaitForResult());
   10960   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   10961 
   10962   LoadTimingInfo load_timing_info1;
   10963   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
   10964   TestLoadTimingNotReusedWithPac(load_timing_info1,
   10965                                  CONNECT_TIMING_HAS_SSL_TIMES);
   10966 
   10967   // Now, start the HTTP request
   10968   HttpRequestInfo request2;
   10969   request2.method = "GET";
   10970   request2.url = GURL(http_url);
   10971   request2.load_flags = 0;
   10972   HttpNetworkTransaction trans2(MEDIUM, session.get());
   10973   TestCompletionCallback callback2;
   10974   EXPECT_EQ(ERR_IO_PENDING,
   10975             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   10976   base::MessageLoop::current()->RunUntilIdle();
   10977   data1.RunFor(3);
   10978 
   10979   EXPECT_EQ(OK, callback2.WaitForResult());
   10980   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   10981 
   10982   LoadTimingInfo load_timing_info2;
   10983   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
   10984   // The established SPDY sessions is considered reused by the HTTP request.
   10985   TestLoadTimingReusedWithPac(load_timing_info2);
   10986   // HTTP requests over a SPDY session should have a different connection
   10987   // socket_log_id than requests over a tunnel.
   10988   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   10989 }
   10990 
   10991 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
   10992   HttpStreamFactory::set_force_spdy_always(true);
   10993   const std::string https_url = "https://www.google.com/";
   10994   const std::string http_url = "http://www.google.com:443/";
   10995 
   10996   // SPDY GET for HTTPS URL
   10997   scoped_ptr<SpdyFrame> req1(
   10998       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   10999   // SPDY GET for the HTTP URL
   11000   scoped_ptr<SpdyFrame> req2(
   11001       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
   11002 
   11003   MockWrite writes[] = {
   11004     CreateMockWrite(*req1, 1),
   11005     CreateMockWrite(*req2, 4),
   11006   };
   11007 
   11008   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11009   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11010   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11011   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   11012   MockRead reads[] = {
   11013     CreateMockRead(*resp1, 2),
   11014     CreateMockRead(*body1, 3),
   11015     CreateMockRead(*resp2, 5),
   11016     CreateMockRead(*body2, 6),
   11017     MockRead(ASYNC, ERR_IO_PENDING, 7)
   11018   };
   11019 
   11020   OrderedSocketData data(reads, arraysize(reads),
   11021                          writes, arraysize(writes));
   11022 
   11023   SSLSocketDataProvider ssl(ASYNC, OK);
   11024   ssl.SetNextProto(GetParam());
   11025   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11026   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11027 
   11028   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11029 
   11030   // Start the first transaction to set up the SpdySession
   11031   HttpRequestInfo request1;
   11032   request1.method = "GET";
   11033   request1.url = GURL(https_url);
   11034   request1.load_flags = 0;
   11035   HttpNetworkTransaction trans1(LOWEST, session.get());
   11036   TestCompletionCallback callback1;
   11037   EXPECT_EQ(ERR_IO_PENDING,
   11038             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11039   base::MessageLoop::current()->RunUntilIdle();
   11040 
   11041   EXPECT_EQ(OK, callback1.WaitForResult());
   11042   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11043 
   11044   // Now, start the HTTP request
   11045   HttpRequestInfo request2;
   11046   request2.method = "GET";
   11047   request2.url = GURL(http_url);
   11048   request2.load_flags = 0;
   11049   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11050   TestCompletionCallback callback2;
   11051   EXPECT_EQ(ERR_IO_PENDING,
   11052             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11053   base::MessageLoop::current()->RunUntilIdle();
   11054 
   11055   EXPECT_EQ(OK, callback2.WaitForResult());
   11056   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11057 }
   11058 
   11059 // Test that in the case where we have a SPDY session to a SPDY proxy
   11060 // that we do not pool other origins that resolve to the same IP when
   11061 // the certificate does not match the new origin.
   11062 // http://crbug.com/134690
   11063 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
   11064   const std::string url1 = "http://www.google.com/";
   11065   const std::string url2 = "https://mail.google.com/";
   11066   const std::string ip_addr = "1.2.3.4";
   11067 
   11068   // SPDY GET for HTTP URL (through SPDY proxy)
   11069   scoped_ptr<SpdyHeaderBlock> headers(
   11070       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   11071   scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
   11072       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   11073 
   11074   MockWrite writes1[] = {
   11075     CreateMockWrite(*req1, 0),
   11076   };
   11077 
   11078   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11079   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11080   MockRead reads1[] = {
   11081     CreateMockRead(*resp1, 1),
   11082     CreateMockRead(*body1, 2),
   11083     MockRead(ASYNC, OK, 3) // EOF
   11084   };
   11085 
   11086   scoped_ptr<DeterministicSocketData> data1(
   11087       new DeterministicSocketData(reads1, arraysize(reads1),
   11088                                   writes1, arraysize(writes1)));
   11089   IPAddressNumber ip;
   11090   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
   11091   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11092   MockConnect connect_data1(ASYNC, OK, peer_addr);
   11093   data1->set_connect_data(connect_data1);
   11094 
   11095   // SPDY GET for HTTPS URL (direct)
   11096   scoped_ptr<SpdyFrame> req2(
   11097       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
   11098 
   11099   MockWrite writes2[] = {
   11100     CreateMockWrite(*req2, 0),
   11101   };
   11102 
   11103   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11104   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11105   MockRead reads2[] = {
   11106     CreateMockRead(*resp2, 1),
   11107     CreateMockRead(*body2, 2),
   11108     MockRead(ASYNC, OK, 3) // EOF
   11109   };
   11110 
   11111   scoped_ptr<DeterministicSocketData> data2(
   11112       new DeterministicSocketData(reads2, arraysize(reads2),
   11113                                   writes2, arraysize(writes2)));
   11114   MockConnect connect_data2(ASYNC, OK);
   11115   data2->set_connect_data(connect_data2);
   11116 
   11117   // Set up a proxy config that sends HTTP requests to a proxy, and
   11118   // all others direct.
   11119   ProxyConfig proxy_config;
   11120   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
   11121   CapturingProxyResolver* capturing_proxy_resolver =
   11122       new CapturingProxyResolver();
   11123   session_deps_.proxy_service.reset(new ProxyService(
   11124       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   11125       NULL));
   11126 
   11127   // Load a valid cert.  Note, that this does not need to
   11128   // be valid for proxy because the MockSSLClientSocket does
   11129   // not actually verify it.  But SpdySession will use this
   11130   // to see if it is valid for the new origin
   11131   base::FilePath certs_dir = GetTestCertsDirectory();
   11132   scoped_refptr<X509Certificate> server_cert(
   11133       ImportCertFromFile(certs_dir, "ok_cert.pem"));
   11134   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
   11135 
   11136   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   11137   ssl1.SetNextProto(GetParam());
   11138   ssl1.cert = server_cert;
   11139   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11140   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11141       data1.get());
   11142 
   11143   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   11144   ssl2.SetNextProto(GetParam());
   11145   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11146   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11147       data2.get());
   11148 
   11149   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   11150   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
   11151   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
   11152 
   11153   scoped_refptr<HttpNetworkSession> session(
   11154       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11155 
   11156   // Start the first transaction to set up the SpdySession
   11157   HttpRequestInfo request1;
   11158   request1.method = "GET";
   11159   request1.url = GURL(url1);
   11160   request1.load_flags = 0;
   11161   HttpNetworkTransaction trans1(LOWEST, session.get());
   11162   TestCompletionCallback callback1;
   11163   ASSERT_EQ(ERR_IO_PENDING,
   11164             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11165   data1->RunFor(3);
   11166 
   11167   ASSERT_TRUE(callback1.have_result());
   11168   EXPECT_EQ(OK, callback1.WaitForResult());
   11169   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11170 
   11171   // Now, start the HTTP request
   11172   HttpRequestInfo request2;
   11173   request2.method = "GET";
   11174   request2.url = GURL(url2);
   11175   request2.load_flags = 0;
   11176   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11177   TestCompletionCallback callback2;
   11178   EXPECT_EQ(ERR_IO_PENDING,
   11179             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11180   base::MessageLoop::current()->RunUntilIdle();
   11181   data2->RunFor(3);
   11182 
   11183   ASSERT_TRUE(callback2.have_result());
   11184   EXPECT_EQ(OK, callback2.WaitForResult());
   11185   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11186 }
   11187 
   11188 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
   11189 // error) in SPDY session, removes the socket from pool and closes the SPDY
   11190 // session. Verify that new url's from the same HttpNetworkSession (and a new
   11191 // SpdySession) do work. http://crbug.com/224701
   11192 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
   11193   const std::string https_url = "https://www.google.com/";
   11194 
   11195   MockRead reads1[] = {
   11196     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
   11197   };
   11198 
   11199   scoped_ptr<DeterministicSocketData> data1(
   11200       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
   11201   data1->SetStop(1);
   11202 
   11203   scoped_ptr<SpdyFrame> req2(
   11204       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
   11205   MockWrite writes2[] = {
   11206     CreateMockWrite(*req2, 0),
   11207   };
   11208 
   11209   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11210   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11211   MockRead reads2[] = {
   11212     CreateMockRead(*resp2, 1),
   11213     CreateMockRead(*body2, 2),
   11214     MockRead(ASYNC, OK, 3)  // EOF
   11215   };
   11216 
   11217   scoped_ptr<DeterministicSocketData> data2(
   11218       new DeterministicSocketData(reads2, arraysize(reads2),
   11219                                   writes2, arraysize(writes2)));
   11220 
   11221   SSLSocketDataProvider ssl1(ASYNC, OK);
   11222   ssl1.SetNextProto(GetParam());
   11223   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11224   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11225       data1.get());
   11226 
   11227   SSLSocketDataProvider ssl2(ASYNC, OK);
   11228   ssl2.SetNextProto(GetParam());
   11229   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11230   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11231       data2.get());
   11232 
   11233   scoped_refptr<HttpNetworkSession> session(
   11234       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11235 
   11236   // Start the first transaction to set up the SpdySession and verify that
   11237   // connection was closed.
   11238   HttpRequestInfo request1;
   11239   request1.method = "GET";
   11240   request1.url = GURL(https_url);
   11241   request1.load_flags = 0;
   11242   HttpNetworkTransaction trans1(MEDIUM, session.get());
   11243   TestCompletionCallback callback1;
   11244   EXPECT_EQ(ERR_IO_PENDING,
   11245             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11246   base::MessageLoop::current()->RunUntilIdle();
   11247   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
   11248 
   11249   // Now, start the second request and make sure it succeeds.
   11250   HttpRequestInfo request2;
   11251   request2.method = "GET";
   11252   request2.url = GURL(https_url);
   11253   request2.load_flags = 0;
   11254   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11255   TestCompletionCallback callback2;
   11256   EXPECT_EQ(ERR_IO_PENDING,
   11257             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11258   base::MessageLoop::current()->RunUntilIdle();
   11259   data2->RunFor(3);
   11260 
   11261   ASSERT_TRUE(callback2.have_result());
   11262   EXPECT_EQ(OK, callback2.WaitForResult());
   11263   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11264 }
   11265 
   11266 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
   11267   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   11268   ClientSocketPoolManager::set_max_sockets_per_group(
   11269       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11270   ClientSocketPoolManager::set_max_sockets_per_pool(
   11271       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11272 
   11273   // Use two different hosts with different IPs so they don't get pooled.
   11274   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
   11275   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
   11276   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11277 
   11278   SSLSocketDataProvider ssl1(ASYNC, OK);
   11279   ssl1.SetNextProto(GetParam());
   11280   SSLSocketDataProvider ssl2(ASYNC, OK);
   11281   ssl2.SetNextProto(GetParam());
   11282   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   11283   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   11284 
   11285   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
   11286       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
   11287   MockWrite spdy1_writes[] = {
   11288     CreateMockWrite(*host1_req, 1),
   11289   };
   11290   scoped_ptr<SpdyFrame> host1_resp(
   11291       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11292   scoped_ptr<SpdyFrame> host1_resp_body(
   11293       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11294   MockRead spdy1_reads[] = {
   11295     CreateMockRead(*host1_resp, 2),
   11296     CreateMockRead(*host1_resp_body, 3),
   11297     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11298   };
   11299 
   11300   scoped_ptr<OrderedSocketData> spdy1_data(
   11301       new OrderedSocketData(
   11302           spdy1_reads, arraysize(spdy1_reads),
   11303           spdy1_writes, arraysize(spdy1_writes)));
   11304   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
   11305 
   11306   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
   11307       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
   11308   MockWrite spdy2_writes[] = {
   11309     CreateMockWrite(*host2_req, 1),
   11310   };
   11311   scoped_ptr<SpdyFrame> host2_resp(
   11312       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11313   scoped_ptr<SpdyFrame> host2_resp_body(
   11314       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11315   MockRead spdy2_reads[] = {
   11316     CreateMockRead(*host2_resp, 2),
   11317     CreateMockRead(*host2_resp_body, 3),
   11318     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11319   };
   11320 
   11321   scoped_ptr<OrderedSocketData> spdy2_data(
   11322       new OrderedSocketData(
   11323           spdy2_reads, arraysize(spdy2_reads),
   11324           spdy2_writes, arraysize(spdy2_writes)));
   11325   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
   11326 
   11327   MockWrite http_write[] = {
   11328     MockWrite("GET / HTTP/1.1\r\n"
   11329               "Host: www.a.com\r\n"
   11330               "Connection: keep-alive\r\n\r\n"),
   11331   };
   11332 
   11333   MockRead http_read[] = {
   11334     MockRead("HTTP/1.1 200 OK\r\n"),
   11335     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   11336     MockRead("Content-Length: 6\r\n\r\n"),
   11337     MockRead("hello!"),
   11338   };
   11339   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
   11340                                      http_write, arraysize(http_write));
   11341   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   11342 
   11343   HostPortPair host_port_pair_a("www.a.com", 443);
   11344   SpdySessionKey spdy_session_key_a(
   11345       host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
   11346   EXPECT_FALSE(
   11347       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11348 
   11349   TestCompletionCallback callback;
   11350   HttpRequestInfo request1;
   11351   request1.method = "GET";
   11352   request1.url = GURL("https://www.a.com/");
   11353   request1.load_flags = 0;
   11354   scoped_ptr<HttpNetworkTransaction> trans(
   11355       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11356 
   11357   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   11358   EXPECT_EQ(ERR_IO_PENDING, rv);
   11359   EXPECT_EQ(OK, callback.WaitForResult());
   11360 
   11361   const HttpResponseInfo* response = trans->GetResponseInfo();
   11362   ASSERT_TRUE(response != NULL);
   11363   ASSERT_TRUE(response->headers.get() != NULL);
   11364   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11365   EXPECT_TRUE(response->was_fetched_via_spdy);
   11366   EXPECT_TRUE(response->was_npn_negotiated);
   11367 
   11368   std::string response_data;
   11369   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11370   EXPECT_EQ("hello!", response_data);
   11371   trans.reset();
   11372   EXPECT_TRUE(
   11373       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11374 
   11375   HostPortPair host_port_pair_b("www.b.com", 443);
   11376   SpdySessionKey spdy_session_key_b(
   11377       host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
   11378   EXPECT_FALSE(
   11379       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11380   HttpRequestInfo request2;
   11381   request2.method = "GET";
   11382   request2.url = GURL("https://www.b.com/");
   11383   request2.load_flags = 0;
   11384   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11385 
   11386   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
   11387   EXPECT_EQ(ERR_IO_PENDING, rv);
   11388   EXPECT_EQ(OK, callback.WaitForResult());
   11389 
   11390   response = trans->GetResponseInfo();
   11391   ASSERT_TRUE(response != NULL);
   11392   ASSERT_TRUE(response->headers.get() != NULL);
   11393   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11394   EXPECT_TRUE(response->was_fetched_via_spdy);
   11395   EXPECT_TRUE(response->was_npn_negotiated);
   11396   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11397   EXPECT_EQ("hello!", response_data);
   11398   EXPECT_FALSE(
   11399       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11400   EXPECT_TRUE(
   11401       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11402 
   11403   HostPortPair host_port_pair_a1("www.a.com", 80);
   11404   SpdySessionKey spdy_session_key_a1(
   11405       host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
   11406   EXPECT_FALSE(
   11407       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
   11408   HttpRequestInfo request3;
   11409   request3.method = "GET";
   11410   request3.url = GURL("http://www.a.com/");
   11411   request3.load_flags = 0;
   11412   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11413 
   11414   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
   11415   EXPECT_EQ(ERR_IO_PENDING, rv);
   11416   EXPECT_EQ(OK, callback.WaitForResult());
   11417 
   11418   response = trans->GetResponseInfo();
   11419   ASSERT_TRUE(response != NULL);
   11420   ASSERT_TRUE(response->headers.get() != NULL);
   11421   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11422   EXPECT_FALSE(response->was_fetched_via_spdy);
   11423   EXPECT_FALSE(response->was_npn_negotiated);
   11424   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11425   EXPECT_EQ("hello!", response_data);
   11426   EXPECT_FALSE(
   11427       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11428   EXPECT_FALSE(
   11429       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11430 }
   11431 
   11432 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
   11433   HttpRequestInfo request;
   11434   request.method = "GET";
   11435   request.url = GURL("http://www.google.com/");
   11436   request.load_flags = 0;
   11437 
   11438   scoped_ptr<HttpTransaction> trans(
   11439       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11440                                  CreateSession(&session_deps_)));
   11441 
   11442   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
   11443   StaticSocketDataProvider data;
   11444   data.set_connect_data(mock_connect);
   11445   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11446 
   11447   TestCompletionCallback callback;
   11448 
   11449   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11450   EXPECT_EQ(ERR_IO_PENDING, rv);
   11451 
   11452   rv = callback.WaitForResult();
   11453   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   11454 
   11455   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11456 
   11457   // We don't care whether this succeeds or fails, but it shouldn't crash.
   11458   HttpRequestHeaders request_headers;
   11459   trans->GetFullRequestHeaders(&request_headers);
   11460 }
   11461 
   11462 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
   11463   HttpRequestInfo request;
   11464   request.method = "GET";
   11465   request.url = GURL("http://www.google.com/");
   11466   request.load_flags = 0;
   11467 
   11468   scoped_ptr<HttpTransaction> trans(
   11469       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11470                                  CreateSession(&session_deps_)));
   11471 
   11472   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   11473   StaticSocketDataProvider data;
   11474   data.set_connect_data(mock_connect);
   11475   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11476 
   11477   TestCompletionCallback callback;
   11478 
   11479   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11480   EXPECT_EQ(ERR_IO_PENDING, rv);
   11481 
   11482   rv = callback.WaitForResult();
   11483   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   11484 
   11485   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11486 
   11487   // We don't care whether this succeeds or fails, but it shouldn't crash.
   11488   HttpRequestHeaders request_headers;
   11489   trans->GetFullRequestHeaders(&request_headers);
   11490 }
   11491 
   11492 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
   11493   HttpRequestInfo request;
   11494   request.method = "GET";
   11495   request.url = GURL("http://www.google.com/");
   11496   request.load_flags = 0;
   11497 
   11498   scoped_ptr<HttpTransaction> trans(
   11499       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11500                                  CreateSession(&session_deps_)));
   11501 
   11502   MockWrite data_writes[] = {
   11503     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   11504   };
   11505   MockRead data_reads[] = {
   11506     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   11507   };
   11508 
   11509   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11510                                 data_writes, arraysize(data_writes));
   11511   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11512 
   11513   TestCompletionCallback callback;
   11514 
   11515   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11516   EXPECT_EQ(ERR_IO_PENDING, rv);
   11517 
   11518   rv = callback.WaitForResult();
   11519   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11520 
   11521   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11522 
   11523   HttpRequestHeaders request_headers;
   11524   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11525   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11526 }
   11527 
   11528 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
   11529   HttpRequestInfo request;
   11530   request.method = "GET";
   11531   request.url = GURL("http://www.google.com/");
   11532   request.load_flags = 0;
   11533 
   11534   scoped_ptr<HttpTransaction> trans(
   11535       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11536                                  CreateSession(&session_deps_)));
   11537 
   11538   MockWrite data_writes[] = {
   11539     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   11540   };
   11541   MockRead data_reads[] = {
   11542     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   11543   };
   11544 
   11545   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11546                                 data_writes, arraysize(data_writes));
   11547   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11548 
   11549   TestCompletionCallback callback;
   11550 
   11551   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11552   EXPECT_EQ(ERR_IO_PENDING, rv);
   11553 
   11554   rv = callback.WaitForResult();
   11555   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11556 
   11557   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11558 
   11559   HttpRequestHeaders request_headers;
   11560   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11561   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11562 }
   11563 
   11564 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
   11565   HttpRequestInfo request;
   11566   request.method = "GET";
   11567   request.url = GURL("http://www.google.com/");
   11568   request.load_flags = 0;
   11569 
   11570   scoped_ptr<HttpTransaction> trans(
   11571       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11572                                  CreateSession(&session_deps_)));
   11573 
   11574   MockWrite data_writes[] = {
   11575     MockWrite("GET / HTTP/1.1\r\n"
   11576               "Host: www.google.com\r\n"
   11577               "Connection: keep-alive\r\n\r\n"),
   11578   };
   11579   MockRead data_reads[] = {
   11580     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
   11581   };
   11582 
   11583   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11584                                 data_writes, arraysize(data_writes));
   11585   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11586 
   11587   TestCompletionCallback callback;
   11588 
   11589   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11590   EXPECT_EQ(ERR_IO_PENDING, rv);
   11591 
   11592   rv = callback.WaitForResult();
   11593   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11594 
   11595   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11596 
   11597   HttpRequestHeaders request_headers;
   11598   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11599   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11600 }
   11601 
   11602 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
   11603   HttpRequestInfo request;
   11604   request.method = "GET";
   11605   request.url = GURL("http://www.google.com/");
   11606   request.load_flags = 0;
   11607 
   11608   scoped_ptr<HttpTransaction> trans(
   11609       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11610                                  CreateSession(&session_deps_)));
   11611 
   11612   MockWrite data_writes[] = {
   11613     MockWrite("GET / HTTP/1.1\r\n"
   11614               "Host: www.google.com\r\n"
   11615               "Connection: keep-alive\r\n\r\n"),
   11616   };
   11617   MockRead data_reads[] = {
   11618     MockRead(ASYNC, ERR_CONNECTION_RESET),
   11619   };
   11620 
   11621   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11622                                 data_writes, arraysize(data_writes));
   11623   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11624 
   11625   TestCompletionCallback callback;
   11626 
   11627   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11628   EXPECT_EQ(ERR_IO_PENDING, rv);
   11629 
   11630   rv = callback.WaitForResult();
   11631   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11632 
   11633   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11634 
   11635   HttpRequestHeaders request_headers;
   11636   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11637   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11638 }
   11639 
   11640 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
   11641   HttpRequestInfo request;
   11642   request.method = "GET";
   11643   request.url = GURL("http://www.google.com/");
   11644   request.load_flags = 0;
   11645   request.extra_headers.SetHeader("X-Foo", "bar");
   11646 
   11647   scoped_ptr<HttpTransaction> trans(
   11648       new HttpNetworkTransaction(DEFAULT_PRIORITY,
   11649                                  CreateSession(&session_deps_)));
   11650 
   11651   MockWrite data_writes[] = {
   11652     MockWrite("GET / HTTP/1.1\r\n"
   11653               "Host: www.google.com\r\n"
   11654               "Connection: keep-alive\r\n"
   11655               "X-Foo: bar\r\n\r\n"),
   11656   };
   11657   MockRead data_reads[] = {
   11658     MockRead("HTTP/1.1 200 OK\r\n"
   11659              "Content-Length: 5\r\n\r\n"
   11660              "hello"),
   11661     MockRead(ASYNC, ERR_UNEXPECTED),
   11662   };
   11663 
   11664   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11665                                 data_writes, arraysize(data_writes));
   11666   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11667 
   11668   TestCompletionCallback callback;
   11669 
   11670   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11671   EXPECT_EQ(ERR_IO_PENDING, rv);
   11672 
   11673   rv = callback.WaitForResult();
   11674   EXPECT_EQ(OK, rv);
   11675 
   11676   HttpRequestHeaders request_headers;
   11677   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11678   std::string foo;
   11679   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
   11680   EXPECT_EQ("bar", foo);
   11681 }
   11682 
   11683 }  // namespace net
   11684