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/memory/weak_ptr.h"
     19 #include "base/strings/string_util.h"
     20 #include "base/strings/utf_string_conversions.h"
     21 #include "base/test/test_file_util.h"
     22 #include "net/base/auth.h"
     23 #include "net/base/capturing_net_log.h"
     24 #include "net/base/completion_callback.h"
     25 #include "net/base/load_timing_info.h"
     26 #include "net/base/load_timing_info_test_util.h"
     27 #include "net/base/net_log.h"
     28 #include "net/base/net_log_unittest.h"
     29 #include "net/base/request_priority.h"
     30 #include "net/base/test_completion_callback.h"
     31 #include "net/base/test_data_directory.h"
     32 #include "net/base/upload_bytes_element_reader.h"
     33 #include "net/base/upload_data_stream.h"
     34 #include "net/base/upload_file_element_reader.h"
     35 #include "net/cert/mock_cert_verifier.h"
     36 #include "net/dns/host_cache.h"
     37 #include "net/dns/mock_host_resolver.h"
     38 #include "net/http/http_auth_handler_digest.h"
     39 #include "net/http/http_auth_handler_mock.h"
     40 #include "net/http/http_auth_handler_ntlm.h"
     41 #include "net/http/http_basic_stream.h"
     42 #include "net/http/http_network_session.h"
     43 #include "net/http/http_network_session_peer.h"
     44 #include "net/http/http_server_properties_impl.h"
     45 #include "net/http/http_stream.h"
     46 #include "net/http/http_stream_factory.h"
     47 #include "net/http/http_transaction_unittest.h"
     48 #include "net/proxy/proxy_config_service_fixed.h"
     49 #include "net/proxy/proxy_info.h"
     50 #include "net/proxy/proxy_resolver.h"
     51 #include "net/proxy/proxy_service.h"
     52 #include "net/socket/client_socket_factory.h"
     53 #include "net/socket/client_socket_pool_manager.h"
     54 #include "net/socket/mock_client_socket_pool_manager.h"
     55 #include "net/socket/next_proto.h"
     56 #include "net/socket/socket_test_util.h"
     57 #include "net/socket/ssl_client_socket.h"
     58 #include "net/spdy/spdy_framer.h"
     59 #include "net/spdy/spdy_session.h"
     60 #include "net/spdy/spdy_session_pool.h"
     61 #include "net/spdy/spdy_test_util_common.h"
     62 #include "net/ssl/ssl_cert_request_info.h"
     63 #include "net/ssl/ssl_config_service.h"
     64 #include "net/ssl/ssl_config_service_defaults.h"
     65 #include "net/ssl/ssl_info.h"
     66 #include "net/test/cert_test_util.h"
     67 #include "net/websockets/websocket_handshake_stream_base.h"
     68 #include "testing/gtest/include/gtest/gtest.h"
     69 #include "testing/platform_test.h"
     70 #include "url/gurl.h"
     71 
     72 //-----------------------------------------------------------------------------
     73 
     74 namespace {
     75 
     76 const base::string16 kBar(ASCIIToUTF16("bar"));
     77 const base::string16 kBar2(ASCIIToUTF16("bar2"));
     78 const base::string16 kBar3(ASCIIToUTF16("bar3"));
     79 const base::string16 kBaz(ASCIIToUTF16("baz"));
     80 const base::string16 kFirst(ASCIIToUTF16("first"));
     81 const base::string16 kFoo(ASCIIToUTF16("foo"));
     82 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
     83 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
     84 const base::string16 kFou(ASCIIToUTF16("fou"));
     85 const base::string16 kSecond(ASCIIToUTF16("second"));
     86 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
     87 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
     88 
     89 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
     90   return session->GetTransportSocketPool(
     91       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     92 }
     93 
     94 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
     95   return session->GetSSLSocketPool(
     96       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     97 }
     98 
     99 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
    100   return session->GetTransportSocketPool(
    101       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
    102 }
    103 
    104 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
    105 // a JSONified list of headers as a single string.  Uses single quotes instead
    106 // of double quotes for easier comparison.  Returns false on failure.
    107 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
    108   if (!params)
    109     return false;
    110   base::ListValue* header_list;
    111   if (!params->GetList("headers", &header_list))
    112     return false;
    113   std::string double_quote_headers;
    114   base::JSONWriter::Write(header_list, &double_quote_headers);
    115   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
    116   return true;
    117 }
    118 
    119 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
    120 // used.
    121 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
    122   EXPECT_TRUE(load_timing_info.socket_reused);
    123   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    124 
    125   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    126   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    127 
    128   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    129   EXPECT_FALSE(load_timing_info.send_start.is_null());
    130 
    131   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    132 
    133   // Set at a higher level.
    134   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    135   EXPECT_TRUE(load_timing_info.request_start.is_null());
    136   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    137 }
    138 
    139 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
    140 // used.
    141 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
    142                              int connect_timing_flags) {
    143   EXPECT_FALSE(load_timing_info.socket_reused);
    144   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    145 
    146   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    147   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    148 
    149   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    150                                    connect_timing_flags);
    151   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    152             load_timing_info.send_start);
    153 
    154   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    155 
    156   // Set at a higher level.
    157   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    158   EXPECT_TRUE(load_timing_info.request_start.is_null());
    159   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    160 }
    161 
    162 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
    163 // used.
    164 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
    165   EXPECT_TRUE(load_timing_info.socket_reused);
    166   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    167 
    168   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    169 
    170   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    171   EXPECT_LE(load_timing_info.proxy_resolve_start,
    172             load_timing_info.proxy_resolve_end);
    173   EXPECT_LE(load_timing_info.proxy_resolve_end,
    174             load_timing_info.send_start);
    175   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    176 
    177   // Set at a higher level.
    178   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    179   EXPECT_TRUE(load_timing_info.request_start.is_null());
    180   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    181 }
    182 
    183 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
    184 // used.
    185 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
    186                                     int connect_timing_flags) {
    187   EXPECT_FALSE(load_timing_info.socket_reused);
    188   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    189 
    190   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    191   EXPECT_LE(load_timing_info.proxy_resolve_start,
    192             load_timing_info.proxy_resolve_end);
    193   EXPECT_LE(load_timing_info.proxy_resolve_end,
    194             load_timing_info.connect_timing.connect_start);
    195   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    196                                    connect_timing_flags);
    197   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    198             load_timing_info.send_start);
    199 
    200   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    201 
    202   // Set at a higher level.
    203   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    204   EXPECT_TRUE(load_timing_info.request_start.is_null());
    205   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    206 }
    207 
    208 }  // namespace
    209 
    210 namespace net {
    211 
    212 namespace {
    213 
    214 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
    215   return SpdySessionDependencies::SpdyCreateSession(session_deps);
    216 }
    217 
    218 }  // namespace
    219 
    220 class HttpNetworkTransactionTest
    221     : public PlatformTest,
    222       public ::testing::WithParamInterface<NextProto> {
    223  public:
    224   virtual ~HttpNetworkTransactionTest() {
    225     // Important to restore the per-pool limit first, since the pool limit must
    226     // always be greater than group limit, and the tests reduce both limits.
    227     ClientSocketPoolManager::set_max_sockets_per_pool(
    228         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    229     ClientSocketPoolManager::set_max_sockets_per_group(
    230         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    231   }
    232 
    233  protected:
    234   HttpNetworkTransactionTest()
    235       : spdy_util_(GetParam()),
    236         session_deps_(GetParam()),
    237         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    238             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    239         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    240             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
    241   }
    242 
    243   struct SimpleGetHelperResult {
    244     int rv;
    245     std::string status_line;
    246     std::string response_data;
    247     LoadTimingInfo load_timing_info;
    248   };
    249 
    250   virtual void SetUp() {
    251     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    252     base::MessageLoop::current()->RunUntilIdle();
    253   }
    254 
    255   virtual void TearDown() {
    256     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    257     base::MessageLoop::current()->RunUntilIdle();
    258     // Empty the current queue.
    259     base::MessageLoop::current()->RunUntilIdle();
    260     PlatformTest::TearDown();
    261     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    262     base::MessageLoop::current()->RunUntilIdle();
    263     HttpStreamFactory::set_use_alternate_protocols(false);
    264     HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
    265   }
    266 
    267   // This is the expected return from a current server advertising SPDY.
    268   std::string GetAlternateProtocolHttpHeader() {
    269     return
    270         std::string("Alternate-Protocol: 443:") +
    271         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
    272         "\r\n\r\n";
    273   }
    274 
    275   // Either |write_failure| specifies a write failure or |read_failure|
    276   // specifies a read failure when using a reused socket.  In either case, the
    277   // failure should cause the network transaction to resend the request, and the
    278   // other argument should be NULL.
    279   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
    280                                             const MockRead* read_failure);
    281 
    282   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
    283                                                size_t data_count) {
    284     SimpleGetHelperResult out;
    285 
    286     HttpRequestInfo request;
    287     request.method = "GET";
    288     request.url = GURL("http://www.google.com/");
    289     request.load_flags = 0;
    290 
    291     CapturingBoundNetLog log;
    292     session_deps_.net_log = log.bound().net_log();
    293     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    294     scoped_ptr<HttpTransaction> trans(
    295         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    296 
    297     for (size_t i = 0; i < data_count; ++i) {
    298       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
    299     }
    300 
    301     TestCompletionCallback callback;
    302 
    303     EXPECT_TRUE(log.bound().IsLoggingAllEvents());
    304     int rv = trans->Start(&request, callback.callback(), log.bound());
    305     EXPECT_EQ(ERR_IO_PENDING, rv);
    306 
    307     out.rv = callback.WaitForResult();
    308 
    309     // Even in the failure cases that use this function, connections are always
    310     // successfully established before the error.
    311     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
    312     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
    313 
    314     if (out.rv != OK)
    315       return out;
    316 
    317     const HttpResponseInfo* response = trans->GetResponseInfo();
    318     // Can't use ASSERT_* inside helper functions like this, so
    319     // return an error.
    320     if (response == NULL || response->headers.get() == NULL) {
    321       out.rv = ERR_UNEXPECTED;
    322       return out;
    323     }
    324     out.status_line = response->headers->GetStatusLine();
    325 
    326     EXPECT_EQ("127.0.0.1", response->socket_address.host());
    327     EXPECT_EQ(80, response->socket_address.port());
    328 
    329     rv = ReadTransaction(trans.get(), &out.response_data);
    330     EXPECT_EQ(OK, rv);
    331 
    332     net::CapturingNetLog::CapturedEntryList entries;
    333     log.GetEntries(&entries);
    334     size_t pos = ExpectLogContainsSomewhere(
    335         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
    336         NetLog::PHASE_NONE);
    337     ExpectLogContainsSomewhere(
    338         entries, pos,
    339         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
    340         NetLog::PHASE_NONE);
    341 
    342     std::string line;
    343     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
    344     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
    345 
    346     HttpRequestHeaders request_headers;
    347     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
    348     std::string value;
    349     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
    350     EXPECT_EQ("www.google.com", value);
    351     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
    352     EXPECT_EQ("keep-alive", value);
    353 
    354     std::string response_headers;
    355     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
    356     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
    357               response_headers);
    358 
    359     return out;
    360   }
    361 
    362   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
    363                                         size_t reads_count) {
    364     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
    365     StaticSocketDataProvider* data[] = { &reads };
    366     return SimpleGetHelperForData(data, 1);
    367   }
    368 
    369   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    370                                              int expected_status);
    371 
    372   void ConnectStatusHelper(const MockRead& status);
    373 
    374   void BypassHostCacheOnRefreshHelper(int load_flags);
    375 
    376   void CheckErrorIsPassedBack(int error, IoMode mode);
    377 
    378   SpdyTestUtil spdy_util_;
    379   SpdySessionDependencies session_deps_;
    380 
    381   // Original socket limits.  Some tests set these.  Safest to always restore
    382   // them once each test has been run.
    383   int old_max_group_sockets_;
    384   int old_max_pool_sockets_;
    385 };
    386 
    387 INSTANTIATE_TEST_CASE_P(
    388     NextProto,
    389     HttpNetworkTransactionTest,
    390     testing::Values(kProtoDeprecatedSPDY2,
    391                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4a2,
    392                     kProtoHTTP2Draft04));
    393 
    394 namespace {
    395 
    396 // Fill |str| with a long header list that consumes >= |size| bytes.
    397 void FillLargeHeadersString(std::string* str, int size) {
    398   const char* row =
    399       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    400   const int sizeof_row = strlen(row);
    401   const int num_rows = static_cast<int>(
    402       ceil(static_cast<float>(size) / sizeof_row));
    403   const int sizeof_data = num_rows * sizeof_row;
    404   DCHECK(sizeof_data >= size);
    405   str->reserve(sizeof_data);
    406 
    407   for (int i = 0; i < num_rows; ++i)
    408     str->append(row, sizeof_row);
    409 }
    410 
    411 // Alternative functions that eliminate randomness and dependency on the local
    412 // host name so that the generated NTLM messages are reproducible.
    413 void MockGenerateRandom1(uint8* output, size_t n) {
    414   static const uint8 bytes[] = {
    415     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    416   };
    417   static size_t current_byte = 0;
    418   for (size_t i = 0; i < n; ++i) {
    419     output[i] = bytes[current_byte++];
    420     current_byte %= arraysize(bytes);
    421   }
    422 }
    423 
    424 void MockGenerateRandom2(uint8* output, size_t n) {
    425   static const uint8 bytes[] = {
    426     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    427     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    428   };
    429   static size_t current_byte = 0;
    430   for (size_t i = 0; i < n; ++i) {
    431     output[i] = bytes[current_byte++];
    432     current_byte %= arraysize(bytes);
    433   }
    434 }
    435 
    436 std::string MockGetHostName() {
    437   return "WTC-WIN7";
    438 }
    439 
    440 template<typename ParentPool>
    441 class CaptureGroupNameSocketPool : public ParentPool {
    442  public:
    443   CaptureGroupNameSocketPool(HostResolver* host_resolver,
    444                              CertVerifier* cert_verifier);
    445 
    446   const std::string last_group_name_received() const {
    447     return last_group_name_;
    448   }
    449 
    450   virtual int RequestSocket(const std::string& group_name,
    451                             const void* socket_params,
    452                             RequestPriority priority,
    453                             ClientSocketHandle* handle,
    454                             const CompletionCallback& callback,
    455                             const BoundNetLog& net_log) {
    456     last_group_name_ = group_name;
    457     return ERR_IO_PENDING;
    458   }
    459   virtual void CancelRequest(const std::string& group_name,
    460                              ClientSocketHandle* handle) {}
    461   virtual void ReleaseSocket(const std::string& group_name,
    462                              scoped_ptr<StreamSocket> socket,
    463                              int id) {}
    464   virtual void CloseIdleSockets() {}
    465   virtual int IdleSocketCount() const {
    466     return 0;
    467   }
    468   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    469     return 0;
    470   }
    471   virtual LoadState GetLoadState(const std::string& group_name,
    472                                  const ClientSocketHandle* handle) const {
    473     return LOAD_STATE_IDLE;
    474   }
    475   virtual base::TimeDelta ConnectionTimeout() const {
    476     return base::TimeDelta();
    477   }
    478 
    479  private:
    480   std::string last_group_name_;
    481 };
    482 
    483 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
    484 CaptureGroupNameTransportSocketPool;
    485 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
    486 CaptureGroupNameHttpProxySocketPool;
    487 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
    488 CaptureGroupNameSOCKSSocketPool;
    489 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
    490 CaptureGroupNameSSLSocketPool;
    491 
    492 template<typename ParentPool>
    493 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
    494     HostResolver* host_resolver,
    495     CertVerifier* /* cert_verifier */)
    496     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
    497 
    498 template<>
    499 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
    500     HostResolver* host_resolver,
    501     CertVerifier* /* cert_verifier */)
    502     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
    503 
    504 template <>
    505 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
    506     HostResolver* host_resolver,
    507     CertVerifier* cert_verifier)
    508     : SSLClientSocketPool(0,
    509                           0,
    510                           NULL,
    511                           host_resolver,
    512                           cert_verifier,
    513                           NULL,
    514                           NULL,
    515                           NULL,
    516                           std::string(),
    517                           NULL,
    518                           NULL,
    519                           NULL,
    520                           NULL,
    521                           NULL,
    522                           NULL) {}
    523 
    524 //-----------------------------------------------------------------------------
    525 
    526 // Helper functions for validating that AuthChallengeInfo's are correctly
    527 // configured for common cases.
    528 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
    529   if (!auth_challenge)
    530     return false;
    531   EXPECT_FALSE(auth_challenge->is_proxy);
    532   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    533   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    534   EXPECT_EQ("basic", auth_challenge->scheme);
    535   return true;
    536 }
    537 
    538 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
    539   if (!auth_challenge)
    540     return false;
    541   EXPECT_TRUE(auth_challenge->is_proxy);
    542   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
    543   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    544   EXPECT_EQ("basic", auth_challenge->scheme);
    545   return true;
    546 }
    547 
    548 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
    549   if (!auth_challenge)
    550     return false;
    551   EXPECT_FALSE(auth_challenge->is_proxy);
    552   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    553   EXPECT_EQ("digestive", auth_challenge->realm);
    554   EXPECT_EQ("digest", auth_challenge->scheme);
    555   return true;
    556 }
    557 
    558 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
    559   if (!auth_challenge)
    560     return false;
    561   EXPECT_FALSE(auth_challenge->is_proxy);
    562   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
    563   EXPECT_EQ(std::string(), auth_challenge->realm);
    564   EXPECT_EQ("ntlm", auth_challenge->scheme);
    565   return true;
    566 }
    567 
    568 }  // namespace
    569 
    570 TEST_P(HttpNetworkTransactionTest, Basic) {
    571   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    572   scoped_ptr<HttpTransaction> trans(
    573       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    574 }
    575 
    576 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
    577   MockRead data_reads[] = {
    578     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    579     MockRead("hello world"),
    580     MockRead(SYNCHRONOUS, OK),
    581   };
    582   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    583                                               arraysize(data_reads));
    584   EXPECT_EQ(OK, out.rv);
    585   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    586   EXPECT_EQ("hello world", out.response_data);
    587 }
    588 
    589 // Response with no status line.
    590 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    591   MockRead data_reads[] = {
    592     MockRead("hello world"),
    593     MockRead(SYNCHRONOUS, OK),
    594   };
    595   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    596                                               arraysize(data_reads));
    597   EXPECT_EQ(OK, out.rv);
    598   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    599   EXPECT_EQ("hello world", out.response_data);
    600 }
    601 
    602 // Allow up to 4 bytes of junk to precede status line.
    603 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
    604   MockRead data_reads[] = {
    605     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    606     MockRead(SYNCHRONOUS, OK),
    607   };
    608   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    609                                               arraysize(data_reads));
    610   EXPECT_EQ(OK, out.rv);
    611   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    612   EXPECT_EQ("DATA", out.response_data);
    613 }
    614 
    615 // Allow up to 4 bytes of junk to precede status line.
    616 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    617   MockRead data_reads[] = {
    618     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    619     MockRead(SYNCHRONOUS, OK),
    620   };
    621   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    622                                               arraysize(data_reads));
    623   EXPECT_EQ(OK, out.rv);
    624   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    625   EXPECT_EQ("DATA", out.response_data);
    626 }
    627 
    628 // Beyond 4 bytes of slop and it should fail to find a status line.
    629 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    630   MockRead data_reads[] = {
    631     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    632     MockRead(SYNCHRONOUS, OK),
    633   };
    634   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    635                                               arraysize(data_reads));
    636   EXPECT_EQ(OK, out.rv);
    637   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    638   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    639 }
    640 
    641 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    642 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    643   MockRead data_reads[] = {
    644     MockRead("\n"),
    645     MockRead("\n"),
    646     MockRead("Q"),
    647     MockRead("J"),
    648     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    649     MockRead(SYNCHRONOUS, OK),
    650   };
    651   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    652                                               arraysize(data_reads));
    653   EXPECT_EQ(OK, out.rv);
    654   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    655   EXPECT_EQ("DATA", out.response_data);
    656 }
    657 
    658 // Close the connection before enough bytes to have a status line.
    659 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
    660   MockRead data_reads[] = {
    661     MockRead("HTT"),
    662     MockRead(SYNCHRONOUS, OK),
    663   };
    664   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    665                                               arraysize(data_reads));
    666   EXPECT_EQ(OK, out.rv);
    667   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    668   EXPECT_EQ("HTT", out.response_data);
    669 }
    670 
    671 // Simulate a 204 response, lacking a Content-Length header, sent over a
    672 // persistent connection.  The response should still terminate since a 204
    673 // cannot have a response body.
    674 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
    675   MockRead data_reads[] = {
    676     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    677     MockRead("junk"),  // Should not be read!!
    678     MockRead(SYNCHRONOUS, OK),
    679   };
    680   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    681                                               arraysize(data_reads));
    682   EXPECT_EQ(OK, out.rv);
    683   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    684   EXPECT_EQ("", out.response_data);
    685 }
    686 
    687 // A simple request using chunked encoding with some extra data after.
    688 // (Like might be seen in a pipelined response.)
    689 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
    690   MockRead data_reads[] = {
    691     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    692     MockRead("5\r\nHello\r\n"),
    693     MockRead("1\r\n"),
    694     MockRead(" \r\n"),
    695     MockRead("5\r\nworld\r\n"),
    696     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    697     MockRead(SYNCHRONOUS, OK),
    698   };
    699   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    700                                               arraysize(data_reads));
    701   EXPECT_EQ(OK, out.rv);
    702   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    703   EXPECT_EQ("Hello world", out.response_data);
    704 }
    705 
    706 // Next tests deal with http://crbug.com/56344.
    707 
    708 TEST_P(HttpNetworkTransactionTest,
    709        MultipleContentLengthHeadersNoTransferEncoding) {
    710   MockRead data_reads[] = {
    711     MockRead("HTTP/1.1 200 OK\r\n"),
    712     MockRead("Content-Length: 10\r\n"),
    713     MockRead("Content-Length: 5\r\n\r\n"),
    714   };
    715   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    716                                               arraysize(data_reads));
    717   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    718 }
    719 
    720 TEST_P(HttpNetworkTransactionTest,
    721        DuplicateContentLengthHeadersNoTransferEncoding) {
    722   MockRead data_reads[] = {
    723     MockRead("HTTP/1.1 200 OK\r\n"),
    724     MockRead("Content-Length: 5\r\n"),
    725     MockRead("Content-Length: 5\r\n\r\n"),
    726     MockRead("Hello"),
    727   };
    728   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    729                                               arraysize(data_reads));
    730   EXPECT_EQ(OK, out.rv);
    731   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    732   EXPECT_EQ("Hello", out.response_data);
    733 }
    734 
    735 TEST_P(HttpNetworkTransactionTest,
    736        ComplexContentLengthHeadersNoTransferEncoding) {
    737   // More than 2 dupes.
    738   {
    739     MockRead data_reads[] = {
    740       MockRead("HTTP/1.1 200 OK\r\n"),
    741       MockRead("Content-Length: 5\r\n"),
    742       MockRead("Content-Length: 5\r\n"),
    743       MockRead("Content-Length: 5\r\n\r\n"),
    744       MockRead("Hello"),
    745     };
    746     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    747                                                 arraysize(data_reads));
    748     EXPECT_EQ(OK, out.rv);
    749     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    750     EXPECT_EQ("Hello", out.response_data);
    751   }
    752   // HTTP/1.0
    753   {
    754     MockRead data_reads[] = {
    755       MockRead("HTTP/1.0 200 OK\r\n"),
    756       MockRead("Content-Length: 5\r\n"),
    757       MockRead("Content-Length: 5\r\n"),
    758       MockRead("Content-Length: 5\r\n\r\n"),
    759       MockRead("Hello"),
    760     };
    761     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    762                                                 arraysize(data_reads));
    763     EXPECT_EQ(OK, out.rv);
    764     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    765     EXPECT_EQ("Hello", out.response_data);
    766   }
    767   // 2 dupes and one mismatched.
    768   {
    769     MockRead data_reads[] = {
    770       MockRead("HTTP/1.1 200 OK\r\n"),
    771       MockRead("Content-Length: 10\r\n"),
    772       MockRead("Content-Length: 10\r\n"),
    773       MockRead("Content-Length: 5\r\n\r\n"),
    774     };
    775     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    776                                                 arraysize(data_reads));
    777     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    778   }
    779 }
    780 
    781 TEST_P(HttpNetworkTransactionTest,
    782        MultipleContentLengthHeadersTransferEncoding) {
    783   MockRead data_reads[] = {
    784     MockRead("HTTP/1.1 200 OK\r\n"),
    785     MockRead("Content-Length: 666\r\n"),
    786     MockRead("Content-Length: 1337\r\n"),
    787     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
    788     MockRead("5\r\nHello\r\n"),
    789     MockRead("1\r\n"),
    790     MockRead(" \r\n"),
    791     MockRead("5\r\nworld\r\n"),
    792     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    793     MockRead(SYNCHRONOUS, OK),
    794   };
    795   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    796                                               arraysize(data_reads));
    797   EXPECT_EQ(OK, out.rv);
    798   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    799   EXPECT_EQ("Hello world", out.response_data);
    800 }
    801 
    802 // Next tests deal with http://crbug.com/98895.
    803 
    804 // Checks that a single Content-Disposition header results in no error.
    805 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
    806   MockRead data_reads[] = {
    807     MockRead("HTTP/1.1 200 OK\r\n"),
    808     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
    809     MockRead("Content-Length: 5\r\n\r\n"),
    810     MockRead("Hello"),
    811   };
    812   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    813                                               arraysize(data_reads));
    814   EXPECT_EQ(OK, out.rv);
    815   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    816   EXPECT_EQ("Hello", out.response_data);
    817 }
    818 
    819 // Checks that two identical Content-Disposition headers result in no error.
    820 TEST_P(HttpNetworkTransactionTest,
    821        TwoIdenticalContentDispositionHeaders) {
    822   MockRead data_reads[] = {
    823     MockRead("HTTP/1.1 200 OK\r\n"),
    824     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    825     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    826     MockRead("Content-Length: 5\r\n\r\n"),
    827     MockRead("Hello"),
    828   };
    829   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    830                                               arraysize(data_reads));
    831   EXPECT_EQ(OK, out.rv);
    832   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    833   EXPECT_EQ("Hello", out.response_data);
    834 }
    835 
    836 // Checks that two distinct Content-Disposition headers result in an error.
    837 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
    838   MockRead data_reads[] = {
    839     MockRead("HTTP/1.1 200 OK\r\n"),
    840     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    841     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
    842     MockRead("Content-Length: 5\r\n\r\n"),
    843     MockRead("Hello"),
    844   };
    845   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    846                                               arraysize(data_reads));
    847   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
    848 }
    849 
    850 // Checks that two identical Location headers result in no error.
    851 // Also tests Location header behavior.
    852 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
    853   MockRead data_reads[] = {
    854     MockRead("HTTP/1.1 302 Redirect\r\n"),
    855     MockRead("Location: http://good.com/\r\n"),
    856     MockRead("Location: http://good.com/\r\n"),
    857     MockRead("Content-Length: 0\r\n\r\n"),
    858     MockRead(SYNCHRONOUS, OK),
    859   };
    860 
    861   HttpRequestInfo request;
    862   request.method = "GET";
    863   request.url = GURL("http://redirect.com/");
    864   request.load_flags = 0;
    865 
    866   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    867   scoped_ptr<HttpTransaction> trans(
    868       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    869 
    870   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    871   session_deps_.socket_factory->AddSocketDataProvider(&data);
    872 
    873   TestCompletionCallback callback;
    874 
    875   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    876   EXPECT_EQ(ERR_IO_PENDING, rv);
    877 
    878   EXPECT_EQ(OK, callback.WaitForResult());
    879 
    880   const HttpResponseInfo* response = trans->GetResponseInfo();
    881   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
    882   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
    883   std::string url;
    884   EXPECT_TRUE(response->headers->IsRedirect(&url));
    885   EXPECT_EQ("http://good.com/", url);
    886 }
    887 
    888 // Checks that two distinct Location headers result in an error.
    889 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
    890   MockRead data_reads[] = {
    891     MockRead("HTTP/1.1 302 Redirect\r\n"),
    892     MockRead("Location: http://good.com/\r\n"),
    893     MockRead("Location: http://evil.com/\r\n"),
    894     MockRead("Content-Length: 0\r\n\r\n"),
    895     MockRead(SYNCHRONOUS, OK),
    896   };
    897   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    898                                               arraysize(data_reads));
    899   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
    900 }
    901 
    902 // Do a request using the HEAD method. Verify that we don't try to read the
    903 // message body (since HEAD has none).
    904 TEST_P(HttpNetworkTransactionTest, Head) {
    905   HttpRequestInfo request;
    906   request.method = "HEAD";
    907   request.url = GURL("http://www.google.com/");
    908   request.load_flags = 0;
    909 
    910   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    911   scoped_ptr<HttpTransaction> trans(
    912       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    913 
    914   MockWrite data_writes1[] = {
    915     MockWrite("HEAD / HTTP/1.1\r\n"
    916               "Host: www.google.com\r\n"
    917               "Connection: keep-alive\r\n"
    918               "Content-Length: 0\r\n\r\n"),
    919   };
    920   MockRead data_reads1[] = {
    921     MockRead("HTTP/1.1 404 Not Found\r\n"),
    922     MockRead("Server: Blah\r\n"),
    923     MockRead("Content-Length: 1234\r\n\r\n"),
    924 
    925     // No response body because the test stops reading here.
    926     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
    927   };
    928 
    929   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
    930                                  data_writes1, arraysize(data_writes1));
    931   session_deps_.socket_factory->AddSocketDataProvider(&data1);
    932 
    933   TestCompletionCallback callback1;
    934 
    935   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
    936   EXPECT_EQ(ERR_IO_PENDING, rv);
    937 
    938   rv = callback1.WaitForResult();
    939   EXPECT_EQ(OK, rv);
    940 
    941   const HttpResponseInfo* response = trans->GetResponseInfo();
    942   ASSERT_TRUE(response != NULL);
    943 
    944   // Check that the headers got parsed.
    945   EXPECT_TRUE(response->headers.get() != NULL);
    946   EXPECT_EQ(1234, response->headers->GetContentLength());
    947   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
    948 
    949   std::string server_header;
    950   void* iter = NULL;
    951   bool has_server_header = response->headers->EnumerateHeader(
    952       &iter, "Server", &server_header);
    953   EXPECT_TRUE(has_server_header);
    954   EXPECT_EQ("Blah", server_header);
    955 
    956   // Reading should give EOF right away, since there is no message body
    957   // (despite non-zero content-length).
    958   std::string response_data;
    959   rv = ReadTransaction(trans.get(), &response_data);
    960   EXPECT_EQ(OK, rv);
    961   EXPECT_EQ("", response_data);
    962 }
    963 
    964 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
    965   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    966 
    967   MockRead data_reads[] = {
    968     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    969     MockRead("hello"),
    970     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    971     MockRead("world"),
    972     MockRead(SYNCHRONOUS, OK),
    973   };
    974   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    975   session_deps_.socket_factory->AddSocketDataProvider(&data);
    976 
    977   const char* const kExpectedResponseData[] = {
    978     "hello", "world"
    979   };
    980 
    981   for (int i = 0; i < 2; ++i) {
    982     HttpRequestInfo request;
    983     request.method = "GET";
    984     request.url = GURL("http://www.google.com/");
    985     request.load_flags = 0;
    986 
    987     scoped_ptr<HttpTransaction> trans(
    988         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
    989 
    990     TestCompletionCallback callback;
    991 
    992     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    993     EXPECT_EQ(ERR_IO_PENDING, rv);
    994 
    995     rv = callback.WaitForResult();
    996     EXPECT_EQ(OK, rv);
    997 
    998     const HttpResponseInfo* response = trans->GetResponseInfo();
    999     ASSERT_TRUE(response != NULL);
   1000 
   1001     EXPECT_TRUE(response->headers.get() != NULL);
   1002     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1003 
   1004     std::string response_data;
   1005     rv = ReadTransaction(trans.get(), &response_data);
   1006     EXPECT_EQ(OK, rv);
   1007     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1008   }
   1009 }
   1010 
   1011 TEST_P(HttpNetworkTransactionTest, Ignores100) {
   1012   ScopedVector<UploadElementReader> element_readers;
   1013   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   1014   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   1015 
   1016   HttpRequestInfo request;
   1017   request.method = "POST";
   1018   request.url = GURL("http://www.foo.com/");
   1019   request.upload_data_stream = &upload_data_stream;
   1020   request.load_flags = 0;
   1021 
   1022   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1023   scoped_ptr<HttpTransaction> trans(
   1024       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1025 
   1026   MockRead data_reads[] = {
   1027     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   1028     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   1029     MockRead("hello world"),
   1030     MockRead(SYNCHRONOUS, OK),
   1031   };
   1032   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1033   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1034 
   1035   TestCompletionCallback callback;
   1036 
   1037   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1038   EXPECT_EQ(ERR_IO_PENDING, rv);
   1039 
   1040   rv = callback.WaitForResult();
   1041   EXPECT_EQ(OK, rv);
   1042 
   1043   const HttpResponseInfo* response = trans->GetResponseInfo();
   1044   ASSERT_TRUE(response != NULL);
   1045 
   1046   EXPECT_TRUE(response->headers.get() != NULL);
   1047   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   1048 
   1049   std::string response_data;
   1050   rv = ReadTransaction(trans.get(), &response_data);
   1051   EXPECT_EQ(OK, rv);
   1052   EXPECT_EQ("hello world", response_data);
   1053 }
   1054 
   1055 // This test is almost the same as Ignores100 above, but the response contains
   1056 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
   1057 // HTTP/1.1 and the two status headers are read in one read.
   1058 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
   1059   HttpRequestInfo request;
   1060   request.method = "GET";
   1061   request.url = GURL("http://www.foo.com/");
   1062   request.load_flags = 0;
   1063 
   1064   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1065   scoped_ptr<HttpTransaction> trans(
   1066       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1067 
   1068   MockRead data_reads[] = {
   1069     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
   1070              "HTTP/1.1 200 OK\r\n\r\n"),
   1071     MockRead("hello world"),
   1072     MockRead(SYNCHRONOUS, OK),
   1073   };
   1074   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1075   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1076 
   1077   TestCompletionCallback callback;
   1078 
   1079   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1080   EXPECT_EQ(ERR_IO_PENDING, rv);
   1081 
   1082   rv = callback.WaitForResult();
   1083   EXPECT_EQ(OK, rv);
   1084 
   1085   const HttpResponseInfo* response = trans->GetResponseInfo();
   1086   ASSERT_TRUE(response != NULL);
   1087 
   1088   EXPECT_TRUE(response->headers.get() != NULL);
   1089   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1090 
   1091   std::string response_data;
   1092   rv = ReadTransaction(trans.get(), &response_data);
   1093   EXPECT_EQ(OK, rv);
   1094   EXPECT_EQ("hello world", response_data);
   1095 }
   1096 
   1097 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
   1098   HttpRequestInfo request;
   1099   request.method = "POST";
   1100   request.url = GURL("http://www.foo.com/");
   1101   request.load_flags = 0;
   1102 
   1103   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1104   scoped_ptr<HttpTransaction> trans(
   1105       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1106 
   1107   MockRead data_reads[] = {
   1108     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
   1109     MockRead(ASYNC, 0),
   1110   };
   1111   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1112   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1113 
   1114   TestCompletionCallback callback;
   1115 
   1116   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1117   EXPECT_EQ(ERR_IO_PENDING, rv);
   1118 
   1119   rv = callback.WaitForResult();
   1120   EXPECT_EQ(OK, rv);
   1121 
   1122   std::string response_data;
   1123   rv = ReadTransaction(trans.get(), &response_data);
   1124   EXPECT_EQ(OK, rv);
   1125   EXPECT_EQ("", response_data);
   1126 }
   1127 
   1128 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
   1129   HttpRequestInfo request;
   1130   request.method = "POST";
   1131   request.url = GURL("http://www.foo.com/");
   1132   request.load_flags = 0;
   1133 
   1134   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1135   scoped_ptr<HttpTransaction> trans(
   1136       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1137 
   1138 
   1139   MockRead data_reads[] = {
   1140     MockRead(ASYNC, 0),
   1141   };
   1142   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1143   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1144 
   1145   TestCompletionCallback callback;
   1146 
   1147   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1148   EXPECT_EQ(ERR_IO_PENDING, rv);
   1149 
   1150   rv = callback.WaitForResult();
   1151   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   1152 }
   1153 
   1154 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
   1155     const MockWrite* write_failure,
   1156     const MockRead* read_failure) {
   1157   HttpRequestInfo request;
   1158   request.method = "GET";
   1159   request.url = GURL("http://www.foo.com/");
   1160   request.load_flags = 0;
   1161 
   1162   CapturingNetLog net_log;
   1163   session_deps_.net_log = &net_log;
   1164   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1165 
   1166   // Written data for successfully sending both requests.
   1167   MockWrite data1_writes[] = {
   1168     MockWrite("GET / HTTP/1.1\r\n"
   1169               "Host: www.foo.com\r\n"
   1170               "Connection: keep-alive\r\n\r\n"),
   1171     MockWrite("GET / HTTP/1.1\r\n"
   1172               "Host: www.foo.com\r\n"
   1173               "Connection: keep-alive\r\n\r\n")
   1174   };
   1175 
   1176   // Read results for the first request.
   1177   MockRead data1_reads[] = {
   1178     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1179     MockRead("hello"),
   1180     MockRead(ASYNC, OK),
   1181   };
   1182 
   1183   if (write_failure) {
   1184     ASSERT_TRUE(!read_failure);
   1185     data1_writes[1] = *write_failure;
   1186   } else {
   1187     ASSERT_TRUE(read_failure);
   1188     data1_reads[2] = *read_failure;
   1189   }
   1190 
   1191   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
   1192                                  data1_writes, arraysize(data1_writes));
   1193   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1194 
   1195   MockRead data2_reads[] = {
   1196     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1197     MockRead("world"),
   1198     MockRead(ASYNC, OK),
   1199   };
   1200   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1201   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1202 
   1203   const char* kExpectedResponseData[] = {
   1204     "hello", "world"
   1205   };
   1206 
   1207   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1208   for (int i = 0; i < 2; ++i) {
   1209     TestCompletionCallback callback;
   1210 
   1211     scoped_ptr<HttpTransaction> trans(
   1212         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1213 
   1214     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1215     EXPECT_EQ(ERR_IO_PENDING, rv);
   1216 
   1217     rv = callback.WaitForResult();
   1218     EXPECT_EQ(OK, rv);
   1219 
   1220     LoadTimingInfo load_timing_info;
   1221     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1222     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1223     if (i == 0) {
   1224       first_socket_log_id = load_timing_info.socket_log_id;
   1225     } else {
   1226       // The second request should be using a new socket.
   1227       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
   1228     }
   1229 
   1230     const HttpResponseInfo* response = trans->GetResponseInfo();
   1231     ASSERT_TRUE(response != NULL);
   1232 
   1233     EXPECT_TRUE(response->headers.get() != NULL);
   1234     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1235 
   1236     std::string response_data;
   1237     rv = ReadTransaction(trans.get(), &response_data);
   1238     EXPECT_EQ(OK, rv);
   1239     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1240   }
   1241 }
   1242 
   1243 TEST_P(HttpNetworkTransactionTest,
   1244        KeepAliveConnectionNotConnectedOnWrite) {
   1245   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1246   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
   1247 }
   1248 
   1249 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
   1250   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1251   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1252 }
   1253 
   1254 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
   1255   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1256   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1257 }
   1258 
   1259 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
   1260   HttpRequestInfo request;
   1261   request.method = "GET";
   1262   request.url = GURL("http://www.google.com/");
   1263   request.load_flags = 0;
   1264 
   1265   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1266   scoped_ptr<HttpTransaction> trans(
   1267       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1268 
   1269   MockRead data_reads[] = {
   1270     MockRead(ASYNC, ERR_CONNECTION_RESET),
   1271     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1272     MockRead("hello world"),
   1273     MockRead(SYNCHRONOUS, OK),
   1274   };
   1275   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1276   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1277 
   1278   TestCompletionCallback callback;
   1279 
   1280   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1281   EXPECT_EQ(ERR_IO_PENDING, rv);
   1282 
   1283   rv = callback.WaitForResult();
   1284   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   1285 
   1286   const HttpResponseInfo* response = trans->GetResponseInfo();
   1287   EXPECT_TRUE(response == NULL);
   1288 }
   1289 
   1290 // What do various browsers do when the server closes a non-keepalive
   1291 // connection without sending any response header or body?
   1292 //
   1293 // IE7: error page
   1294 // Safari 3.1.2 (Windows): error page
   1295 // Firefox 3.0.1: blank page
   1296 // Opera 9.52: after five attempts, blank page
   1297 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
   1298 // Us: error page (EMPTY_RESPONSE)
   1299 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
   1300   MockRead data_reads[] = {
   1301     MockRead(SYNCHRONOUS, OK),  // EOF
   1302     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1303     MockRead("hello world"),
   1304     MockRead(SYNCHRONOUS, OK),
   1305   };
   1306   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
   1307                                               arraysize(data_reads));
   1308   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
   1309 }
   1310 
   1311 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
   1312 // tests. There was a bug causing HttpNetworkTransaction to hang in the
   1313 // destructor in such situations.
   1314 // See http://crbug.com/154712 and http://crbug.com/156609.
   1315 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
   1316   HttpRequestInfo request;
   1317   request.method = "GET";
   1318   request.url = GURL("http://www.google.com/");
   1319   request.load_flags = 0;
   1320 
   1321   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1322   scoped_ptr<HttpTransaction> trans(
   1323       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1324 
   1325   MockRead data_reads[] = {
   1326     MockRead("HTTP/1.0 200 OK\r\n"),
   1327     MockRead("Connection: keep-alive\r\n"),
   1328     MockRead("Content-Length: 100\r\n\r\n"),
   1329     MockRead("hello"),
   1330     MockRead(SYNCHRONOUS, 0),
   1331   };
   1332   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1333   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1334 
   1335   TestCompletionCallback callback;
   1336 
   1337   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1338   EXPECT_EQ(ERR_IO_PENDING, rv);
   1339 
   1340   rv = callback.WaitForResult();
   1341   EXPECT_EQ(OK, rv);
   1342 
   1343   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1344   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1345   if (rv == ERR_IO_PENDING)
   1346     rv = callback.WaitForResult();
   1347   EXPECT_EQ(5, rv);
   1348   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1349   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1350 
   1351   trans.reset();
   1352   base::MessageLoop::current()->RunUntilIdle();
   1353   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1354 }
   1355 
   1356 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
   1357   HttpRequestInfo request;
   1358   request.method = "GET";
   1359   request.url = GURL("http://www.google.com/");
   1360   request.load_flags = 0;
   1361 
   1362   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1363   scoped_ptr<HttpTransaction> trans(
   1364       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1365 
   1366   MockRead data_reads[] = {
   1367     MockRead("HTTP/1.0 200 OK\r\n"),
   1368     MockRead("Connection: keep-alive\r\n"),
   1369     MockRead("Content-Length: 100\r\n\r\n"),
   1370     MockRead(SYNCHRONOUS, 0),
   1371   };
   1372   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1373   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1374 
   1375   TestCompletionCallback callback;
   1376 
   1377   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1378   EXPECT_EQ(ERR_IO_PENDING, rv);
   1379 
   1380   rv = callback.WaitForResult();
   1381   EXPECT_EQ(OK, rv);
   1382 
   1383   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1384   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1385   if (rv == ERR_IO_PENDING)
   1386     rv = callback.WaitForResult();
   1387   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1388 
   1389   trans.reset();
   1390   base::MessageLoop::current()->RunUntilIdle();
   1391   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1392 }
   1393 
   1394 // Test that we correctly reuse a keep-alive connection after not explicitly
   1395 // reading the body.
   1396 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
   1397   HttpRequestInfo request;
   1398   request.method = "GET";
   1399   request.url = GURL("http://www.foo.com/");
   1400   request.load_flags = 0;
   1401 
   1402   CapturingNetLog net_log;
   1403   session_deps_.net_log = &net_log;
   1404   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1405 
   1406   // Note that because all these reads happen in the same
   1407   // StaticSocketDataProvider, it shows that the same socket is being reused for
   1408   // all transactions.
   1409   MockRead data1_reads[] = {
   1410     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
   1411     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
   1412     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
   1413     MockRead("HTTP/1.1 302 Found\r\n"
   1414              "Content-Length: 0\r\n\r\n"),
   1415     MockRead("HTTP/1.1 302 Found\r\n"
   1416              "Content-Length: 5\r\n\r\n"
   1417              "hello"),
   1418     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1419              "Content-Length: 0\r\n\r\n"),
   1420     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1421              "Content-Length: 5\r\n\r\n"
   1422              "hello"),
   1423     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1424     MockRead("hello"),
   1425   };
   1426   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
   1427   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1428 
   1429   MockRead data2_reads[] = {
   1430     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   1431   };
   1432   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1433   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1434 
   1435   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
   1436   std::string response_lines[kNumUnreadBodies];
   1437 
   1438   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1439   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
   1440     TestCompletionCallback callback;
   1441 
   1442     scoped_ptr<HttpTransaction> trans(
   1443         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1444 
   1445     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1446     EXPECT_EQ(ERR_IO_PENDING, rv);
   1447 
   1448     rv = callback.WaitForResult();
   1449     EXPECT_EQ(OK, rv);
   1450 
   1451     LoadTimingInfo load_timing_info;
   1452     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1453     if (i == 0) {
   1454       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1455       first_socket_log_id = load_timing_info.socket_log_id;
   1456     } else {
   1457       TestLoadTimingReused(load_timing_info);
   1458       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
   1459     }
   1460 
   1461     const HttpResponseInfo* response = trans->GetResponseInfo();
   1462     ASSERT_TRUE(response != NULL);
   1463 
   1464     ASSERT_TRUE(response->headers.get() != NULL);
   1465     response_lines[i] = response->headers->GetStatusLine();
   1466 
   1467     // We intentionally don't read the response bodies.
   1468   }
   1469 
   1470   const char* const kStatusLines[] = {
   1471     "HTTP/1.1 204 No Content",
   1472     "HTTP/1.1 205 Reset Content",
   1473     "HTTP/1.1 304 Not Modified",
   1474     "HTTP/1.1 302 Found",
   1475     "HTTP/1.1 302 Found",
   1476     "HTTP/1.1 301 Moved Permanently",
   1477     "HTTP/1.1 301 Moved Permanently",
   1478   };
   1479 
   1480   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
   1481                  forgot_to_update_kStatusLines);
   1482 
   1483   for (int i = 0; i < kNumUnreadBodies; ++i)
   1484     EXPECT_EQ(kStatusLines[i], response_lines[i]);
   1485 
   1486   TestCompletionCallback callback;
   1487   scoped_ptr<HttpTransaction> trans(
   1488       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1489   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1490   EXPECT_EQ(ERR_IO_PENDING, rv);
   1491   rv = callback.WaitForResult();
   1492   EXPECT_EQ(OK, rv);
   1493   const HttpResponseInfo* response = trans->GetResponseInfo();
   1494   ASSERT_TRUE(response != NULL);
   1495   ASSERT_TRUE(response->headers.get() != NULL);
   1496   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1497   std::string response_data;
   1498   rv = ReadTransaction(trans.get(), &response_data);
   1499   EXPECT_EQ(OK, rv);
   1500   EXPECT_EQ("hello", response_data);
   1501 }
   1502 
   1503 // Test the request-challenge-retry sequence for basic auth.
   1504 // (basic auth is the easiest to mock, because it has no randomness).
   1505 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
   1506   HttpRequestInfo request;
   1507   request.method = "GET";
   1508   request.url = GURL("http://www.google.com/");
   1509   request.load_flags = 0;
   1510 
   1511   CapturingNetLog log;
   1512   session_deps_.net_log = &log;
   1513   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1514   scoped_ptr<HttpTransaction> trans(
   1515       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1516 
   1517   MockWrite data_writes1[] = {
   1518     MockWrite("GET / HTTP/1.1\r\n"
   1519               "Host: www.google.com\r\n"
   1520               "Connection: keep-alive\r\n\r\n"),
   1521   };
   1522 
   1523   MockRead data_reads1[] = {
   1524     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1525     // Give a couple authenticate options (only the middle one is actually
   1526     // supported).
   1527     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
   1528     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1529     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1530     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1531     // Large content-length -- won't matter, as connection will be reset.
   1532     MockRead("Content-Length: 10000\r\n\r\n"),
   1533     MockRead(SYNCHRONOUS, ERR_FAILED),
   1534   };
   1535 
   1536   // After calling trans->RestartWithAuth(), this is the request we should
   1537   // be issuing -- the final header line contains the credentials.
   1538   MockWrite data_writes2[] = {
   1539     MockWrite("GET / HTTP/1.1\r\n"
   1540               "Host: www.google.com\r\n"
   1541               "Connection: keep-alive\r\n"
   1542               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1543   };
   1544 
   1545   // Lastly, the server responds with the actual content.
   1546   MockRead data_reads2[] = {
   1547     MockRead("HTTP/1.0 200 OK\r\n"),
   1548     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1549     MockRead("Content-Length: 100\r\n\r\n"),
   1550     MockRead(SYNCHRONOUS, OK),
   1551   };
   1552 
   1553   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1554                                  data_writes1, arraysize(data_writes1));
   1555   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1556                                  data_writes2, arraysize(data_writes2));
   1557   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1558   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1559 
   1560   TestCompletionCallback callback1;
   1561 
   1562   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1563   EXPECT_EQ(ERR_IO_PENDING, rv);
   1564 
   1565   rv = callback1.WaitForResult();
   1566   EXPECT_EQ(OK, rv);
   1567 
   1568   LoadTimingInfo load_timing_info1;
   1569   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1570   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1571 
   1572   const HttpResponseInfo* response = trans->GetResponseInfo();
   1573   ASSERT_TRUE(response != NULL);
   1574   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1575 
   1576   TestCompletionCallback callback2;
   1577 
   1578   rv = trans->RestartWithAuth(
   1579       AuthCredentials(kFoo, kBar), callback2.callback());
   1580   EXPECT_EQ(ERR_IO_PENDING, rv);
   1581 
   1582   rv = callback2.WaitForResult();
   1583   EXPECT_EQ(OK, rv);
   1584 
   1585   LoadTimingInfo load_timing_info2;
   1586   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1587   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
   1588   // The load timing after restart should have a new socket ID, and times after
   1589   // those of the first load timing.
   1590   EXPECT_LE(load_timing_info1.receive_headers_end,
   1591             load_timing_info2.connect_timing.connect_start);
   1592   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1593 
   1594   response = trans->GetResponseInfo();
   1595   ASSERT_TRUE(response != NULL);
   1596   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1597   EXPECT_EQ(100, response->headers->GetContentLength());
   1598 }
   1599 
   1600 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
   1601   HttpRequestInfo request;
   1602   request.method = "GET";
   1603   request.url = GURL("http://www.google.com/");
   1604   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1605 
   1606   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1607   scoped_ptr<HttpTransaction> trans(
   1608       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1609 
   1610   MockWrite data_writes[] = {
   1611     MockWrite("GET / HTTP/1.1\r\n"
   1612               "Host: www.google.com\r\n"
   1613               "Connection: keep-alive\r\n\r\n"),
   1614   };
   1615 
   1616   MockRead data_reads[] = {
   1617     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1618     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1619     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1620     // Large content-length -- won't matter, as connection will be reset.
   1621     MockRead("Content-Length: 10000\r\n\r\n"),
   1622     MockRead(SYNCHRONOUS, ERR_FAILED),
   1623   };
   1624 
   1625   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1626                                 data_writes, arraysize(data_writes));
   1627   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1628   TestCompletionCallback callback;
   1629 
   1630   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1631   EXPECT_EQ(ERR_IO_PENDING, rv);
   1632 
   1633   rv = callback.WaitForResult();
   1634   EXPECT_EQ(0, rv);
   1635 
   1636   const HttpResponseInfo* response = trans->GetResponseInfo();
   1637   ASSERT_TRUE(response != NULL);
   1638   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1639 }
   1640 
   1641 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1642 // connection.
   1643 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   1644   HttpRequestInfo request;
   1645   request.method = "GET";
   1646   request.url = GURL("http://www.google.com/");
   1647   request.load_flags = 0;
   1648 
   1649   CapturingNetLog log;
   1650   session_deps_.net_log = &log;
   1651   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1652 
   1653   MockWrite data_writes1[] = {
   1654     MockWrite("GET / HTTP/1.1\r\n"
   1655               "Host: www.google.com\r\n"
   1656               "Connection: keep-alive\r\n\r\n"),
   1657 
   1658     // After calling trans->RestartWithAuth(), this is the request we should
   1659     // be issuing -- the final header line contains the credentials.
   1660     MockWrite("GET / HTTP/1.1\r\n"
   1661               "Host: www.google.com\r\n"
   1662               "Connection: keep-alive\r\n"
   1663               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1664   };
   1665 
   1666   MockRead data_reads1[] = {
   1667     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1668     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1669     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1670     MockRead("Content-Length: 14\r\n\r\n"),
   1671     MockRead("Unauthorized\r\n"),
   1672 
   1673     // Lastly, the server responds with the actual content.
   1674     MockRead("HTTP/1.1 200 OK\r\n"),
   1675     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1676     MockRead("Content-Length: 5\r\n\r\n"),
   1677     MockRead("Hello"),
   1678   };
   1679 
   1680   // If there is a regression where we disconnect a Keep-Alive
   1681   // connection during an auth roundtrip, we'll end up reading this.
   1682   MockRead data_reads2[] = {
   1683     MockRead(SYNCHRONOUS, ERR_FAILED),
   1684   };
   1685 
   1686   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1687                                  data_writes1, arraysize(data_writes1));
   1688   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1689                                  NULL, 0);
   1690   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1691   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1692 
   1693   TestCompletionCallback callback1;
   1694 
   1695   scoped_ptr<HttpTransaction> trans(
   1696       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1697   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1698   EXPECT_EQ(ERR_IO_PENDING, rv);
   1699 
   1700   rv = callback1.WaitForResult();
   1701   EXPECT_EQ(OK, rv);
   1702 
   1703   LoadTimingInfo load_timing_info1;
   1704   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1705   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1706 
   1707   const HttpResponseInfo* response = trans->GetResponseInfo();
   1708   ASSERT_TRUE(response != NULL);
   1709   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1710 
   1711   TestCompletionCallback callback2;
   1712 
   1713   rv = trans->RestartWithAuth(
   1714       AuthCredentials(kFoo, kBar), callback2.callback());
   1715   EXPECT_EQ(ERR_IO_PENDING, rv);
   1716 
   1717   rv = callback2.WaitForResult();
   1718   EXPECT_EQ(OK, rv);
   1719 
   1720   LoadTimingInfo load_timing_info2;
   1721   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1722   TestLoadTimingReused(load_timing_info2);
   1723   // The load timing after restart should have the same socket ID, and times
   1724   // those of the first load timing.
   1725   EXPECT_LE(load_timing_info1.receive_headers_end,
   1726             load_timing_info2.send_start);
   1727   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1728 
   1729   response = trans->GetResponseInfo();
   1730   ASSERT_TRUE(response != NULL);
   1731   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1732   EXPECT_EQ(5, response->headers->GetContentLength());
   1733 }
   1734 
   1735 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1736 // connection and with no response body to drain.
   1737 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   1738   HttpRequestInfo request;
   1739   request.method = "GET";
   1740   request.url = GURL("http://www.google.com/");
   1741   request.load_flags = 0;
   1742 
   1743   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1744 
   1745   MockWrite data_writes1[] = {
   1746     MockWrite("GET / HTTP/1.1\r\n"
   1747               "Host: www.google.com\r\n"
   1748               "Connection: keep-alive\r\n\r\n"),
   1749 
   1750     // After calling trans->RestartWithAuth(), this is the request we should
   1751     // be issuing -- the final header line contains the credentials.
   1752     MockWrite("GET / HTTP/1.1\r\n"
   1753               "Host: www.google.com\r\n"
   1754               "Connection: keep-alive\r\n"
   1755               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1756   };
   1757 
   1758   MockRead data_reads1[] = {
   1759     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1760     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1761     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   1762 
   1763     // Lastly, the server responds with the actual content.
   1764     MockRead("HTTP/1.1 200 OK\r\n"),
   1765     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1766     MockRead("Content-Length: 5\r\n\r\n"),
   1767     MockRead("hello"),
   1768   };
   1769 
   1770   // An incorrect reconnect would cause this to be read.
   1771   MockRead data_reads2[] = {
   1772     MockRead(SYNCHRONOUS, ERR_FAILED),
   1773   };
   1774 
   1775   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1776                                  data_writes1, arraysize(data_writes1));
   1777   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1778                                  NULL, 0);
   1779   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1780   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1781 
   1782   TestCompletionCallback callback1;
   1783 
   1784   scoped_ptr<HttpTransaction> trans(
   1785       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1786   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1787   EXPECT_EQ(ERR_IO_PENDING, rv);
   1788 
   1789   rv = callback1.WaitForResult();
   1790   EXPECT_EQ(OK, rv);
   1791 
   1792   const HttpResponseInfo* response = trans->GetResponseInfo();
   1793   ASSERT_TRUE(response != NULL);
   1794   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1795 
   1796   TestCompletionCallback callback2;
   1797 
   1798   rv = trans->RestartWithAuth(
   1799       AuthCredentials(kFoo, kBar), callback2.callback());
   1800   EXPECT_EQ(ERR_IO_PENDING, rv);
   1801 
   1802   rv = callback2.WaitForResult();
   1803   EXPECT_EQ(OK, rv);
   1804 
   1805   response = trans->GetResponseInfo();
   1806   ASSERT_TRUE(response != NULL);
   1807   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1808   EXPECT_EQ(5, response->headers->GetContentLength());
   1809 }
   1810 
   1811 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1812 // connection and with a large response body to drain.
   1813 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   1814   HttpRequestInfo request;
   1815   request.method = "GET";
   1816   request.url = GURL("http://www.google.com/");
   1817   request.load_flags = 0;
   1818 
   1819   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1820 
   1821   MockWrite data_writes1[] = {
   1822     MockWrite("GET / HTTP/1.1\r\n"
   1823               "Host: www.google.com\r\n"
   1824               "Connection: keep-alive\r\n\r\n"),
   1825 
   1826     // After calling trans->RestartWithAuth(), this is the request we should
   1827     // be issuing -- the final header line contains the credentials.
   1828     MockWrite("GET / HTTP/1.1\r\n"
   1829               "Host: www.google.com\r\n"
   1830               "Connection: keep-alive\r\n"
   1831               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1832   };
   1833 
   1834   // Respond with 5 kb of response body.
   1835   std::string large_body_string("Unauthorized");
   1836   large_body_string.append(5 * 1024, ' ');
   1837   large_body_string.append("\r\n");
   1838 
   1839   MockRead data_reads1[] = {
   1840     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1841     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1842     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1843     // 5134 = 12 + 5 * 1024 + 2
   1844     MockRead("Content-Length: 5134\r\n\r\n"),
   1845     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
   1846 
   1847     // Lastly, the server responds with the actual content.
   1848     MockRead("HTTP/1.1 200 OK\r\n"),
   1849     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1850     MockRead("Content-Length: 5\r\n\r\n"),
   1851     MockRead("hello"),
   1852   };
   1853 
   1854   // An incorrect reconnect would cause this to be read.
   1855   MockRead data_reads2[] = {
   1856     MockRead(SYNCHRONOUS, ERR_FAILED),
   1857   };
   1858 
   1859   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1860                                  data_writes1, arraysize(data_writes1));
   1861   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1862                                  NULL, 0);
   1863   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1864   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1865 
   1866   TestCompletionCallback callback1;
   1867 
   1868   scoped_ptr<HttpTransaction> trans(
   1869       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1870   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1871   EXPECT_EQ(ERR_IO_PENDING, rv);
   1872 
   1873   rv = callback1.WaitForResult();
   1874   EXPECT_EQ(OK, rv);
   1875 
   1876   const HttpResponseInfo* response = trans->GetResponseInfo();
   1877   ASSERT_TRUE(response != NULL);
   1878   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1879 
   1880   TestCompletionCallback callback2;
   1881 
   1882   rv = trans->RestartWithAuth(
   1883       AuthCredentials(kFoo, kBar), callback2.callback());
   1884   EXPECT_EQ(ERR_IO_PENDING, rv);
   1885 
   1886   rv = callback2.WaitForResult();
   1887   EXPECT_EQ(OK, rv);
   1888 
   1889   response = trans->GetResponseInfo();
   1890   ASSERT_TRUE(response != NULL);
   1891   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1892   EXPECT_EQ(5, response->headers->GetContentLength());
   1893 }
   1894 
   1895 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1896 // connection, but the server gets impatient and closes the connection.
   1897 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   1898   HttpRequestInfo request;
   1899   request.method = "GET";
   1900   request.url = GURL("http://www.google.com/");
   1901   request.load_flags = 0;
   1902 
   1903   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1904 
   1905   MockWrite data_writes1[] = {
   1906     MockWrite("GET / HTTP/1.1\r\n"
   1907               "Host: www.google.com\r\n"
   1908               "Connection: keep-alive\r\n\r\n"),
   1909     // This simulates the seemingly successful write to a closed connection
   1910     // if the bug is not fixed.
   1911     MockWrite("GET / HTTP/1.1\r\n"
   1912               "Host: www.google.com\r\n"
   1913               "Connection: keep-alive\r\n"
   1914               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1915   };
   1916 
   1917   MockRead data_reads1[] = {
   1918     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1919     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1920     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1921     MockRead("Content-Length: 14\r\n\r\n"),
   1922     // Tell MockTCPClientSocket to simulate the server closing the connection.
   1923     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   1924     MockRead("Unauthorized\r\n"),
   1925     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
   1926   };
   1927 
   1928   // After calling trans->RestartWithAuth(), this is the request we should
   1929   // be issuing -- the final header line contains the credentials.
   1930   MockWrite data_writes2[] = {
   1931     MockWrite("GET / HTTP/1.1\r\n"
   1932               "Host: www.google.com\r\n"
   1933               "Connection: keep-alive\r\n"
   1934               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1935   };
   1936 
   1937   // Lastly, the server responds with the actual content.
   1938   MockRead data_reads2[] = {
   1939     MockRead("HTTP/1.1 200 OK\r\n"),
   1940     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1941     MockRead("Content-Length: 5\r\n\r\n"),
   1942     MockRead("hello"),
   1943   };
   1944 
   1945   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1946                                  data_writes1, arraysize(data_writes1));
   1947   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1948                                  data_writes2, arraysize(data_writes2));
   1949   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1950   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1951 
   1952   TestCompletionCallback callback1;
   1953 
   1954   scoped_ptr<HttpTransaction> trans(
   1955       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1956   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1957   EXPECT_EQ(ERR_IO_PENDING, rv);
   1958 
   1959   rv = callback1.WaitForResult();
   1960   EXPECT_EQ(OK, rv);
   1961 
   1962   const HttpResponseInfo* response = trans->GetResponseInfo();
   1963   ASSERT_TRUE(response != NULL);
   1964   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1965 
   1966   TestCompletionCallback callback2;
   1967 
   1968   rv = trans->RestartWithAuth(
   1969       AuthCredentials(kFoo, kBar), callback2.callback());
   1970   EXPECT_EQ(ERR_IO_PENDING, rv);
   1971 
   1972   rv = callback2.WaitForResult();
   1973   EXPECT_EQ(OK, rv);
   1974 
   1975   response = trans->GetResponseInfo();
   1976   ASSERT_TRUE(response != NULL);
   1977   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1978   EXPECT_EQ(5, response->headers->GetContentLength());
   1979 }
   1980 
   1981 // Test the request-challenge-retry sequence for basic auth, over a connection
   1982 // that requires a restart when setting up an SSL tunnel.
   1983 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
   1984   HttpRequestInfo request;
   1985   request.method = "GET";
   1986   request.url = GURL("https://www.google.com/");
   1987   // when the no authentication data flag is set.
   1988   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1989 
   1990   // Configure against proxy server "myproxy:70".
   1991   session_deps_.proxy_service.reset(
   1992       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   1993   CapturingBoundNetLog log;
   1994   session_deps_.net_log = log.bound().net_log();
   1995   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1996 
   1997   // Since we have proxy, should try to establish tunnel.
   1998   MockWrite data_writes1[] = {
   1999     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2000               "Host: www.google.com\r\n"
   2001               "Proxy-Connection: keep-alive\r\n\r\n"),
   2002 
   2003     // After calling trans->RestartWithAuth(), this is the request we should
   2004     // be issuing -- the final header line contains the credentials.
   2005     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2006               "Host: www.google.com\r\n"
   2007               "Proxy-Connection: keep-alive\r\n"
   2008               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2009 
   2010     MockWrite("GET / HTTP/1.1\r\n"
   2011               "Host: www.google.com\r\n"
   2012               "Connection: keep-alive\r\n\r\n"),
   2013   };
   2014 
   2015   // The proxy responds to the connect with a 407, using a persistent
   2016   // connection.
   2017   MockRead data_reads1[] = {
   2018     // No credentials.
   2019     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2020     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2021     MockRead("Proxy-Connection: close\r\n\r\n"),
   2022 
   2023     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2024 
   2025     MockRead("HTTP/1.1 200 OK\r\n"),
   2026     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2027     MockRead("Content-Length: 5\r\n\r\n"),
   2028     MockRead(SYNCHRONOUS, "hello"),
   2029   };
   2030 
   2031   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2032                                  data_writes1, arraysize(data_writes1));
   2033   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2034   SSLSocketDataProvider ssl(ASYNC, OK);
   2035   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2036 
   2037   TestCompletionCallback callback1;
   2038 
   2039   scoped_ptr<HttpTransaction> trans(
   2040       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2041 
   2042   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2043   EXPECT_EQ(ERR_IO_PENDING, rv);
   2044 
   2045   rv = callback1.WaitForResult();
   2046   EXPECT_EQ(OK, rv);
   2047   net::CapturingNetLog::CapturedEntryList entries;
   2048   log.GetEntries(&entries);
   2049   size_t pos = ExpectLogContainsSomewhere(
   2050       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2051       NetLog::PHASE_NONE);
   2052   ExpectLogContainsSomewhere(
   2053       entries, pos,
   2054       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2055       NetLog::PHASE_NONE);
   2056 
   2057   const HttpResponseInfo* response = trans->GetResponseInfo();
   2058   ASSERT_TRUE(response != NULL);
   2059   ASSERT_FALSE(response->headers.get() == NULL);
   2060   EXPECT_EQ(407, response->headers->response_code());
   2061   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2062   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2063 
   2064   LoadTimingInfo load_timing_info;
   2065   // CONNECT requests and responses are handled at the connect job level, so
   2066   // the transaction does not yet have a connection.
   2067   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
   2068 
   2069   TestCompletionCallback callback2;
   2070 
   2071   rv = trans->RestartWithAuth(
   2072       AuthCredentials(kFoo, kBar), callback2.callback());
   2073   EXPECT_EQ(ERR_IO_PENDING, rv);
   2074 
   2075   rv = callback2.WaitForResult();
   2076   EXPECT_EQ(OK, rv);
   2077 
   2078   response = trans->GetResponseInfo();
   2079   ASSERT_TRUE(response != NULL);
   2080 
   2081   EXPECT_TRUE(response->headers->IsKeepAlive());
   2082   EXPECT_EQ(200, response->headers->response_code());
   2083   EXPECT_EQ(5, response->headers->GetContentLength());
   2084   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2085 
   2086   // The password prompt info should not be set.
   2087   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2088 
   2089   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2090   TestLoadTimingNotReusedWithPac(load_timing_info,
   2091                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2092 
   2093   trans.reset();
   2094   session->CloseAllConnections();
   2095 }
   2096 
   2097 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2098 // proxy connection, when setting up an SSL tunnel.
   2099 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   2100   HttpRequestInfo request;
   2101   request.method = "GET";
   2102   request.url = GURL("https://www.google.com/");
   2103   // Ensure that proxy authentication is attempted even
   2104   // when the no authentication data flag is set.
   2105   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2106 
   2107   // Configure against proxy server "myproxy:70".
   2108   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2109   CapturingBoundNetLog log;
   2110   session_deps_.net_log = log.bound().net_log();
   2111   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2112 
   2113   scoped_ptr<HttpTransaction> trans(
   2114       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2115 
   2116   // Since we have proxy, should try to establish tunnel.
   2117   MockWrite data_writes1[] = {
   2118     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2119               "Host: www.google.com\r\n"
   2120               "Proxy-Connection: keep-alive\r\n\r\n"),
   2121 
   2122     // After calling trans->RestartWithAuth(), this is the request we should
   2123     // be issuing -- the final header line contains the credentials.
   2124     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2125               "Host: www.google.com\r\n"
   2126               "Proxy-Connection: keep-alive\r\n"
   2127               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   2128   };
   2129 
   2130   // The proxy responds to the connect with a 407, using a persistent
   2131   // connection.
   2132   MockRead data_reads1[] = {
   2133     // No credentials.
   2134     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2135     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2136     MockRead("Content-Length: 10\r\n\r\n"),
   2137     MockRead("0123456789"),
   2138 
   2139     // Wrong credentials (wrong password).
   2140     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2141     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2142     MockRead("Content-Length: 10\r\n\r\n"),
   2143     // No response body because the test stops reading here.
   2144     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2145   };
   2146 
   2147   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2148                                  data_writes1, arraysize(data_writes1));
   2149   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2150 
   2151   TestCompletionCallback callback1;
   2152 
   2153   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2154   EXPECT_EQ(ERR_IO_PENDING, rv);
   2155 
   2156   rv = callback1.WaitForResult();
   2157   EXPECT_EQ(OK, rv);
   2158   net::CapturingNetLog::CapturedEntryList entries;
   2159   log.GetEntries(&entries);
   2160   size_t pos = ExpectLogContainsSomewhere(
   2161       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2162       NetLog::PHASE_NONE);
   2163   ExpectLogContainsSomewhere(
   2164       entries, pos,
   2165       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2166       NetLog::PHASE_NONE);
   2167 
   2168   const HttpResponseInfo* response = trans->GetResponseInfo();
   2169   ASSERT_TRUE(response != NULL);
   2170   ASSERT_FALSE(response->headers.get() == NULL);
   2171   EXPECT_TRUE(response->headers->IsKeepAlive());
   2172   EXPECT_EQ(407, response->headers->response_code());
   2173   EXPECT_EQ(10, response->headers->GetContentLength());
   2174   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2175   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2176 
   2177   TestCompletionCallback callback2;
   2178 
   2179   // Wrong password (should be "bar").
   2180   rv = trans->RestartWithAuth(
   2181       AuthCredentials(kFoo, kBaz), callback2.callback());
   2182   EXPECT_EQ(ERR_IO_PENDING, rv);
   2183 
   2184   rv = callback2.WaitForResult();
   2185   EXPECT_EQ(OK, rv);
   2186 
   2187   response = trans->GetResponseInfo();
   2188   ASSERT_TRUE(response != NULL);
   2189   ASSERT_FALSE(response->headers.get() == NULL);
   2190   EXPECT_TRUE(response->headers->IsKeepAlive());
   2191   EXPECT_EQ(407, response->headers->response_code());
   2192   EXPECT_EQ(10, response->headers->GetContentLength());
   2193   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2194   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2195 
   2196   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
   2197   // out of scope.
   2198   session->CloseAllConnections();
   2199 }
   2200 
   2201 // Test that we don't read the response body when we fail to establish a tunnel,
   2202 // even if the user cancels the proxy's auth attempt.
   2203 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   2204   HttpRequestInfo request;
   2205   request.method = "GET";
   2206   request.url = GURL("https://www.google.com/");
   2207   request.load_flags = 0;
   2208 
   2209   // Configure against proxy server "myproxy:70".
   2210   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2211 
   2212   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2213 
   2214   scoped_ptr<HttpTransaction> trans(
   2215       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2216 
   2217   // Since we have proxy, should try to establish tunnel.
   2218   MockWrite data_writes[] = {
   2219     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2220               "Host: www.google.com\r\n"
   2221               "Proxy-Connection: keep-alive\r\n\r\n"),
   2222   };
   2223 
   2224   // The proxy responds to the connect with a 407.
   2225   MockRead data_reads[] = {
   2226     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2227     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2228     MockRead("Content-Length: 10\r\n\r\n"),
   2229     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2230   };
   2231 
   2232   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   2233                                 data_writes, arraysize(data_writes));
   2234   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2235 
   2236   TestCompletionCallback callback;
   2237 
   2238   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2239   EXPECT_EQ(ERR_IO_PENDING, rv);
   2240 
   2241   rv = callback.WaitForResult();
   2242   EXPECT_EQ(OK, rv);
   2243 
   2244   const HttpResponseInfo* response = trans->GetResponseInfo();
   2245   ASSERT_TRUE(response != NULL);
   2246 
   2247   EXPECT_TRUE(response->headers->IsKeepAlive());
   2248   EXPECT_EQ(407, response->headers->response_code());
   2249   EXPECT_EQ(10, response->headers->GetContentLength());
   2250   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2251 
   2252   std::string response_data;
   2253   rv = ReadTransaction(trans.get(), &response_data);
   2254   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   2255 
   2256   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
   2257   session->CloseAllConnections();
   2258 }
   2259 
   2260 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
   2261 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
   2262 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   2263   HttpRequestInfo request;
   2264   request.method = "GET";
   2265   request.url = GURL("http://www.google.com/");
   2266   request.load_flags = 0;
   2267 
   2268   // We are using a DIRECT connection (i.e. no proxy) for this session.
   2269   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2270   scoped_ptr<HttpTransaction> trans(
   2271       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   2272 
   2273   MockWrite data_writes1[] = {
   2274     MockWrite("GET / HTTP/1.1\r\n"
   2275               "Host: www.google.com\r\n"
   2276               "Connection: keep-alive\r\n\r\n"),
   2277   };
   2278 
   2279   MockRead data_reads1[] = {
   2280     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
   2281     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2282     // Large content-length -- won't matter, as connection will be reset.
   2283     MockRead("Content-Length: 10000\r\n\r\n"),
   2284     MockRead(SYNCHRONOUS, ERR_FAILED),
   2285   };
   2286 
   2287   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2288                                  data_writes1, arraysize(data_writes1));
   2289   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2290 
   2291   TestCompletionCallback callback;
   2292 
   2293   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2294   EXPECT_EQ(ERR_IO_PENDING, rv);
   2295 
   2296   rv = callback.WaitForResult();
   2297   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2298 }
   2299 
   2300 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
   2301 // through a non-authenticating proxy. The request should fail with
   2302 // ERR_UNEXPECTED_PROXY_AUTH.
   2303 // Note that it is impossible to detect if an HTTP server returns a 407 through
   2304 // a non-authenticating proxy - there is nothing to indicate whether the
   2305 // response came from the proxy or the server, so it is treated as if the proxy
   2306 // issued the challenge.
   2307 TEST_P(HttpNetworkTransactionTest,
   2308        HttpsServerRequestsProxyAuthThroughProxy) {
   2309   HttpRequestInfo request;
   2310   request.method = "GET";
   2311   request.url = GURL("https://www.google.com/");
   2312 
   2313   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2314   CapturingBoundNetLog log;
   2315   session_deps_.net_log = log.bound().net_log();
   2316   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2317 
   2318   // Since we have proxy, should try to establish tunnel.
   2319   MockWrite data_writes1[] = {
   2320     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2321               "Host: www.google.com\r\n"
   2322               "Proxy-Connection: keep-alive\r\n\r\n"),
   2323 
   2324     MockWrite("GET / HTTP/1.1\r\n"
   2325               "Host: www.google.com\r\n"
   2326               "Connection: keep-alive\r\n\r\n"),
   2327   };
   2328 
   2329   MockRead data_reads1[] = {
   2330     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2331 
   2332     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
   2333     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2334     MockRead("\r\n"),
   2335     MockRead(SYNCHRONOUS, OK),
   2336   };
   2337 
   2338   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2339                                  data_writes1, arraysize(data_writes1));
   2340   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2341   SSLSocketDataProvider ssl(ASYNC, OK);
   2342   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2343 
   2344   TestCompletionCallback callback1;
   2345 
   2346   scoped_ptr<HttpTransaction> trans(
   2347       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2348 
   2349   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2350   EXPECT_EQ(ERR_IO_PENDING, rv);
   2351 
   2352   rv = callback1.WaitForResult();
   2353   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2354   net::CapturingNetLog::CapturedEntryList entries;
   2355   log.GetEntries(&entries);
   2356   size_t pos = ExpectLogContainsSomewhere(
   2357       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2358       NetLog::PHASE_NONE);
   2359   ExpectLogContainsSomewhere(
   2360       entries, pos,
   2361       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2362       NetLog::PHASE_NONE);
   2363 }
   2364 
   2365 // Test the load timing for HTTPS requests with an HTTP proxy.
   2366 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
   2367   HttpRequestInfo request1;
   2368   request1.method = "GET";
   2369   request1.url = GURL("https://www.google.com/1");
   2370 
   2371   HttpRequestInfo request2;
   2372   request2.method = "GET";
   2373   request2.url = GURL("https://www.google.com/2");
   2374 
   2375   // Configure against proxy server "myproxy:70".
   2376   session_deps_.proxy_service.reset(
   2377       ProxyService::CreateFixed("PROXY myproxy:70"));
   2378   CapturingBoundNetLog log;
   2379   session_deps_.net_log = log.bound().net_log();
   2380   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2381 
   2382   // Since we have proxy, should try to establish tunnel.
   2383   MockWrite data_writes1[] = {
   2384     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2385               "Host: www.google.com\r\n"
   2386               "Proxy-Connection: keep-alive\r\n\r\n"),
   2387 
   2388     MockWrite("GET /1 HTTP/1.1\r\n"
   2389               "Host: www.google.com\r\n"
   2390               "Connection: keep-alive\r\n\r\n"),
   2391 
   2392     MockWrite("GET /2 HTTP/1.1\r\n"
   2393               "Host: www.google.com\r\n"
   2394               "Connection: keep-alive\r\n\r\n"),
   2395   };
   2396 
   2397   // The proxy responds to the connect with a 407, using a persistent
   2398   // connection.
   2399   MockRead data_reads1[] = {
   2400     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2401 
   2402     MockRead("HTTP/1.1 200 OK\r\n"),
   2403     MockRead("Content-Length: 1\r\n\r\n"),
   2404     MockRead(SYNCHRONOUS, "1"),
   2405 
   2406     MockRead("HTTP/1.1 200 OK\r\n"),
   2407     MockRead("Content-Length: 2\r\n\r\n"),
   2408     MockRead(SYNCHRONOUS, "22"),
   2409   };
   2410 
   2411   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2412                                  data_writes1, arraysize(data_writes1));
   2413   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2414   SSLSocketDataProvider ssl(ASYNC, OK);
   2415   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2416 
   2417   TestCompletionCallback callback1;
   2418   scoped_ptr<HttpTransaction> trans1(
   2419       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2420 
   2421   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2422   EXPECT_EQ(ERR_IO_PENDING, rv);
   2423 
   2424   rv = callback1.WaitForResult();
   2425   EXPECT_EQ(OK, rv);
   2426 
   2427   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2428   ASSERT_TRUE(response1 != NULL);
   2429   ASSERT_TRUE(response1->headers.get() != NULL);
   2430   EXPECT_EQ(1, response1->headers->GetContentLength());
   2431 
   2432   LoadTimingInfo load_timing_info1;
   2433   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2434   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
   2435 
   2436   trans1.reset();
   2437 
   2438   TestCompletionCallback callback2;
   2439   scoped_ptr<HttpTransaction> trans2(
   2440       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2441 
   2442   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2443   EXPECT_EQ(ERR_IO_PENDING, rv);
   2444 
   2445   rv = callback2.WaitForResult();
   2446   EXPECT_EQ(OK, rv);
   2447 
   2448   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2449   ASSERT_TRUE(response2 != NULL);
   2450   ASSERT_TRUE(response2->headers.get() != NULL);
   2451   EXPECT_EQ(2, response2->headers->GetContentLength());
   2452 
   2453   LoadTimingInfo load_timing_info2;
   2454   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2455   TestLoadTimingReused(load_timing_info2);
   2456 
   2457   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2458 
   2459   trans2.reset();
   2460   session->CloseAllConnections();
   2461 }
   2462 
   2463 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
   2464 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
   2465   HttpRequestInfo request1;
   2466   request1.method = "GET";
   2467   request1.url = GURL("https://www.google.com/1");
   2468 
   2469   HttpRequestInfo request2;
   2470   request2.method = "GET";
   2471   request2.url = GURL("https://www.google.com/2");
   2472 
   2473   // Configure against proxy server "myproxy:70".
   2474   session_deps_.proxy_service.reset(
   2475       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2476   CapturingBoundNetLog log;
   2477   session_deps_.net_log = log.bound().net_log();
   2478   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2479 
   2480   // Since we have proxy, should try to establish tunnel.
   2481   MockWrite data_writes1[] = {
   2482     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2483               "Host: www.google.com\r\n"
   2484               "Proxy-Connection: keep-alive\r\n\r\n"),
   2485 
   2486     MockWrite("GET /1 HTTP/1.1\r\n"
   2487               "Host: www.google.com\r\n"
   2488               "Connection: keep-alive\r\n\r\n"),
   2489 
   2490     MockWrite("GET /2 HTTP/1.1\r\n"
   2491               "Host: www.google.com\r\n"
   2492               "Connection: keep-alive\r\n\r\n"),
   2493   };
   2494 
   2495   // The proxy responds to the connect with a 407, using a persistent
   2496   // connection.
   2497   MockRead data_reads1[] = {
   2498     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2499 
   2500     MockRead("HTTP/1.1 200 OK\r\n"),
   2501     MockRead("Content-Length: 1\r\n\r\n"),
   2502     MockRead(SYNCHRONOUS, "1"),
   2503 
   2504     MockRead("HTTP/1.1 200 OK\r\n"),
   2505     MockRead("Content-Length: 2\r\n\r\n"),
   2506     MockRead(SYNCHRONOUS, "22"),
   2507   };
   2508 
   2509   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2510                                  data_writes1, arraysize(data_writes1));
   2511   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2512   SSLSocketDataProvider ssl(ASYNC, OK);
   2513   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2514 
   2515   TestCompletionCallback callback1;
   2516   scoped_ptr<HttpTransaction> trans1(
   2517       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2518 
   2519   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2520   EXPECT_EQ(ERR_IO_PENDING, rv);
   2521 
   2522   rv = callback1.WaitForResult();
   2523   EXPECT_EQ(OK, rv);
   2524 
   2525   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2526   ASSERT_TRUE(response1 != NULL);
   2527   ASSERT_TRUE(response1->headers.get() != NULL);
   2528   EXPECT_EQ(1, response1->headers->GetContentLength());
   2529 
   2530   LoadTimingInfo load_timing_info1;
   2531   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2532   TestLoadTimingNotReusedWithPac(load_timing_info1,
   2533                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2534 
   2535   trans1.reset();
   2536 
   2537   TestCompletionCallback callback2;
   2538   scoped_ptr<HttpTransaction> trans2(
   2539       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2540 
   2541   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2542   EXPECT_EQ(ERR_IO_PENDING, rv);
   2543 
   2544   rv = callback2.WaitForResult();
   2545   EXPECT_EQ(OK, rv);
   2546 
   2547   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2548   ASSERT_TRUE(response2 != NULL);
   2549   ASSERT_TRUE(response2->headers.get() != NULL);
   2550   EXPECT_EQ(2, response2->headers->GetContentLength());
   2551 
   2552   LoadTimingInfo load_timing_info2;
   2553   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2554   TestLoadTimingReusedWithPac(load_timing_info2);
   2555 
   2556   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2557 
   2558   trans2.reset();
   2559   session->CloseAllConnections();
   2560 }
   2561 
   2562 // Test a simple get through an HTTPS Proxy.
   2563 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
   2564   HttpRequestInfo request;
   2565   request.method = "GET";
   2566   request.url = GURL("http://www.google.com/");
   2567 
   2568   // Configure against https proxy server "proxy:70".
   2569   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2570       "https://proxy:70"));
   2571   CapturingBoundNetLog log;
   2572   session_deps_.net_log = log.bound().net_log();
   2573   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2574 
   2575   // Since we have proxy, should use full url
   2576   MockWrite data_writes1[] = {
   2577     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2578               "Host: www.google.com\r\n"
   2579               "Proxy-Connection: keep-alive\r\n\r\n"),
   2580   };
   2581 
   2582   MockRead data_reads1[] = {
   2583     MockRead("HTTP/1.1 200 OK\r\n"),
   2584     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2585     MockRead("Content-Length: 100\r\n\r\n"),
   2586     MockRead(SYNCHRONOUS, OK),
   2587   };
   2588 
   2589   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2590                                  data_writes1, arraysize(data_writes1));
   2591   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2592   SSLSocketDataProvider ssl(ASYNC, OK);
   2593   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2594 
   2595   TestCompletionCallback callback1;
   2596 
   2597   scoped_ptr<HttpTransaction> trans(
   2598       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2599 
   2600   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2601   EXPECT_EQ(ERR_IO_PENDING, rv);
   2602 
   2603   rv = callback1.WaitForResult();
   2604   EXPECT_EQ(OK, rv);
   2605 
   2606   LoadTimingInfo load_timing_info;
   2607   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2608   TestLoadTimingNotReused(load_timing_info,
   2609                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2610 
   2611   const HttpResponseInfo* response = trans->GetResponseInfo();
   2612   ASSERT_TRUE(response != NULL);
   2613 
   2614   EXPECT_TRUE(response->headers->IsKeepAlive());
   2615   EXPECT_EQ(200, response->headers->response_code());
   2616   EXPECT_EQ(100, response->headers->GetContentLength());
   2617   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2618 
   2619   // The password prompt info should not be set.
   2620   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2621 }
   2622 
   2623 // Test a SPDY get through an HTTPS Proxy.
   2624 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   2625   HttpRequestInfo request;
   2626   request.method = "GET";
   2627   request.url = GURL("http://www.google.com/");
   2628   request.load_flags = 0;
   2629 
   2630   // Configure against https proxy server "proxy:70".
   2631   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2632       "https://proxy:70"));
   2633   CapturingBoundNetLog log;
   2634   session_deps_.net_log = log.bound().net_log();
   2635   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2636 
   2637   // fetch http://www.google.com/ via SPDY
   2638   scoped_ptr<SpdyFrame> req(
   2639       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2640   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   2641 
   2642   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2643   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2644   MockRead spdy_reads[] = {
   2645     CreateMockRead(*resp),
   2646     CreateMockRead(*data),
   2647     MockRead(ASYNC, 0, 0),
   2648   };
   2649 
   2650   DelayedSocketData spdy_data(
   2651       1,  // wait for one write to finish before reading.
   2652       spdy_reads, arraysize(spdy_reads),
   2653       spdy_writes, arraysize(spdy_writes));
   2654   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2655 
   2656   SSLSocketDataProvider ssl(ASYNC, OK);
   2657   ssl.SetNextProto(GetParam());
   2658   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2659 
   2660   TestCompletionCallback callback1;
   2661 
   2662   scoped_ptr<HttpTransaction> trans(
   2663       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2664 
   2665   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2666   EXPECT_EQ(ERR_IO_PENDING, rv);
   2667 
   2668   rv = callback1.WaitForResult();
   2669   EXPECT_EQ(OK, rv);
   2670 
   2671   LoadTimingInfo load_timing_info;
   2672   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2673   TestLoadTimingNotReused(load_timing_info,
   2674                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2675 
   2676   const HttpResponseInfo* response = trans->GetResponseInfo();
   2677   ASSERT_TRUE(response != NULL);
   2678   ASSERT_TRUE(response->headers.get() != NULL);
   2679   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2680 
   2681   std::string response_data;
   2682   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2683   EXPECT_EQ(kUploadData, response_data);
   2684 }
   2685 
   2686 // Test a SPDY get through an HTTPS Proxy.
   2687 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   2688   HttpRequestInfo request;
   2689   request.method = "GET";
   2690   request.url = GURL("http://www.google.com/");
   2691   request.load_flags = 0;
   2692 
   2693   // Configure against https proxy server "myproxy:70".
   2694   session_deps_.proxy_service.reset(
   2695       ProxyService::CreateFixed("https://myproxy:70"));
   2696   CapturingBoundNetLog log;
   2697   session_deps_.net_log = log.bound().net_log();
   2698   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2699 
   2700   // The first request will be a bare GET, the second request will be a
   2701   // GET with a Proxy-Authorization header.
   2702   scoped_ptr<SpdyFrame> req_get(
   2703       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2704   const char* const kExtraAuthorizationHeaders[] = {
   2705     "proxy-authorization", "Basic Zm9vOmJhcg=="
   2706   };
   2707   scoped_ptr<SpdyFrame> req_get_authorization(
   2708       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
   2709                                   arraysize(kExtraAuthorizationHeaders) / 2,
   2710                                   false,
   2711                                   3,
   2712                                   LOWEST,
   2713                                   false));
   2714   MockWrite spdy_writes[] = {
   2715     CreateMockWrite(*req_get, 1),
   2716     CreateMockWrite(*req_get_authorization, 4),
   2717   };
   2718 
   2719   // The first response is a 407 proxy authentication challenge, and the second
   2720   // response will be a 200 response since the second request includes a valid
   2721   // Authorization header.
   2722   const char* const kExtraAuthenticationHeaders[] = {
   2723     "proxy-authenticate", "Basic realm=\"MyRealm1\""
   2724   };
   2725   scoped_ptr<SpdyFrame> resp_authentication(
   2726       spdy_util_.ConstructSpdySynReplyError(
   2727           "407 Proxy Authentication Required",
   2728           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
   2729           1));
   2730   scoped_ptr<SpdyFrame> body_authentication(
   2731       spdy_util_.ConstructSpdyBodyFrame(1, true));
   2732   scoped_ptr<SpdyFrame> resp_data(
   2733       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   2734   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
   2735   MockRead spdy_reads[] = {
   2736     CreateMockRead(*resp_authentication, 2),
   2737     CreateMockRead(*body_authentication, 3),
   2738     CreateMockRead(*resp_data, 5),
   2739     CreateMockRead(*body_data, 6),
   2740     MockRead(ASYNC, 0, 7),
   2741   };
   2742 
   2743   OrderedSocketData data(
   2744       spdy_reads, arraysize(spdy_reads),
   2745       spdy_writes, arraysize(spdy_writes));
   2746   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2747 
   2748   SSLSocketDataProvider ssl(ASYNC, OK);
   2749   ssl.SetNextProto(GetParam());
   2750   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2751 
   2752   TestCompletionCallback callback1;
   2753 
   2754   scoped_ptr<HttpTransaction> trans(
   2755       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2756 
   2757   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2758   EXPECT_EQ(ERR_IO_PENDING, rv);
   2759 
   2760   rv = callback1.WaitForResult();
   2761   EXPECT_EQ(OK, rv);
   2762 
   2763   const HttpResponseInfo* const response = trans->GetResponseInfo();
   2764 
   2765   ASSERT_TRUE(response != NULL);
   2766   ASSERT_TRUE(response->headers.get() != NULL);
   2767   EXPECT_EQ(407, response->headers->response_code());
   2768   EXPECT_TRUE(response->was_fetched_via_spdy);
   2769   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2770 
   2771   TestCompletionCallback callback2;
   2772 
   2773   rv = trans->RestartWithAuth(
   2774       AuthCredentials(kFoo, kBar), callback2.callback());
   2775   EXPECT_EQ(ERR_IO_PENDING, rv);
   2776 
   2777   rv = callback2.WaitForResult();
   2778   EXPECT_EQ(OK, rv);
   2779 
   2780   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   2781 
   2782   ASSERT_TRUE(response_restart != NULL);
   2783   ASSERT_TRUE(response_restart->headers.get() != NULL);
   2784   EXPECT_EQ(200, response_restart->headers->response_code());
   2785   // The password prompt info should not be set.
   2786   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   2787 }
   2788 
   2789 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
   2790 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   2791   HttpRequestInfo request;
   2792   request.method = "GET";
   2793   request.url = GURL("https://www.google.com/");
   2794   request.load_flags = 0;
   2795 
   2796   // Configure against https proxy server "proxy:70".
   2797   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2798       "https://proxy:70"));
   2799   CapturingBoundNetLog log;
   2800   session_deps_.net_log = log.bound().net_log();
   2801   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2802 
   2803   scoped_ptr<HttpTransaction> trans(
   2804       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2805 
   2806   // CONNECT to www.google.com:443 via SPDY
   2807   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   2808                                                                 LOWEST));
   2809   // fetch https://www.google.com/ via HTTP
   2810 
   2811   const char get[] = "GET / HTTP/1.1\r\n"
   2812     "Host: www.google.com\r\n"
   2813     "Connection: keep-alive\r\n\r\n";
   2814   scoped_ptr<SpdyFrame> wrapped_get(
   2815       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
   2816   scoped_ptr<SpdyFrame> conn_resp(
   2817       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2818   const char resp[] = "HTTP/1.1 200 OK\r\n"
   2819       "Content-Length: 10\r\n\r\n";
   2820   scoped_ptr<SpdyFrame> wrapped_get_resp(
   2821       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
   2822   scoped_ptr<SpdyFrame> wrapped_body(
   2823       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
   2824   scoped_ptr<SpdyFrame> window_update(
   2825       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   2826 
   2827   MockWrite spdy_writes[] = {
   2828       CreateMockWrite(*connect, 1),
   2829       CreateMockWrite(*wrapped_get, 3),
   2830       CreateMockWrite(*window_update, 5),
   2831   };
   2832 
   2833   MockRead spdy_reads[] = {
   2834     CreateMockRead(*conn_resp, 2, ASYNC),
   2835     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   2836     CreateMockRead(*wrapped_body, 6, ASYNC),
   2837     CreateMockRead(*wrapped_body, 7, ASYNC),
   2838     MockRead(ASYNC, 0, 8),
   2839   };
   2840 
   2841   OrderedSocketData spdy_data(
   2842       spdy_reads, arraysize(spdy_reads),
   2843       spdy_writes, arraysize(spdy_writes));
   2844   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2845 
   2846   SSLSocketDataProvider ssl(ASYNC, OK);
   2847   ssl.SetNextProto(GetParam());
   2848   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2849   SSLSocketDataProvider ssl2(ASYNC, OK);
   2850   ssl2.was_npn_negotiated = false;
   2851   ssl2.protocol_negotiated = kProtoUnknown;
   2852   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   2853 
   2854   TestCompletionCallback callback1;
   2855 
   2856   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2857   EXPECT_EQ(ERR_IO_PENDING, rv);
   2858 
   2859   rv = callback1.WaitForResult();
   2860   EXPECT_EQ(OK, rv);
   2861 
   2862   LoadTimingInfo load_timing_info;
   2863   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2864   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   2865 
   2866   const HttpResponseInfo* response = trans->GetResponseInfo();
   2867   ASSERT_TRUE(response != NULL);
   2868   ASSERT_TRUE(response->headers.get() != NULL);
   2869   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2870 
   2871   std::string response_data;
   2872   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2873   EXPECT_EQ("1234567890", response_data);
   2874 }
   2875 
   2876 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
   2877 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   2878   HttpRequestInfo request;
   2879   request.method = "GET";
   2880   request.url = GURL("https://www.google.com/");
   2881   request.load_flags = 0;
   2882 
   2883   // Configure against https proxy server "proxy:70".
   2884   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2885       "https://proxy:70"));
   2886   CapturingBoundNetLog log;
   2887   session_deps_.net_log = log.bound().net_log();
   2888   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2889 
   2890   scoped_ptr<HttpTransaction> trans(
   2891       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2892 
   2893   // CONNECT to www.google.com:443 via SPDY
   2894   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   2895                                                                 LOWEST));
   2896   // fetch https://www.google.com/ via SPDY
   2897   const char* const kMyUrl = "https://www.google.com/";
   2898   scoped_ptr<SpdyFrame> get(
   2899       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   2900   scoped_ptr<SpdyFrame> wrapped_get(
   2901       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
   2902   scoped_ptr<SpdyFrame> conn_resp(
   2903       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2904   scoped_ptr<SpdyFrame> get_resp(
   2905       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2906   scoped_ptr<SpdyFrame> wrapped_get_resp(
   2907       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
   2908   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2909   scoped_ptr<SpdyFrame> wrapped_body(
   2910       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
   2911   scoped_ptr<SpdyFrame> window_update_get_resp(
   2912       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   2913   scoped_ptr<SpdyFrame> window_update_body(
   2914       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
   2915 
   2916   MockWrite spdy_writes[] = {
   2917       CreateMockWrite(*connect, 1),
   2918       CreateMockWrite(*wrapped_get, 3),
   2919       CreateMockWrite(*window_update_get_resp, 5),
   2920       CreateMockWrite(*window_update_body, 7),
   2921   };
   2922 
   2923   MockRead spdy_reads[] = {
   2924     CreateMockRead(*conn_resp, 2, ASYNC),
   2925     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   2926     CreateMockRead(*wrapped_body, 6, ASYNC),
   2927     MockRead(ASYNC, 0, 8),
   2928   };
   2929 
   2930   OrderedSocketData spdy_data(
   2931       spdy_reads, arraysize(spdy_reads),
   2932       spdy_writes, arraysize(spdy_writes));
   2933   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   2934 
   2935   SSLSocketDataProvider ssl(ASYNC, OK);
   2936   ssl.SetNextProto(GetParam());
   2937   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2938   SSLSocketDataProvider ssl2(ASYNC, OK);
   2939   ssl2.SetNextProto(GetParam());
   2940   ssl2.protocol_negotiated = GetParam();
   2941   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   2942 
   2943   TestCompletionCallback callback1;
   2944 
   2945   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2946   EXPECT_EQ(ERR_IO_PENDING, rv);
   2947 
   2948   rv = callback1.WaitForResult();
   2949   EXPECT_EQ(OK, rv);
   2950 
   2951   LoadTimingInfo load_timing_info;
   2952   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2953   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   2954 
   2955   const HttpResponseInfo* response = trans->GetResponseInfo();
   2956   ASSERT_TRUE(response != NULL);
   2957   ASSERT_TRUE(response->headers.get() != NULL);
   2958   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2959 
   2960   std::string response_data;
   2961   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2962   EXPECT_EQ(kUploadData, response_data);
   2963 }
   2964 
   2965 // Test a SPDY CONNECT failure through an HTTPS Proxy.
   2966 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   2967   HttpRequestInfo request;
   2968   request.method = "GET";
   2969   request.url = GURL("https://www.google.com/");
   2970   request.load_flags = 0;
   2971 
   2972   // Configure against https proxy server "proxy:70".
   2973   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2974       "https://proxy:70"));
   2975   CapturingBoundNetLog log;
   2976   session_deps_.net_log = log.bound().net_log();
   2977   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2978 
   2979   scoped_ptr<HttpTransaction> trans(
   2980       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2981 
   2982   // CONNECT to www.google.com:443 via SPDY
   2983   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   2984                                                                 LOWEST));
   2985   scoped_ptr<SpdyFrame> get(
   2986       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   2987 
   2988   MockWrite spdy_writes[] = {
   2989       CreateMockWrite(*connect, 1),
   2990       CreateMockWrite(*get, 3),
   2991   };
   2992 
   2993   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
   2994   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2995   MockRead spdy_reads[] = {
   2996     CreateMockRead(*resp, 2, ASYNC),
   2997     MockRead(ASYNC, 0, 4),
   2998   };
   2999 
   3000   OrderedSocketData spdy_data(
   3001       spdy_reads, arraysize(spdy_reads),
   3002       spdy_writes, arraysize(spdy_writes));
   3003   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3004 
   3005   SSLSocketDataProvider ssl(ASYNC, OK);
   3006   ssl.SetNextProto(GetParam());
   3007   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3008   SSLSocketDataProvider ssl2(ASYNC, OK);
   3009   ssl2.SetNextProto(GetParam());
   3010   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3011 
   3012   TestCompletionCallback callback1;
   3013 
   3014   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3015   EXPECT_EQ(ERR_IO_PENDING, rv);
   3016 
   3017   rv = callback1.WaitForResult();
   3018   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3019 
   3020   // TODO(ttuttle): Anything else to check here?
   3021 }
   3022 
   3023 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3024 // HTTPS Proxy to different servers.
   3025 TEST_P(HttpNetworkTransactionTest,
   3026        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
   3027   // Configure against https proxy server "proxy:70".
   3028   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3029       "https://proxy:70"));
   3030   CapturingBoundNetLog log;
   3031   session_deps_.net_log = log.bound().net_log();
   3032   scoped_refptr<HttpNetworkSession> session(
   3033       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3034 
   3035   HttpRequestInfo request1;
   3036   request1.method = "GET";
   3037   request1.url = GURL("https://www.google.com/");
   3038   request1.load_flags = 0;
   3039 
   3040   HttpRequestInfo request2;
   3041   request2.method = "GET";
   3042   request2.url = GURL("https://news.google.com/");
   3043   request2.load_flags = 0;
   3044 
   3045   // CONNECT to www.google.com:443 via SPDY.
   3046   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3047                                                                  LOWEST));
   3048   scoped_ptr<SpdyFrame> conn_resp1(
   3049       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3050 
   3051   // Fetch https://www.google.com/ via HTTP.
   3052   const char get1[] = "GET / HTTP/1.1\r\n"
   3053       "Host: www.google.com\r\n"
   3054       "Connection: keep-alive\r\n\r\n";
   3055   scoped_ptr<SpdyFrame> wrapped_get1(
   3056       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3057   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3058       "Content-Length: 1\r\n\r\n";
   3059   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3060       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3061   scoped_ptr<SpdyFrame> wrapped_body1(
   3062       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3063   scoped_ptr<SpdyFrame> window_update(
   3064       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3065 
   3066   // CONNECT to news.google.com:443 via SPDY.
   3067   const char* const kConnectHeaders2[] = {
   3068     spdy_util_.GetMethodKey(), "CONNECT",
   3069     spdy_util_.GetPathKey(), "news.google.com:443",
   3070     spdy_util_.GetHostKey(), "news.google.com",
   3071     spdy_util_.GetVersionKey(), "HTTP/1.1",
   3072   };
   3073   scoped_ptr<SpdyFrame> connect2(
   3074       spdy_util_.ConstructSpdyControlFrame(NULL,
   3075                                            0,
   3076                                            /*compressed*/ false,
   3077                                            3,
   3078                                            LOWEST,
   3079                                            SYN_STREAM,
   3080                                            CONTROL_FLAG_NONE,
   3081                                            kConnectHeaders2,
   3082                                            arraysize(kConnectHeaders2),
   3083                                            0));
   3084   scoped_ptr<SpdyFrame> conn_resp2(
   3085       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3086 
   3087   // Fetch https://news.google.com/ via HTTP.
   3088   const char get2[] = "GET / HTTP/1.1\r\n"
   3089       "Host: news.google.com\r\n"
   3090       "Connection: keep-alive\r\n\r\n";
   3091   scoped_ptr<SpdyFrame> wrapped_get2(
   3092       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
   3093   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3094       "Content-Length: 2\r\n\r\n";
   3095   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3096       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
   3097   scoped_ptr<SpdyFrame> wrapped_body2(
   3098       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
   3099 
   3100   MockWrite spdy_writes[] = {
   3101       CreateMockWrite(*connect1, 0),
   3102       CreateMockWrite(*wrapped_get1, 2),
   3103       CreateMockWrite(*connect2, 5),
   3104       CreateMockWrite(*wrapped_get2, 7),
   3105   };
   3106 
   3107   MockRead spdy_reads[] = {
   3108     CreateMockRead(*conn_resp1, 1, ASYNC),
   3109     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3110     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3111     CreateMockRead(*conn_resp2, 6, ASYNC),
   3112     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
   3113     CreateMockRead(*wrapped_body2, 9, ASYNC),
   3114     MockRead(ASYNC, 0, 10),
   3115   };
   3116 
   3117   DeterministicSocketData spdy_data(
   3118       spdy_reads, arraysize(spdy_reads),
   3119       spdy_writes, arraysize(spdy_writes));
   3120   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3121 
   3122   SSLSocketDataProvider ssl(ASYNC, OK);
   3123   ssl.SetNextProto(GetParam());
   3124   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3125   SSLSocketDataProvider ssl2(ASYNC, OK);
   3126   ssl2.was_npn_negotiated = false;
   3127   ssl2.protocol_negotiated = kProtoUnknown;
   3128   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3129   SSLSocketDataProvider ssl3(ASYNC, OK);
   3130   ssl3.was_npn_negotiated = false;
   3131   ssl3.protocol_negotiated = kProtoUnknown;
   3132   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
   3133 
   3134   TestCompletionCallback callback;
   3135 
   3136   scoped_ptr<HttpTransaction> trans(
   3137       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3138   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3139   EXPECT_EQ(ERR_IO_PENDING, rv);
   3140   // The first connect and request, each of their responses, and the body.
   3141   spdy_data.RunFor(5);
   3142 
   3143   rv = callback.WaitForResult();
   3144   EXPECT_EQ(OK, rv);
   3145 
   3146   LoadTimingInfo load_timing_info;
   3147   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3148   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3149 
   3150   const HttpResponseInfo* response = trans->GetResponseInfo();
   3151   ASSERT_TRUE(response != NULL);
   3152   ASSERT_TRUE(response->headers.get() != NULL);
   3153   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3154 
   3155   std::string response_data;
   3156   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3157   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3158 
   3159   scoped_ptr<HttpTransaction> trans2(
   3160       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3161   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3162   EXPECT_EQ(ERR_IO_PENDING, rv);
   3163 
   3164   // The second connect and request, each of their responses, and the body.
   3165   spdy_data.RunFor(5);
   3166   rv = callback.WaitForResult();
   3167   EXPECT_EQ(OK, rv);
   3168 
   3169   LoadTimingInfo load_timing_info2;
   3170   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3171   // Even though the SPDY connection is reused, a new tunnelled connection has
   3172   // to be created, so the socket's load timing looks like a fresh connection.
   3173   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
   3174 
   3175   // The requests should have different IDs, since they each are using their own
   3176   // separate stream.
   3177   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3178 
   3179   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3180 }
   3181 
   3182 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3183 // HTTPS Proxy to the same server.
   3184 TEST_P(HttpNetworkTransactionTest,
   3185        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
   3186   // Configure against https proxy server "proxy:70".
   3187   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3188       "https://proxy:70"));
   3189   CapturingBoundNetLog log;
   3190   session_deps_.net_log = log.bound().net_log();
   3191   scoped_refptr<HttpNetworkSession> session(
   3192       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3193 
   3194   HttpRequestInfo request1;
   3195   request1.method = "GET";
   3196   request1.url = GURL("https://www.google.com/");
   3197   request1.load_flags = 0;
   3198 
   3199   HttpRequestInfo request2;
   3200   request2.method = "GET";
   3201   request2.url = GURL("https://www.google.com/2");
   3202   request2.load_flags = 0;
   3203 
   3204   // CONNECT to www.google.com:443 via SPDY.
   3205   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3206                                                                  LOWEST));
   3207   scoped_ptr<SpdyFrame> conn_resp1(
   3208       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3209 
   3210   // Fetch https://www.google.com/ via HTTP.
   3211   const char get1[] = "GET / HTTP/1.1\r\n"
   3212       "Host: www.google.com\r\n"
   3213       "Connection: keep-alive\r\n\r\n";
   3214   scoped_ptr<SpdyFrame> wrapped_get1(
   3215       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3216   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3217       "Content-Length: 1\r\n\r\n";
   3218   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3219       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3220   scoped_ptr<SpdyFrame> wrapped_body1(
   3221       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3222   scoped_ptr<SpdyFrame> window_update(
   3223       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3224 
   3225   // Fetch https://www.google.com/2 via HTTP.
   3226   const char get2[] = "GET /2 HTTP/1.1\r\n"
   3227       "Host: www.google.com\r\n"
   3228       "Connection: keep-alive\r\n\r\n";
   3229   scoped_ptr<SpdyFrame> wrapped_get2(
   3230       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
   3231   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3232       "Content-Length: 2\r\n\r\n";
   3233   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3234       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
   3235   scoped_ptr<SpdyFrame> wrapped_body2(
   3236       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
   3237 
   3238   MockWrite spdy_writes[] = {
   3239       CreateMockWrite(*connect1, 0),
   3240       CreateMockWrite(*wrapped_get1, 2),
   3241       CreateMockWrite(*wrapped_get2, 5),
   3242   };
   3243 
   3244   MockRead spdy_reads[] = {
   3245     CreateMockRead(*conn_resp1, 1, ASYNC),
   3246     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3247     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3248     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
   3249     CreateMockRead(*wrapped_body2, 7, ASYNC),
   3250     MockRead(ASYNC, 0, 8),
   3251   };
   3252 
   3253   DeterministicSocketData spdy_data(
   3254       spdy_reads, arraysize(spdy_reads),
   3255       spdy_writes, arraysize(spdy_writes));
   3256   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3257 
   3258   SSLSocketDataProvider ssl(ASYNC, OK);
   3259   ssl.SetNextProto(GetParam());
   3260   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3261   SSLSocketDataProvider ssl2(ASYNC, OK);
   3262   ssl2.was_npn_negotiated = false;
   3263   ssl2.protocol_negotiated = kProtoUnknown;
   3264   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3265 
   3266   TestCompletionCallback callback;
   3267 
   3268   scoped_ptr<HttpTransaction> trans(
   3269       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3270   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3271   EXPECT_EQ(ERR_IO_PENDING, rv);
   3272   // The first connect and request, each of their responses, and the body.
   3273   spdy_data.RunFor(5);
   3274 
   3275   rv = callback.WaitForResult();
   3276   EXPECT_EQ(OK, rv);
   3277 
   3278   LoadTimingInfo load_timing_info;
   3279   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3280   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3281 
   3282   const HttpResponseInfo* response = trans->GetResponseInfo();
   3283   ASSERT_TRUE(response != NULL);
   3284   ASSERT_TRUE(response->headers.get() != NULL);
   3285   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3286 
   3287   std::string response_data;
   3288   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3289   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3290   trans.reset();
   3291 
   3292   scoped_ptr<HttpTransaction> trans2(
   3293       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3294   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3295   EXPECT_EQ(ERR_IO_PENDING, rv);
   3296 
   3297   // The second request, response, and body.  There should not be a second
   3298   // connect.
   3299   spdy_data.RunFor(3);
   3300   rv = callback.WaitForResult();
   3301   EXPECT_EQ(OK, rv);
   3302 
   3303   LoadTimingInfo load_timing_info2;
   3304   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3305   TestLoadTimingReused(load_timing_info2);
   3306 
   3307   // The requests should have the same ID.
   3308   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3309 
   3310   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3311 }
   3312 
   3313 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
   3314 // Proxy to different servers.
   3315 TEST_P(HttpNetworkTransactionTest,
   3316        HttpsProxySpdyLoadTimingTwoHttpRequests) {
   3317   // Configure against https proxy server "proxy:70".
   3318   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3319       "https://proxy:70"));
   3320   CapturingBoundNetLog log;
   3321   session_deps_.net_log = log.bound().net_log();
   3322   scoped_refptr<HttpNetworkSession> session(
   3323       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3324 
   3325   HttpRequestInfo request1;
   3326   request1.method = "GET";
   3327   request1.url = GURL("http://www.google.com/");
   3328   request1.load_flags = 0;
   3329 
   3330   HttpRequestInfo request2;
   3331   request2.method = "GET";
   3332   request2.url = GURL("http://news.google.com/");
   3333   request2.load_flags = 0;
   3334 
   3335   // http://www.google.com/
   3336   scoped_ptr<SpdyHeaderBlock> headers(
   3337       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   3338   scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
   3339       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3340   scoped_ptr<SpdyFrame> get_resp1(
   3341       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3342   scoped_ptr<SpdyFrame> body1(
   3343       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
   3344 
   3345   // http://news.google.com/
   3346   scoped_ptr<SpdyHeaderBlock> headers2(
   3347       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
   3348   scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
   3349       headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3350   scoped_ptr<SpdyFrame> get_resp2(
   3351       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3352   scoped_ptr<SpdyFrame> body2(
   3353       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
   3354 
   3355   MockWrite spdy_writes[] = {
   3356       CreateMockWrite(*get1, 0),
   3357       CreateMockWrite(*get2, 3),
   3358   };
   3359 
   3360   MockRead spdy_reads[] = {
   3361     CreateMockRead(*get_resp1, 1, ASYNC),
   3362     CreateMockRead(*body1, 2, ASYNC),
   3363     CreateMockRead(*get_resp2, 4, ASYNC),
   3364     CreateMockRead(*body2, 5, ASYNC),
   3365     MockRead(ASYNC, 0, 6),
   3366   };
   3367 
   3368   DeterministicSocketData spdy_data(
   3369       spdy_reads, arraysize(spdy_reads),
   3370       spdy_writes, arraysize(spdy_writes));
   3371   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3372 
   3373   SSLSocketDataProvider ssl(ASYNC, OK);
   3374   ssl.SetNextProto(GetParam());
   3375   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3376 
   3377   TestCompletionCallback callback;
   3378 
   3379   scoped_ptr<HttpTransaction> trans(
   3380       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3381   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3382   EXPECT_EQ(ERR_IO_PENDING, rv);
   3383   spdy_data.RunFor(2);
   3384 
   3385   rv = callback.WaitForResult();
   3386   EXPECT_EQ(OK, rv);
   3387 
   3388   LoadTimingInfo load_timing_info;
   3389   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3390   TestLoadTimingNotReused(load_timing_info,
   3391                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3392 
   3393   const HttpResponseInfo* response = trans->GetResponseInfo();
   3394   ASSERT_TRUE(response != NULL);
   3395   ASSERT_TRUE(response->headers.get() != NULL);
   3396   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3397 
   3398   std::string response_data;
   3399   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3400   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
   3401   spdy_data.RunFor(1);
   3402   EXPECT_EQ(1, callback.WaitForResult());
   3403   // Delete the first request, so the second one can reuse the socket.
   3404   trans.reset();
   3405 
   3406   scoped_ptr<HttpTransaction> trans2(
   3407       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3408   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3409   EXPECT_EQ(ERR_IO_PENDING, rv);
   3410 
   3411   spdy_data.RunFor(2);
   3412   rv = callback.WaitForResult();
   3413   EXPECT_EQ(OK, rv);
   3414 
   3415   LoadTimingInfo load_timing_info2;
   3416   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3417   TestLoadTimingReused(load_timing_info2);
   3418 
   3419   // The requests should have the same ID.
   3420   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3421 
   3422   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
   3423   spdy_data.RunFor(1);
   3424   EXPECT_EQ(2, callback.WaitForResult());
   3425 }
   3426 
   3427 // Test the challenge-response-retry sequence through an HTTPS Proxy
   3428 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   3429   HttpRequestInfo request;
   3430   request.method = "GET";
   3431   request.url = GURL("http://www.google.com/");
   3432   // when the no authentication data flag is set.
   3433   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   3434 
   3435   // Configure against https proxy server "myproxy:70".
   3436   session_deps_.proxy_service.reset(
   3437       ProxyService::CreateFixed("https://myproxy:70"));
   3438   CapturingBoundNetLog log;
   3439   session_deps_.net_log = log.bound().net_log();
   3440   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3441 
   3442   // Since we have proxy, should use full url
   3443   MockWrite data_writes1[] = {
   3444     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3445               "Host: www.google.com\r\n"
   3446               "Proxy-Connection: keep-alive\r\n\r\n"),
   3447 
   3448     // After calling trans->RestartWithAuth(), this is the request we should
   3449     // be issuing -- the final header line contains the credentials.
   3450     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3451               "Host: www.google.com\r\n"
   3452               "Proxy-Connection: keep-alive\r\n"
   3453               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3454   };
   3455 
   3456   // The proxy responds to the GET with a 407, using a persistent
   3457   // connection.
   3458   MockRead data_reads1[] = {
   3459     // No credentials.
   3460     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3461     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3462     MockRead("Proxy-Connection: keep-alive\r\n"),
   3463     MockRead("Content-Length: 0\r\n\r\n"),
   3464 
   3465     MockRead("HTTP/1.1 200 OK\r\n"),
   3466     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3467     MockRead("Content-Length: 100\r\n\r\n"),
   3468     MockRead(SYNCHRONOUS, OK),
   3469   };
   3470 
   3471   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3472                                  data_writes1, arraysize(data_writes1));
   3473   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3474   SSLSocketDataProvider ssl(ASYNC, OK);
   3475   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3476 
   3477   TestCompletionCallback callback1;
   3478 
   3479   scoped_ptr<HttpTransaction> trans(
   3480       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3481 
   3482   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3483   EXPECT_EQ(ERR_IO_PENDING, rv);
   3484 
   3485   rv = callback1.WaitForResult();
   3486   EXPECT_EQ(OK, rv);
   3487 
   3488   LoadTimingInfo load_timing_info;
   3489   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3490   TestLoadTimingNotReused(load_timing_info,
   3491                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3492 
   3493   const HttpResponseInfo* response = trans->GetResponseInfo();
   3494   ASSERT_TRUE(response != NULL);
   3495   ASSERT_FALSE(response->headers.get() == NULL);
   3496   EXPECT_EQ(407, response->headers->response_code());
   3497   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3498   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3499 
   3500   TestCompletionCallback callback2;
   3501 
   3502   rv = trans->RestartWithAuth(
   3503       AuthCredentials(kFoo, kBar), callback2.callback());
   3504   EXPECT_EQ(ERR_IO_PENDING, rv);
   3505 
   3506   rv = callback2.WaitForResult();
   3507   EXPECT_EQ(OK, rv);
   3508 
   3509   load_timing_info = LoadTimingInfo();
   3510   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3511   // Retrying with HTTP AUTH is considered to be reusing a socket.
   3512   TestLoadTimingReused(load_timing_info);
   3513 
   3514   response = trans->GetResponseInfo();
   3515   ASSERT_TRUE(response != NULL);
   3516 
   3517   EXPECT_TRUE(response->headers->IsKeepAlive());
   3518   EXPECT_EQ(200, response->headers->response_code());
   3519   EXPECT_EQ(100, response->headers->GetContentLength());
   3520   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3521 
   3522   // The password prompt info should not be set.
   3523   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3524 }
   3525 
   3526 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   3527     const MockRead& status, int expected_status) {
   3528   HttpRequestInfo request;
   3529   request.method = "GET";
   3530   request.url = GURL("https://www.google.com/");
   3531   request.load_flags = 0;
   3532 
   3533   // Configure against proxy server "myproxy:70".
   3534   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3535   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3536 
   3537   // Since we have proxy, should try to establish tunnel.
   3538   MockWrite data_writes[] = {
   3539     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   3540               "Host: www.google.com\r\n"
   3541               "Proxy-Connection: keep-alive\r\n\r\n"),
   3542   };
   3543 
   3544   MockRead data_reads[] = {
   3545     status,
   3546     MockRead("Content-Length: 10\r\n\r\n"),
   3547     // No response body because the test stops reading here.
   3548     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   3549   };
   3550 
   3551   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3552                                 data_writes, arraysize(data_writes));
   3553   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3554 
   3555   TestCompletionCallback callback;
   3556 
   3557   scoped_ptr<HttpTransaction> trans(
   3558       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3559 
   3560   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   3561   EXPECT_EQ(ERR_IO_PENDING, rv);
   3562 
   3563   rv = callback.WaitForResult();
   3564   EXPECT_EQ(expected_status, rv);
   3565 }
   3566 
   3567 void HttpNetworkTransactionTest::ConnectStatusHelper(
   3568     const MockRead& status) {
   3569   ConnectStatusHelperWithExpectedStatus(
   3570       status, ERR_TUNNEL_CONNECTION_FAILED);
   3571 }
   3572 
   3573 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
   3574   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   3575 }
   3576 
   3577 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
   3578   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   3579 }
   3580 
   3581 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
   3582   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   3583 }
   3584 
   3585 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
   3586   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   3587 }
   3588 
   3589 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
   3590   ConnectStatusHelper(
   3591       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   3592 }
   3593 
   3594 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
   3595   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   3596 }
   3597 
   3598 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
   3599   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   3600 }
   3601 
   3602 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
   3603   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   3604 }
   3605 
   3606 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
   3607   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   3608 }
   3609 
   3610 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
   3611   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   3612 }
   3613 
   3614 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
   3615   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   3616 }
   3617 
   3618 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
   3619   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   3620 }
   3621 
   3622 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
   3623   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   3624 }
   3625 
   3626 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
   3627   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   3628 }
   3629 
   3630 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
   3631   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   3632 }
   3633 
   3634 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
   3635   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   3636 }
   3637 
   3638 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
   3639   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   3640 }
   3641 
   3642 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
   3643   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   3644 }
   3645 
   3646 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
   3647   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   3648 }
   3649 
   3650 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
   3651   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   3652 }
   3653 
   3654 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
   3655   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   3656 }
   3657 
   3658 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
   3659   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   3660 }
   3661 
   3662 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
   3663   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   3664 }
   3665 
   3666 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
   3667   ConnectStatusHelperWithExpectedStatus(
   3668       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3669       ERR_PROXY_AUTH_UNSUPPORTED);
   3670 }
   3671 
   3672 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
   3673   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   3674 }
   3675 
   3676 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
   3677   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   3678 }
   3679 
   3680 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
   3681   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   3682 }
   3683 
   3684 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
   3685   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   3686 }
   3687 
   3688 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
   3689   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   3690 }
   3691 
   3692 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
   3693   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   3694 }
   3695 
   3696 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
   3697   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   3698 }
   3699 
   3700 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
   3701   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   3702 }
   3703 
   3704 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
   3705   ConnectStatusHelper(
   3706       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   3707 }
   3708 
   3709 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
   3710   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   3711 }
   3712 
   3713 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
   3714   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   3715 }
   3716 
   3717 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
   3718   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   3719 }
   3720 
   3721 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
   3722   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   3723 }
   3724 
   3725 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
   3726   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   3727 }
   3728 
   3729 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
   3730   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   3731 }
   3732 
   3733 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
   3734   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   3735 }
   3736 
   3737 // Test the flow when both the proxy server AND origin server require
   3738 // authentication. Again, this uses basic auth for both since that is
   3739 // the simplest to mock.
   3740 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   3741   HttpRequestInfo request;
   3742   request.method = "GET";
   3743   request.url = GURL("http://www.google.com/");
   3744   request.load_flags = 0;
   3745 
   3746   // Configure against proxy server "myproxy:70".
   3747   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3748   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3749 
   3750   scoped_ptr<HttpTransaction> trans(
   3751       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   3752 
   3753   MockWrite data_writes1[] = {
   3754     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3755               "Host: www.google.com\r\n"
   3756               "Proxy-Connection: keep-alive\r\n\r\n"),
   3757   };
   3758 
   3759   MockRead data_reads1[] = {
   3760     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   3761     // Give a couple authenticate options (only the middle one is actually
   3762     // supported).
   3763     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   3764     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3765     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   3766     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3767     // Large content-length -- won't matter, as connection will be reset.
   3768     MockRead("Content-Length: 10000\r\n\r\n"),
   3769     MockRead(SYNCHRONOUS, ERR_FAILED),
   3770   };
   3771 
   3772   // After calling trans->RestartWithAuth() the first time, this is the
   3773   // request we should be issuing -- the final header line contains the
   3774   // proxy's credentials.
   3775   MockWrite data_writes2[] = {
   3776     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3777               "Host: www.google.com\r\n"
   3778               "Proxy-Connection: keep-alive\r\n"
   3779               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3780   };
   3781 
   3782   // Now the proxy server lets the request pass through to origin server.
   3783   // The origin server responds with a 401.
   3784   MockRead data_reads2[] = {
   3785     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3786     // Note: We are using the same realm-name as the proxy server. This is
   3787     // completely valid, as realms are unique across hosts.
   3788     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3789     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3790     MockRead("Content-Length: 2000\r\n\r\n"),
   3791     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
   3792   };
   3793 
   3794   // After calling trans->RestartWithAuth() the second time, we should send
   3795   // the credentials for both the proxy and origin server.
   3796   MockWrite data_writes3[] = {
   3797     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3798               "Host: www.google.com\r\n"
   3799               "Proxy-Connection: keep-alive\r\n"
   3800               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   3801               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   3802   };
   3803 
   3804   // Lastly we get the desired content.
   3805   MockRead data_reads3[] = {
   3806     MockRead("HTTP/1.0 200 OK\r\n"),
   3807     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3808     MockRead("Content-Length: 100\r\n\r\n"),
   3809     MockRead(SYNCHRONOUS, OK),
   3810   };
   3811 
   3812   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3813                                  data_writes1, arraysize(data_writes1));
   3814   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3815                                  data_writes2, arraysize(data_writes2));
   3816   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   3817                                  data_writes3, arraysize(data_writes3));
   3818   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3819   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   3820   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   3821 
   3822   TestCompletionCallback callback1;
   3823 
   3824   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   3825   EXPECT_EQ(ERR_IO_PENDING, rv);
   3826 
   3827   rv = callback1.WaitForResult();
   3828   EXPECT_EQ(OK, rv);
   3829 
   3830   const HttpResponseInfo* response = trans->GetResponseInfo();
   3831   ASSERT_TRUE(response != NULL);
   3832   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3833 
   3834   TestCompletionCallback callback2;
   3835 
   3836   rv = trans->RestartWithAuth(
   3837       AuthCredentials(kFoo, kBar), callback2.callback());
   3838   EXPECT_EQ(ERR_IO_PENDING, rv);
   3839 
   3840   rv = callback2.WaitForResult();
   3841   EXPECT_EQ(OK, rv);
   3842 
   3843   response = trans->GetResponseInfo();
   3844   ASSERT_TRUE(response != NULL);
   3845   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   3846 
   3847   TestCompletionCallback callback3;
   3848 
   3849   rv = trans->RestartWithAuth(
   3850       AuthCredentials(kFoo2, kBar2), callback3.callback());
   3851   EXPECT_EQ(ERR_IO_PENDING, rv);
   3852 
   3853   rv = callback3.WaitForResult();
   3854   EXPECT_EQ(OK, rv);
   3855 
   3856   response = trans->GetResponseInfo();
   3857   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3858   EXPECT_EQ(100, response->headers->GetContentLength());
   3859 }
   3860 
   3861 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   3862 // can't hook into its internals to cause it to generate predictable NTLM
   3863 // authorization headers.
   3864 #if defined(NTLM_PORTABLE)
   3865 // The NTLM authentication unit tests were generated by capturing the HTTP
   3866 // requests and responses using Fiddler 2 and inspecting the generated random
   3867 // bytes in the debugger.
   3868 
   3869 // Enter the correct password and authenticate successfully.
   3870 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
   3871   HttpRequestInfo request;
   3872   request.method = "GET";
   3873   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   3874 
   3875   // Ensure load is not disrupted by flags which suppress behaviour specific
   3876   // to other auth schemes.
   3877   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   3878 
   3879   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   3880                                                     MockGetHostName);
   3881   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3882 
   3883   MockWrite data_writes1[] = {
   3884     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3885               "Host: 172.22.68.17\r\n"
   3886               "Connection: keep-alive\r\n\r\n"),
   3887   };
   3888 
   3889   MockRead data_reads1[] = {
   3890     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   3891     // Negotiate and NTLM are often requested together.  However, we only want
   3892     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   3893     // the header that requests Negotiate for this test.
   3894     MockRead("WWW-Authenticate: NTLM\r\n"),
   3895     MockRead("Connection: close\r\n"),
   3896     MockRead("Content-Length: 42\r\n"),
   3897     MockRead("Content-Type: text/html\r\n\r\n"),
   3898     // Missing content -- won't matter, as connection will be reset.
   3899     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   3900   };
   3901 
   3902   MockWrite data_writes2[] = {
   3903     // After restarting with a null identity, this is the
   3904     // request we should be issuing -- the final header line contains a Type
   3905     // 1 message.
   3906     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3907               "Host: 172.22.68.17\r\n"
   3908               "Connection: keep-alive\r\n"
   3909               "Authorization: NTLM "
   3910               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   3911 
   3912     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   3913     // (the credentials for the origin server).  The second request continues
   3914     // on the same connection.
   3915     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   3916               "Host: 172.22.68.17\r\n"
   3917               "Connection: keep-alive\r\n"
   3918               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   3919               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   3920               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   3921               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   3922               "ahlhx5I=\r\n\r\n"),
   3923   };
   3924 
   3925   MockRead data_reads2[] = {
   3926     // The origin server responds with a Type 2 message.
   3927     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   3928     MockRead("WWW-Authenticate: NTLM "
   3929              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   3930              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   3931              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   3932              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   3933              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   3934              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   3935              "BtAAAAAAA=\r\n"),
   3936     MockRead("Content-Length: 42\r\n"),
   3937     MockRead("Content-Type: text/html\r\n\r\n"),
   3938     MockRead("You are not authorized to view this page\r\n"),
   3939 
   3940     // Lastly we get the desired content.
   3941     MockRead("HTTP/1.1 200 OK\r\n"),
   3942     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   3943     MockRead("Content-Length: 13\r\n\r\n"),
   3944     MockRead("Please Login\r\n"),
   3945     MockRead(SYNCHRONOUS, OK),
   3946   };
   3947 
   3948   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3949                                  data_writes1, arraysize(data_writes1));
   3950   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3951                                  data_writes2, arraysize(data_writes2));
   3952   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3953   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   3954 
   3955   TestCompletionCallback callback1;
   3956 
   3957   scoped_ptr<HttpTransaction> trans(
   3958       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3959 
   3960   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   3961   EXPECT_EQ(ERR_IO_PENDING, rv);
   3962 
   3963   rv = callback1.WaitForResult();
   3964   EXPECT_EQ(OK, rv);
   3965 
   3966   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3967 
   3968   const HttpResponseInfo* response = trans->GetResponseInfo();
   3969   ASSERT_FALSE(response == NULL);
   3970   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   3971 
   3972   TestCompletionCallback callback2;
   3973 
   3974   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   3975                               callback2.callback());
   3976   EXPECT_EQ(ERR_IO_PENDING, rv);
   3977 
   3978   rv = callback2.WaitForResult();
   3979   EXPECT_EQ(OK, rv);
   3980 
   3981   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3982 
   3983   response = trans->GetResponseInfo();
   3984   ASSERT_TRUE(response != NULL);
   3985   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3986 
   3987   TestCompletionCallback callback3;
   3988 
   3989   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   3990   EXPECT_EQ(ERR_IO_PENDING, rv);
   3991 
   3992   rv = callback3.WaitForResult();
   3993   EXPECT_EQ(OK, rv);
   3994 
   3995   response = trans->GetResponseInfo();
   3996   ASSERT_TRUE(response != NULL);
   3997   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3998   EXPECT_EQ(13, response->headers->GetContentLength());
   3999 }
   4000 
   4001 // Enter a wrong password, and then the correct one.
   4002 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
   4003   HttpRequestInfo request;
   4004   request.method = "GET";
   4005   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   4006   request.load_flags = 0;
   4007 
   4008   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   4009                                                     MockGetHostName);
   4010   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4011 
   4012   MockWrite data_writes1[] = {
   4013     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4014               "Host: 172.22.68.17\r\n"
   4015               "Connection: keep-alive\r\n\r\n"),
   4016   };
   4017 
   4018   MockRead data_reads1[] = {
   4019     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4020     // Negotiate and NTLM are often requested together.  However, we only want
   4021     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4022     // the header that requests Negotiate for this test.
   4023     MockRead("WWW-Authenticate: NTLM\r\n"),
   4024     MockRead("Connection: close\r\n"),
   4025     MockRead("Content-Length: 42\r\n"),
   4026     MockRead("Content-Type: text/html\r\n\r\n"),
   4027     // Missing content -- won't matter, as connection will be reset.
   4028     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4029   };
   4030 
   4031   MockWrite data_writes2[] = {
   4032     // After restarting with a null identity, this is the
   4033     // request we should be issuing -- the final header line contains a Type
   4034     // 1 message.
   4035     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4036               "Host: 172.22.68.17\r\n"
   4037               "Connection: keep-alive\r\n"
   4038               "Authorization: NTLM "
   4039               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4040 
   4041     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4042     // (the credentials for the origin server).  The second request continues
   4043     // on the same connection.
   4044     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4045               "Host: 172.22.68.17\r\n"
   4046               "Connection: keep-alive\r\n"
   4047               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4048               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4049               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   4050               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   4051               "4Ww7b7E=\r\n\r\n"),
   4052   };
   4053 
   4054   MockRead data_reads2[] = {
   4055     // The origin server responds with a Type 2 message.
   4056     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4057     MockRead("WWW-Authenticate: NTLM "
   4058              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   4059              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4060              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4061              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4062              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4063              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4064              "BtAAAAAAA=\r\n"),
   4065     MockRead("Content-Length: 42\r\n"),
   4066     MockRead("Content-Type: text/html\r\n\r\n"),
   4067     MockRead("You are not authorized to view this page\r\n"),
   4068 
   4069     // Wrong password.
   4070     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4071     MockRead("WWW-Authenticate: NTLM\r\n"),
   4072     MockRead("Connection: close\r\n"),
   4073     MockRead("Content-Length: 42\r\n"),
   4074     MockRead("Content-Type: text/html\r\n\r\n"),
   4075     // Missing content -- won't matter, as connection will be reset.
   4076     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4077   };
   4078 
   4079   MockWrite data_writes3[] = {
   4080     // After restarting with a null identity, this is the
   4081     // request we should be issuing -- the final header line contains a Type
   4082     // 1 message.
   4083     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4084               "Host: 172.22.68.17\r\n"
   4085               "Connection: keep-alive\r\n"
   4086               "Authorization: NTLM "
   4087               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4088 
   4089     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4090     // (the credentials for the origin server).  The second request continues
   4091     // on the same connection.
   4092     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4093               "Host: 172.22.68.17\r\n"
   4094               "Connection: keep-alive\r\n"
   4095               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4096               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4097               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   4098               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   4099               "+4MUm7c=\r\n\r\n"),
   4100   };
   4101 
   4102   MockRead data_reads3[] = {
   4103     // The origin server responds with a Type 2 message.
   4104     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4105     MockRead("WWW-Authenticate: NTLM "
   4106              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   4107              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4108              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4109              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4110              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4111              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4112              "BtAAAAAAA=\r\n"),
   4113     MockRead("Content-Length: 42\r\n"),
   4114     MockRead("Content-Type: text/html\r\n\r\n"),
   4115     MockRead("You are not authorized to view this page\r\n"),
   4116 
   4117     // Lastly we get the desired content.
   4118     MockRead("HTTP/1.1 200 OK\r\n"),
   4119     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4120     MockRead("Content-Length: 13\r\n\r\n"),
   4121     MockRead("Please Login\r\n"),
   4122     MockRead(SYNCHRONOUS, OK),
   4123   };
   4124 
   4125   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4126                                  data_writes1, arraysize(data_writes1));
   4127   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4128                                  data_writes2, arraysize(data_writes2));
   4129   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4130                                  data_writes3, arraysize(data_writes3));
   4131   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4132   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4133   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4134 
   4135   TestCompletionCallback callback1;
   4136 
   4137   scoped_ptr<HttpTransaction> trans(
   4138       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4139 
   4140   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4141   EXPECT_EQ(ERR_IO_PENDING, rv);
   4142 
   4143   rv = callback1.WaitForResult();
   4144   EXPECT_EQ(OK, rv);
   4145 
   4146   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4147 
   4148   const HttpResponseInfo* response = trans->GetResponseInfo();
   4149   ASSERT_TRUE(response != NULL);
   4150   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4151 
   4152   TestCompletionCallback callback2;
   4153 
   4154   // Enter the wrong password.
   4155   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
   4156                               callback2.callback());
   4157   EXPECT_EQ(ERR_IO_PENDING, rv);
   4158 
   4159   rv = callback2.WaitForResult();
   4160   EXPECT_EQ(OK, rv);
   4161 
   4162   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4163   TestCompletionCallback callback3;
   4164   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4165   EXPECT_EQ(ERR_IO_PENDING, rv);
   4166   rv = callback3.WaitForResult();
   4167   EXPECT_EQ(OK, rv);
   4168   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4169 
   4170   response = trans->GetResponseInfo();
   4171   ASSERT_FALSE(response == NULL);
   4172   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4173 
   4174   TestCompletionCallback callback4;
   4175 
   4176   // Now enter the right password.
   4177   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4178                               callback4.callback());
   4179   EXPECT_EQ(ERR_IO_PENDING, rv);
   4180 
   4181   rv = callback4.WaitForResult();
   4182   EXPECT_EQ(OK, rv);
   4183 
   4184   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4185 
   4186   TestCompletionCallback callback5;
   4187 
   4188   // One more roundtrip
   4189   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
   4190   EXPECT_EQ(ERR_IO_PENDING, rv);
   4191 
   4192   rv = callback5.WaitForResult();
   4193   EXPECT_EQ(OK, rv);
   4194 
   4195   response = trans->GetResponseInfo();
   4196   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4197   EXPECT_EQ(13, response->headers->GetContentLength());
   4198 }
   4199 #endif  // NTLM_PORTABLE
   4200 
   4201 // Test reading a server response which has only headers, and no body.
   4202 // After some maximum number of bytes is consumed, the transaction should
   4203 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   4204 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   4205   HttpRequestInfo request;
   4206   request.method = "GET";
   4207   request.url = GURL("http://www.google.com/");
   4208   request.load_flags = 0;
   4209 
   4210   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4211   scoped_ptr<HttpTransaction> trans(
   4212       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4213 
   4214   // Respond with 300 kb of headers (we should fail after 256 kb).
   4215   std::string large_headers_string;
   4216   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   4217 
   4218   MockRead data_reads[] = {
   4219     MockRead("HTTP/1.0 200 OK\r\n"),
   4220     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
   4221     MockRead("\r\nBODY"),
   4222     MockRead(SYNCHRONOUS, OK),
   4223   };
   4224   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4225   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4226 
   4227   TestCompletionCallback callback;
   4228 
   4229   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4230   EXPECT_EQ(ERR_IO_PENDING, rv);
   4231 
   4232   rv = callback.WaitForResult();
   4233   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   4234 
   4235   const HttpResponseInfo* response = trans->GetResponseInfo();
   4236   EXPECT_TRUE(response == NULL);
   4237 }
   4238 
   4239 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   4240 // establish tunnel.
   4241 // http://code.google.com/p/chromium/issues/detail?id=3772
   4242 TEST_P(HttpNetworkTransactionTest,
   4243        DontRecycleTransportSocketForSSLTunnel) {
   4244   HttpRequestInfo request;
   4245   request.method = "GET";
   4246   request.url = GURL("https://www.google.com/");
   4247   request.load_flags = 0;
   4248 
   4249   // Configure against proxy server "myproxy:70".
   4250   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4251 
   4252   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4253 
   4254   scoped_ptr<HttpTransaction> trans(
   4255       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4256 
   4257   // Since we have proxy, should try to establish tunnel.
   4258   MockWrite data_writes1[] = {
   4259     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4260               "Host: www.google.com\r\n"
   4261               "Proxy-Connection: keep-alive\r\n\r\n"),
   4262   };
   4263 
   4264   // The proxy responds to the connect with a 404, using a persistent
   4265   // connection. Usually a proxy would return 501 (not implemented),
   4266   // or 200 (tunnel established).
   4267   MockRead data_reads1[] = {
   4268     MockRead("HTTP/1.1 404 Not Found\r\n"),
   4269     MockRead("Content-Length: 10\r\n\r\n"),
   4270     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   4271   };
   4272 
   4273   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4274                                  data_writes1, arraysize(data_writes1));
   4275   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4276 
   4277   TestCompletionCallback callback1;
   4278 
   4279   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4280   EXPECT_EQ(ERR_IO_PENDING, rv);
   4281 
   4282   rv = callback1.WaitForResult();
   4283   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   4284 
   4285   const HttpResponseInfo* response = trans->GetResponseInfo();
   4286   EXPECT_TRUE(response == NULL);
   4287 
   4288   // Empty the current queue.  This is necessary because idle sockets are
   4289   // added to the connection pool asynchronously with a PostTask.
   4290   base::MessageLoop::current()->RunUntilIdle();
   4291 
   4292   // We now check to make sure the TCPClientSocket was not added back to
   4293   // the pool.
   4294   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4295   trans.reset();
   4296   base::MessageLoop::current()->RunUntilIdle();
   4297   // Make sure that the socket didn't get recycled after calling the destructor.
   4298   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4299 }
   4300 
   4301 // Make sure that we recycle a socket after reading all of the response body.
   4302 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
   4303   HttpRequestInfo request;
   4304   request.method = "GET";
   4305   request.url = GURL("http://www.google.com/");
   4306   request.load_flags = 0;
   4307 
   4308   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4309 
   4310   scoped_ptr<HttpTransaction> trans(
   4311       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4312 
   4313   MockRead data_reads[] = {
   4314     // A part of the response body is received with the response headers.
   4315     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   4316     // The rest of the response body is received in two parts.
   4317     MockRead("lo"),
   4318     MockRead(" world"),
   4319     MockRead("junk"),  // Should not be read!!
   4320     MockRead(SYNCHRONOUS, OK),
   4321   };
   4322 
   4323   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4324   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4325 
   4326   TestCompletionCallback callback;
   4327 
   4328   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4329   EXPECT_EQ(ERR_IO_PENDING, rv);
   4330 
   4331   rv = callback.WaitForResult();
   4332   EXPECT_EQ(OK, rv);
   4333 
   4334   const HttpResponseInfo* response = trans->GetResponseInfo();
   4335   ASSERT_TRUE(response != NULL);
   4336 
   4337   EXPECT_TRUE(response->headers.get() != NULL);
   4338   std::string status_line = response->headers->GetStatusLine();
   4339   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   4340 
   4341   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4342 
   4343   std::string response_data;
   4344   rv = ReadTransaction(trans.get(), &response_data);
   4345   EXPECT_EQ(OK, rv);
   4346   EXPECT_EQ("hello world", response_data);
   4347 
   4348   // Empty the current queue.  This is necessary because idle sockets are
   4349   // added to the connection pool asynchronously with a PostTask.
   4350   base::MessageLoop::current()->RunUntilIdle();
   4351 
   4352   // We now check to make sure the socket was added back to the pool.
   4353   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4354 }
   4355 
   4356 // Make sure that we recycle a SSL socket after reading all of the response
   4357 // body.
   4358 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
   4359   HttpRequestInfo request;
   4360   request.method = "GET";
   4361   request.url = GURL("https://www.google.com/");
   4362   request.load_flags = 0;
   4363 
   4364   MockWrite data_writes[] = {
   4365     MockWrite("GET / HTTP/1.1\r\n"
   4366               "Host: www.google.com\r\n"
   4367               "Connection: keep-alive\r\n\r\n"),
   4368   };
   4369 
   4370   MockRead data_reads[] = {
   4371     MockRead("HTTP/1.1 200 OK\r\n"),
   4372     MockRead("Content-Length: 11\r\n\r\n"),
   4373     MockRead("hello world"),
   4374     MockRead(SYNCHRONOUS, OK),
   4375   };
   4376 
   4377   SSLSocketDataProvider ssl(ASYNC, OK);
   4378   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4379 
   4380   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4381                                 data_writes, arraysize(data_writes));
   4382   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4383 
   4384   TestCompletionCallback callback;
   4385 
   4386   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4387   scoped_ptr<HttpTransaction> trans(
   4388       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4389 
   4390   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4391 
   4392   EXPECT_EQ(ERR_IO_PENDING, rv);
   4393   EXPECT_EQ(OK, callback.WaitForResult());
   4394 
   4395   const HttpResponseInfo* response = trans->GetResponseInfo();
   4396   ASSERT_TRUE(response != NULL);
   4397   ASSERT_TRUE(response->headers.get() != NULL);
   4398   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4399 
   4400   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4401 
   4402   std::string response_data;
   4403   rv = ReadTransaction(trans.get(), &response_data);
   4404   EXPECT_EQ(OK, rv);
   4405   EXPECT_EQ("hello world", response_data);
   4406 
   4407   // Empty the current queue.  This is necessary because idle sockets are
   4408   // added to the connection pool asynchronously with a PostTask.
   4409   base::MessageLoop::current()->RunUntilIdle();
   4410 
   4411   // We now check to make sure the socket was added back to the pool.
   4412   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4413 }
   4414 
   4415 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
   4416 // from the pool and make sure that we recover okay.
   4417 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   4418   HttpRequestInfo request;
   4419   request.method = "GET";
   4420   request.url = GURL("https://www.google.com/");
   4421   request.load_flags = 0;
   4422 
   4423   MockWrite data_writes[] = {
   4424     MockWrite("GET / HTTP/1.1\r\n"
   4425               "Host: www.google.com\r\n"
   4426               "Connection: keep-alive\r\n\r\n"),
   4427     MockWrite("GET / HTTP/1.1\r\n"
   4428               "Host: www.google.com\r\n"
   4429               "Connection: keep-alive\r\n\r\n"),
   4430   };
   4431 
   4432   MockRead data_reads[] = {
   4433     MockRead("HTTP/1.1 200 OK\r\n"),
   4434     MockRead("Content-Length: 11\r\n\r\n"),
   4435     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   4436     MockRead("hello world"),
   4437     MockRead(ASYNC, 0, 0)   // EOF
   4438   };
   4439 
   4440   SSLSocketDataProvider ssl(ASYNC, OK);
   4441   SSLSocketDataProvider ssl2(ASYNC, OK);
   4442   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4443   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   4444 
   4445   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4446                                 data_writes, arraysize(data_writes));
   4447   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
   4448                                 data_writes, arraysize(data_writes));
   4449   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4450   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4451 
   4452   TestCompletionCallback callback;
   4453 
   4454   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4455   scoped_ptr<HttpTransaction> trans(
   4456       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4457 
   4458   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4459 
   4460   EXPECT_EQ(ERR_IO_PENDING, rv);
   4461   EXPECT_EQ(OK, callback.WaitForResult());
   4462 
   4463   const HttpResponseInfo* response = trans->GetResponseInfo();
   4464   ASSERT_TRUE(response != NULL);
   4465   ASSERT_TRUE(response->headers.get() != NULL);
   4466   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4467 
   4468   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4469 
   4470   std::string response_data;
   4471   rv = ReadTransaction(trans.get(), &response_data);
   4472   EXPECT_EQ(OK, rv);
   4473   EXPECT_EQ("hello world", response_data);
   4474 
   4475   // Empty the current queue.  This is necessary because idle sockets are
   4476   // added to the connection pool asynchronously with a PostTask.
   4477   base::MessageLoop::current()->RunUntilIdle();
   4478 
   4479   // We now check to make sure the socket was added back to the pool.
   4480   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4481 
   4482   // Now start the second transaction, which should reuse the previous socket.
   4483 
   4484   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4485 
   4486   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4487 
   4488   EXPECT_EQ(ERR_IO_PENDING, rv);
   4489   EXPECT_EQ(OK, callback.WaitForResult());
   4490 
   4491   response = trans->GetResponseInfo();
   4492   ASSERT_TRUE(response != NULL);
   4493   ASSERT_TRUE(response->headers.get() != NULL);
   4494   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4495 
   4496   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4497 
   4498   rv = ReadTransaction(trans.get(), &response_data);
   4499   EXPECT_EQ(OK, rv);
   4500   EXPECT_EQ("hello world", response_data);
   4501 
   4502   // Empty the current queue.  This is necessary because idle sockets are
   4503   // added to the connection pool asynchronously with a PostTask.
   4504   base::MessageLoop::current()->RunUntilIdle();
   4505 
   4506   // We now check to make sure the socket was added back to the pool.
   4507   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4508 }
   4509 
   4510 // Make sure that we recycle a socket after a zero-length response.
   4511 // http://crbug.com/9880
   4512 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   4513   HttpRequestInfo request;
   4514   request.method = "GET";
   4515   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   4516                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   4517                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   4518                      "rt=prt.2642,ol.2649,xjs.2951");
   4519   request.load_flags = 0;
   4520 
   4521   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4522 
   4523   scoped_ptr<HttpTransaction> trans(
   4524       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4525 
   4526   MockRead data_reads[] = {
   4527     MockRead("HTTP/1.1 204 No Content\r\n"
   4528              "Content-Length: 0\r\n"
   4529              "Content-Type: text/html\r\n\r\n"),
   4530     MockRead("junk"),  // Should not be read!!
   4531     MockRead(SYNCHRONOUS, OK),
   4532   };
   4533 
   4534   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4535   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4536 
   4537   TestCompletionCallback callback;
   4538 
   4539   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4540   EXPECT_EQ(ERR_IO_PENDING, rv);
   4541 
   4542   rv = callback.WaitForResult();
   4543   EXPECT_EQ(OK, rv);
   4544 
   4545   const HttpResponseInfo* response = trans->GetResponseInfo();
   4546   ASSERT_TRUE(response != NULL);
   4547 
   4548   EXPECT_TRUE(response->headers.get() != NULL);
   4549   std::string status_line = response->headers->GetStatusLine();
   4550   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   4551 
   4552   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4553 
   4554   std::string response_data;
   4555   rv = ReadTransaction(trans.get(), &response_data);
   4556   EXPECT_EQ(OK, rv);
   4557   EXPECT_EQ("", response_data);
   4558 
   4559   // Empty the current queue.  This is necessary because idle sockets are
   4560   // added to the connection pool asynchronously with a PostTask.
   4561   base::MessageLoop::current()->RunUntilIdle();
   4562 
   4563   // We now check to make sure the socket was added back to the pool.
   4564   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4565 }
   4566 
   4567 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   4568   ScopedVector<UploadElementReader> element_readers;
   4569   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   4570   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   4571 
   4572   HttpRequestInfo request[2];
   4573   // Transaction 1: a GET request that succeeds.  The socket is recycled
   4574   // after use.
   4575   request[0].method = "GET";
   4576   request[0].url = GURL("http://www.google.com/");
   4577   request[0].load_flags = 0;
   4578   // Transaction 2: a POST request.  Reuses the socket kept alive from
   4579   // transaction 1.  The first attempts fails when writing the POST data.
   4580   // This causes the transaction to retry with a new socket.  The second
   4581   // attempt succeeds.
   4582   request[1].method = "POST";
   4583   request[1].url = GURL("http://www.google.com/login.cgi");
   4584   request[1].upload_data_stream = &upload_data_stream;
   4585   request[1].load_flags = 0;
   4586 
   4587   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4588 
   4589   // The first socket is used for transaction 1 and the first attempt of
   4590   // transaction 2.
   4591 
   4592   // The response of transaction 1.
   4593   MockRead data_reads1[] = {
   4594     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   4595     MockRead("hello world"),
   4596     MockRead(SYNCHRONOUS, OK),
   4597   };
   4598   // The mock write results of transaction 1 and the first attempt of
   4599   // transaction 2.
   4600   MockWrite data_writes1[] = {
   4601     MockWrite(SYNCHRONOUS, 64),  // GET
   4602     MockWrite(SYNCHRONOUS, 93),  // POST
   4603     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
   4604   };
   4605   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4606                                  data_writes1, arraysize(data_writes1));
   4607 
   4608   // The second socket is used for the second attempt of transaction 2.
   4609 
   4610   // The response of transaction 2.
   4611   MockRead data_reads2[] = {
   4612     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   4613     MockRead("welcome"),
   4614     MockRead(SYNCHRONOUS, OK),
   4615   };
   4616   // The mock write results of the second attempt of transaction 2.
   4617   MockWrite data_writes2[] = {
   4618     MockWrite(SYNCHRONOUS, 93),  // POST
   4619     MockWrite(SYNCHRONOUS, 3),  // POST data
   4620   };
   4621   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4622                                  data_writes2, arraysize(data_writes2));
   4623 
   4624   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4625   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4626 
   4627   const char* kExpectedResponseData[] = {
   4628     "hello world", "welcome"
   4629   };
   4630 
   4631   for (int i = 0; i < 2; ++i) {
   4632     scoped_ptr<HttpTransaction> trans(
   4633         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4634 
   4635     TestCompletionCallback callback;
   4636 
   4637     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
   4638     EXPECT_EQ(ERR_IO_PENDING, rv);
   4639 
   4640     rv = callback.WaitForResult();
   4641     EXPECT_EQ(OK, rv);
   4642 
   4643     const HttpResponseInfo* response = trans->GetResponseInfo();
   4644     ASSERT_TRUE(response != NULL);
   4645 
   4646     EXPECT_TRUE(response->headers.get() != NULL);
   4647     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4648 
   4649     std::string response_data;
   4650     rv = ReadTransaction(trans.get(), &response_data);
   4651     EXPECT_EQ(OK, rv);
   4652     EXPECT_EQ(kExpectedResponseData[i], response_data);
   4653   }
   4654 }
   4655 
   4656 // Test the request-challenge-retry sequence for basic auth when there is
   4657 // an identity in the URL. The request should be sent as normal, but when
   4658 // it fails the identity from the URL is used to answer the challenge.
   4659 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
   4660   HttpRequestInfo request;
   4661   request.method = "GET";
   4662   request.url = GURL("http://foo:b@r@www.google.com/");
   4663   request.load_flags = LOAD_NORMAL;
   4664 
   4665   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4666   scoped_ptr<HttpTransaction> trans(
   4667       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4668 
   4669   // The password contains an escaped character -- for this test to pass it
   4670   // will need to be unescaped by HttpNetworkTransaction.
   4671   EXPECT_EQ("b%40r", request.url.password());
   4672 
   4673   MockWrite data_writes1[] = {
   4674     MockWrite("GET / HTTP/1.1\r\n"
   4675               "Host: www.google.com\r\n"
   4676               "Connection: keep-alive\r\n\r\n"),
   4677   };
   4678 
   4679   MockRead data_reads1[] = {
   4680     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4681     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4682     MockRead("Content-Length: 10\r\n\r\n"),
   4683     MockRead(SYNCHRONOUS, ERR_FAILED),
   4684   };
   4685 
   4686   // After the challenge above, the transaction will be restarted using the
   4687   // identity from the url (foo, b@r) to answer the challenge.
   4688   MockWrite data_writes2[] = {
   4689     MockWrite("GET / HTTP/1.1\r\n"
   4690               "Host: www.google.com\r\n"
   4691               "Connection: keep-alive\r\n"
   4692               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   4693   };
   4694 
   4695   MockRead data_reads2[] = {
   4696     MockRead("HTTP/1.0 200 OK\r\n"),
   4697     MockRead("Content-Length: 100\r\n\r\n"),
   4698     MockRead(SYNCHRONOUS, OK),
   4699   };
   4700 
   4701   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4702                                  data_writes1, arraysize(data_writes1));
   4703   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4704                                  data_writes2, arraysize(data_writes2));
   4705   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4706   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4707 
   4708   TestCompletionCallback callback1;
   4709   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4710   EXPECT_EQ(ERR_IO_PENDING, rv);
   4711   rv = callback1.WaitForResult();
   4712   EXPECT_EQ(OK, rv);
   4713   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4714 
   4715   TestCompletionCallback callback2;
   4716   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   4717   EXPECT_EQ(ERR_IO_PENDING, rv);
   4718   rv = callback2.WaitForResult();
   4719   EXPECT_EQ(OK, rv);
   4720   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4721 
   4722   const HttpResponseInfo* response = trans->GetResponseInfo();
   4723   ASSERT_TRUE(response != NULL);
   4724 
   4725   // There is no challenge info, since the identity in URL worked.
   4726   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4727 
   4728   EXPECT_EQ(100, response->headers->GetContentLength());
   4729 
   4730   // Empty the current queue.
   4731   base::MessageLoop::current()->RunUntilIdle();
   4732 }
   4733 
   4734 // Test the request-challenge-retry sequence for basic auth when there is an
   4735 // incorrect identity in the URL. The identity from the URL should be used only
   4736 // once.
   4737 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   4738   HttpRequestInfo request;
   4739   request.method = "GET";
   4740   // Note: the URL has a username:password in it.  The password "baz" is
   4741   // wrong (should be "bar").
   4742   request.url = GURL("http://foo:baz@www.google.com/");
   4743 
   4744   request.load_flags = LOAD_NORMAL;
   4745 
   4746   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4747   scoped_ptr<HttpTransaction> trans(
   4748       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4749 
   4750   MockWrite data_writes1[] = {
   4751     MockWrite("GET / HTTP/1.1\r\n"
   4752               "Host: www.google.com\r\n"
   4753               "Connection: keep-alive\r\n\r\n"),
   4754   };
   4755 
   4756   MockRead data_reads1[] = {
   4757     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4758     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4759     MockRead("Content-Length: 10\r\n\r\n"),
   4760     MockRead(SYNCHRONOUS, ERR_FAILED),
   4761   };
   4762 
   4763   // After the challenge above, the transaction will be restarted using the
   4764   // identity from the url (foo, baz) to answer the challenge.
   4765   MockWrite data_writes2[] = {
   4766     MockWrite("GET / HTTP/1.1\r\n"
   4767               "Host: www.google.com\r\n"
   4768               "Connection: keep-alive\r\n"
   4769               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   4770   };
   4771 
   4772   MockRead data_reads2[] = {
   4773     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4774     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4775     MockRead("Content-Length: 10\r\n\r\n"),
   4776     MockRead(SYNCHRONOUS, ERR_FAILED),
   4777   };
   4778 
   4779   // After the challenge above, the transaction will be restarted using the
   4780   // identity supplied by the user (foo, bar) to answer the challenge.
   4781   MockWrite data_writes3[] = {
   4782     MockWrite("GET / HTTP/1.1\r\n"
   4783               "Host: www.google.com\r\n"
   4784               "Connection: keep-alive\r\n"
   4785               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4786   };
   4787 
   4788   MockRead data_reads3[] = {
   4789     MockRead("HTTP/1.0 200 OK\r\n"),
   4790     MockRead("Content-Length: 100\r\n\r\n"),
   4791     MockRead(SYNCHRONOUS, OK),
   4792   };
   4793 
   4794   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4795                                  data_writes1, arraysize(data_writes1));
   4796   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4797                                  data_writes2, arraysize(data_writes2));
   4798   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4799                                  data_writes3, arraysize(data_writes3));
   4800   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4801   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4802   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4803 
   4804   TestCompletionCallback callback1;
   4805 
   4806   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4807   EXPECT_EQ(ERR_IO_PENDING, rv);
   4808 
   4809   rv = callback1.WaitForResult();
   4810   EXPECT_EQ(OK, rv);
   4811 
   4812   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4813   TestCompletionCallback callback2;
   4814   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   4815   EXPECT_EQ(ERR_IO_PENDING, rv);
   4816   rv = callback2.WaitForResult();
   4817   EXPECT_EQ(OK, rv);
   4818   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4819 
   4820   const HttpResponseInfo* response = trans->GetResponseInfo();
   4821   ASSERT_TRUE(response != NULL);
   4822   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4823 
   4824   TestCompletionCallback callback3;
   4825   rv = trans->RestartWithAuth(
   4826       AuthCredentials(kFoo, kBar), callback3.callback());
   4827   EXPECT_EQ(ERR_IO_PENDING, rv);
   4828   rv = callback3.WaitForResult();
   4829   EXPECT_EQ(OK, rv);
   4830   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4831 
   4832   response = trans->GetResponseInfo();
   4833   ASSERT_TRUE(response != NULL);
   4834 
   4835   // There is no challenge info, since the identity worked.
   4836   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4837 
   4838   EXPECT_EQ(100, response->headers->GetContentLength());
   4839 
   4840   // Empty the current queue.
   4841   base::MessageLoop::current()->RunUntilIdle();
   4842 }
   4843 
   4844 
   4845 // Test the request-challenge-retry sequence for basic auth when there is a
   4846 // correct identity in the URL, but its use is being suppressed. The identity
   4847 // from the URL should never be used.
   4848 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
   4849   HttpRequestInfo request;
   4850   request.method = "GET";
   4851   request.url = GURL("http://foo:bar@www.google.com/");
   4852   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   4853 
   4854   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4855   scoped_ptr<HttpTransaction> trans(
   4856       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4857 
   4858   MockWrite data_writes1[] = {
   4859     MockWrite("GET / HTTP/1.1\r\n"
   4860               "Host: www.google.com\r\n"
   4861               "Connection: keep-alive\r\n\r\n"),
   4862   };
   4863 
   4864   MockRead data_reads1[] = {
   4865     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4866     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4867     MockRead("Content-Length: 10\r\n\r\n"),
   4868     MockRead(SYNCHRONOUS, ERR_FAILED),
   4869   };
   4870 
   4871   // After the challenge above, the transaction will be restarted using the
   4872   // identity supplied by the user, not the one in the URL, to answer the
   4873   // challenge.
   4874   MockWrite data_writes3[] = {
   4875     MockWrite("GET / HTTP/1.1\r\n"
   4876               "Host: www.google.com\r\n"
   4877               "Connection: keep-alive\r\n"
   4878               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4879   };
   4880 
   4881   MockRead data_reads3[] = {
   4882     MockRead("HTTP/1.0 200 OK\r\n"),
   4883     MockRead("Content-Length: 100\r\n\r\n"),
   4884     MockRead(SYNCHRONOUS, OK),
   4885   };
   4886 
   4887   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4888                                  data_writes1, arraysize(data_writes1));
   4889   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4890                                  data_writes3, arraysize(data_writes3));
   4891   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4892   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4893 
   4894   TestCompletionCallback callback1;
   4895   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4896   EXPECT_EQ(ERR_IO_PENDING, rv);
   4897   rv = callback1.WaitForResult();
   4898   EXPECT_EQ(OK, rv);
   4899   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4900 
   4901   const HttpResponseInfo* response = trans->GetResponseInfo();
   4902   ASSERT_TRUE(response != NULL);
   4903   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4904 
   4905   TestCompletionCallback callback3;
   4906   rv = trans->RestartWithAuth(
   4907       AuthCredentials(kFoo, kBar), callback3.callback());
   4908   EXPECT_EQ(ERR_IO_PENDING, rv);
   4909   rv = callback3.WaitForResult();
   4910   EXPECT_EQ(OK, rv);
   4911   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4912 
   4913   response = trans->GetResponseInfo();
   4914   ASSERT_TRUE(response != NULL);
   4915 
   4916   // There is no challenge info, since the identity worked.
   4917   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4918   EXPECT_EQ(100, response->headers->GetContentLength());
   4919 
   4920   // Empty the current queue.
   4921   base::MessageLoop::current()->RunUntilIdle();
   4922 }
   4923 
   4924 // Test that previously tried username/passwords for a realm get re-used.
   4925 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   4926   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4927 
   4928   // Transaction 1: authenticate (foo, bar) on MyRealm1
   4929   {
   4930     HttpRequestInfo request;
   4931     request.method = "GET";
   4932     request.url = GURL("http://www.google.com/x/y/z");
   4933     request.load_flags = 0;
   4934 
   4935     scoped_ptr<HttpTransaction> trans(
   4936         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4937 
   4938     MockWrite data_writes1[] = {
   4939       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4940                 "Host: www.google.com\r\n"
   4941                 "Connection: keep-alive\r\n\r\n"),
   4942     };
   4943 
   4944     MockRead data_reads1[] = {
   4945       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4946       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4947       MockRead("Content-Length: 10000\r\n\r\n"),
   4948       MockRead(SYNCHRONOUS, ERR_FAILED),
   4949     };
   4950 
   4951     // Resend with authorization (username=foo, password=bar)
   4952     MockWrite data_writes2[] = {
   4953       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4954                 "Host: www.google.com\r\n"
   4955                 "Connection: keep-alive\r\n"
   4956                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4957     };
   4958 
   4959     // Sever accepts the authorization.
   4960     MockRead data_reads2[] = {
   4961       MockRead("HTTP/1.0 200 OK\r\n"),
   4962       MockRead("Content-Length: 100\r\n\r\n"),
   4963       MockRead(SYNCHRONOUS, OK),
   4964     };
   4965 
   4966     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4967                                    data_writes1, arraysize(data_writes1));
   4968     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4969                                    data_writes2, arraysize(data_writes2));
   4970     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4971     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4972 
   4973     TestCompletionCallback callback1;
   4974 
   4975     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4976     EXPECT_EQ(ERR_IO_PENDING, rv);
   4977 
   4978     rv = callback1.WaitForResult();
   4979     EXPECT_EQ(OK, rv);
   4980 
   4981     const HttpResponseInfo* response = trans->GetResponseInfo();
   4982     ASSERT_TRUE(response != NULL);
   4983     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4984 
   4985     TestCompletionCallback callback2;
   4986 
   4987     rv = trans->RestartWithAuth(
   4988         AuthCredentials(kFoo, kBar), callback2.callback());
   4989     EXPECT_EQ(ERR_IO_PENDING, rv);
   4990 
   4991     rv = callback2.WaitForResult();
   4992     EXPECT_EQ(OK, rv);
   4993 
   4994     response = trans->GetResponseInfo();
   4995     ASSERT_TRUE(response != NULL);
   4996     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4997     EXPECT_EQ(100, response->headers->GetContentLength());
   4998   }
   4999 
   5000   // ------------------------------------------------------------------------
   5001 
   5002   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   5003   {
   5004     HttpRequestInfo request;
   5005     request.method = "GET";
   5006     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5007     // protection space as MyRealm1.
   5008     request.url = GURL("http://www.google.com/x/y/a/b");
   5009     request.load_flags = 0;
   5010 
   5011     scoped_ptr<HttpTransaction> trans(
   5012         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5013 
   5014     MockWrite data_writes1[] = {
   5015       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5016                 "Host: www.google.com\r\n"
   5017                 "Connection: keep-alive\r\n"
   5018                 // Send preemptive authorization for MyRealm1
   5019                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5020     };
   5021 
   5022     // The server didn't like the preemptive authorization, and
   5023     // challenges us for a different realm (MyRealm2).
   5024     MockRead data_reads1[] = {
   5025       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5026       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   5027       MockRead("Content-Length: 10000\r\n\r\n"),
   5028       MockRead(SYNCHRONOUS, ERR_FAILED),
   5029     };
   5030 
   5031     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   5032     MockWrite data_writes2[] = {
   5033       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5034                 "Host: www.google.com\r\n"
   5035                 "Connection: keep-alive\r\n"
   5036                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   5037     };
   5038 
   5039     // Sever accepts the authorization.
   5040     MockRead data_reads2[] = {
   5041       MockRead("HTTP/1.0 200 OK\r\n"),
   5042       MockRead("Content-Length: 100\r\n\r\n"),
   5043       MockRead(SYNCHRONOUS, OK),
   5044     };
   5045 
   5046     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5047                                    data_writes1, arraysize(data_writes1));
   5048     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5049                                    data_writes2, arraysize(data_writes2));
   5050     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5051     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5052 
   5053     TestCompletionCallback callback1;
   5054 
   5055     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5056     EXPECT_EQ(ERR_IO_PENDING, rv);
   5057 
   5058     rv = callback1.WaitForResult();
   5059     EXPECT_EQ(OK, rv);
   5060 
   5061     const HttpResponseInfo* response = trans->GetResponseInfo();
   5062     ASSERT_TRUE(response != NULL);
   5063     ASSERT_TRUE(response->auth_challenge.get());
   5064     EXPECT_FALSE(response->auth_challenge->is_proxy);
   5065     EXPECT_EQ("www.google.com:80",
   5066               response->auth_challenge->challenger.ToString());
   5067     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
   5068     EXPECT_EQ("basic", response->auth_challenge->scheme);
   5069 
   5070     TestCompletionCallback callback2;
   5071 
   5072     rv = trans->RestartWithAuth(
   5073         AuthCredentials(kFoo2, kBar2), callback2.callback());
   5074     EXPECT_EQ(ERR_IO_PENDING, rv);
   5075 
   5076     rv = callback2.WaitForResult();
   5077     EXPECT_EQ(OK, rv);
   5078 
   5079     response = trans->GetResponseInfo();
   5080     ASSERT_TRUE(response != NULL);
   5081     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5082     EXPECT_EQ(100, response->headers->GetContentLength());
   5083   }
   5084 
   5085   // ------------------------------------------------------------------------
   5086 
   5087   // Transaction 3: Resend a request in MyRealm's protection space --
   5088   // succeed with preemptive authorization.
   5089   {
   5090     HttpRequestInfo request;
   5091     request.method = "GET";
   5092     request.url = GURL("http://www.google.com/x/y/z2");
   5093     request.load_flags = 0;
   5094 
   5095     scoped_ptr<HttpTransaction> trans(
   5096         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5097 
   5098     MockWrite data_writes1[] = {
   5099       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   5100                 "Host: www.google.com\r\n"
   5101                 "Connection: keep-alive\r\n"
   5102                 // The authorization for MyRealm1 gets sent preemptively
   5103                 // (since the url is in the same protection space)
   5104                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5105     };
   5106 
   5107     // Sever accepts the preemptive authorization
   5108     MockRead data_reads1[] = {
   5109       MockRead("HTTP/1.0 200 OK\r\n"),
   5110       MockRead("Content-Length: 100\r\n\r\n"),
   5111       MockRead(SYNCHRONOUS, OK),
   5112     };
   5113 
   5114     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5115                                    data_writes1, arraysize(data_writes1));
   5116     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5117 
   5118     TestCompletionCallback callback1;
   5119 
   5120     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5121     EXPECT_EQ(ERR_IO_PENDING, rv);
   5122 
   5123     rv = callback1.WaitForResult();
   5124     EXPECT_EQ(OK, rv);
   5125 
   5126     const HttpResponseInfo* response = trans->GetResponseInfo();
   5127     ASSERT_TRUE(response != NULL);
   5128 
   5129     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5130     EXPECT_EQ(100, response->headers->GetContentLength());
   5131   }
   5132 
   5133   // ------------------------------------------------------------------------
   5134 
   5135   // Transaction 4: request another URL in MyRealm (however the
   5136   // url is not known to belong to the protection space, so no pre-auth).
   5137   {
   5138     HttpRequestInfo request;
   5139     request.method = "GET";
   5140     request.url = GURL("http://www.google.com/x/1");
   5141     request.load_flags = 0;
   5142 
   5143     scoped_ptr<HttpTransaction> trans(
   5144         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5145 
   5146     MockWrite data_writes1[] = {
   5147       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5148                 "Host: www.google.com\r\n"
   5149                 "Connection: keep-alive\r\n\r\n"),
   5150     };
   5151 
   5152     MockRead data_reads1[] = {
   5153       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5154       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5155       MockRead("Content-Length: 10000\r\n\r\n"),
   5156       MockRead(SYNCHRONOUS, ERR_FAILED),
   5157     };
   5158 
   5159     // Resend with authorization from MyRealm's cache.
   5160     MockWrite data_writes2[] = {
   5161       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5162                 "Host: www.google.com\r\n"
   5163                 "Connection: keep-alive\r\n"
   5164                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5165     };
   5166 
   5167     // Sever accepts the authorization.
   5168     MockRead data_reads2[] = {
   5169       MockRead("HTTP/1.0 200 OK\r\n"),
   5170       MockRead("Content-Length: 100\r\n\r\n"),
   5171       MockRead(SYNCHRONOUS, OK),
   5172     };
   5173 
   5174     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5175                                    data_writes1, arraysize(data_writes1));
   5176     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5177                                    data_writes2, arraysize(data_writes2));
   5178     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5179     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5180 
   5181     TestCompletionCallback callback1;
   5182 
   5183     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5184     EXPECT_EQ(ERR_IO_PENDING, rv);
   5185 
   5186     rv = callback1.WaitForResult();
   5187     EXPECT_EQ(OK, rv);
   5188 
   5189     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5190     TestCompletionCallback callback2;
   5191     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5192     EXPECT_EQ(ERR_IO_PENDING, rv);
   5193     rv = callback2.WaitForResult();
   5194     EXPECT_EQ(OK, rv);
   5195     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5196 
   5197     const HttpResponseInfo* response = trans->GetResponseInfo();
   5198     ASSERT_TRUE(response != NULL);
   5199     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5200     EXPECT_EQ(100, response->headers->GetContentLength());
   5201   }
   5202 
   5203   // ------------------------------------------------------------------------
   5204 
   5205   // Transaction 5: request a URL in MyRealm, but the server rejects the
   5206   // cached identity. Should invalidate and re-prompt.
   5207   {
   5208     HttpRequestInfo request;
   5209     request.method = "GET";
   5210     request.url = GURL("http://www.google.com/p/q/t");
   5211     request.load_flags = 0;
   5212 
   5213     scoped_ptr<HttpTransaction> trans(
   5214         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5215 
   5216     MockWrite data_writes1[] = {
   5217       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5218                 "Host: www.google.com\r\n"
   5219                 "Connection: keep-alive\r\n\r\n"),
   5220     };
   5221 
   5222     MockRead data_reads1[] = {
   5223       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5224       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5225       MockRead("Content-Length: 10000\r\n\r\n"),
   5226       MockRead(SYNCHRONOUS, ERR_FAILED),
   5227     };
   5228 
   5229     // Resend with authorization from cache for MyRealm.
   5230     MockWrite data_writes2[] = {
   5231       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5232                 "Host: www.google.com\r\n"
   5233                 "Connection: keep-alive\r\n"
   5234                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5235     };
   5236 
   5237     // Sever rejects the authorization.
   5238     MockRead data_reads2[] = {
   5239       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5240       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5241       MockRead("Content-Length: 10000\r\n\r\n"),
   5242       MockRead(SYNCHRONOUS, ERR_FAILED),
   5243     };
   5244 
   5245     // At this point we should prompt for new credentials for MyRealm.
   5246     // Restart with username=foo3, password=foo4.
   5247     MockWrite data_writes3[] = {
   5248       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5249                 "Host: www.google.com\r\n"
   5250                 "Connection: keep-alive\r\n"
   5251                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   5252     };
   5253 
   5254     // Sever accepts the authorization.
   5255     MockRead data_reads3[] = {
   5256       MockRead("HTTP/1.0 200 OK\r\n"),
   5257       MockRead("Content-Length: 100\r\n\r\n"),
   5258       MockRead(SYNCHRONOUS, OK),
   5259     };
   5260 
   5261     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5262                                    data_writes1, arraysize(data_writes1));
   5263     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5264                                    data_writes2, arraysize(data_writes2));
   5265     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5266                                    data_writes3, arraysize(data_writes3));
   5267     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5268     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5269     session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5270 
   5271     TestCompletionCallback callback1;
   5272 
   5273     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5274     EXPECT_EQ(ERR_IO_PENDING, rv);
   5275 
   5276     rv = callback1.WaitForResult();
   5277     EXPECT_EQ(OK, rv);
   5278 
   5279     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5280     TestCompletionCallback callback2;
   5281     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5282     EXPECT_EQ(ERR_IO_PENDING, rv);
   5283     rv = callback2.WaitForResult();
   5284     EXPECT_EQ(OK, rv);
   5285     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5286 
   5287     const HttpResponseInfo* response = trans->GetResponseInfo();
   5288     ASSERT_TRUE(response != NULL);
   5289     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5290 
   5291     TestCompletionCallback callback3;
   5292 
   5293     rv = trans->RestartWithAuth(
   5294         AuthCredentials(kFoo3, kBar3), callback3.callback());
   5295     EXPECT_EQ(ERR_IO_PENDING, rv);
   5296 
   5297     rv = callback3.WaitForResult();
   5298     EXPECT_EQ(OK, rv);
   5299 
   5300     response = trans->GetResponseInfo();
   5301     ASSERT_TRUE(response != NULL);
   5302     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5303     EXPECT_EQ(100, response->headers->GetContentLength());
   5304   }
   5305 }
   5306 
   5307 // Tests that nonce count increments when multiple auth attempts
   5308 // are started with the same nonce.
   5309 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
   5310   HttpAuthHandlerDigest::Factory* digest_factory =
   5311       new HttpAuthHandlerDigest::Factory();
   5312   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
   5313       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
   5314   digest_factory->set_nonce_generator(nonce_generator);
   5315   session_deps_.http_auth_handler_factory.reset(digest_factory);
   5316   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5317 
   5318   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5319   {
   5320     HttpRequestInfo request;
   5321     request.method = "GET";
   5322     request.url = GURL("http://www.google.com/x/y/z");
   5323     request.load_flags = 0;
   5324 
   5325     scoped_ptr<HttpTransaction> trans(
   5326         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5327 
   5328     MockWrite data_writes1[] = {
   5329       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5330                 "Host: www.google.com\r\n"
   5331                 "Connection: keep-alive\r\n\r\n"),
   5332     };
   5333 
   5334     MockRead data_reads1[] = {
   5335       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5336       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
   5337                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
   5338       MockRead(SYNCHRONOUS, OK),
   5339     };
   5340 
   5341     // Resend with authorization (username=foo, password=bar)
   5342     MockWrite data_writes2[] = {
   5343       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5344                 "Host: www.google.com\r\n"
   5345                 "Connection: keep-alive\r\n"
   5346                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5347                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
   5348                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
   5349                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5350     };
   5351 
   5352     // Sever accepts the authorization.
   5353     MockRead data_reads2[] = {
   5354       MockRead("HTTP/1.0 200 OK\r\n"),
   5355       MockRead(SYNCHRONOUS, OK),
   5356     };
   5357 
   5358     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5359                                    data_writes1, arraysize(data_writes1));
   5360     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5361                                    data_writes2, arraysize(data_writes2));
   5362     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5363     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5364 
   5365     TestCompletionCallback callback1;
   5366 
   5367     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5368     EXPECT_EQ(ERR_IO_PENDING, rv);
   5369 
   5370     rv = callback1.WaitForResult();
   5371     EXPECT_EQ(OK, rv);
   5372 
   5373     const HttpResponseInfo* response = trans->GetResponseInfo();
   5374     ASSERT_TRUE(response != NULL);
   5375     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
   5376 
   5377     TestCompletionCallback callback2;
   5378 
   5379     rv = trans->RestartWithAuth(
   5380         AuthCredentials(kFoo, kBar), callback2.callback());
   5381     EXPECT_EQ(ERR_IO_PENDING, rv);
   5382 
   5383     rv = callback2.WaitForResult();
   5384     EXPECT_EQ(OK, rv);
   5385 
   5386     response = trans->GetResponseInfo();
   5387     ASSERT_TRUE(response != NULL);
   5388     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5389   }
   5390 
   5391   // ------------------------------------------------------------------------
   5392 
   5393   // Transaction 2: Request another resource in digestive's protection space.
   5394   // This will preemptively add an Authorization header which should have an
   5395   // "nc" value of 2 (as compared to 1 in the first use.
   5396   {
   5397     HttpRequestInfo request;
   5398     request.method = "GET";
   5399     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5400     // protection space as digest.
   5401     request.url = GURL("http://www.google.com/x/y/a/b");
   5402     request.load_flags = 0;
   5403 
   5404     scoped_ptr<HttpTransaction> trans(
   5405         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5406 
   5407     MockWrite data_writes1[] = {
   5408       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5409                 "Host: www.google.com\r\n"
   5410                 "Connection: keep-alive\r\n"
   5411                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5412                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
   5413                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
   5414                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5415     };
   5416 
   5417     // Sever accepts the authorization.
   5418     MockRead data_reads1[] = {
   5419       MockRead("HTTP/1.0 200 OK\r\n"),
   5420       MockRead("Content-Length: 100\r\n\r\n"),
   5421       MockRead(SYNCHRONOUS, OK),
   5422     };
   5423 
   5424     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5425                                    data_writes1, arraysize(data_writes1));
   5426     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5427 
   5428     TestCompletionCallback callback1;
   5429 
   5430     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5431     EXPECT_EQ(ERR_IO_PENDING, rv);
   5432 
   5433     rv = callback1.WaitForResult();
   5434     EXPECT_EQ(OK, rv);
   5435 
   5436     const HttpResponseInfo* response = trans->GetResponseInfo();
   5437     ASSERT_TRUE(response != NULL);
   5438     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5439   }
   5440 }
   5441 
   5442 // Test the ResetStateForRestart() private method.
   5443 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
   5444   // Create a transaction (the dependencies aren't important).
   5445   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5446   scoped_ptr<HttpNetworkTransaction> trans(
   5447       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5448 
   5449   // Setup some state (which we expect ResetStateForRestart() will clear).
   5450   trans->read_buf_ = new IOBuffer(15);
   5451   trans->read_buf_len_ = 15;
   5452   trans->request_headers_.SetHeader("Authorization", "NTLM");
   5453 
   5454   // Setup state in response_
   5455   HttpResponseInfo* response = &trans->response_;
   5456   response->auth_challenge = new AuthChallengeInfo();
   5457   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
   5458   response->response_time = base::Time::Now();
   5459   response->was_cached = true;  // (Wouldn't ever actually be true...)
   5460 
   5461   { // Setup state for response_.vary_data
   5462     HttpRequestInfo request;
   5463     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   5464     std::replace(temp.begin(), temp.end(), '\n', '\0');
   5465     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
   5466     request.extra_headers.SetHeader("Foo", "1");
   5467     request.extra_headers.SetHeader("bar", "23");
   5468     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
   5469   }
   5470 
   5471   // Cause the above state to be reset.
   5472   trans->ResetStateForRestart();
   5473 
   5474   // Verify that the state that needed to be reset, has been reset.
   5475   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   5476   EXPECT_EQ(0, trans->read_buf_len_);
   5477   EXPECT_TRUE(trans->request_headers_.IsEmpty());
   5478   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5479   EXPECT_TRUE(response->headers.get() == NULL);
   5480   EXPECT_FALSE(response->was_cached);
   5481   EXPECT_EQ(0U, response->ssl_info.cert_status);
   5482   EXPECT_FALSE(response->vary_data.is_valid());
   5483 }
   5484 
   5485 // Test HTTPS connections to a site with a bad certificate
   5486 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   5487   HttpRequestInfo request;
   5488   request.method = "GET";
   5489   request.url = GURL("https://www.google.com/");
   5490   request.load_flags = 0;
   5491 
   5492   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5493   scoped_ptr<HttpTransaction> trans(
   5494       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5495 
   5496   MockWrite data_writes[] = {
   5497     MockWrite("GET / HTTP/1.1\r\n"
   5498               "Host: www.google.com\r\n"
   5499               "Connection: keep-alive\r\n\r\n"),
   5500   };
   5501 
   5502   MockRead data_reads[] = {
   5503     MockRead("HTTP/1.0 200 OK\r\n"),
   5504     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5505     MockRead("Content-Length: 100\r\n\r\n"),
   5506     MockRead(SYNCHRONOUS, OK),
   5507   };
   5508 
   5509   StaticSocketDataProvider ssl_bad_certificate;
   5510   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5511                                 data_writes, arraysize(data_writes));
   5512   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5513   SSLSocketDataProvider ssl(ASYNC, OK);
   5514 
   5515   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5516   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5517   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5518   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5519 
   5520   TestCompletionCallback callback;
   5521 
   5522   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5523   EXPECT_EQ(ERR_IO_PENDING, rv);
   5524 
   5525   rv = callback.WaitForResult();
   5526   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5527 
   5528   rv = trans->RestartIgnoringLastError(callback.callback());
   5529   EXPECT_EQ(ERR_IO_PENDING, rv);
   5530 
   5531   rv = callback.WaitForResult();
   5532   EXPECT_EQ(OK, rv);
   5533 
   5534   const HttpResponseInfo* response = trans->GetResponseInfo();
   5535 
   5536   ASSERT_TRUE(response != NULL);
   5537   EXPECT_EQ(100, response->headers->GetContentLength());
   5538 }
   5539 
   5540 // Test HTTPS connections to a site with a bad certificate, going through a
   5541 // proxy
   5542 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   5543   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   5544 
   5545   HttpRequestInfo request;
   5546   request.method = "GET";
   5547   request.url = GURL("https://www.google.com/");
   5548   request.load_flags = 0;
   5549 
   5550   MockWrite proxy_writes[] = {
   5551     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5552               "Host: www.google.com\r\n"
   5553               "Proxy-Connection: keep-alive\r\n\r\n"),
   5554   };
   5555 
   5556   MockRead proxy_reads[] = {
   5557     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5558     MockRead(SYNCHRONOUS, OK)
   5559   };
   5560 
   5561   MockWrite data_writes[] = {
   5562     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5563               "Host: www.google.com\r\n"
   5564               "Proxy-Connection: keep-alive\r\n\r\n"),
   5565     MockWrite("GET / HTTP/1.1\r\n"
   5566               "Host: www.google.com\r\n"
   5567               "Connection: keep-alive\r\n\r\n"),
   5568   };
   5569 
   5570   MockRead data_reads[] = {
   5571     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5572     MockRead("HTTP/1.0 200 OK\r\n"),
   5573     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5574     MockRead("Content-Length: 100\r\n\r\n"),
   5575     MockRead(SYNCHRONOUS, OK),
   5576   };
   5577 
   5578   StaticSocketDataProvider ssl_bad_certificate(
   5579       proxy_reads, arraysize(proxy_reads),
   5580       proxy_writes, arraysize(proxy_writes));
   5581   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5582                                 data_writes, arraysize(data_writes));
   5583   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5584   SSLSocketDataProvider ssl(ASYNC, OK);
   5585 
   5586   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5587   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5588   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5589   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5590 
   5591   TestCompletionCallback callback;
   5592 
   5593   for (int i = 0; i < 2; i++) {
   5594     session_deps_.socket_factory->ResetNextMockIndexes();
   5595 
   5596     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5597     scoped_ptr<HttpTransaction> trans(
   5598         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5599 
   5600     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5601     EXPECT_EQ(ERR_IO_PENDING, rv);
   5602 
   5603     rv = callback.WaitForResult();
   5604     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5605 
   5606     rv = trans->RestartIgnoringLastError(callback.callback());
   5607     EXPECT_EQ(ERR_IO_PENDING, rv);
   5608 
   5609     rv = callback.WaitForResult();
   5610     EXPECT_EQ(OK, rv);
   5611 
   5612     const HttpResponseInfo* response = trans->GetResponseInfo();
   5613 
   5614     ASSERT_TRUE(response != NULL);
   5615     EXPECT_EQ(100, response->headers->GetContentLength());
   5616   }
   5617 }
   5618 
   5619 
   5620 // Test HTTPS connections to a site, going through an HTTPS proxy
   5621 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
   5622   session_deps_.proxy_service.reset(
   5623       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   5624   CapturingNetLog net_log;
   5625   session_deps_.net_log = &net_log;
   5626 
   5627   HttpRequestInfo request;
   5628   request.method = "GET";
   5629   request.url = GURL("https://www.google.com/");
   5630   request.load_flags = 0;
   5631 
   5632   MockWrite data_writes[] = {
   5633     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5634               "Host: www.google.com\r\n"
   5635               "Proxy-Connection: keep-alive\r\n\r\n"),
   5636     MockWrite("GET / HTTP/1.1\r\n"
   5637               "Host: www.google.com\r\n"
   5638               "Connection: keep-alive\r\n\r\n"),
   5639   };
   5640 
   5641   MockRead data_reads[] = {
   5642     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5643     MockRead("HTTP/1.1 200 OK\r\n"),
   5644     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5645     MockRead("Content-Length: 100\r\n\r\n"),
   5646     MockRead(SYNCHRONOUS, OK),
   5647   };
   5648 
   5649   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5650                                 data_writes, arraysize(data_writes));
   5651   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5652   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
   5653 
   5654   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5655   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5656   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
   5657 
   5658   TestCompletionCallback callback;
   5659 
   5660   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5661   scoped_ptr<HttpTransaction> trans(
   5662       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5663 
   5664   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5665   EXPECT_EQ(ERR_IO_PENDING, rv);
   5666 
   5667   rv = callback.WaitForResult();
   5668   EXPECT_EQ(OK, rv);
   5669   const HttpResponseInfo* response = trans->GetResponseInfo();
   5670 
   5671   ASSERT_TRUE(response != NULL);
   5672 
   5673   EXPECT_TRUE(response->headers->IsKeepAlive());
   5674   EXPECT_EQ(200, response->headers->response_code());
   5675   EXPECT_EQ(100, response->headers->GetContentLength());
   5676   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   5677 
   5678   LoadTimingInfo load_timing_info;
   5679   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   5680   TestLoadTimingNotReusedWithPac(load_timing_info,
   5681                                  CONNECT_TIMING_HAS_SSL_TIMES);
   5682 }
   5683 
   5684 // Test an HTTPS Proxy's ability to redirect a CONNECT request
   5685 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
   5686   session_deps_.proxy_service.reset(
   5687       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   5688   CapturingNetLog net_log;
   5689   session_deps_.net_log = &net_log;
   5690 
   5691   HttpRequestInfo request;
   5692   request.method = "GET";
   5693   request.url = GURL("https://www.google.com/");
   5694   request.load_flags = 0;
   5695 
   5696   MockWrite data_writes[] = {
   5697     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5698               "Host: www.google.com\r\n"
   5699               "Proxy-Connection: keep-alive\r\n\r\n"),
   5700   };
   5701 
   5702   MockRead data_reads[] = {
   5703     MockRead("HTTP/1.1 302 Redirect\r\n"),
   5704     MockRead("Location: http://login.example.com/\r\n"),
   5705     MockRead("Content-Length: 0\r\n\r\n"),
   5706     MockRead(SYNCHRONOUS, OK),
   5707   };
   5708 
   5709   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5710                                 data_writes, arraysize(data_writes));
   5711   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5712 
   5713   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5714   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5715 
   5716   TestCompletionCallback callback;
   5717 
   5718   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5719   scoped_ptr<HttpTransaction> trans(
   5720       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5721 
   5722   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5723   EXPECT_EQ(ERR_IO_PENDING, rv);
   5724 
   5725   rv = callback.WaitForResult();
   5726   EXPECT_EQ(OK, rv);
   5727   const HttpResponseInfo* response = trans->GetResponseInfo();
   5728 
   5729   ASSERT_TRUE(response != NULL);
   5730 
   5731   EXPECT_EQ(302, response->headers->response_code());
   5732   std::string url;
   5733   EXPECT_TRUE(response->headers->IsRedirect(&url));
   5734   EXPECT_EQ("http://login.example.com/", url);
   5735 
   5736   // In the case of redirects from proxies, HttpNetworkTransaction returns
   5737   // timing for the proxy connection instead of the connection to the host,
   5738   // and no send / receive times.
   5739   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
   5740   LoadTimingInfo load_timing_info;
   5741   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   5742 
   5743   EXPECT_FALSE(load_timing_info.socket_reused);
   5744   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
   5745 
   5746   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
   5747   EXPECT_LE(load_timing_info.proxy_resolve_start,
   5748             load_timing_info.proxy_resolve_end);
   5749   EXPECT_LE(load_timing_info.proxy_resolve_end,
   5750             load_timing_info.connect_timing.connect_start);
   5751   ExpectConnectTimingHasTimes(
   5752       load_timing_info.connect_timing,
   5753       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
   5754 
   5755   EXPECT_TRUE(load_timing_info.send_start.is_null());
   5756   EXPECT_TRUE(load_timing_info.send_end.is_null());
   5757   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
   5758 }
   5759 
   5760 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
   5761 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
   5762   session_deps_.proxy_service.reset(
   5763       ProxyService::CreateFixed("https://proxy:70"));
   5764 
   5765   HttpRequestInfo request;
   5766   request.method = "GET";
   5767   request.url = GURL("https://www.google.com/");
   5768   request.load_flags = 0;
   5769 
   5770   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   5771                                                              LOWEST));
   5772   scoped_ptr<SpdyFrame> goaway(
   5773       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5774   MockWrite data_writes[] = {
   5775     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   5776     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
   5777   };
   5778 
   5779   static const char* const kExtraHeaders[] = {
   5780     "location",
   5781     "http://login.example.com/",
   5782   };
   5783   scoped_ptr<SpdyFrame> resp(
   5784       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
   5785                                  arraysize(kExtraHeaders)/2, 1));
   5786   MockRead data_reads[] = {
   5787     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   5788     MockRead(ASYNC, 0, 2),  // EOF
   5789   };
   5790 
   5791   DelayedSocketData data(
   5792       1,  // wait for one write to finish before reading.
   5793       data_reads, arraysize(data_reads),
   5794       data_writes, arraysize(data_writes));
   5795   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5796   proxy_ssl.SetNextProto(GetParam());
   5797 
   5798   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5799   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5800 
   5801   TestCompletionCallback callback;
   5802 
   5803   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5804   scoped_ptr<HttpTransaction> trans(
   5805       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5806 
   5807   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5808   EXPECT_EQ(ERR_IO_PENDING, rv);
   5809 
   5810   rv = callback.WaitForResult();
   5811   EXPECT_EQ(OK, rv);
   5812   const HttpResponseInfo* response = trans->GetResponseInfo();
   5813 
   5814   ASSERT_TRUE(response != NULL);
   5815 
   5816   EXPECT_EQ(302, response->headers->response_code());
   5817   std::string url;
   5818   EXPECT_TRUE(response->headers->IsRedirect(&url));
   5819   EXPECT_EQ("http://login.example.com/", url);
   5820 }
   5821 
   5822 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
   5823 TEST_P(HttpNetworkTransactionTest,
   5824        ErrorResponseToHttpsConnectViaHttpsProxy) {
   5825   session_deps_.proxy_service.reset(
   5826       ProxyService::CreateFixed("https://proxy:70"));
   5827 
   5828   HttpRequestInfo request;
   5829   request.method = "GET";
   5830   request.url = GURL("https://www.google.com/");
   5831   request.load_flags = 0;
   5832 
   5833   MockWrite data_writes[] = {
   5834     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5835               "Host: www.google.com\r\n"
   5836               "Proxy-Connection: keep-alive\r\n\r\n"),
   5837   };
   5838 
   5839   MockRead data_reads[] = {
   5840     MockRead("HTTP/1.1 404 Not Found\r\n"),
   5841     MockRead("Content-Length: 23\r\n\r\n"),
   5842     MockRead("The host does not exist"),
   5843     MockRead(SYNCHRONOUS, OK),
   5844   };
   5845 
   5846   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5847                                 data_writes, arraysize(data_writes));
   5848   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5849 
   5850   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5851   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5852 
   5853   TestCompletionCallback callback;
   5854 
   5855   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5856   scoped_ptr<HttpTransaction> trans(
   5857       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5858 
   5859   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5860   EXPECT_EQ(ERR_IO_PENDING, rv);
   5861 
   5862   rv = callback.WaitForResult();
   5863   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   5864 
   5865   // TODO(ttuttle): Anything else to check here?
   5866 }
   5867 
   5868 // Test that a SPDY proxy's response to a CONNECT request is filtered.
   5869 TEST_P(HttpNetworkTransactionTest,
   5870        ErrorResponseToHttpsConnectViaSpdyProxy) {
   5871   session_deps_.proxy_service.reset(
   5872      ProxyService::CreateFixed("https://proxy:70"));
   5873 
   5874   HttpRequestInfo request;
   5875   request.method = "GET";
   5876   request.url = GURL("https://www.google.com/");
   5877   request.load_flags = 0;
   5878 
   5879   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   5880                                                              LOWEST));
   5881   scoped_ptr<SpdyFrame> rst(
   5882       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5883   MockWrite data_writes[] = {
   5884     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   5885     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
   5886   };
   5887 
   5888   static const char* const kExtraHeaders[] = {
   5889     "location",
   5890     "http://login.example.com/",
   5891   };
   5892   scoped_ptr<SpdyFrame> resp(
   5893       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
   5894                                  arraysize(kExtraHeaders)/2, 1));
   5895   scoped_ptr<SpdyFrame> body(
   5896       spdy_util_.ConstructSpdyBodyFrame(
   5897           1, "The host does not exist", 23, true));
   5898   MockRead data_reads[] = {
   5899     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   5900     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
   5901     MockRead(ASYNC, 0, 4),  // EOF
   5902   };
   5903 
   5904   DelayedSocketData data(
   5905       1,  // wait for one write to finish before reading.
   5906       data_reads, arraysize(data_reads),
   5907       data_writes, arraysize(data_writes));
   5908   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   5909   proxy_ssl.SetNextProto(GetParam());
   5910 
   5911   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5912   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   5913 
   5914   TestCompletionCallback callback;
   5915 
   5916   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5917   scoped_ptr<HttpTransaction> trans(
   5918       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5919 
   5920   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5921   EXPECT_EQ(ERR_IO_PENDING, rv);
   5922 
   5923   rv = callback.WaitForResult();
   5924   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   5925 
   5926   // TODO(ttuttle): Anything else to check here?
   5927 }
   5928 
   5929 // Test the request-challenge-retry sequence for basic auth, through
   5930 // a SPDY proxy over a single SPDY session.
   5931 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
   5932   HttpRequestInfo request;
   5933   request.method = "GET";
   5934   request.url = GURL("https://www.google.com/");
   5935   // when the no authentication data flag is set.
   5936   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   5937 
   5938   // Configure against https proxy server "myproxy:70".
   5939   session_deps_.proxy_service.reset(
   5940       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   5941   CapturingBoundNetLog log;
   5942   session_deps_.net_log = log.bound().net_log();
   5943   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5944 
   5945   // Since we have proxy, should try to establish tunnel.
   5946   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   5947                                                             LOWEST));
   5948   scoped_ptr<SpdyFrame> rst(
   5949       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   5950 
   5951   // After calling trans->RestartWithAuth(), this is the request we should
   5952   // be issuing -- the final header line contains the credentials.
   5953   const char* const kAuthCredentials[] = {
   5954       "proxy-authorization", "Basic Zm9vOmJhcg==",
   5955   };
   5956   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
   5957       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
   5958   // fetch https://www.google.com/ via HTTP
   5959   const char get[] = "GET / HTTP/1.1\r\n"
   5960     "Host: www.google.com\r\n"
   5961     "Connection: keep-alive\r\n\r\n";
   5962   scoped_ptr<SpdyFrame> wrapped_get(
   5963       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
   5964 
   5965   MockWrite spdy_writes[] = {
   5966     CreateMockWrite(*req, 1, ASYNC),
   5967     CreateMockWrite(*rst, 4, ASYNC),
   5968     CreateMockWrite(*connect2, 5),
   5969     CreateMockWrite(*wrapped_get, 8),
   5970   };
   5971 
   5972   // The proxy responds to the connect with a 407, using a persistent
   5973   // connection.
   5974   const char* const kAuthChallenge[] = {
   5975     spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
   5976     spdy_util_.GetVersionKey(), "HTTP/1.1",
   5977     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
   5978   };
   5979 
   5980   scoped_ptr<SpdyFrame> conn_auth_resp(
   5981       spdy_util_.ConstructSpdyControlFrame(NULL,
   5982                                            0,
   5983                                            false,
   5984                                            1,
   5985                                            LOWEST,
   5986                                            SYN_REPLY,
   5987                                            CONTROL_FLAG_NONE,
   5988                                            kAuthChallenge,
   5989                                            arraysize(kAuthChallenge),
   5990                                            0));
   5991 
   5992   scoped_ptr<SpdyFrame> conn_resp(
   5993       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   5994   const char resp[] = "HTTP/1.1 200 OK\r\n"
   5995       "Content-Length: 5\r\n\r\n";
   5996 
   5997   scoped_ptr<SpdyFrame> wrapped_get_resp(
   5998       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
   5999   scoped_ptr<SpdyFrame> wrapped_body(
   6000       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
   6001   MockRead spdy_reads[] = {
   6002     CreateMockRead(*conn_auth_resp, 2, ASYNC),
   6003     CreateMockRead(*conn_resp, 6, ASYNC),
   6004     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
   6005     CreateMockRead(*wrapped_body, 10, ASYNC),
   6006     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
   6007   };
   6008 
   6009   OrderedSocketData spdy_data(
   6010       spdy_reads, arraysize(spdy_reads),
   6011       spdy_writes, arraysize(spdy_writes));
   6012   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6013   // Negotiate SPDY to the proxy
   6014   SSLSocketDataProvider proxy(ASYNC, OK);
   6015   proxy.SetNextProto(GetParam());
   6016   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6017   // Vanilla SSL to the server
   6018   SSLSocketDataProvider server(ASYNC, OK);
   6019   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
   6020 
   6021   TestCompletionCallback callback1;
   6022 
   6023   scoped_ptr<HttpTransaction> trans(
   6024       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6025 
   6026   int rv = trans->Start(&request, callback1.callback(), log.bound());
   6027   EXPECT_EQ(ERR_IO_PENDING, rv);
   6028 
   6029   rv = callback1.WaitForResult();
   6030   EXPECT_EQ(OK, rv);
   6031   net::CapturingNetLog::CapturedEntryList entries;
   6032   log.GetEntries(&entries);
   6033   size_t pos = ExpectLogContainsSomewhere(
   6034       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   6035       NetLog::PHASE_NONE);
   6036   ExpectLogContainsSomewhere(
   6037       entries, pos,
   6038       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   6039       NetLog::PHASE_NONE);
   6040 
   6041   const HttpResponseInfo* response = trans->GetResponseInfo();
   6042   ASSERT_TRUE(response != NULL);
   6043   ASSERT_FALSE(response->headers.get() == NULL);
   6044   EXPECT_EQ(407, response->headers->response_code());
   6045   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6046   EXPECT_TRUE(response->auth_challenge.get() != NULL);
   6047   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   6048 
   6049   TestCompletionCallback callback2;
   6050 
   6051   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
   6052                               callback2.callback());
   6053   EXPECT_EQ(ERR_IO_PENDING, rv);
   6054 
   6055   rv = callback2.WaitForResult();
   6056   EXPECT_EQ(OK, rv);
   6057 
   6058   response = trans->GetResponseInfo();
   6059   ASSERT_TRUE(response != NULL);
   6060 
   6061   EXPECT_TRUE(response->headers->IsKeepAlive());
   6062   EXPECT_EQ(200, response->headers->response_code());
   6063   EXPECT_EQ(5, response->headers->GetContentLength());
   6064   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6065 
   6066   // The password prompt info should not be set.
   6067   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6068 
   6069   LoadTimingInfo load_timing_info;
   6070   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6071   TestLoadTimingNotReusedWithPac(load_timing_info,
   6072                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6073 
   6074   trans.reset();
   6075   session->CloseAllConnections();
   6076 }
   6077 
   6078 // Test that an explicitly trusted SPDY proxy can push a resource from an
   6079 // origin that is different from that of its associated resource.
   6080 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
   6081   HttpRequestInfo request;
   6082   HttpRequestInfo push_request;
   6083 
   6084   request.method = "GET";
   6085   request.url = GURL("http://www.google.com/");
   6086   push_request.method = "GET";
   6087   push_request.url = GURL("http://www.another-origin.com/foo.dat");
   6088 
   6089   // Configure against https proxy server "myproxy:70".
   6090   session_deps_.proxy_service.reset(
   6091       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   6092   CapturingBoundNetLog log;
   6093   session_deps_.net_log = log.bound().net_log();
   6094 
   6095   // Enable cross-origin push.
   6096   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6097 
   6098   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6099 
   6100   scoped_ptr<SpdyFrame> stream1_syn(
   6101       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6102 
   6103   MockWrite spdy_writes[] = {
   6104     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6105   };
   6106 
   6107   scoped_ptr<SpdyFrame>
   6108       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6109 
   6110   scoped_ptr<SpdyFrame>
   6111       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6112 
   6113   scoped_ptr<SpdyFrame>
   6114       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6115                                     0,
   6116                                     2,
   6117                                     1,
   6118                                     "http://www.another-origin.com/foo.dat"));
   6119   const char kPushedData[] = "pushed";
   6120   scoped_ptr<SpdyFrame> stream2_body(
   6121       spdy_util_.ConstructSpdyBodyFrame(
   6122           2, kPushedData, strlen(kPushedData), true));
   6123 
   6124   MockRead spdy_reads[] = {
   6125     CreateMockRead(*stream1_reply, 2, ASYNC),
   6126     CreateMockRead(*stream2_syn, 3, ASYNC),
   6127     CreateMockRead(*stream1_body, 4, ASYNC),
   6128     CreateMockRead(*stream2_body, 5, ASYNC),
   6129     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6130   };
   6131 
   6132   OrderedSocketData spdy_data(
   6133       spdy_reads, arraysize(spdy_reads),
   6134       spdy_writes, arraysize(spdy_writes));
   6135   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6136   // Negotiate SPDY to the proxy
   6137   SSLSocketDataProvider proxy(ASYNC, OK);
   6138   proxy.SetNextProto(GetParam());
   6139   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6140 
   6141   scoped_ptr<HttpTransaction> trans(
   6142       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6143   TestCompletionCallback callback;
   6144   int rv = trans->Start(&request, callback.callback(), log.bound());
   6145   EXPECT_EQ(ERR_IO_PENDING, rv);
   6146 
   6147   rv = callback.WaitForResult();
   6148   EXPECT_EQ(OK, rv);
   6149   const HttpResponseInfo* response = trans->GetResponseInfo();
   6150 
   6151   scoped_ptr<HttpTransaction> push_trans(
   6152       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6153   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
   6154   EXPECT_EQ(ERR_IO_PENDING, rv);
   6155 
   6156   rv = callback.WaitForResult();
   6157   EXPECT_EQ(OK, rv);
   6158   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
   6159 
   6160   ASSERT_TRUE(response != NULL);
   6161   EXPECT_TRUE(response->headers->IsKeepAlive());
   6162 
   6163   EXPECT_EQ(200, response->headers->response_code());
   6164   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6165 
   6166   std::string response_data;
   6167   rv = ReadTransaction(trans.get(), &response_data);
   6168   EXPECT_EQ(OK, rv);
   6169   EXPECT_EQ("hello!", response_data);
   6170 
   6171   LoadTimingInfo load_timing_info;
   6172   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6173   TestLoadTimingNotReusedWithPac(load_timing_info,
   6174                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6175 
   6176   // Verify the pushed stream.
   6177   EXPECT_TRUE(push_response->headers.get() != NULL);
   6178   EXPECT_EQ(200, push_response->headers->response_code());
   6179 
   6180   rv = ReadTransaction(push_trans.get(), &response_data);
   6181   EXPECT_EQ(OK, rv);
   6182   EXPECT_EQ("pushed", response_data);
   6183 
   6184   LoadTimingInfo push_load_timing_info;
   6185   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
   6186   TestLoadTimingReusedWithPac(push_load_timing_info);
   6187   // The transactions should share a socket ID, despite being for different
   6188   // origins.
   6189   EXPECT_EQ(load_timing_info.socket_log_id,
   6190             push_load_timing_info.socket_log_id);
   6191 
   6192   trans.reset();
   6193   push_trans.reset();
   6194   session->CloseAllConnections();
   6195 }
   6196 
   6197 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
   6198 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
   6199   HttpRequestInfo request;
   6200 
   6201   request.method = "GET";
   6202   request.url = GURL("http://www.google.com/");
   6203 
   6204   // Configure against https proxy server "myproxy:70".
   6205   session_deps_.proxy_service.reset(
   6206       ProxyService::CreateFixed("https://myproxy:70"));
   6207   CapturingBoundNetLog log;
   6208   session_deps_.net_log = log.bound().net_log();
   6209 
   6210   // Enable cross-origin push.
   6211   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6212 
   6213   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6214 
   6215   scoped_ptr<SpdyFrame> stream1_syn(
   6216       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6217 
   6218   scoped_ptr<SpdyFrame> push_rst(
   6219       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   6220 
   6221   MockWrite spdy_writes[] = {
   6222     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6223     CreateMockWrite(*push_rst, 4),
   6224   };
   6225 
   6226   scoped_ptr<SpdyFrame>
   6227       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6228 
   6229   scoped_ptr<SpdyFrame>
   6230       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6231 
   6232   scoped_ptr<SpdyFrame>
   6233       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6234                                     0,
   6235                                     2,
   6236                                     1,
   6237                                     "https://www.another-origin.com/foo.dat"));
   6238 
   6239   MockRead spdy_reads[] = {
   6240     CreateMockRead(*stream1_reply, 2, ASYNC),
   6241     CreateMockRead(*stream2_syn, 3, ASYNC),
   6242     CreateMockRead(*stream1_body, 5, ASYNC),
   6243     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6244   };
   6245 
   6246   OrderedSocketData spdy_data(
   6247       spdy_reads, arraysize(spdy_reads),
   6248       spdy_writes, arraysize(spdy_writes));
   6249   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6250   // Negotiate SPDY to the proxy
   6251   SSLSocketDataProvider proxy(ASYNC, OK);
   6252   proxy.SetNextProto(GetParam());
   6253   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6254 
   6255   scoped_ptr<HttpTransaction> trans(
   6256       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6257   TestCompletionCallback callback;
   6258   int rv = trans->Start(&request, callback.callback(), log.bound());
   6259   EXPECT_EQ(ERR_IO_PENDING, rv);
   6260 
   6261   rv = callback.WaitForResult();
   6262   EXPECT_EQ(OK, rv);
   6263   const HttpResponseInfo* response = trans->GetResponseInfo();
   6264 
   6265   ASSERT_TRUE(response != NULL);
   6266   EXPECT_TRUE(response->headers->IsKeepAlive());
   6267 
   6268   EXPECT_EQ(200, response->headers->response_code());
   6269   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6270 
   6271   std::string response_data;
   6272   rv = ReadTransaction(trans.get(), &response_data);
   6273   EXPECT_EQ(OK, rv);
   6274   EXPECT_EQ("hello!", response_data);
   6275 
   6276   trans.reset();
   6277   session->CloseAllConnections();
   6278 }
   6279 
   6280 // Test HTTPS connections to a site with a bad certificate, going through an
   6281 // HTTPS proxy
   6282 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
   6283   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   6284       "https://proxy:70"));
   6285 
   6286   HttpRequestInfo request;
   6287   request.method = "GET";
   6288   request.url = GURL("https://www.google.com/");
   6289   request.load_flags = 0;
   6290 
   6291   // Attempt to fetch the URL from a server with a bad cert
   6292   MockWrite bad_cert_writes[] = {
   6293     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6294               "Host: www.google.com\r\n"
   6295               "Proxy-Connection: keep-alive\r\n\r\n"),
   6296   };
   6297 
   6298   MockRead bad_cert_reads[] = {
   6299     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6300     MockRead(SYNCHRONOUS, OK)
   6301   };
   6302 
   6303   // Attempt to fetch the URL with a good cert
   6304   MockWrite good_data_writes[] = {
   6305     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6306               "Host: www.google.com\r\n"
   6307               "Proxy-Connection: keep-alive\r\n\r\n"),
   6308     MockWrite("GET / HTTP/1.1\r\n"
   6309               "Host: www.google.com\r\n"
   6310               "Connection: keep-alive\r\n\r\n"),
   6311   };
   6312 
   6313   MockRead good_cert_reads[] = {
   6314     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6315     MockRead("HTTP/1.0 200 OK\r\n"),
   6316     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6317     MockRead("Content-Length: 100\r\n\r\n"),
   6318     MockRead(SYNCHRONOUS, OK),
   6319   };
   6320 
   6321   StaticSocketDataProvider ssl_bad_certificate(
   6322       bad_cert_reads, arraysize(bad_cert_reads),
   6323       bad_cert_writes, arraysize(bad_cert_writes));
   6324   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
   6325                                 good_data_writes, arraysize(good_data_writes));
   6326   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6327   SSLSocketDataProvider ssl(ASYNC, OK);
   6328 
   6329   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
   6330   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6331   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6332   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6333 
   6334   // SSL to the proxy, then CONNECT request, then valid SSL certificate
   6335   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6336   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6337   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6338 
   6339   TestCompletionCallback callback;
   6340 
   6341   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6342   scoped_ptr<HttpTransaction> trans(
   6343       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6344 
   6345   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6346   EXPECT_EQ(ERR_IO_PENDING, rv);
   6347 
   6348   rv = callback.WaitForResult();
   6349   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6350 
   6351   rv = trans->RestartIgnoringLastError(callback.callback());
   6352   EXPECT_EQ(ERR_IO_PENDING, rv);
   6353 
   6354   rv = callback.WaitForResult();
   6355   EXPECT_EQ(OK, rv);
   6356 
   6357   const HttpResponseInfo* response = trans->GetResponseInfo();
   6358 
   6359   ASSERT_TRUE(response != NULL);
   6360   EXPECT_EQ(100, response->headers->GetContentLength());
   6361 }
   6362 
   6363 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   6364   HttpRequestInfo request;
   6365   request.method = "GET";
   6366   request.url = GURL("http://www.google.com/");
   6367   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6368                                   "Chromium Ultra Awesome X Edition");
   6369 
   6370   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6371   scoped_ptr<HttpTransaction> trans(
   6372       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6373 
   6374   MockWrite data_writes[] = {
   6375     MockWrite("GET / HTTP/1.1\r\n"
   6376               "Host: www.google.com\r\n"
   6377               "Connection: keep-alive\r\n"
   6378               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6379   };
   6380 
   6381   // Lastly, the server responds with the actual content.
   6382   MockRead data_reads[] = {
   6383     MockRead("HTTP/1.0 200 OK\r\n"),
   6384     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6385     MockRead("Content-Length: 100\r\n\r\n"),
   6386     MockRead(SYNCHRONOUS, OK),
   6387   };
   6388 
   6389   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6390                                 data_writes, arraysize(data_writes));
   6391   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6392 
   6393   TestCompletionCallback callback;
   6394 
   6395   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6396   EXPECT_EQ(ERR_IO_PENDING, rv);
   6397 
   6398   rv = callback.WaitForResult();
   6399   EXPECT_EQ(OK, rv);
   6400 }
   6401 
   6402 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   6403   HttpRequestInfo request;
   6404   request.method = "GET";
   6405   request.url = GURL("https://www.google.com/");
   6406   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6407                                   "Chromium Ultra Awesome X Edition");
   6408 
   6409   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   6410   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6411   scoped_ptr<HttpTransaction> trans(
   6412       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6413 
   6414   MockWrite data_writes[] = {
   6415     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6416               "Host: www.google.com\r\n"
   6417               "Proxy-Connection: keep-alive\r\n"
   6418               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6419   };
   6420   MockRead data_reads[] = {
   6421     // Return an error, so the transaction stops here (this test isn't
   6422     // interested in the rest).
   6423     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   6424     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   6425     MockRead("Proxy-Connection: close\r\n\r\n"),
   6426   };
   6427 
   6428   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6429                                 data_writes, arraysize(data_writes));
   6430   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6431 
   6432   TestCompletionCallback callback;
   6433 
   6434   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6435   EXPECT_EQ(ERR_IO_PENDING, rv);
   6436 
   6437   rv = callback.WaitForResult();
   6438   EXPECT_EQ(OK, rv);
   6439 }
   6440 
   6441 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
   6442   HttpRequestInfo request;
   6443   request.method = "GET";
   6444   request.url = GURL("http://www.google.com/");
   6445   request.load_flags = 0;
   6446   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
   6447                                   "http://the.previous.site.com/");
   6448 
   6449   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6450   scoped_ptr<HttpTransaction> trans(
   6451       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6452 
   6453   MockWrite data_writes[] = {
   6454     MockWrite("GET / HTTP/1.1\r\n"
   6455               "Host: www.google.com\r\n"
   6456               "Connection: keep-alive\r\n"
   6457               "Referer: http://the.previous.site.com/\r\n\r\n"),
   6458   };
   6459 
   6460   // Lastly, the server responds with the actual content.
   6461   MockRead data_reads[] = {
   6462     MockRead("HTTP/1.0 200 OK\r\n"),
   6463     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6464     MockRead("Content-Length: 100\r\n\r\n"),
   6465     MockRead(SYNCHRONOUS, OK),
   6466   };
   6467 
   6468   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6469                                 data_writes, arraysize(data_writes));
   6470   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6471 
   6472   TestCompletionCallback callback;
   6473 
   6474   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6475   EXPECT_EQ(ERR_IO_PENDING, rv);
   6476 
   6477   rv = callback.WaitForResult();
   6478   EXPECT_EQ(OK, rv);
   6479 }
   6480 
   6481 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   6482   HttpRequestInfo request;
   6483   request.method = "POST";
   6484   request.url = GURL("http://www.google.com/");
   6485 
   6486   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6487   scoped_ptr<HttpTransaction> trans(
   6488       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6489 
   6490   MockWrite data_writes[] = {
   6491     MockWrite("POST / HTTP/1.1\r\n"
   6492               "Host: www.google.com\r\n"
   6493               "Connection: keep-alive\r\n"
   6494               "Content-Length: 0\r\n\r\n"),
   6495   };
   6496 
   6497   // Lastly, the server responds with the actual content.
   6498   MockRead data_reads[] = {
   6499     MockRead("HTTP/1.0 200 OK\r\n"),
   6500     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6501     MockRead("Content-Length: 100\r\n\r\n"),
   6502     MockRead(SYNCHRONOUS, OK),
   6503   };
   6504 
   6505   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6506                                 data_writes, arraysize(data_writes));
   6507   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6508 
   6509   TestCompletionCallback callback;
   6510 
   6511   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6512   EXPECT_EQ(ERR_IO_PENDING, rv);
   6513 
   6514   rv = callback.WaitForResult();
   6515   EXPECT_EQ(OK, rv);
   6516 }
   6517 
   6518 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   6519   HttpRequestInfo request;
   6520   request.method = "PUT";
   6521   request.url = GURL("http://www.google.com/");
   6522 
   6523   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6524   scoped_ptr<HttpTransaction> trans(
   6525       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6526 
   6527   MockWrite data_writes[] = {
   6528     MockWrite("PUT / HTTP/1.1\r\n"
   6529               "Host: www.google.com\r\n"
   6530               "Connection: keep-alive\r\n"
   6531               "Content-Length: 0\r\n\r\n"),
   6532   };
   6533 
   6534   // Lastly, the server responds with the actual content.
   6535   MockRead data_reads[] = {
   6536     MockRead("HTTP/1.0 200 OK\r\n"),
   6537     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6538     MockRead("Content-Length: 100\r\n\r\n"),
   6539     MockRead(SYNCHRONOUS, OK),
   6540   };
   6541 
   6542   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6543                                 data_writes, arraysize(data_writes));
   6544   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6545 
   6546   TestCompletionCallback callback;
   6547 
   6548   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6549   EXPECT_EQ(ERR_IO_PENDING, rv);
   6550 
   6551   rv = callback.WaitForResult();
   6552   EXPECT_EQ(OK, rv);
   6553 }
   6554 
   6555 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   6556   HttpRequestInfo request;
   6557   request.method = "HEAD";
   6558   request.url = GURL("http://www.google.com/");
   6559 
   6560   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6561   scoped_ptr<HttpTransaction> trans(
   6562       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6563 
   6564   MockWrite data_writes[] = {
   6565     MockWrite("HEAD / HTTP/1.1\r\n"
   6566               "Host: www.google.com\r\n"
   6567               "Connection: keep-alive\r\n"
   6568               "Content-Length: 0\r\n\r\n"),
   6569   };
   6570 
   6571   // Lastly, the server responds with the actual content.
   6572   MockRead data_reads[] = {
   6573     MockRead("HTTP/1.0 200 OK\r\n"),
   6574     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6575     MockRead("Content-Length: 100\r\n\r\n"),
   6576     MockRead(SYNCHRONOUS, OK),
   6577   };
   6578 
   6579   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6580                                 data_writes, arraysize(data_writes));
   6581   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6582 
   6583   TestCompletionCallback callback;
   6584 
   6585   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6586   EXPECT_EQ(ERR_IO_PENDING, rv);
   6587 
   6588   rv = callback.WaitForResult();
   6589   EXPECT_EQ(OK, rv);
   6590 }
   6591 
   6592 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   6593   HttpRequestInfo request;
   6594   request.method = "GET";
   6595   request.url = GURL("http://www.google.com/");
   6596   request.load_flags = LOAD_BYPASS_CACHE;
   6597 
   6598   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6599   scoped_ptr<HttpTransaction> trans(
   6600       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6601 
   6602   MockWrite data_writes[] = {
   6603     MockWrite("GET / HTTP/1.1\r\n"
   6604               "Host: www.google.com\r\n"
   6605               "Connection: keep-alive\r\n"
   6606               "Pragma: no-cache\r\n"
   6607               "Cache-Control: no-cache\r\n\r\n"),
   6608   };
   6609 
   6610   // Lastly, the server responds with the actual content.
   6611   MockRead data_reads[] = {
   6612     MockRead("HTTP/1.0 200 OK\r\n"),
   6613     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6614     MockRead("Content-Length: 100\r\n\r\n"),
   6615     MockRead(SYNCHRONOUS, OK),
   6616   };
   6617 
   6618   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6619                                 data_writes, arraysize(data_writes));
   6620   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6621 
   6622   TestCompletionCallback callback;
   6623 
   6624   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6625   EXPECT_EQ(ERR_IO_PENDING, rv);
   6626 
   6627   rv = callback.WaitForResult();
   6628   EXPECT_EQ(OK, rv);
   6629 }
   6630 
   6631 TEST_P(HttpNetworkTransactionTest,
   6632        BuildRequest_CacheControlValidateCache) {
   6633   HttpRequestInfo request;
   6634   request.method = "GET";
   6635   request.url = GURL("http://www.google.com/");
   6636   request.load_flags = LOAD_VALIDATE_CACHE;
   6637 
   6638   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6639   scoped_ptr<HttpTransaction> trans(
   6640       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6641 
   6642   MockWrite data_writes[] = {
   6643     MockWrite("GET / HTTP/1.1\r\n"
   6644               "Host: www.google.com\r\n"
   6645               "Connection: keep-alive\r\n"
   6646               "Cache-Control: max-age=0\r\n\r\n"),
   6647   };
   6648 
   6649   // Lastly, the server responds with the actual content.
   6650   MockRead data_reads[] = {
   6651     MockRead("HTTP/1.0 200 OK\r\n"),
   6652     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6653     MockRead("Content-Length: 100\r\n\r\n"),
   6654     MockRead(SYNCHRONOUS, OK),
   6655   };
   6656 
   6657   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6658                                 data_writes, arraysize(data_writes));
   6659   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6660 
   6661   TestCompletionCallback callback;
   6662 
   6663   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6664   EXPECT_EQ(ERR_IO_PENDING, rv);
   6665 
   6666   rv = callback.WaitForResult();
   6667   EXPECT_EQ(OK, rv);
   6668 }
   6669 
   6670 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   6671   HttpRequestInfo request;
   6672   request.method = "GET";
   6673   request.url = GURL("http://www.google.com/");
   6674   request.extra_headers.SetHeader("FooHeader", "Bar");
   6675 
   6676   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6677   scoped_ptr<HttpTransaction> trans(
   6678       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6679 
   6680   MockWrite data_writes[] = {
   6681     MockWrite("GET / HTTP/1.1\r\n"
   6682               "Host: www.google.com\r\n"
   6683               "Connection: keep-alive\r\n"
   6684               "FooHeader: Bar\r\n\r\n"),
   6685   };
   6686 
   6687   // Lastly, the server responds with the actual content.
   6688   MockRead data_reads[] = {
   6689     MockRead("HTTP/1.0 200 OK\r\n"),
   6690     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6691     MockRead("Content-Length: 100\r\n\r\n"),
   6692     MockRead(SYNCHRONOUS, OK),
   6693   };
   6694 
   6695   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6696                                 data_writes, arraysize(data_writes));
   6697   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6698 
   6699   TestCompletionCallback callback;
   6700 
   6701   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6702   EXPECT_EQ(ERR_IO_PENDING, rv);
   6703 
   6704   rv = callback.WaitForResult();
   6705   EXPECT_EQ(OK, rv);
   6706 }
   6707 
   6708 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   6709   HttpRequestInfo request;
   6710   request.method = "GET";
   6711   request.url = GURL("http://www.google.com/");
   6712   request.extra_headers.SetHeader("referer", "www.foo.com");
   6713   request.extra_headers.SetHeader("hEllo", "Kitty");
   6714   request.extra_headers.SetHeader("FoO", "bar");
   6715 
   6716   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6717   scoped_ptr<HttpTransaction> trans(
   6718       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6719 
   6720   MockWrite data_writes[] = {
   6721     MockWrite("GET / HTTP/1.1\r\n"
   6722               "Host: www.google.com\r\n"
   6723               "Connection: keep-alive\r\n"
   6724               "referer: www.foo.com\r\n"
   6725               "hEllo: Kitty\r\n"
   6726               "FoO: bar\r\n\r\n"),
   6727   };
   6728 
   6729   // Lastly, the server responds with the actual content.
   6730   MockRead data_reads[] = {
   6731     MockRead("HTTP/1.0 200 OK\r\n"),
   6732     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6733     MockRead("Content-Length: 100\r\n\r\n"),
   6734     MockRead(SYNCHRONOUS, OK),
   6735   };
   6736 
   6737   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6738                                 data_writes, arraysize(data_writes));
   6739   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6740 
   6741   TestCompletionCallback callback;
   6742 
   6743   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6744   EXPECT_EQ(ERR_IO_PENDING, rv);
   6745 
   6746   rv = callback.WaitForResult();
   6747   EXPECT_EQ(OK, rv);
   6748 }
   6749 
   6750 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   6751   HttpRequestInfo request;
   6752   request.method = "GET";
   6753   request.url = GURL("http://www.google.com/");
   6754   request.load_flags = 0;
   6755 
   6756   session_deps_.proxy_service.reset(
   6757       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   6758   CapturingNetLog net_log;
   6759   session_deps_.net_log = &net_log;
   6760 
   6761   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6762   scoped_ptr<HttpTransaction> trans(
   6763       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6764 
   6765   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   6766   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6767 
   6768   MockWrite data_writes[] = {
   6769     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   6770     MockWrite("GET / HTTP/1.1\r\n"
   6771               "Host: www.google.com\r\n"
   6772               "Connection: keep-alive\r\n\r\n")
   6773   };
   6774 
   6775   MockRead data_reads[] = {
   6776     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   6777     MockRead("HTTP/1.0 200 OK\r\n"),
   6778     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6779     MockRead("Payload"),
   6780     MockRead(SYNCHRONOUS, OK)
   6781   };
   6782 
   6783   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6784                                 data_writes, arraysize(data_writes));
   6785   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6786 
   6787   TestCompletionCallback callback;
   6788 
   6789   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6790   EXPECT_EQ(ERR_IO_PENDING, rv);
   6791 
   6792   rv = callback.WaitForResult();
   6793   EXPECT_EQ(OK, rv);
   6794 
   6795   const HttpResponseInfo* response = trans->GetResponseInfo();
   6796   ASSERT_TRUE(response != NULL);
   6797 
   6798   LoadTimingInfo load_timing_info;
   6799   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6800   TestLoadTimingNotReusedWithPac(load_timing_info,
   6801                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6802 
   6803   std::string response_text;
   6804   rv = ReadTransaction(trans.get(), &response_text);
   6805   EXPECT_EQ(OK, rv);
   6806   EXPECT_EQ("Payload", response_text);
   6807 }
   6808 
   6809 TEST_P(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   6810   HttpRequestInfo request;
   6811   request.method = "GET";
   6812   request.url = GURL("https://www.google.com/");
   6813   request.load_flags = 0;
   6814 
   6815   session_deps_.proxy_service.reset(
   6816       ProxyService::CreateFixedFromPacResult("SOCKS myproxy:1080"));
   6817   CapturingNetLog net_log;
   6818   session_deps_.net_log = &net_log;
   6819 
   6820   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6821   scoped_ptr<HttpTransaction> trans(
   6822       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6823 
   6824   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
   6825   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6826 
   6827   MockWrite data_writes[] = {
   6828     MockWrite(ASYNC, reinterpret_cast<char*>(write_buffer),
   6829               arraysize(write_buffer)),
   6830     MockWrite("GET / HTTP/1.1\r\n"
   6831               "Host: www.google.com\r\n"
   6832               "Connection: keep-alive\r\n\r\n")
   6833   };
   6834 
   6835   MockRead data_reads[] = {
   6836     MockRead(ASYNC, reinterpret_cast<char*>(read_buffer),
   6837              arraysize(read_buffer)),
   6838     MockRead("HTTP/1.0 200 OK\r\n"),
   6839     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6840     MockRead("Payload"),
   6841     MockRead(SYNCHRONOUS, OK)
   6842   };
   6843 
   6844   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6845                                 data_writes, arraysize(data_writes));
   6846   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6847 
   6848   SSLSocketDataProvider ssl(ASYNC, OK);
   6849   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6850 
   6851   TestCompletionCallback callback;
   6852 
   6853   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6854   EXPECT_EQ(ERR_IO_PENDING, rv);
   6855 
   6856   rv = callback.WaitForResult();
   6857   EXPECT_EQ(OK, rv);
   6858 
   6859   LoadTimingInfo load_timing_info;
   6860   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6861   TestLoadTimingNotReusedWithPac(load_timing_info,
   6862                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6863 
   6864   const HttpResponseInfo* response = trans->GetResponseInfo();
   6865   ASSERT_TRUE(response != NULL);
   6866 
   6867   std::string response_text;
   6868   rv = ReadTransaction(trans.get(), &response_text);
   6869   EXPECT_EQ(OK, rv);
   6870   EXPECT_EQ("Payload", response_text);
   6871 }
   6872 
   6873 TEST_P(HttpNetworkTransactionTest, SOCKS4_HTTP_GET_no_PAC) {
   6874   HttpRequestInfo request;
   6875   request.method = "GET";
   6876   request.url = GURL("http://www.google.com/");
   6877   request.load_flags = 0;
   6878 
   6879   session_deps_.proxy_service.reset(
   6880       ProxyService::CreateFixed("socks4://myproxy:1080"));
   6881   CapturingNetLog net_log;
   6882   session_deps_.net_log = &net_log;
   6883 
   6884   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6885   scoped_ptr<HttpTransaction> trans(
   6886       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6887 
   6888   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   6889   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   6890 
   6891   MockWrite data_writes[] = {
   6892     MockWrite(ASYNC, write_buffer, arraysize(write_buffer)),
   6893     MockWrite("GET / HTTP/1.1\r\n"
   6894               "Host: www.google.com\r\n"
   6895               "Connection: keep-alive\r\n\r\n")
   6896   };
   6897 
   6898   MockRead data_reads[] = {
   6899     MockRead(ASYNC, read_buffer, arraysize(read_buffer)),
   6900     MockRead("HTTP/1.0 200 OK\r\n"),
   6901     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6902     MockRead("Payload"),
   6903     MockRead(SYNCHRONOUS, OK)
   6904   };
   6905 
   6906   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6907                                 data_writes, arraysize(data_writes));
   6908   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6909 
   6910   TestCompletionCallback callback;
   6911 
   6912   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6913   EXPECT_EQ(ERR_IO_PENDING, rv);
   6914 
   6915   rv = callback.WaitForResult();
   6916   EXPECT_EQ(OK, rv);
   6917 
   6918   const HttpResponseInfo* response = trans->GetResponseInfo();
   6919   ASSERT_TRUE(response != NULL);
   6920 
   6921   LoadTimingInfo load_timing_info;
   6922   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6923   TestLoadTimingNotReused(load_timing_info,
   6924                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6925 
   6926   std::string response_text;
   6927   rv = ReadTransaction(trans.get(), &response_text);
   6928   EXPECT_EQ(OK, rv);
   6929   EXPECT_EQ("Payload", response_text);
   6930 }
   6931 
   6932 TEST_P(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   6933   HttpRequestInfo request;
   6934   request.method = "GET";
   6935   request.url = GURL("http://www.google.com/");
   6936   request.load_flags = 0;
   6937 
   6938   session_deps_.proxy_service.reset(
   6939       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   6940   CapturingNetLog net_log;
   6941   session_deps_.net_log = &net_log;
   6942 
   6943   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6944   scoped_ptr<HttpTransaction> trans(
   6945       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6946 
   6947   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   6948   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   6949   const char kSOCKS5OkRequest[] = {
   6950     0x05,  // Version
   6951     0x01,  // Command (CONNECT)
   6952     0x00,  // Reserved.
   6953     0x03,  // Address type (DOMAINNAME).
   6954     0x0E,  // Length of domain (14)
   6955     // Domain string:
   6956     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   6957     0x00, 0x50,  // 16-bit port (80)
   6958   };
   6959   const char kSOCKS5OkResponse[] =
   6960       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
   6961 
   6962   MockWrite data_writes[] = {
   6963     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   6964     MockWrite(ASYNC, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
   6965     MockWrite("GET / HTTP/1.1\r\n"
   6966               "Host: www.google.com\r\n"
   6967               "Connection: keep-alive\r\n\r\n")
   6968   };
   6969 
   6970   MockRead data_reads[] = {
   6971     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   6972     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   6973     MockRead("HTTP/1.0 200 OK\r\n"),
   6974     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   6975     MockRead("Payload"),
   6976     MockRead(SYNCHRONOUS, OK)
   6977   };
   6978 
   6979   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6980                                 data_writes, arraysize(data_writes));
   6981   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6982 
   6983   TestCompletionCallback callback;
   6984 
   6985   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6986   EXPECT_EQ(ERR_IO_PENDING, rv);
   6987 
   6988   rv = callback.WaitForResult();
   6989   EXPECT_EQ(OK, rv);
   6990 
   6991   const HttpResponseInfo* response = trans->GetResponseInfo();
   6992   ASSERT_TRUE(response != NULL);
   6993 
   6994   LoadTimingInfo load_timing_info;
   6995   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6996   TestLoadTimingNotReusedWithPac(load_timing_info,
   6997                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6998 
   6999   std::string response_text;
   7000   rv = ReadTransaction(trans.get(), &response_text);
   7001   EXPECT_EQ(OK, rv);
   7002   EXPECT_EQ("Payload", response_text);
   7003 }
   7004 
   7005 TEST_P(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   7006   HttpRequestInfo request;
   7007   request.method = "GET";
   7008   request.url = GURL("https://www.google.com/");
   7009   request.load_flags = 0;
   7010 
   7011   session_deps_.proxy_service.reset(
   7012       ProxyService::CreateFixedFromPacResult("SOCKS5 myproxy:1080"));
   7013   CapturingNetLog net_log;
   7014   session_deps_.net_log = &net_log;
   7015 
   7016   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7017   scoped_ptr<HttpTransaction> trans(
   7018       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7019 
   7020   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   7021   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   7022   const unsigned char kSOCKS5OkRequest[] = {
   7023     0x05,  // Version
   7024     0x01,  // Command (CONNECT)
   7025     0x00,  // Reserved.
   7026     0x03,  // Address type (DOMAINNAME).
   7027     0x0E,  // Length of domain (14)
   7028     // Domain string:
   7029     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   7030     0x01, 0xBB,  // 16-bit port (443)
   7031   };
   7032 
   7033   const char kSOCKS5OkResponse[] =
   7034       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
   7035 
   7036   MockWrite data_writes[] = {
   7037     MockWrite(ASYNC, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   7038     MockWrite(ASYNC, reinterpret_cast<const char*>(kSOCKS5OkRequest),
   7039               arraysize(kSOCKS5OkRequest)),
   7040     MockWrite("GET / HTTP/1.1\r\n"
   7041               "Host: www.google.com\r\n"
   7042               "Connection: keep-alive\r\n\r\n")
   7043   };
   7044 
   7045   MockRead data_reads[] = {
   7046     MockRead(ASYNC, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   7047     MockRead(ASYNC, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   7048     MockRead("HTTP/1.0 200 OK\r\n"),
   7049     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   7050     MockRead("Payload"),
   7051     MockRead(SYNCHRONOUS, OK)
   7052   };
   7053 
   7054   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7055                                 data_writes, arraysize(data_writes));
   7056   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7057 
   7058   SSLSocketDataProvider ssl(ASYNC, OK);
   7059   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   7060 
   7061   TestCompletionCallback callback;
   7062 
   7063   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7064   EXPECT_EQ(ERR_IO_PENDING, rv);
   7065 
   7066   rv = callback.WaitForResult();
   7067   EXPECT_EQ(OK, rv);
   7068 
   7069   const HttpResponseInfo* response = trans->GetResponseInfo();
   7070   ASSERT_TRUE(response != NULL);
   7071 
   7072   LoadTimingInfo load_timing_info;
   7073   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   7074   TestLoadTimingNotReusedWithPac(load_timing_info,
   7075                                  CONNECT_TIMING_HAS_SSL_TIMES);
   7076 
   7077   std::string response_text;
   7078   rv = ReadTransaction(trans.get(), &response_text);
   7079   EXPECT_EQ(OK, rv);
   7080   EXPECT_EQ("Payload", response_text);
   7081 }
   7082 
   7083 namespace {
   7084 
   7085 // Tests that for connection endpoints the group names are correctly set.
   7086 
   7087 struct GroupNameTest {
   7088   std::string proxy_server;
   7089   std::string url;
   7090   std::string expected_group_name;
   7091   bool ssl;
   7092 };
   7093 
   7094 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
   7095     NextProto next_proto,
   7096     SpdySessionDependencies* session_deps_) {
   7097   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps_));
   7098 
   7099   base::WeakPtr<HttpServerProperties> http_server_properties =
   7100       session->http_server_properties();
   7101   http_server_properties->SetAlternateProtocol(
   7102       HostPortPair("host.with.alternate", 80), 443,
   7103       AlternateProtocolFromNextProto(next_proto));
   7104 
   7105   return session;
   7106 }
   7107 
   7108 int GroupNameTransactionHelper(
   7109     const std::string& url,
   7110     const scoped_refptr<HttpNetworkSession>& session) {
   7111   HttpRequestInfo request;
   7112   request.method = "GET";
   7113   request.url = GURL(url);
   7114   request.load_flags = 0;
   7115 
   7116   scoped_ptr<HttpTransaction> trans(
   7117       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7118 
   7119   TestCompletionCallback callback;
   7120 
   7121   // We do not complete this request, the dtor will clean the transaction up.
   7122   return trans->Start(&request, callback.callback(), BoundNetLog());
   7123 }
   7124 
   7125 }  // namespace
   7126 
   7127 TEST_P(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
   7128   const GroupNameTest tests[] = {
   7129     {
   7130       "",  // unused
   7131       "http://www.google.com/direct",
   7132       "www.google.com:80",
   7133       false,
   7134     },
   7135     {
   7136       "",  // unused
   7137       "http://[2001:1418:13:1::25]/direct",
   7138       "[2001:1418:13:1::25]:80",
   7139       false,
   7140     },
   7141 
   7142     // SSL Tests
   7143     {
   7144       "",  // unused
   7145       "https://www.google.com/direct_ssl",
   7146       "ssl/www.google.com:443",
   7147       true,
   7148     },
   7149     {
   7150       "",  // unused
   7151       "https://[2001:1418:13:1::25]/direct",
   7152       "ssl/[2001:1418:13:1::25]:443",
   7153       true,
   7154     },
   7155     {
   7156       "",  // unused
   7157       "http://host.with.alternate/direct",
   7158       "ssl/host.with.alternate:443",
   7159       true,
   7160     },
   7161   };
   7162 
   7163   HttpStreamFactory::set_use_alternate_protocols(true);
   7164 
   7165   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7166     session_deps_.proxy_service.reset(
   7167         ProxyService::CreateFixed(tests[i].proxy_server));
   7168     scoped_refptr<HttpNetworkSession> session(
   7169         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7170 
   7171     HttpNetworkSessionPeer peer(session);
   7172     CaptureGroupNameTransportSocketPool* transport_conn_pool =
   7173         new CaptureGroupNameTransportSocketPool(NULL, NULL);
   7174     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7175         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7176     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7177         new MockClientSocketPoolManager);
   7178     mock_pool_manager->SetTransportSocketPool(transport_conn_pool);
   7179     mock_pool_manager->SetSSLSocketPool(ssl_conn_pool);
   7180     peer.SetClientSocketPoolManager(
   7181         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7182 
   7183     EXPECT_EQ(ERR_IO_PENDING,
   7184               GroupNameTransactionHelper(tests[i].url, session));
   7185     if (tests[i].ssl)
   7186       EXPECT_EQ(tests[i].expected_group_name,
   7187                 ssl_conn_pool->last_group_name_received());
   7188     else
   7189       EXPECT_EQ(tests[i].expected_group_name,
   7190                 transport_conn_pool->last_group_name_received());
   7191   }
   7192 
   7193 }
   7194 
   7195 TEST_P(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
   7196   const GroupNameTest tests[] = {
   7197     {
   7198       "http_proxy",
   7199       "http://www.google.com/http_proxy_normal",
   7200       "www.google.com:80",
   7201       false,
   7202     },
   7203 
   7204     // SSL Tests
   7205     {
   7206       "http_proxy",
   7207       "https://www.google.com/http_connect_ssl",
   7208       "ssl/www.google.com:443",
   7209       true,
   7210     },
   7211 
   7212     {
   7213       "http_proxy",
   7214       "http://host.with.alternate/direct",
   7215       "ssl/host.with.alternate:443",
   7216       true,
   7217     },
   7218 
   7219     {
   7220       "http_proxy",
   7221       "ftp://ftp.google.com/http_proxy_normal",
   7222       "ftp/ftp.google.com:21",
   7223       false,
   7224     },
   7225   };
   7226 
   7227   HttpStreamFactory::set_use_alternate_protocols(true);
   7228 
   7229   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7230     session_deps_.proxy_service.reset(
   7231         ProxyService::CreateFixed(tests[i].proxy_server));
   7232     scoped_refptr<HttpNetworkSession> session(
   7233         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7234 
   7235     HttpNetworkSessionPeer peer(session);
   7236 
   7237     HostPortPair proxy_host("http_proxy", 80);
   7238     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
   7239         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
   7240     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7241         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7242 
   7243     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7244         new MockClientSocketPoolManager);
   7245     mock_pool_manager->SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
   7246     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7247     peer.SetClientSocketPoolManager(
   7248         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7249 
   7250     EXPECT_EQ(ERR_IO_PENDING,
   7251               GroupNameTransactionHelper(tests[i].url, session));
   7252     if (tests[i].ssl)
   7253       EXPECT_EQ(tests[i].expected_group_name,
   7254                 ssl_conn_pool->last_group_name_received());
   7255     else
   7256       EXPECT_EQ(tests[i].expected_group_name,
   7257                 http_proxy_pool->last_group_name_received());
   7258   }
   7259 }
   7260 
   7261 TEST_P(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
   7262   const GroupNameTest tests[] = {
   7263     {
   7264       "socks4://socks_proxy:1080",
   7265       "http://www.google.com/socks4_direct",
   7266       "socks4/www.google.com:80",
   7267       false,
   7268     },
   7269     {
   7270       "socks5://socks_proxy:1080",
   7271       "http://www.google.com/socks5_direct",
   7272       "socks5/www.google.com:80",
   7273       false,
   7274     },
   7275 
   7276     // SSL Tests
   7277     {
   7278       "socks4://socks_proxy:1080",
   7279       "https://www.google.com/socks4_ssl",
   7280       "socks4/ssl/www.google.com:443",
   7281       true,
   7282     },
   7283     {
   7284       "socks5://socks_proxy:1080",
   7285       "https://www.google.com/socks5_ssl",
   7286       "socks5/ssl/www.google.com:443",
   7287       true,
   7288     },
   7289 
   7290     {
   7291       "socks4://socks_proxy:1080",
   7292       "http://host.with.alternate/direct",
   7293       "socks4/ssl/host.with.alternate:443",
   7294       true,
   7295     },
   7296   };
   7297 
   7298   HttpStreamFactory::set_use_alternate_protocols(true);
   7299 
   7300   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   7301     session_deps_.proxy_service.reset(
   7302         ProxyService::CreateFixed(tests[i].proxy_server));
   7303     scoped_refptr<HttpNetworkSession> session(
   7304         SetupSessionForGroupNameTests(GetParam(), &session_deps_));
   7305 
   7306     HttpNetworkSessionPeer peer(session);
   7307 
   7308     HostPortPair proxy_host("socks_proxy", 1080);
   7309     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
   7310         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
   7311     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   7312         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   7313 
   7314     scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   7315         new MockClientSocketPoolManager);
   7316     mock_pool_manager->SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
   7317     mock_pool_manager->SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   7318     peer.SetClientSocketPoolManager(
   7319         mock_pool_manager.PassAs<ClientSocketPoolManager>());
   7320 
   7321     scoped_ptr<HttpTransaction> trans(
   7322         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7323 
   7324     EXPECT_EQ(ERR_IO_PENDING,
   7325               GroupNameTransactionHelper(tests[i].url, session));
   7326     if (tests[i].ssl)
   7327       EXPECT_EQ(tests[i].expected_group_name,
   7328                 ssl_conn_pool->last_group_name_received());
   7329     else
   7330       EXPECT_EQ(tests[i].expected_group_name,
   7331                 socks_conn_pool->last_group_name_received());
   7332   }
   7333 }
   7334 
   7335 TEST_P(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   7336   HttpRequestInfo request;
   7337   request.method = "GET";
   7338   request.url = GURL("http://www.google.com/");
   7339 
   7340   session_deps_.proxy_service.reset(
   7341       ProxyService::CreateFixed("myproxy:70;foobar:80"));
   7342 
   7343   // This simulates failure resolving all hostnames; that means we will fail
   7344   // connecting to both proxies (myproxy:70 and foobar:80).
   7345   session_deps_.host_resolver->rules()->AddSimulatedFailure("*");
   7346 
   7347   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7348   scoped_ptr<HttpTransaction> trans(
   7349       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7350 
   7351   TestCompletionCallback callback;
   7352 
   7353   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7354   EXPECT_EQ(ERR_IO_PENDING, rv);
   7355 
   7356   rv = callback.WaitForResult();
   7357   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
   7358 }
   7359 
   7360 // Base test to make sure that when the load flags for a request specify to
   7361 // bypass the cache, the DNS cache is not used.
   7362 void HttpNetworkTransactionTest::BypassHostCacheOnRefreshHelper(
   7363     int load_flags) {
   7364   // Issue a request, asking to bypass the cache(s).
   7365   HttpRequestInfo request;
   7366   request.method = "GET";
   7367   request.load_flags = load_flags;
   7368   request.url = GURL("http://www.google.com/");
   7369 
   7370   // Select a host resolver that does caching.
   7371   session_deps_.host_resolver.reset(new MockCachingHostResolver);
   7372 
   7373   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7374   scoped_ptr<HttpTransaction> trans(
   7375       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7376 
   7377   // Warm up the host cache so it has an entry for "www.google.com".
   7378   AddressList addrlist;
   7379   TestCompletionCallback callback;
   7380   int rv = session_deps_.host_resolver->Resolve(
   7381       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
   7382       DEFAULT_PRIORITY,
   7383       &addrlist,
   7384       callback.callback(),
   7385       NULL,
   7386       BoundNetLog());
   7387   EXPECT_EQ(ERR_IO_PENDING, rv);
   7388   rv = callback.WaitForResult();
   7389   EXPECT_EQ(OK, rv);
   7390 
   7391   // Verify that it was added to host cache, by doing a subsequent async lookup
   7392   // and confirming it completes synchronously.
   7393   rv = session_deps_.host_resolver->Resolve(
   7394       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)),
   7395       DEFAULT_PRIORITY,
   7396       &addrlist,
   7397       callback.callback(),
   7398       NULL,
   7399       BoundNetLog());
   7400   ASSERT_EQ(OK, rv);
   7401 
   7402   // Inject a failure the next time that "www.google.com" is resolved. This way
   7403   // we can tell if the next lookup hit the cache, or the "network".
   7404   // (cache --> success, "network" --> failure).
   7405   session_deps_.host_resolver->rules()->AddSimulatedFailure("www.google.com");
   7406 
   7407   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   7408   // first read -- this won't be reached as the host resolution will fail first.
   7409   MockRead data_reads[] = { MockRead(SYNCHRONOUS, ERR_UNEXPECTED) };
   7410   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7411   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7412 
   7413   // Run the request.
   7414   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7415   ASSERT_EQ(ERR_IO_PENDING, rv);
   7416   rv = callback.WaitForResult();
   7417 
   7418   // If we bypassed the cache, we would have gotten a failure while resolving
   7419   // "www.google.com".
   7420   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   7421 }
   7422 
   7423 // There are multiple load flags that should trigger the host cache bypass.
   7424 // Test each in isolation:
   7425 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
   7426   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
   7427 }
   7428 
   7429 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
   7430   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
   7431 }
   7432 
   7433 TEST_P(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
   7434   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
   7435 }
   7436 
   7437 // Make sure we can handle an error when writing the request.
   7438 TEST_P(HttpNetworkTransactionTest, RequestWriteError) {
   7439   HttpRequestInfo request;
   7440   request.method = "GET";
   7441   request.url = GURL("http://www.foo.com/");
   7442   request.load_flags = 0;
   7443 
   7444   MockWrite write_failure[] = {
   7445     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   7446   };
   7447   StaticSocketDataProvider data(NULL, 0,
   7448                                 write_failure, arraysize(write_failure));
   7449   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7450   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7451 
   7452   TestCompletionCallback callback;
   7453 
   7454   scoped_ptr<HttpTransaction> trans(
   7455       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7456 
   7457   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7458   EXPECT_EQ(ERR_IO_PENDING, rv);
   7459 
   7460   rv = callback.WaitForResult();
   7461   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   7462 }
   7463 
   7464 // Check that a connection closed after the start of the headers finishes ok.
   7465 TEST_P(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
   7466   HttpRequestInfo request;
   7467   request.method = "GET";
   7468   request.url = GURL("http://www.foo.com/");
   7469   request.load_flags = 0;
   7470 
   7471   MockRead data_reads[] = {
   7472     MockRead("HTTP/1."),
   7473     MockRead(SYNCHRONOUS, OK),
   7474   };
   7475 
   7476   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7477   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7478   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7479 
   7480   TestCompletionCallback callback;
   7481 
   7482   scoped_ptr<HttpTransaction> trans(
   7483       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7484 
   7485   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7486   EXPECT_EQ(ERR_IO_PENDING, rv);
   7487 
   7488   rv = callback.WaitForResult();
   7489   EXPECT_EQ(OK, rv);
   7490 
   7491   const HttpResponseInfo* response = trans->GetResponseInfo();
   7492   ASSERT_TRUE(response != NULL);
   7493 
   7494   EXPECT_TRUE(response->headers.get() != NULL);
   7495   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7496 
   7497   std::string response_data;
   7498   rv = ReadTransaction(trans.get(), &response_data);
   7499   EXPECT_EQ(OK, rv);
   7500   EXPECT_EQ("", response_data);
   7501 }
   7502 
   7503 // Make sure that a dropped connection while draining the body for auth
   7504 // restart does the right thing.
   7505 TEST_P(HttpNetworkTransactionTest, DrainResetOK) {
   7506   HttpRequestInfo request;
   7507   request.method = "GET";
   7508   request.url = GURL("http://www.google.com/");
   7509   request.load_flags = 0;
   7510 
   7511   MockWrite data_writes1[] = {
   7512     MockWrite("GET / HTTP/1.1\r\n"
   7513               "Host: www.google.com\r\n"
   7514               "Connection: keep-alive\r\n\r\n"),
   7515   };
   7516 
   7517   MockRead data_reads1[] = {
   7518     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   7519     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   7520     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7521     MockRead("Content-Length: 14\r\n\r\n"),
   7522     MockRead("Unauth"),
   7523     MockRead(ASYNC, ERR_CONNECTION_RESET),
   7524   };
   7525 
   7526   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   7527                                  data_writes1, arraysize(data_writes1));
   7528   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   7529 
   7530   // After calling trans->RestartWithAuth(), this is the request we should
   7531   // be issuing -- the final header line contains the credentials.
   7532   MockWrite data_writes2[] = {
   7533     MockWrite("GET / HTTP/1.1\r\n"
   7534               "Host: www.google.com\r\n"
   7535               "Connection: keep-alive\r\n"
   7536               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   7537   };
   7538 
   7539   // Lastly, the server responds with the actual content.
   7540   MockRead data_reads2[] = {
   7541     MockRead("HTTP/1.1 200 OK\r\n"),
   7542     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7543     MockRead("Content-Length: 100\r\n\r\n"),
   7544     MockRead(SYNCHRONOUS, OK),
   7545   };
   7546 
   7547   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   7548                                  data_writes2, arraysize(data_writes2));
   7549   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   7550   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7551 
   7552   TestCompletionCallback callback1;
   7553 
   7554   scoped_ptr<HttpTransaction> trans(
   7555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7556 
   7557   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7558   EXPECT_EQ(ERR_IO_PENDING, rv);
   7559 
   7560   rv = callback1.WaitForResult();
   7561   EXPECT_EQ(OK, rv);
   7562 
   7563   const HttpResponseInfo* response = trans->GetResponseInfo();
   7564   ASSERT_TRUE(response != NULL);
   7565   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   7566 
   7567   TestCompletionCallback callback2;
   7568 
   7569   rv = trans->RestartWithAuth(
   7570       AuthCredentials(kFoo, kBar), callback2.callback());
   7571   EXPECT_EQ(ERR_IO_PENDING, rv);
   7572 
   7573   rv = callback2.WaitForResult();
   7574   EXPECT_EQ(OK, rv);
   7575 
   7576   response = trans->GetResponseInfo();
   7577   ASSERT_TRUE(response != NULL);
   7578   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7579   EXPECT_EQ(100, response->headers->GetContentLength());
   7580 }
   7581 
   7582 // Test HTTPS connections going through a proxy that sends extra data.
   7583 TEST_P(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
   7584   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   7585 
   7586   HttpRequestInfo request;
   7587   request.method = "GET";
   7588   request.url = GURL("https://www.google.com/");
   7589   request.load_flags = 0;
   7590 
   7591   MockRead proxy_reads[] = {
   7592     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
   7593     MockRead(SYNCHRONOUS, OK)
   7594   };
   7595 
   7596   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
   7597   SSLSocketDataProvider ssl(ASYNC, OK);
   7598 
   7599   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7600   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   7601 
   7602   TestCompletionCallback callback;
   7603 
   7604   session_deps_.socket_factory->ResetNextMockIndexes();
   7605 
   7606   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7607   scoped_ptr<HttpTransaction> trans(
   7608       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7609 
   7610   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7611   EXPECT_EQ(ERR_IO_PENDING, rv);
   7612 
   7613   rv = callback.WaitForResult();
   7614   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   7615 }
   7616 
   7617 TEST_P(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   7618   HttpRequestInfo request;
   7619   request.method = "GET";
   7620   request.url = GURL("http://www.google.com/");
   7621   request.load_flags = 0;
   7622 
   7623   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7624   scoped_ptr<HttpTransaction> trans(
   7625       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7626 
   7627   MockRead data_reads[] = {
   7628     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
   7629     MockRead(SYNCHRONOUS, OK),
   7630   };
   7631 
   7632   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7633   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7634 
   7635   TestCompletionCallback callback;
   7636 
   7637   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7638   EXPECT_EQ(ERR_IO_PENDING, rv);
   7639 
   7640   EXPECT_EQ(OK, callback.WaitForResult());
   7641 
   7642   const HttpResponseInfo* response = trans->GetResponseInfo();
   7643   ASSERT_TRUE(response != NULL);
   7644 
   7645   EXPECT_TRUE(response->headers.get() != NULL);
   7646   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7647 
   7648   std::string response_data;
   7649   rv = ReadTransaction(trans.get(), &response_data);
   7650   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   7651 }
   7652 
   7653 TEST_P(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
   7654   base::FilePath temp_file_path;
   7655   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path));
   7656   const uint64 kFakeSize = 100000;  // file is actually blank
   7657   UploadFileElementReader::ScopedOverridingContentLengthForTests
   7658       overriding_content_length(kFakeSize);
   7659 
   7660   ScopedVector<UploadElementReader> element_readers;
   7661   element_readers.push_back(
   7662       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   7663                                   temp_file_path,
   7664                                   0,
   7665                                   kuint64max,
   7666                                   base::Time()));
   7667   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   7668 
   7669   HttpRequestInfo request;
   7670   request.method = "POST";
   7671   request.url = GURL("http://www.google.com/upload");
   7672   request.upload_data_stream = &upload_data_stream;
   7673   request.load_flags = 0;
   7674 
   7675   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7676   scoped_ptr<HttpTransaction> trans(
   7677       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7678 
   7679   MockRead data_reads[] = {
   7680     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   7681     MockRead("hello world"),
   7682     MockRead(SYNCHRONOUS, OK),
   7683   };
   7684   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7685   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7686 
   7687   TestCompletionCallback callback;
   7688 
   7689   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7690   EXPECT_EQ(ERR_IO_PENDING, rv);
   7691 
   7692   rv = callback.WaitForResult();
   7693   EXPECT_EQ(OK, rv);
   7694 
   7695   const HttpResponseInfo* response = trans->GetResponseInfo();
   7696   ASSERT_TRUE(response != NULL);
   7697 
   7698   EXPECT_TRUE(response->headers.get() != NULL);
   7699   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   7700 
   7701   std::string response_data;
   7702   rv = ReadTransaction(trans.get(), &response_data);
   7703   EXPECT_EQ(OK, rv);
   7704   EXPECT_EQ("hello world", response_data);
   7705 
   7706   base::DeleteFile(temp_file_path, false);
   7707 }
   7708 
   7709 TEST_P(HttpNetworkTransactionTest, UploadUnreadableFile) {
   7710   base::FilePath temp_file;
   7711   ASSERT_TRUE(base::CreateTemporaryFile(&temp_file));
   7712   std::string temp_file_content("Unreadable file.");
   7713   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
   7714                                    temp_file_content.length()));
   7715   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
   7716 
   7717   ScopedVector<UploadElementReader> element_readers;
   7718   element_readers.push_back(
   7719       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
   7720                                   temp_file,
   7721                                   0,
   7722                                   kuint64max,
   7723                                   base::Time()));
   7724   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   7725 
   7726   HttpRequestInfo request;
   7727   request.method = "POST";
   7728   request.url = GURL("http://www.google.com/upload");
   7729   request.upload_data_stream = &upload_data_stream;
   7730   request.load_flags = 0;
   7731 
   7732   // If we try to upload an unreadable file, the transaction should fail.
   7733   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7734   scoped_ptr<HttpTransaction> trans(
   7735       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7736 
   7737   StaticSocketDataProvider data(NULL, 0, NULL, 0);
   7738   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7739 
   7740   TestCompletionCallback callback;
   7741 
   7742   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7743   EXPECT_EQ(ERR_IO_PENDING, rv);
   7744 
   7745   rv = callback.WaitForResult();
   7746   EXPECT_EQ(ERR_ACCESS_DENIED, rv);
   7747 
   7748   const HttpResponseInfo* response = trans->GetResponseInfo();
   7749   EXPECT_FALSE(response);
   7750 
   7751   base::DeleteFile(temp_file, false);
   7752 }
   7753 
   7754 TEST_P(HttpNetworkTransactionTest, CancelDuringInitRequestBody) {
   7755   class FakeUploadElementReader : public UploadElementReader {
   7756    public:
   7757     FakeUploadElementReader() {}
   7758     virtual ~FakeUploadElementReader() {}
   7759 
   7760     const CompletionCallback& callback() const { return callback_; }
   7761 
   7762     // UploadElementReader overrides:
   7763     virtual int Init(const CompletionCallback& callback) OVERRIDE {
   7764       callback_ = callback;
   7765       return ERR_IO_PENDING;
   7766     }
   7767     virtual uint64 GetContentLength() const OVERRIDE { return 0; }
   7768     virtual uint64 BytesRemaining() const OVERRIDE { return 0; }
   7769     virtual int Read(IOBuffer* buf,
   7770                      int buf_length,
   7771                      const CompletionCallback& callback) OVERRIDE {
   7772       return ERR_FAILED;
   7773     }
   7774 
   7775    private:
   7776     CompletionCallback callback_;
   7777   };
   7778 
   7779   FakeUploadElementReader* fake_reader = new FakeUploadElementReader;
   7780   ScopedVector<UploadElementReader> element_readers;
   7781   element_readers.push_back(fake_reader);
   7782   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   7783 
   7784   HttpRequestInfo request;
   7785   request.method = "POST";
   7786   request.url = GURL("http://www.google.com/upload");
   7787   request.upload_data_stream = &upload_data_stream;
   7788   request.load_flags = 0;
   7789 
   7790   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7791   scoped_ptr<HttpTransaction> trans(
   7792       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7793 
   7794   StaticSocketDataProvider data;
   7795   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7796 
   7797   TestCompletionCallback callback;
   7798   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7799   EXPECT_EQ(ERR_IO_PENDING, rv);
   7800   base::MessageLoop::current()->RunUntilIdle();
   7801 
   7802   // Transaction is pending on request body initialization.
   7803   ASSERT_FALSE(fake_reader->callback().is_null());
   7804 
   7805   // Return Init()'s result after the transaction gets destroyed.
   7806   trans.reset();
   7807   fake_reader->callback().Run(OK);  // Should not crash.
   7808 }
   7809 
   7810 // Tests that changes to Auth realms are treated like auth rejections.
   7811 TEST_P(HttpNetworkTransactionTest, ChangeAuthRealms) {
   7812 
   7813   HttpRequestInfo request;
   7814   request.method = "GET";
   7815   request.url = GURL("http://www.google.com/");
   7816   request.load_flags = 0;
   7817 
   7818   // First transaction will request a resource and receive a Basic challenge
   7819   // with realm="first_realm".
   7820   MockWrite data_writes1[] = {
   7821     MockWrite("GET / HTTP/1.1\r\n"
   7822               "Host: www.google.com\r\n"
   7823               "Connection: keep-alive\r\n"
   7824               "\r\n"),
   7825   };
   7826   MockRead data_reads1[] = {
   7827     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7828              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   7829              "\r\n"),
   7830   };
   7831 
   7832   // After calling trans->RestartWithAuth(), provide an Authentication header
   7833   // for first_realm. The server will reject and provide a challenge with
   7834   // second_realm.
   7835   MockWrite data_writes2[] = {
   7836     MockWrite("GET / HTTP/1.1\r\n"
   7837               "Host: www.google.com\r\n"
   7838               "Connection: keep-alive\r\n"
   7839               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
   7840               "\r\n"),
   7841   };
   7842   MockRead data_reads2[] = {
   7843     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7844              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
   7845              "\r\n"),
   7846   };
   7847 
   7848   // This again fails, and goes back to first_realm. Make sure that the
   7849   // entry is removed from cache.
   7850   MockWrite data_writes3[] = {
   7851     MockWrite("GET / HTTP/1.1\r\n"
   7852               "Host: www.google.com\r\n"
   7853               "Connection: keep-alive\r\n"
   7854               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
   7855               "\r\n"),
   7856   };
   7857   MockRead data_reads3[] = {
   7858     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   7859              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   7860              "\r\n"),
   7861   };
   7862 
   7863   // Try one last time (with the correct password) and get the resource.
   7864   MockWrite data_writes4[] = {
   7865     MockWrite("GET / HTTP/1.1\r\n"
   7866               "Host: www.google.com\r\n"
   7867               "Connection: keep-alive\r\n"
   7868               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
   7869               "\r\n"),
   7870   };
   7871   MockRead data_reads4[] = {
   7872     MockRead("HTTP/1.1 200 OK\r\n"
   7873              "Content-Type: text/html; charset=iso-8859-1\r\n"
   7874              "Content-Length: 5\r\n"
   7875              "\r\n"
   7876              "hello"),
   7877   };
   7878 
   7879   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   7880                                  data_writes1, arraysize(data_writes1));
   7881   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   7882                                  data_writes2, arraysize(data_writes2));
   7883   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   7884                                  data_writes3, arraysize(data_writes3));
   7885   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
   7886                                  data_writes4, arraysize(data_writes4));
   7887   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   7888   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   7889   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   7890   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   7891 
   7892   TestCompletionCallback callback1;
   7893 
   7894   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7895   scoped_ptr<HttpTransaction> trans(
   7896       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7897 
   7898   // Issue the first request with Authorize headers. There should be a
   7899   // password prompt for first_realm waiting to be filled in after the
   7900   // transaction completes.
   7901   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   7902   EXPECT_EQ(ERR_IO_PENDING, rv);
   7903   rv = callback1.WaitForResult();
   7904   EXPECT_EQ(OK, rv);
   7905   const HttpResponseInfo* response = trans->GetResponseInfo();
   7906   ASSERT_TRUE(response != NULL);
   7907   const AuthChallengeInfo* challenge = response->auth_challenge.get();
   7908   ASSERT_FALSE(challenge == NULL);
   7909   EXPECT_FALSE(challenge->is_proxy);
   7910   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7911   EXPECT_EQ("first_realm", challenge->realm);
   7912   EXPECT_EQ("basic", challenge->scheme);
   7913 
   7914   // Issue the second request with an incorrect password. There should be a
   7915   // password prompt for second_realm waiting to be filled in after the
   7916   // transaction completes.
   7917   TestCompletionCallback callback2;
   7918   rv = trans->RestartWithAuth(
   7919       AuthCredentials(kFirst, kBaz), callback2.callback());
   7920   EXPECT_EQ(ERR_IO_PENDING, rv);
   7921   rv = callback2.WaitForResult();
   7922   EXPECT_EQ(OK, rv);
   7923   response = trans->GetResponseInfo();
   7924   ASSERT_TRUE(response != NULL);
   7925   challenge = response->auth_challenge.get();
   7926   ASSERT_FALSE(challenge == NULL);
   7927   EXPECT_FALSE(challenge->is_proxy);
   7928   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7929   EXPECT_EQ("second_realm", challenge->realm);
   7930   EXPECT_EQ("basic", challenge->scheme);
   7931 
   7932   // Issue the third request with another incorrect password. There should be
   7933   // a password prompt for first_realm waiting to be filled in. If the password
   7934   // prompt is not present, it indicates that the HttpAuthCacheEntry for
   7935   // first_realm was not correctly removed.
   7936   TestCompletionCallback callback3;
   7937   rv = trans->RestartWithAuth(
   7938       AuthCredentials(kSecond, kFou), callback3.callback());
   7939   EXPECT_EQ(ERR_IO_PENDING, rv);
   7940   rv = callback3.WaitForResult();
   7941   EXPECT_EQ(OK, rv);
   7942   response = trans->GetResponseInfo();
   7943   ASSERT_TRUE(response != NULL);
   7944   challenge = response->auth_challenge.get();
   7945   ASSERT_FALSE(challenge == NULL);
   7946   EXPECT_FALSE(challenge->is_proxy);
   7947   EXPECT_EQ("www.google.com:80", challenge->challenger.ToString());
   7948   EXPECT_EQ("first_realm", challenge->realm);
   7949   EXPECT_EQ("basic", challenge->scheme);
   7950 
   7951   // Issue the fourth request with the correct password and username.
   7952   TestCompletionCallback callback4;
   7953   rv = trans->RestartWithAuth(
   7954       AuthCredentials(kFirst, kBar), callback4.callback());
   7955   EXPECT_EQ(ERR_IO_PENDING, rv);
   7956   rv = callback4.WaitForResult();
   7957   EXPECT_EQ(OK, rv);
   7958   response = trans->GetResponseInfo();
   7959   ASSERT_TRUE(response != NULL);
   7960   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7961 }
   7962 
   7963 TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
   7964   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   7965   HttpStreamFactory::set_use_alternate_protocols(true);
   7966 
   7967   std::string alternate_protocol_http_header =
   7968       GetAlternateProtocolHttpHeader();
   7969 
   7970   MockRead data_reads[] = {
   7971     MockRead("HTTP/1.1 200 OK\r\n"),
   7972     MockRead(alternate_protocol_http_header.c_str()),
   7973     MockRead("hello world"),
   7974     MockRead(SYNCHRONOUS, OK),
   7975   };
   7976 
   7977   HttpRequestInfo request;
   7978   request.method = "GET";
   7979   request.url = GURL("http://www.google.com/");
   7980   request.load_flags = 0;
   7981 
   7982   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   7983 
   7984   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7985 
   7986   TestCompletionCallback callback;
   7987 
   7988   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7989   scoped_ptr<HttpTransaction> trans(
   7990       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   7991 
   7992   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7993   EXPECT_EQ(ERR_IO_PENDING, rv);
   7994 
   7995   HostPortPair http_host_port_pair("www.google.com", 80);
   7996   const HttpServerProperties& http_server_properties =
   7997       *session->http_server_properties();
   7998   EXPECT_FALSE(
   7999       http_server_properties.HasAlternateProtocol(http_host_port_pair));
   8000 
   8001   EXPECT_EQ(OK, callback.WaitForResult());
   8002 
   8003   const HttpResponseInfo* response = trans->GetResponseInfo();
   8004   ASSERT_TRUE(response != NULL);
   8005   ASSERT_TRUE(response->headers.get() != NULL);
   8006   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8007   EXPECT_FALSE(response->was_fetched_via_spdy);
   8008   EXPECT_FALSE(response->was_npn_negotiated);
   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(http_host_port_pair));
   8015   const PortAlternateProtocolPair alternate =
   8016       http_server_properties.GetAlternateProtocol(http_host_port_pair);
   8017   PortAlternateProtocolPair expected_alternate;
   8018   expected_alternate.port = 443;
   8019   expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam());
   8020   EXPECT_TRUE(expected_alternate.Equals(alternate));
   8021 }
   8022 
   8023 TEST_P(HttpNetworkTransactionTest,
   8024        MarkBrokenAlternateProtocolAndFallback) {
   8025   HttpStreamFactory::set_use_alternate_protocols(true);
   8026 
   8027   HttpRequestInfo request;
   8028   request.method = "GET";
   8029   request.url = GURL("http://www.google.com/");
   8030   request.load_flags = 0;
   8031 
   8032   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8033   StaticSocketDataProvider first_data;
   8034   first_data.set_connect_data(mock_connect);
   8035   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8036 
   8037   MockRead data_reads[] = {
   8038     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8039     MockRead("hello world"),
   8040     MockRead(ASYNC, OK),
   8041   };
   8042   StaticSocketDataProvider second_data(
   8043       data_reads, arraysize(data_reads), NULL, 0);
   8044   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8045 
   8046   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8047 
   8048   base::WeakPtr<HttpServerProperties> http_server_properties =
   8049       session->http_server_properties();
   8050   // Port must be < 1024, or the header will be ignored (since initial port was
   8051   // port 80 (another restricted port).
   8052   http_server_properties->SetAlternateProtocol(
   8053       HostPortPair::FromURL(request.url),
   8054       666 /* port is ignored by MockConnect anyway */,
   8055       AlternateProtocolFromNextProto(GetParam()));
   8056 
   8057   scoped_ptr<HttpTransaction> trans(
   8058       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8059   TestCompletionCallback callback;
   8060 
   8061   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8062   EXPECT_EQ(ERR_IO_PENDING, rv);
   8063   EXPECT_EQ(OK, callback.WaitForResult());
   8064 
   8065   const HttpResponseInfo* response = trans->GetResponseInfo();
   8066   ASSERT_TRUE(response != NULL);
   8067   ASSERT_TRUE(response->headers.get() != NULL);
   8068   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8069 
   8070   std::string response_data;
   8071   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8072   EXPECT_EQ("hello world", response_data);
   8073 
   8074   ASSERT_TRUE(http_server_properties->HasAlternateProtocol(
   8075       HostPortPair::FromURL(request.url)));
   8076   const PortAlternateProtocolPair alternate =
   8077       http_server_properties->GetAlternateProtocol(
   8078           HostPortPair::FromURL(request.url));
   8079   EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
   8080 }
   8081 
   8082 TEST_P(HttpNetworkTransactionTest,
   8083        AlternateProtocolPortRestrictedBlocked) {
   8084   // Ensure that we're not allowed to redirect traffic via an alternate
   8085   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8086   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8087   // other cases.
   8088   HttpStreamFactory::set_use_alternate_protocols(true);
   8089 
   8090   HttpRequestInfo restricted_port_request;
   8091   restricted_port_request.method = "GET";
   8092   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8093   restricted_port_request.load_flags = 0;
   8094 
   8095   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8096   StaticSocketDataProvider first_data;
   8097   first_data.set_connect_data(mock_connect);
   8098   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8099 
   8100   MockRead data_reads[] = {
   8101     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8102     MockRead("hello world"),
   8103     MockRead(ASYNC, OK),
   8104   };
   8105   StaticSocketDataProvider second_data(
   8106       data_reads, arraysize(data_reads), NULL, 0);
   8107   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8108 
   8109   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8110 
   8111   base::WeakPtr<HttpServerProperties> http_server_properties =
   8112       session->http_server_properties();
   8113   const int kUnrestrictedAlternatePort = 1024;
   8114   http_server_properties->SetAlternateProtocol(
   8115       HostPortPair::FromURL(restricted_port_request.url),
   8116       kUnrestrictedAlternatePort,
   8117       AlternateProtocolFromNextProto(GetParam()));
   8118 
   8119   scoped_ptr<HttpTransaction> trans(
   8120       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8121   TestCompletionCallback callback;
   8122 
   8123   int rv = trans->Start(
   8124       &restricted_port_request,
   8125       callback.callback(), BoundNetLog());
   8126   EXPECT_EQ(ERR_IO_PENDING, rv);
   8127   // Invalid change to unrestricted port should fail.
   8128   EXPECT_EQ(ERR_CONNECTION_REFUSED, callback.WaitForResult());
   8129 }
   8130 
   8131 TEST_P(HttpNetworkTransactionTest,
   8132        AlternateProtocolPortRestrictedPermitted) {
   8133   // Ensure that we're allowed to redirect traffic via an alternate
   8134   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8135   // on a restricted port (port < 1024) if we set
   8136   // enable_user_alternate_protocol_ports.
   8137 
   8138   HttpStreamFactory::set_use_alternate_protocols(true);
   8139   session_deps_.enable_user_alternate_protocol_ports = true;
   8140 
   8141   HttpRequestInfo restricted_port_request;
   8142   restricted_port_request.method = "GET";
   8143   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8144   restricted_port_request.load_flags = 0;
   8145 
   8146   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8147   StaticSocketDataProvider first_data;
   8148   first_data.set_connect_data(mock_connect);
   8149   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8150 
   8151   MockRead data_reads[] = {
   8152     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8153     MockRead("hello world"),
   8154     MockRead(ASYNC, OK),
   8155   };
   8156   StaticSocketDataProvider second_data(
   8157       data_reads, arraysize(data_reads), NULL, 0);
   8158   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8159 
   8160   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8161 
   8162   base::WeakPtr<HttpServerProperties> http_server_properties =
   8163       session->http_server_properties();
   8164   const int kUnrestrictedAlternatePort = 1024;
   8165   http_server_properties->SetAlternateProtocol(
   8166       HostPortPair::FromURL(restricted_port_request.url),
   8167       kUnrestrictedAlternatePort,
   8168       AlternateProtocolFromNextProto(GetParam()));
   8169 
   8170   scoped_ptr<HttpTransaction> trans(
   8171       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8172   TestCompletionCallback callback;
   8173 
   8174   EXPECT_EQ(ERR_IO_PENDING, trans->Start(
   8175       &restricted_port_request,
   8176       callback.callback(), BoundNetLog()));
   8177   // Change to unrestricted port should succeed.
   8178   EXPECT_EQ(OK, callback.WaitForResult());
   8179 }
   8180 
   8181 TEST_P(HttpNetworkTransactionTest,
   8182        AlternateProtocolPortRestrictedAllowed) {
   8183   // Ensure that we're not allowed to redirect traffic via an alternate
   8184   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8185   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8186   // other cases.
   8187   HttpStreamFactory::set_use_alternate_protocols(true);
   8188 
   8189   HttpRequestInfo restricted_port_request;
   8190   restricted_port_request.method = "GET";
   8191   restricted_port_request.url = GURL("http://www.google.com:1023/");
   8192   restricted_port_request.load_flags = 0;
   8193 
   8194   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8195   StaticSocketDataProvider first_data;
   8196   first_data.set_connect_data(mock_connect);
   8197   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8198 
   8199   MockRead data_reads[] = {
   8200     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8201     MockRead("hello world"),
   8202     MockRead(ASYNC, OK),
   8203   };
   8204   StaticSocketDataProvider second_data(
   8205       data_reads, arraysize(data_reads), NULL, 0);
   8206   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8207 
   8208   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8209 
   8210   base::WeakPtr<HttpServerProperties> http_server_properties =
   8211       session->http_server_properties();
   8212   const int kRestrictedAlternatePort = 80;
   8213   http_server_properties->SetAlternateProtocol(
   8214       HostPortPair::FromURL(restricted_port_request.url),
   8215       kRestrictedAlternatePort,
   8216       AlternateProtocolFromNextProto(GetParam()));
   8217 
   8218   scoped_ptr<HttpTransaction> trans(
   8219       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8220   TestCompletionCallback callback;
   8221 
   8222   int rv = trans->Start(
   8223       &restricted_port_request,
   8224       callback.callback(), BoundNetLog());
   8225   EXPECT_EQ(ERR_IO_PENDING, rv);
   8226   // Valid change to restricted port should pass.
   8227   EXPECT_EQ(OK, callback.WaitForResult());
   8228 }
   8229 
   8230 TEST_P(HttpNetworkTransactionTest,
   8231        AlternateProtocolPortUnrestrictedAllowed1) {
   8232   // Ensure that we're not allowed to redirect traffic via an alternate
   8233   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8234   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8235   // other cases.
   8236   HttpStreamFactory::set_use_alternate_protocols(true);
   8237 
   8238   HttpRequestInfo unrestricted_port_request;
   8239   unrestricted_port_request.method = "GET";
   8240   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8241   unrestricted_port_request.load_flags = 0;
   8242 
   8243   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8244   StaticSocketDataProvider first_data;
   8245   first_data.set_connect_data(mock_connect);
   8246   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8247 
   8248   MockRead data_reads[] = {
   8249     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8250     MockRead("hello world"),
   8251     MockRead(ASYNC, OK),
   8252   };
   8253   StaticSocketDataProvider second_data(
   8254       data_reads, arraysize(data_reads), NULL, 0);
   8255   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8256 
   8257   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8258 
   8259   base::WeakPtr<HttpServerProperties> http_server_properties =
   8260       session->http_server_properties();
   8261   const int kRestrictedAlternatePort = 80;
   8262   http_server_properties->SetAlternateProtocol(
   8263       HostPortPair::FromURL(unrestricted_port_request.url),
   8264       kRestrictedAlternatePort,
   8265       AlternateProtocolFromNextProto(GetParam()));
   8266 
   8267   scoped_ptr<HttpTransaction> trans(
   8268       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8269   TestCompletionCallback callback;
   8270 
   8271   int rv = trans->Start(
   8272       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8273   EXPECT_EQ(ERR_IO_PENDING, rv);
   8274   // Valid change to restricted port should pass.
   8275   EXPECT_EQ(OK, callback.WaitForResult());
   8276 }
   8277 
   8278 TEST_P(HttpNetworkTransactionTest,
   8279        AlternateProtocolPortUnrestrictedAllowed2) {
   8280   // Ensure that we're not allowed to redirect traffic via an alternate
   8281   // protocol to an unrestricted (port >= 1024) when the original traffic was
   8282   // on a restricted port (port < 1024).  Ensure that we can redirect in all
   8283   // other cases.
   8284   HttpStreamFactory::set_use_alternate_protocols(true);
   8285 
   8286   HttpRequestInfo unrestricted_port_request;
   8287   unrestricted_port_request.method = "GET";
   8288   unrestricted_port_request.url = GURL("http://www.google.com:1024/");
   8289   unrestricted_port_request.load_flags = 0;
   8290 
   8291   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   8292   StaticSocketDataProvider first_data;
   8293   first_data.set_connect_data(mock_connect);
   8294   session_deps_.socket_factory->AddSocketDataProvider(&first_data);
   8295 
   8296   MockRead data_reads[] = {
   8297     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8298     MockRead("hello world"),
   8299     MockRead(ASYNC, OK),
   8300   };
   8301   StaticSocketDataProvider second_data(
   8302       data_reads, arraysize(data_reads), NULL, 0);
   8303   session_deps_.socket_factory->AddSocketDataProvider(&second_data);
   8304 
   8305   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8306 
   8307   base::WeakPtr<HttpServerProperties> http_server_properties =
   8308       session->http_server_properties();
   8309   const int kUnrestrictedAlternatePort = 1024;
   8310   http_server_properties->SetAlternateProtocol(
   8311       HostPortPair::FromURL(unrestricted_port_request.url),
   8312       kUnrestrictedAlternatePort,
   8313       AlternateProtocolFromNextProto(GetParam()));
   8314 
   8315   scoped_ptr<HttpTransaction> trans(
   8316       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8317   TestCompletionCallback callback;
   8318 
   8319   int rv = trans->Start(
   8320       &unrestricted_port_request, callback.callback(), BoundNetLog());
   8321   EXPECT_EQ(ERR_IO_PENDING, rv);
   8322   // Valid change to an unrestricted port should pass.
   8323   EXPECT_EQ(OK, callback.WaitForResult());
   8324 }
   8325 
   8326 TEST_P(HttpNetworkTransactionTest,
   8327        AlternateProtocolUnsafeBlocked) {
   8328   // Ensure that we're not allowed to redirect traffic via an alternate
   8329   // protocol to an unsafe port, and that we resume the second
   8330   // HttpStreamFactoryImpl::Job once the alternate protocol request fails.
   8331   HttpStreamFactory::set_use_alternate_protocols(true);
   8332 
   8333   HttpRequestInfo request;
   8334   request.method = "GET";
   8335   request.url = GURL("http://www.google.com/");
   8336   request.load_flags = 0;
   8337 
   8338   // The alternate protocol request will error out before we attempt to connect,
   8339   // so only the standard HTTP request will try to connect.
   8340   MockRead data_reads[] = {
   8341     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   8342     MockRead("hello world"),
   8343     MockRead(ASYNC, OK),
   8344   };
   8345   StaticSocketDataProvider data(
   8346       data_reads, arraysize(data_reads), NULL, 0);
   8347   session_deps_.socket_factory->AddSocketDataProvider(&data);
   8348 
   8349   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8350 
   8351   base::WeakPtr<HttpServerProperties> http_server_properties =
   8352       session->http_server_properties();
   8353   const int kUnsafePort = 7;
   8354   http_server_properties->SetAlternateProtocol(
   8355       HostPortPair::FromURL(request.url),
   8356       kUnsafePort,
   8357       AlternateProtocolFromNextProto(GetParam()));
   8358 
   8359   scoped_ptr<HttpTransaction> trans(
   8360       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8361   TestCompletionCallback callback;
   8362 
   8363   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8364   EXPECT_EQ(ERR_IO_PENDING, rv);
   8365   // The HTTP request should succeed.
   8366   EXPECT_EQ(OK, callback.WaitForResult());
   8367 
   8368   // Disable alternate protocol before the asserts.
   8369   HttpStreamFactory::set_use_alternate_protocols(false);
   8370 
   8371   const HttpResponseInfo* response = trans->GetResponseInfo();
   8372   ASSERT_TRUE(response != NULL);
   8373   ASSERT_TRUE(response->headers.get() != NULL);
   8374   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8375 
   8376   std::string response_data;
   8377   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8378   EXPECT_EQ("hello world", response_data);
   8379 }
   8380 
   8381 TEST_P(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
   8382   HttpStreamFactory::set_use_alternate_protocols(true);
   8383   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8384 
   8385   HttpRequestInfo request;
   8386   request.method = "GET";
   8387   request.url = GURL("http://www.google.com/");
   8388   request.load_flags = 0;
   8389 
   8390   std::string alternate_protocol_http_header =
   8391       GetAlternateProtocolHttpHeader();
   8392 
   8393   MockRead data_reads[] = {
   8394     MockRead("HTTP/1.1 200 OK\r\n"),
   8395     MockRead(alternate_protocol_http_header.c_str()),
   8396     MockRead("hello world"),
   8397     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8398     MockRead(ASYNC, OK)
   8399   };
   8400 
   8401   StaticSocketDataProvider first_transaction(
   8402       data_reads, arraysize(data_reads), NULL, 0);
   8403   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8404 
   8405   SSLSocketDataProvider ssl(ASYNC, OK);
   8406   ssl.SetNextProto(GetParam());
   8407   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8408 
   8409   scoped_ptr<SpdyFrame> req(
   8410       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8411   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8412 
   8413   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8414   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8415   MockRead spdy_reads[] = {
   8416     CreateMockRead(*resp),
   8417     CreateMockRead(*data),
   8418     MockRead(ASYNC, 0, 0),
   8419   };
   8420 
   8421   DelayedSocketData spdy_data(
   8422       1,  // wait for one write to finish before reading.
   8423       spdy_reads, arraysize(spdy_reads),
   8424       spdy_writes, arraysize(spdy_writes));
   8425   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8426 
   8427   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8428   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8429       NULL, 0, NULL, 0);
   8430   hanging_non_alternate_protocol_socket.set_connect_data(
   8431       never_finishing_connect);
   8432   session_deps_.socket_factory->AddSocketDataProvider(
   8433       &hanging_non_alternate_protocol_socket);
   8434 
   8435   TestCompletionCallback callback;
   8436 
   8437   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8438   scoped_ptr<HttpTransaction> trans(
   8439       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8440 
   8441   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8442   EXPECT_EQ(ERR_IO_PENDING, rv);
   8443   EXPECT_EQ(OK, callback.WaitForResult());
   8444 
   8445   const HttpResponseInfo* response = trans->GetResponseInfo();
   8446   ASSERT_TRUE(response != NULL);
   8447   ASSERT_TRUE(response->headers.get() != NULL);
   8448   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8449 
   8450   std::string response_data;
   8451   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8452   EXPECT_EQ("hello world", response_data);
   8453 
   8454   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8455 
   8456   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8457   EXPECT_EQ(ERR_IO_PENDING, rv);
   8458   EXPECT_EQ(OK, callback.WaitForResult());
   8459 
   8460   response = trans->GetResponseInfo();
   8461   ASSERT_TRUE(response != NULL);
   8462   ASSERT_TRUE(response->headers.get() != NULL);
   8463   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8464   EXPECT_TRUE(response->was_fetched_via_spdy);
   8465   EXPECT_TRUE(response->was_npn_negotiated);
   8466 
   8467   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8468   EXPECT_EQ("hello!", response_data);
   8469 }
   8470 
   8471 TEST_P(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
   8472   HttpStreamFactory::set_use_alternate_protocols(true);
   8473   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8474 
   8475   HttpRequestInfo request;
   8476   request.method = "GET";
   8477   request.url = GURL("http://www.google.com/");
   8478   request.load_flags = 0;
   8479 
   8480   std::string alternate_protocol_http_header =
   8481       GetAlternateProtocolHttpHeader();
   8482 
   8483   MockRead data_reads[] = {
   8484     MockRead("HTTP/1.1 200 OK\r\n"),
   8485     MockRead(alternate_protocol_http_header.c_str()),
   8486     MockRead("hello world"),
   8487     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8488     MockRead(ASYNC, OK),
   8489   };
   8490 
   8491   StaticSocketDataProvider first_transaction(
   8492       data_reads, arraysize(data_reads), NULL, 0);
   8493   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
   8494   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8495 
   8496   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8497   StaticSocketDataProvider hanging_socket(
   8498       NULL, 0, NULL, 0);
   8499   hanging_socket.set_connect_data(never_finishing_connect);
   8500   // Socket 2 and 3 are the hanging Alternate-Protocol and
   8501   // non-Alternate-Protocol jobs from the 2nd transaction.
   8502   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8503   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8504 
   8505   SSLSocketDataProvider ssl(ASYNC, OK);
   8506   ssl.SetNextProto(GetParam());
   8507   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8508 
   8509   scoped_ptr<SpdyFrame> req1(
   8510       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8511   scoped_ptr<SpdyFrame> req2(
   8512       spdy_util_.ConstructSpdyGet(NULL, 0, false, 3, LOWEST, true));
   8513   MockWrite spdy_writes[] = {
   8514     CreateMockWrite(*req1),
   8515     CreateMockWrite(*req2),
   8516   };
   8517   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8518   scoped_ptr<SpdyFrame> data1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8519   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   8520   scoped_ptr<SpdyFrame> data2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   8521   MockRead spdy_reads[] = {
   8522     CreateMockRead(*resp1),
   8523     CreateMockRead(*data1),
   8524     CreateMockRead(*resp2),
   8525     CreateMockRead(*data2),
   8526     MockRead(ASYNC, 0, 0),
   8527   };
   8528 
   8529   DelayedSocketData spdy_data(
   8530       2,  // wait for writes to finish before reading.
   8531       spdy_reads, arraysize(spdy_reads),
   8532       spdy_writes, arraysize(spdy_writes));
   8533   // Socket 4 is the successful Alternate-Protocol for transaction 3.
   8534   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8535 
   8536   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
   8537   session_deps_.socket_factory->AddSocketDataProvider(&hanging_socket);
   8538 
   8539   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8540   TestCompletionCallback callback1;
   8541   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   8542 
   8543   int rv = trans1.Start(&request, callback1.callback(), BoundNetLog());
   8544   EXPECT_EQ(ERR_IO_PENDING, rv);
   8545   EXPECT_EQ(OK, callback1.WaitForResult());
   8546 
   8547   const HttpResponseInfo* response = trans1.GetResponseInfo();
   8548   ASSERT_TRUE(response != NULL);
   8549   ASSERT_TRUE(response->headers.get() != NULL);
   8550   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8551 
   8552   std::string response_data;
   8553   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   8554   EXPECT_EQ("hello world", response_data);
   8555 
   8556   TestCompletionCallback callback2;
   8557   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   8558   rv = trans2.Start(&request, callback2.callback(), BoundNetLog());
   8559   EXPECT_EQ(ERR_IO_PENDING, rv);
   8560 
   8561   TestCompletionCallback callback3;
   8562   HttpNetworkTransaction trans3(DEFAULT_PRIORITY, session.get());
   8563   rv = trans3.Start(&request, callback3.callback(), BoundNetLog());
   8564   EXPECT_EQ(ERR_IO_PENDING, rv);
   8565 
   8566   EXPECT_EQ(OK, callback2.WaitForResult());
   8567   EXPECT_EQ(OK, callback3.WaitForResult());
   8568 
   8569   response = trans2.GetResponseInfo();
   8570   ASSERT_TRUE(response != NULL);
   8571   ASSERT_TRUE(response->headers.get() != NULL);
   8572   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8573   EXPECT_TRUE(response->was_fetched_via_spdy);
   8574   EXPECT_TRUE(response->was_npn_negotiated);
   8575   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   8576   EXPECT_EQ("hello!", response_data);
   8577 
   8578   response = trans3.GetResponseInfo();
   8579   ASSERT_TRUE(response != NULL);
   8580   ASSERT_TRUE(response->headers.get() != NULL);
   8581   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8582   EXPECT_TRUE(response->was_fetched_via_spdy);
   8583   EXPECT_TRUE(response->was_npn_negotiated);
   8584   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
   8585   EXPECT_EQ("hello!", response_data);
   8586 }
   8587 
   8588 TEST_P(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
   8589   HttpStreamFactory::set_use_alternate_protocols(true);
   8590   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8591 
   8592   HttpRequestInfo request;
   8593   request.method = "GET";
   8594   request.url = GURL("http://www.google.com/");
   8595   request.load_flags = 0;
   8596 
   8597   std::string alternate_protocol_http_header =
   8598       GetAlternateProtocolHttpHeader();
   8599 
   8600   MockRead data_reads[] = {
   8601     MockRead("HTTP/1.1 200 OK\r\n"),
   8602     MockRead(alternate_protocol_http_header.c_str()),
   8603     MockRead("hello world"),
   8604     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8605     MockRead(ASYNC, OK),
   8606   };
   8607 
   8608   StaticSocketDataProvider first_transaction(
   8609       data_reads, arraysize(data_reads), NULL, 0);
   8610   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8611 
   8612   SSLSocketDataProvider ssl(ASYNC, OK);
   8613   ssl.SetNextProto(GetParam());
   8614   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8615 
   8616   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8617   StaticSocketDataProvider hanging_alternate_protocol_socket(
   8618       NULL, 0, NULL, 0);
   8619   hanging_alternate_protocol_socket.set_connect_data(
   8620       never_finishing_connect);
   8621   session_deps_.socket_factory->AddSocketDataProvider(
   8622       &hanging_alternate_protocol_socket);
   8623 
   8624   // 2nd request is just a copy of the first one, over HTTP again.
   8625   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8626 
   8627   TestCompletionCallback callback;
   8628 
   8629   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8630   scoped_ptr<HttpTransaction> trans(
   8631       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8632 
   8633   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8634   EXPECT_EQ(ERR_IO_PENDING, rv);
   8635   EXPECT_EQ(OK, callback.WaitForResult());
   8636 
   8637   const HttpResponseInfo* response = trans->GetResponseInfo();
   8638   ASSERT_TRUE(response != NULL);
   8639   ASSERT_TRUE(response->headers.get() != NULL);
   8640   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8641 
   8642   std::string response_data;
   8643   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8644   EXPECT_EQ("hello world", response_data);
   8645 
   8646   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8647 
   8648   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8649   EXPECT_EQ(ERR_IO_PENDING, rv);
   8650   EXPECT_EQ(OK, callback.WaitForResult());
   8651 
   8652   response = trans->GetResponseInfo();
   8653   ASSERT_TRUE(response != NULL);
   8654   ASSERT_TRUE(response->headers.get() != NULL);
   8655   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8656   EXPECT_FALSE(response->was_fetched_via_spdy);
   8657   EXPECT_FALSE(response->was_npn_negotiated);
   8658 
   8659   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8660   EXPECT_EQ("hello world", response_data);
   8661 }
   8662 
   8663 class CapturingProxyResolver : public ProxyResolver {
   8664  public:
   8665   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
   8666   virtual ~CapturingProxyResolver() {}
   8667 
   8668   virtual int GetProxyForURL(const GURL& url,
   8669                              ProxyInfo* results,
   8670                              const CompletionCallback& callback,
   8671                              RequestHandle* request,
   8672                              const BoundNetLog& net_log) OVERRIDE {
   8673     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
   8674                              HostPortPair("myproxy", 80));
   8675     results->UseProxyServer(proxy_server);
   8676     resolved_.push_back(url);
   8677     return OK;
   8678   }
   8679 
   8680   virtual void CancelRequest(RequestHandle request) OVERRIDE {
   8681     NOTREACHED();
   8682   }
   8683 
   8684   virtual LoadState GetLoadState(RequestHandle request) const OVERRIDE {
   8685     NOTREACHED();
   8686     return LOAD_STATE_IDLE;
   8687   }
   8688 
   8689   virtual void CancelSetPacScript() OVERRIDE {
   8690     NOTREACHED();
   8691   }
   8692 
   8693   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
   8694                            const CompletionCallback& /*callback*/) OVERRIDE {
   8695     return OK;
   8696   }
   8697 
   8698   const std::vector<GURL>& resolved() const { return resolved_; }
   8699 
   8700  private:
   8701   std::vector<GURL> resolved_;
   8702 
   8703   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
   8704 };
   8705 
   8706 TEST_P(HttpNetworkTransactionTest,
   8707        UseAlternateProtocolForTunneledNpnSpdy) {
   8708   HttpStreamFactory::set_use_alternate_protocols(true);
   8709   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8710 
   8711   ProxyConfig proxy_config;
   8712   proxy_config.set_auto_detect(true);
   8713   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
   8714 
   8715   CapturingProxyResolver* capturing_proxy_resolver =
   8716       new CapturingProxyResolver();
   8717   session_deps_.proxy_service.reset(new ProxyService(
   8718       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   8719       NULL));
   8720   CapturingNetLog net_log;
   8721   session_deps_.net_log = &net_log;
   8722 
   8723   HttpRequestInfo request;
   8724   request.method = "GET";
   8725   request.url = GURL("http://www.google.com/");
   8726   request.load_flags = 0;
   8727 
   8728   std::string alternate_protocol_http_header =
   8729       GetAlternateProtocolHttpHeader();
   8730 
   8731   MockRead data_reads[] = {
   8732     MockRead("HTTP/1.1 200 OK\r\n"),
   8733     MockRead(alternate_protocol_http_header.c_str()),
   8734     MockRead("hello world"),
   8735     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8736     MockRead(ASYNC, OK),
   8737   };
   8738 
   8739   StaticSocketDataProvider first_transaction(
   8740       data_reads, arraysize(data_reads), NULL, 0);
   8741   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8742 
   8743   SSLSocketDataProvider ssl(ASYNC, OK);
   8744   ssl.SetNextProto(GetParam());
   8745   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8746 
   8747   scoped_ptr<SpdyFrame> req(
   8748       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8749   MockWrite spdy_writes[] = {
   8750     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   8751               "Host: www.google.com\r\n"
   8752               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
   8753     CreateMockWrite(*req),                              // 3
   8754   };
   8755 
   8756   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   8757 
   8758   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8759   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8760   MockRead spdy_reads[] = {
   8761     MockRead(ASYNC, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
   8762     CreateMockRead(*resp.get(), 4),  // 2, 4
   8763     CreateMockRead(*data.get(), 4),  // 5
   8764     MockRead(ASYNC, 0, 0, 4),  // 6
   8765   };
   8766 
   8767   OrderedSocketData spdy_data(
   8768       spdy_reads, arraysize(spdy_reads),
   8769       spdy_writes, arraysize(spdy_writes));
   8770   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8771 
   8772   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   8773   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8774       NULL, 0, NULL, 0);
   8775   hanging_non_alternate_protocol_socket.set_connect_data(
   8776       never_finishing_connect);
   8777   session_deps_.socket_factory->AddSocketDataProvider(
   8778       &hanging_non_alternate_protocol_socket);
   8779 
   8780   TestCompletionCallback callback;
   8781 
   8782   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8783   scoped_ptr<HttpTransaction> trans(
   8784       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8785 
   8786   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8787   EXPECT_EQ(ERR_IO_PENDING, rv);
   8788   EXPECT_EQ(OK, callback.WaitForResult());
   8789 
   8790   const HttpResponseInfo* response = trans->GetResponseInfo();
   8791   ASSERT_TRUE(response != NULL);
   8792   ASSERT_TRUE(response->headers.get() != NULL);
   8793   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8794   EXPECT_FALSE(response->was_fetched_via_spdy);
   8795   EXPECT_FALSE(response->was_npn_negotiated);
   8796 
   8797   std::string response_data;
   8798   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8799   EXPECT_EQ("hello world", response_data);
   8800 
   8801   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8802 
   8803   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8804   EXPECT_EQ(ERR_IO_PENDING, rv);
   8805   EXPECT_EQ(OK, callback.WaitForResult());
   8806 
   8807   response = trans->GetResponseInfo();
   8808   ASSERT_TRUE(response != NULL);
   8809   ASSERT_TRUE(response->headers.get() != NULL);
   8810   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8811   EXPECT_TRUE(response->was_fetched_via_spdy);
   8812   EXPECT_TRUE(response->was_npn_negotiated);
   8813 
   8814   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8815   EXPECT_EQ("hello!", response_data);
   8816   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
   8817   EXPECT_EQ("http://www.google.com/",
   8818             capturing_proxy_resolver->resolved()[0].spec());
   8819   EXPECT_EQ("https://www.google.com/",
   8820             capturing_proxy_resolver->resolved()[1].spec());
   8821 
   8822   LoadTimingInfo load_timing_info;
   8823   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   8824   TestLoadTimingNotReusedWithPac(load_timing_info,
   8825                                  CONNECT_TIMING_HAS_SSL_TIMES);
   8826 }
   8827 
   8828 TEST_P(HttpNetworkTransactionTest,
   8829        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
   8830   HttpStreamFactory::set_use_alternate_protocols(true);
   8831   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   8832 
   8833   HttpRequestInfo request;
   8834   request.method = "GET";
   8835   request.url = GURL("http://www.google.com/");
   8836   request.load_flags = 0;
   8837 
   8838   std::string alternate_protocol_http_header =
   8839       GetAlternateProtocolHttpHeader();
   8840 
   8841   MockRead data_reads[] = {
   8842     MockRead("HTTP/1.1 200 OK\r\n"),
   8843     MockRead(alternate_protocol_http_header.c_str()),
   8844     MockRead("hello world"),
   8845     MockRead(ASYNC, OK),
   8846   };
   8847 
   8848   StaticSocketDataProvider first_transaction(
   8849       data_reads, arraysize(data_reads), NULL, 0);
   8850   session_deps_.socket_factory->AddSocketDataProvider(&first_transaction);
   8851 
   8852   SSLSocketDataProvider ssl(ASYNC, OK);
   8853   ssl.SetNextProto(GetParam());
   8854   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   8855 
   8856   scoped_ptr<SpdyFrame> req(
   8857       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   8858   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8859 
   8860   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   8861   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   8862   MockRead spdy_reads[] = {
   8863     CreateMockRead(*resp),
   8864     CreateMockRead(*data),
   8865     MockRead(ASYNC, 0, 0),
   8866   };
   8867 
   8868   DelayedSocketData spdy_data(
   8869       1,  // wait for one write to finish before reading.
   8870       spdy_reads, arraysize(spdy_reads),
   8871       spdy_writes, arraysize(spdy_writes));
   8872   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   8873 
   8874   TestCompletionCallback callback;
   8875 
   8876   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   8877 
   8878   scoped_ptr<HttpTransaction> trans(
   8879       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8880 
   8881   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8882   EXPECT_EQ(ERR_IO_PENDING, rv);
   8883   EXPECT_EQ(OK, callback.WaitForResult());
   8884 
   8885   const HttpResponseInfo* response = trans->GetResponseInfo();
   8886   ASSERT_TRUE(response != NULL);
   8887   ASSERT_TRUE(response->headers.get() != NULL);
   8888   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8889 
   8890   std::string response_data;
   8891   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8892   EXPECT_EQ("hello world", response_data);
   8893 
   8894   // Set up an initial SpdySession in the pool to reuse.
   8895   HostPortPair host_port_pair("www.google.com", 443);
   8896   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   8897                      kPrivacyModeDisabled);
   8898   base::WeakPtr<SpdySession> spdy_session =
   8899       CreateSecureSpdySession(session, key, BoundNetLog());
   8900 
   8901   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   8902 
   8903   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   8904   EXPECT_EQ(ERR_IO_PENDING, rv);
   8905   EXPECT_EQ(OK, callback.WaitForResult());
   8906 
   8907   response = trans->GetResponseInfo();
   8908   ASSERT_TRUE(response != NULL);
   8909   ASSERT_TRUE(response->headers.get() != NULL);
   8910   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   8911   EXPECT_TRUE(response->was_fetched_via_spdy);
   8912   EXPECT_TRUE(response->was_npn_negotiated);
   8913 
   8914   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   8915   EXPECT_EQ("hello!", response_data);
   8916 }
   8917 
   8918 // GenerateAuthToken is a mighty big test.
   8919 // It tests all permutation of GenerateAuthToken behavior:
   8920 //   - Synchronous and Asynchronous completion.
   8921 //   - OK or error on completion.
   8922 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
   8923 //   - HTTP or HTTPS backend (to include proxy tunneling).
   8924 //   - Non-authenticating and authenticating backend.
   8925 //
   8926 // In all, there are 44 reasonable permuations (for example, if there are
   8927 // problems generating an auth token for an authenticating proxy, we don't
   8928 // need to test all permutations of the backend server).
   8929 //
   8930 // The test proceeds by going over each of the configuration cases, and
   8931 // potentially running up to three rounds in each of the tests. The TestConfig
   8932 // specifies both the configuration for the test as well as the expectations
   8933 // for the results.
   8934 TEST_P(HttpNetworkTransactionTest, GenerateAuthToken) {
   8935   static const char kServer[] = "http://www.example.com";
   8936   static const char kSecureServer[] = "https://www.example.com";
   8937   static const char kProxy[] = "myproxy:70";
   8938   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
   8939 
   8940   enum AuthTiming {
   8941     AUTH_NONE,
   8942     AUTH_SYNC,
   8943     AUTH_ASYNC,
   8944   };
   8945 
   8946   const MockWrite kGet(
   8947       "GET / HTTP/1.1\r\n"
   8948       "Host: www.example.com\r\n"
   8949       "Connection: keep-alive\r\n\r\n");
   8950   const MockWrite kGetProxy(
   8951       "GET http://www.example.com/ HTTP/1.1\r\n"
   8952       "Host: www.example.com\r\n"
   8953       "Proxy-Connection: keep-alive\r\n\r\n");
   8954   const MockWrite kGetAuth(
   8955       "GET / HTTP/1.1\r\n"
   8956       "Host: www.example.com\r\n"
   8957       "Connection: keep-alive\r\n"
   8958       "Authorization: auth_token\r\n\r\n");
   8959   const MockWrite kGetProxyAuth(
   8960       "GET http://www.example.com/ HTTP/1.1\r\n"
   8961       "Host: www.example.com\r\n"
   8962       "Proxy-Connection: keep-alive\r\n"
   8963       "Proxy-Authorization: auth_token\r\n\r\n");
   8964   const MockWrite kGetAuthThroughProxy(
   8965       "GET http://www.example.com/ HTTP/1.1\r\n"
   8966       "Host: www.example.com\r\n"
   8967       "Proxy-Connection: keep-alive\r\n"
   8968       "Authorization: auth_token\r\n\r\n");
   8969   const MockWrite kGetAuthWithProxyAuth(
   8970       "GET http://www.example.com/ HTTP/1.1\r\n"
   8971       "Host: www.example.com\r\n"
   8972       "Proxy-Connection: keep-alive\r\n"
   8973       "Proxy-Authorization: auth_token\r\n"
   8974       "Authorization: auth_token\r\n\r\n");
   8975   const MockWrite kConnect(
   8976       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   8977       "Host: www.example.com\r\n"
   8978       "Proxy-Connection: keep-alive\r\n\r\n");
   8979   const MockWrite kConnectProxyAuth(
   8980       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   8981       "Host: www.example.com\r\n"
   8982       "Proxy-Connection: keep-alive\r\n"
   8983       "Proxy-Authorization: auth_token\r\n\r\n");
   8984 
   8985   const MockRead kSuccess(
   8986       "HTTP/1.1 200 OK\r\n"
   8987       "Content-Type: text/html; charset=iso-8859-1\r\n"
   8988       "Content-Length: 3\r\n\r\n"
   8989       "Yes");
   8990   const MockRead kFailure(
   8991       "Should not be called.");
   8992   const MockRead kServerChallenge(
   8993       "HTTP/1.1 401 Unauthorized\r\n"
   8994       "WWW-Authenticate: Mock realm=server\r\n"
   8995       "Content-Type: text/html; charset=iso-8859-1\r\n"
   8996       "Content-Length: 14\r\n\r\n"
   8997       "Unauthorized\r\n");
   8998   const MockRead kProxyChallenge(
   8999       "HTTP/1.1 407 Unauthorized\r\n"
   9000       "Proxy-Authenticate: Mock realm=proxy\r\n"
   9001       "Proxy-Connection: close\r\n"
   9002       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9003       "Content-Length: 14\r\n\r\n"
   9004       "Unauthorized\r\n");
   9005   const MockRead kProxyConnected(
   9006       "HTTP/1.1 200 Connection Established\r\n\r\n");
   9007 
   9008   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
   9009   // no constructors, but the C++ compiler on Windows warns about
   9010   // unspecified data in compound literals. So, moved to using constructors,
   9011   // and TestRound's created with the default constructor should not be used.
   9012   struct TestRound {
   9013     TestRound()
   9014         : expected_rv(ERR_UNEXPECTED),
   9015           extra_write(NULL),
   9016           extra_read(NULL) {
   9017     }
   9018     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   9019               int expected_rv_arg)
   9020         : write(write_arg),
   9021           read(read_arg),
   9022           expected_rv(expected_rv_arg),
   9023           extra_write(NULL),
   9024           extra_read(NULL) {
   9025     }
   9026     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   9027               int expected_rv_arg, const MockWrite* extra_write_arg,
   9028               const MockRead* extra_read_arg)
   9029         : write(write_arg),
   9030           read(read_arg),
   9031           expected_rv(expected_rv_arg),
   9032           extra_write(extra_write_arg),
   9033           extra_read(extra_read_arg) {
   9034     }
   9035     MockWrite write;
   9036     MockRead read;
   9037     int expected_rv;
   9038     const MockWrite* extra_write;
   9039     const MockRead* extra_read;
   9040   };
   9041 
   9042   static const int kNoSSL = 500;
   9043 
   9044   struct TestConfig {
   9045     const char* proxy_url;
   9046     AuthTiming proxy_auth_timing;
   9047     int proxy_auth_rv;
   9048     const char* server_url;
   9049     AuthTiming server_auth_timing;
   9050     int server_auth_rv;
   9051     int num_auth_rounds;
   9052     int first_ssl_round;
   9053     TestRound rounds[3];
   9054   } test_configs[] = {
   9055     // Non-authenticating HTTP server with a direct connection.
   9056     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   9057       { TestRound(kGet, kSuccess, OK)}},
   9058     // Authenticating HTTP server with a direct connection.
   9059     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9060       { TestRound(kGet, kServerChallenge, OK),
   9061         TestRound(kGetAuth, kSuccess, OK)}},
   9062     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9063       { TestRound(kGet, kServerChallenge, OK),
   9064         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9065     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9066       { TestRound(kGet, kServerChallenge, OK),
   9067         TestRound(kGetAuth, kSuccess, OK)}},
   9068     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9069       { TestRound(kGet, kServerChallenge, OK),
   9070         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9071     // Non-authenticating HTTP server through a non-authenticating proxy.
   9072     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   9073       { TestRound(kGetProxy, kSuccess, OK)}},
   9074     // Authenticating HTTP server through a non-authenticating proxy.
   9075     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   9076       { TestRound(kGetProxy, kServerChallenge, OK),
   9077         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9078     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   9079       { TestRound(kGetProxy, kServerChallenge, OK),
   9080         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9081     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   9082       { TestRound(kGetProxy, kServerChallenge, OK),
   9083         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   9084     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   9085       { TestRound(kGetProxy, kServerChallenge, OK),
   9086         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   9087     // Non-authenticating HTTP server through an authenticating proxy.
   9088     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9089       { TestRound(kGetProxy, kProxyChallenge, OK),
   9090         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9091     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9092       { TestRound(kGetProxy, kProxyChallenge, OK),
   9093         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9094     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9095       { TestRound(kGetProxy, kProxyChallenge, OK),
   9096         TestRound(kGetProxyAuth, kSuccess, OK)}},
   9097     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   9098       { TestRound(kGetProxy, kProxyChallenge, OK),
   9099         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   9100     // Authenticating HTTP server through an authenticating proxy.
   9101     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9102       { TestRound(kGetProxy, kProxyChallenge, OK),
   9103         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9104         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9105     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9106       { TestRound(kGetProxy, kProxyChallenge, OK),
   9107         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9108         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9109     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   9110       { TestRound(kGetProxy, kProxyChallenge, OK),
   9111         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9112         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9113     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   9114       { TestRound(kGetProxy, kProxyChallenge, OK),
   9115         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9116         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9117     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9118       { TestRound(kGetProxy, kProxyChallenge, OK),
   9119         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9120         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9121     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9122       { TestRound(kGetProxy, kProxyChallenge, OK),
   9123         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9124         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9125     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   9126       { TestRound(kGetProxy, kProxyChallenge, OK),
   9127         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9128         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   9129     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   9130       { TestRound(kGetProxy, kProxyChallenge, OK),
   9131         TestRound(kGetProxyAuth, kServerChallenge, OK),
   9132         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   9133     // Non-authenticating HTTPS server with a direct connection.
   9134     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9135       { TestRound(kGet, kSuccess, OK)}},
   9136     // Authenticating HTTPS server with a direct connection.
   9137     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9138       { TestRound(kGet, kServerChallenge, OK),
   9139         TestRound(kGetAuth, kSuccess, OK)}},
   9140     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9141       { TestRound(kGet, kServerChallenge, OK),
   9142         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9143     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9144       { TestRound(kGet, kServerChallenge, OK),
   9145         TestRound(kGetAuth, kSuccess, OK)}},
   9146     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9147       { TestRound(kGet, kServerChallenge, OK),
   9148         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9149     // Non-authenticating HTTPS server with a non-authenticating proxy.
   9150     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   9151       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
   9152     // Authenticating HTTPS server through a non-authenticating proxy.
   9153     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   9154       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9155         TestRound(kGetAuth, kSuccess, OK)}},
   9156     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   9157       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9158         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9159     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   9160       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9161         TestRound(kGetAuth, kSuccess, OK)}},
   9162     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   9163       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   9164         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9165     // Non-Authenticating HTTPS server through an authenticating proxy.
   9166     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9167       { TestRound(kConnect, kProxyChallenge, OK),
   9168         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9169     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9170       { TestRound(kConnect, kProxyChallenge, OK),
   9171         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9172     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   9173       { TestRound(kConnect, kProxyChallenge, OK),
   9174         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   9175     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   9176       { TestRound(kConnect, kProxyChallenge, OK),
   9177         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   9178     // Authenticating HTTPS server through an authenticating proxy.
   9179     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9180       { TestRound(kConnect, kProxyChallenge, OK),
   9181         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9182                   &kGet, &kServerChallenge),
   9183         TestRound(kGetAuth, kSuccess, OK)}},
   9184     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9185       { TestRound(kConnect, kProxyChallenge, OK),
   9186         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9187                   &kGet, &kServerChallenge),
   9188         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9189     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   9190       { TestRound(kConnect, kProxyChallenge, OK),
   9191         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9192                   &kGet, &kServerChallenge),
   9193         TestRound(kGetAuth, kSuccess, OK)}},
   9194     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   9195       { TestRound(kConnect, kProxyChallenge, OK),
   9196         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9197                   &kGet, &kServerChallenge),
   9198         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9199     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9200       { TestRound(kConnect, kProxyChallenge, OK),
   9201         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9202                   &kGet, &kServerChallenge),
   9203         TestRound(kGetAuth, kSuccess, OK)}},
   9204     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9205       { TestRound(kConnect, kProxyChallenge, OK),
   9206         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9207                   &kGet, &kServerChallenge),
   9208         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9209     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   9210       { TestRound(kConnect, kProxyChallenge, OK),
   9211         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9212                   &kGet, &kServerChallenge),
   9213         TestRound(kGetAuth, kSuccess, OK)}},
   9214     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   9215       { TestRound(kConnect, kProxyChallenge, OK),
   9216         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   9217                   &kGet, &kServerChallenge),
   9218         TestRound(kGetAuth, kFailure, kAuthErr)}},
   9219   };
   9220 
   9221   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
   9222     HttpAuthHandlerMock::Factory* auth_factory(
   9223         new HttpAuthHandlerMock::Factory());
   9224     session_deps_.http_auth_handler_factory.reset(auth_factory);
   9225     const TestConfig& test_config = test_configs[i];
   9226 
   9227     // Set up authentication handlers as necessary.
   9228     if (test_config.proxy_auth_timing != AUTH_NONE) {
   9229       for (int n = 0; n < 2; n++) {
   9230         HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9231         std::string auth_challenge = "Mock realm=proxy";
   9232         GURL origin(test_config.proxy_url);
   9233         HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9234                                                auth_challenge.end());
   9235         auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
   9236                                         origin, BoundNetLog());
   9237         auth_handler->SetGenerateExpectation(
   9238             test_config.proxy_auth_timing == AUTH_ASYNC,
   9239             test_config.proxy_auth_rv);
   9240         auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   9241       }
   9242     }
   9243     if (test_config.server_auth_timing != AUTH_NONE) {
   9244       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9245       std::string auth_challenge = "Mock realm=server";
   9246       GURL origin(test_config.server_url);
   9247       HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9248                                              auth_challenge.end());
   9249       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9250                                       origin, BoundNetLog());
   9251       auth_handler->SetGenerateExpectation(
   9252           test_config.server_auth_timing == AUTH_ASYNC,
   9253           test_config.server_auth_rv);
   9254       auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9255     }
   9256     if (test_config.proxy_url) {
   9257       session_deps_.proxy_service.reset(
   9258           ProxyService::CreateFixed(test_config.proxy_url));
   9259     } else {
   9260       session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9261     }
   9262 
   9263     HttpRequestInfo request;
   9264     request.method = "GET";
   9265     request.url = GURL(test_config.server_url);
   9266     request.load_flags = 0;
   9267 
   9268     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9269     HttpNetworkTransaction trans(DEFAULT_PRIORITY, session);
   9270 
   9271     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
   9272       const TestRound& read_write_round = test_config.rounds[round];
   9273 
   9274       // Set up expected reads and writes.
   9275       MockRead reads[2];
   9276       reads[0] = read_write_round.read;
   9277       size_t length_reads = 1;
   9278       if (read_write_round.extra_read) {
   9279         reads[1] = *read_write_round.extra_read;
   9280         length_reads = 2;
   9281       }
   9282 
   9283       MockWrite writes[2];
   9284       writes[0] = read_write_round.write;
   9285       size_t length_writes = 1;
   9286       if (read_write_round.extra_write) {
   9287         writes[1] = *read_write_round.extra_write;
   9288         length_writes = 2;
   9289       }
   9290       StaticSocketDataProvider data_provider(
   9291           reads, length_reads, writes, length_writes);
   9292       session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9293 
   9294       // Add an SSL sequence if necessary.
   9295       SSLSocketDataProvider ssl_socket_data_provider(SYNCHRONOUS, OK);
   9296       if (round >= test_config.first_ssl_round)
   9297         session_deps_.socket_factory->AddSSLSocketDataProvider(
   9298             &ssl_socket_data_provider);
   9299 
   9300       // Start or restart the transaction.
   9301       TestCompletionCallback callback;
   9302       int rv;
   9303       if (round == 0) {
   9304         rv = trans.Start(&request, callback.callback(), BoundNetLog());
   9305       } else {
   9306         rv = trans.RestartWithAuth(
   9307             AuthCredentials(kFoo, kBar), callback.callback());
   9308       }
   9309       if (rv == ERR_IO_PENDING)
   9310         rv = callback.WaitForResult();
   9311 
   9312       // Compare results with expected data.
   9313       EXPECT_EQ(read_write_round.expected_rv, rv);
   9314       const HttpResponseInfo* response = trans.GetResponseInfo();
   9315       if (read_write_round.expected_rv == OK) {
   9316         ASSERT_TRUE(response != NULL);
   9317       } else {
   9318         EXPECT_TRUE(response == NULL);
   9319         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
   9320         continue;
   9321       }
   9322       if (round + 1 < test_config.num_auth_rounds) {
   9323         EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9324       } else {
   9325         EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9326       }
   9327     }
   9328   }
   9329 }
   9330 
   9331 TEST_P(HttpNetworkTransactionTest, MultiRoundAuth) {
   9332   // Do multi-round authentication and make sure it works correctly.
   9333   HttpAuthHandlerMock::Factory* auth_factory(
   9334       new HttpAuthHandlerMock::Factory());
   9335   session_deps_.http_auth_handler_factory.reset(auth_factory);
   9336   session_deps_.proxy_service.reset(ProxyService::CreateDirect());
   9337   session_deps_.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
   9338   session_deps_.host_resolver->set_synchronous_mode(true);
   9339 
   9340   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   9341   auth_handler->set_connection_based(true);
   9342   std::string auth_challenge = "Mock realm=server";
   9343   GURL origin("http://www.example.com");
   9344   HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   9345                                          auth_challenge.end());
   9346   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   9347                                   origin, BoundNetLog());
   9348   auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_SERVER);
   9349 
   9350   int rv = OK;
   9351   const HttpResponseInfo* response = NULL;
   9352   HttpRequestInfo request;
   9353   request.method = "GET";
   9354   request.url = origin;
   9355   request.load_flags = 0;
   9356 
   9357   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9358 
   9359   // Use a TCP Socket Pool with only one connection per group. This is used
   9360   // to validate that the TCP socket is not released to the pool between
   9361   // each round of multi-round authentication.
   9362   HttpNetworkSessionPeer session_peer(session);
   9363   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
   9364   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
   9365       50,  // Max sockets for pool
   9366       1,   // Max sockets per group
   9367       &transport_pool_histograms,
   9368       session_deps_.host_resolver.get(),
   9369       session_deps_.socket_factory.get(),
   9370       session_deps_.net_log);
   9371   scoped_ptr<MockClientSocketPoolManager> mock_pool_manager(
   9372       new MockClientSocketPoolManager);
   9373   mock_pool_manager->SetTransportSocketPool(transport_pool);
   9374   session_peer.SetClientSocketPoolManager(
   9375       mock_pool_manager.PassAs<ClientSocketPoolManager>());
   9376 
   9377   scoped_ptr<HttpTransaction> trans(
   9378       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9379   TestCompletionCallback callback;
   9380 
   9381   const MockWrite kGet(
   9382       "GET / HTTP/1.1\r\n"
   9383       "Host: www.example.com\r\n"
   9384       "Connection: keep-alive\r\n\r\n");
   9385   const MockWrite kGetAuth(
   9386       "GET / HTTP/1.1\r\n"
   9387       "Host: www.example.com\r\n"
   9388       "Connection: keep-alive\r\n"
   9389       "Authorization: auth_token\r\n\r\n");
   9390 
   9391   const MockRead kServerChallenge(
   9392       "HTTP/1.1 401 Unauthorized\r\n"
   9393       "WWW-Authenticate: Mock realm=server\r\n"
   9394       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9395       "Content-Length: 14\r\n\r\n"
   9396       "Unauthorized\r\n");
   9397   const MockRead kSuccess(
   9398       "HTTP/1.1 200 OK\r\n"
   9399       "Content-Type: text/html; charset=iso-8859-1\r\n"
   9400       "Content-Length: 3\r\n\r\n"
   9401       "Yes");
   9402 
   9403   MockWrite writes[] = {
   9404     // First round
   9405     kGet,
   9406     // Second round
   9407     kGetAuth,
   9408     // Third round
   9409     kGetAuth,
   9410     // Fourth round
   9411     kGetAuth,
   9412     // Competing request
   9413     kGet,
   9414   };
   9415   MockRead reads[] = {
   9416     // First round
   9417     kServerChallenge,
   9418     // Second round
   9419     kServerChallenge,
   9420     // Third round
   9421     kServerChallenge,
   9422     // Fourth round
   9423     kSuccess,
   9424     // Competing response
   9425     kSuccess,
   9426   };
   9427   StaticSocketDataProvider data_provider(reads, arraysize(reads),
   9428                                          writes, arraysize(writes));
   9429   session_deps_.socket_factory->AddSocketDataProvider(&data_provider);
   9430 
   9431   const char* const kSocketGroup = "www.example.com:80";
   9432 
   9433   // First round of authentication.
   9434   auth_handler->SetGenerateExpectation(false, OK);
   9435   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9436   if (rv == ERR_IO_PENDING)
   9437     rv = callback.WaitForResult();
   9438   EXPECT_EQ(OK, rv);
   9439   response = trans->GetResponseInfo();
   9440   ASSERT_TRUE(response != NULL);
   9441   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   9442   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9443 
   9444   // In between rounds, another request comes in for the same domain.
   9445   // It should not be able to grab the TCP socket that trans has already
   9446   // claimed.
   9447   scoped_ptr<HttpTransaction> trans_compete(
   9448       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9449   TestCompletionCallback callback_compete;
   9450   rv = trans_compete->Start(
   9451       &request, callback_compete.callback(), BoundNetLog());
   9452   EXPECT_EQ(ERR_IO_PENDING, rv);
   9453   // callback_compete.WaitForResult at this point would stall forever,
   9454   // since the HttpNetworkTransaction does not release the request back to
   9455   // the pool until after authentication completes.
   9456 
   9457   // Second round of authentication.
   9458   auth_handler->SetGenerateExpectation(false, OK);
   9459   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar), callback.callback());
   9460   if (rv == ERR_IO_PENDING)
   9461     rv = callback.WaitForResult();
   9462   EXPECT_EQ(OK, rv);
   9463   response = trans->GetResponseInfo();
   9464   ASSERT_TRUE(response != NULL);
   9465   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9466   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9467 
   9468   // Third round of authentication.
   9469   auth_handler->SetGenerateExpectation(false, OK);
   9470   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9471   if (rv == ERR_IO_PENDING)
   9472     rv = callback.WaitForResult();
   9473   EXPECT_EQ(OK, rv);
   9474   response = trans->GetResponseInfo();
   9475   ASSERT_TRUE(response != NULL);
   9476   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9477   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9478 
   9479   // Fourth round of authentication, which completes successfully.
   9480   auth_handler->SetGenerateExpectation(false, OK);
   9481   rv = trans->RestartWithAuth(AuthCredentials(), callback.callback());
   9482   if (rv == ERR_IO_PENDING)
   9483     rv = callback.WaitForResult();
   9484   EXPECT_EQ(OK, rv);
   9485   response = trans->GetResponseInfo();
   9486   ASSERT_TRUE(response != NULL);
   9487   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   9488   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9489 
   9490   // Read the body since the fourth round was successful. This will also
   9491   // release the socket back to the pool.
   9492   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
   9493   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9494   if (rv == ERR_IO_PENDING)
   9495     rv = callback.WaitForResult();
   9496   EXPECT_EQ(3, rv);
   9497   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   9498   EXPECT_EQ(0, rv);
   9499   // There are still 0 idle sockets, since the trans_compete transaction
   9500   // will be handed it immediately after trans releases it to the group.
   9501   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9502 
   9503   // The competing request can now finish. Wait for the headers and then
   9504   // read the body.
   9505   rv = callback_compete.WaitForResult();
   9506   EXPECT_EQ(OK, rv);
   9507   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9508   if (rv == ERR_IO_PENDING)
   9509     rv = callback.WaitForResult();
   9510   EXPECT_EQ(3, rv);
   9511   rv = trans_compete->Read(io_buf.get(), io_buf->size(), callback.callback());
   9512   EXPECT_EQ(0, rv);
   9513 
   9514   // Finally, the socket is released to the group.
   9515   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   9516 }
   9517 
   9518 // This tests the case that a request is issued via http instead of spdy after
   9519 // npn is negotiated.
   9520 TEST_P(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
   9521   HttpStreamFactory::set_use_alternate_protocols(true);
   9522   std::vector<NextProto> next_protos;
   9523   next_protos.push_back(kProtoHTTP11);
   9524   HttpStreamFactory::SetNextProtos(next_protos);
   9525   HttpRequestInfo request;
   9526   request.method = "GET";
   9527   request.url = GURL("https://www.google.com/");
   9528   request.load_flags = 0;
   9529 
   9530   MockWrite data_writes[] = {
   9531     MockWrite("GET / HTTP/1.1\r\n"
   9532               "Host: www.google.com\r\n"
   9533               "Connection: keep-alive\r\n\r\n"),
   9534   };
   9535 
   9536   std::string alternate_protocol_http_header =
   9537       GetAlternateProtocolHttpHeader();
   9538 
   9539   MockRead data_reads[] = {
   9540     MockRead("HTTP/1.1 200 OK\r\n"),
   9541     MockRead(alternate_protocol_http_header.c_str()),
   9542     MockRead("hello world"),
   9543     MockRead(SYNCHRONOUS, OK),
   9544   };
   9545 
   9546   SSLSocketDataProvider ssl(ASYNC, OK);
   9547   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   9548   ssl.next_proto = "http/1.1";
   9549   ssl.protocol_negotiated = kProtoHTTP11;
   9550 
   9551   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9552 
   9553   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   9554                                 data_writes, arraysize(data_writes));
   9555   session_deps_.socket_factory->AddSocketDataProvider(&data);
   9556 
   9557   TestCompletionCallback callback;
   9558 
   9559   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9560   scoped_ptr<HttpTransaction> trans(
   9561       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9562 
   9563   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9564 
   9565   EXPECT_EQ(ERR_IO_PENDING, rv);
   9566   EXPECT_EQ(OK, callback.WaitForResult());
   9567 
   9568   const HttpResponseInfo* response = trans->GetResponseInfo();
   9569   ASSERT_TRUE(response != NULL);
   9570   ASSERT_TRUE(response->headers.get() != NULL);
   9571   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   9572 
   9573   std::string response_data;
   9574   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   9575   EXPECT_EQ("hello world", response_data);
   9576 
   9577   EXPECT_FALSE(response->was_fetched_via_spdy);
   9578   EXPECT_TRUE(response->was_npn_negotiated);
   9579 }
   9580 
   9581 TEST_P(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
   9582   // Simulate the SSL handshake completing with an NPN negotiation
   9583   // followed by an immediate server closing of the socket.
   9584   // Fix crash:  http://crbug.com/46369
   9585   HttpStreamFactory::set_use_alternate_protocols(true);
   9586   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   9587 
   9588   HttpRequestInfo request;
   9589   request.method = "GET";
   9590   request.url = GURL("https://www.google.com/");
   9591   request.load_flags = 0;
   9592 
   9593   SSLSocketDataProvider ssl(ASYNC, OK);
   9594   ssl.SetNextProto(GetParam());
   9595   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9596 
   9597   scoped_ptr<SpdyFrame> req(
   9598       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9599   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   9600 
   9601   MockRead spdy_reads[] = {
   9602     MockRead(SYNCHRONOUS, 0, 0)   // Not async - return 0 immediately.
   9603   };
   9604 
   9605   DelayedSocketData spdy_data(
   9606       0,  // don't wait in this case, immediate hangup.
   9607       spdy_reads, arraysize(spdy_reads),
   9608       spdy_writes, arraysize(spdy_writes));
   9609   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   9610 
   9611   TestCompletionCallback callback;
   9612 
   9613   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9614   scoped_ptr<HttpTransaction> trans(
   9615       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9616 
   9617   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   9618   EXPECT_EQ(ERR_IO_PENDING, rv);
   9619   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
   9620 }
   9621 
   9622 // A subclass of HttpAuthHandlerMock that records the request URL when
   9623 // it gets it. This is needed since the auth handler may get destroyed
   9624 // before we get a chance to query it.
   9625 class UrlRecordingHttpAuthHandlerMock : public HttpAuthHandlerMock {
   9626  public:
   9627   explicit UrlRecordingHttpAuthHandlerMock(GURL* url) : url_(url) {}
   9628 
   9629   virtual ~UrlRecordingHttpAuthHandlerMock() {}
   9630 
   9631  protected:
   9632   virtual int GenerateAuthTokenImpl(const AuthCredentials* credentials,
   9633                                     const HttpRequestInfo* request,
   9634                                     const CompletionCallback& callback,
   9635                                     std::string* auth_token) OVERRIDE {
   9636     *url_ = request->url;
   9637     return HttpAuthHandlerMock::GenerateAuthTokenImpl(
   9638         credentials, request, callback, auth_token);
   9639   }
   9640 
   9641  private:
   9642   GURL* url_;
   9643 };
   9644 
   9645 TEST_P(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
   9646   // This test ensures that the URL passed into the proxy is upgraded
   9647   // to https when doing an Alternate Protocol upgrade.
   9648   HttpStreamFactory::set_use_alternate_protocols(true);
   9649   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   9650 
   9651   session_deps_.proxy_service.reset(
   9652       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9653   CapturingNetLog net_log;
   9654   session_deps_.net_log = &net_log;
   9655   GURL request_url;
   9656   {
   9657     HttpAuthHandlerMock::Factory* auth_factory =
   9658         new HttpAuthHandlerMock::Factory();
   9659     UrlRecordingHttpAuthHandlerMock* auth_handler =
   9660         new UrlRecordingHttpAuthHandlerMock(&request_url);
   9661     auth_factory->AddMockHandler(auth_handler, HttpAuth::AUTH_PROXY);
   9662     auth_factory->set_do_init_from_challenge(true);
   9663     session_deps_.http_auth_handler_factory.reset(auth_factory);
   9664   }
   9665 
   9666   HttpRequestInfo request;
   9667   request.method = "GET";
   9668   request.url = GURL("http://www.google.com");
   9669   request.load_flags = 0;
   9670 
   9671   // First round goes unauthenticated through the proxy.
   9672   MockWrite data_writes_1[] = {
   9673     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   9674               "Host: www.google.com\r\n"
   9675               "Proxy-Connection: keep-alive\r\n"
   9676               "\r\n"),
   9677   };
   9678   MockRead data_reads_1[] = {
   9679     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9680     MockRead("HTTP/1.1 200 OK\r\n"
   9681              "Alternate-Protocol: 443:npn-spdy/2\r\n"
   9682              "Proxy-Connection: close\r\n"
   9683              "\r\n"),
   9684   };
   9685   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
   9686                                   data_writes_1, arraysize(data_writes_1));
   9687 
   9688   // Second round tries to tunnel to www.google.com due to the
   9689   // Alternate-Protocol announcement in the first round. It fails due
   9690   // to a proxy authentication challenge.
   9691   // After the failure, a tunnel is established to www.google.com using
   9692   // Proxy-Authorization headers. There is then a SPDY request round.
   9693   //
   9694   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
   9695   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
   9696   // does a Disconnect and Connect on the same socket, rather than trying
   9697   // to obtain a new one.
   9698   //
   9699   // NOTE: Originally, the proxy response to the second CONNECT request
   9700   // simply returned another 407 so the unit test could skip the SSL connection
   9701   // establishment and SPDY framing issues. Alas, the
   9702   // retry-http-when-alternate-protocol fails logic kicks in, which was more
   9703   // complicated to set up expectations for than the SPDY session.
   9704 
   9705   scoped_ptr<SpdyFrame> req(
   9706       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, true));
   9707   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   9708   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   9709 
   9710   MockWrite data_writes_2[] = {
   9711     // First connection attempt without Proxy-Authorization.
   9712     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9713               "Host: www.google.com\r\n"
   9714               "Proxy-Connection: keep-alive\r\n"
   9715               "\r\n"),
   9716 
   9717     // Second connection attempt with Proxy-Authorization.
   9718     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9719               "Host: www.google.com\r\n"
   9720               "Proxy-Connection: keep-alive\r\n"
   9721               "Proxy-Authorization: auth_token\r\n"
   9722               "\r\n"),
   9723 
   9724     // SPDY request
   9725     CreateMockWrite(*req),
   9726   };
   9727   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
   9728                                          "Proxy-Authenticate: Mock\r\n"
   9729                                          "Proxy-Connection: close\r\n"
   9730                                          "\r\n");
   9731   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   9732   MockRead data_reads_2[] = {
   9733     // First connection attempt fails
   9734     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
   9735     MockRead(ASYNC, kRejectConnectResponse,
   9736              arraysize(kRejectConnectResponse) - 1, 1),
   9737 
   9738     // Second connection attempt passes
   9739     MockRead(ASYNC, kAcceptConnectResponse,
   9740              arraysize(kAcceptConnectResponse) -1, 4),
   9741 
   9742     // SPDY response
   9743     CreateMockRead(*resp.get(), 6),
   9744     CreateMockRead(*data.get(), 6),
   9745     MockRead(ASYNC, 0, 0, 6),
   9746   };
   9747   OrderedSocketData data_2(
   9748       data_reads_2, arraysize(data_reads_2),
   9749       data_writes_2, arraysize(data_writes_2));
   9750 
   9751   SSLSocketDataProvider ssl(ASYNC, OK);
   9752   ssl.SetNextProto(GetParam());
   9753 
   9754   MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
   9755   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   9756       NULL, 0, NULL, 0);
   9757   hanging_non_alternate_protocol_socket.set_connect_data(
   9758       never_finishing_connect);
   9759 
   9760   session_deps_.socket_factory->AddSocketDataProvider(&data_1);
   9761   session_deps_.socket_factory->AddSocketDataProvider(&data_2);
   9762   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9763   session_deps_.socket_factory->AddSocketDataProvider(
   9764       &hanging_non_alternate_protocol_socket);
   9765   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9766 
   9767   // First round should work and provide the Alternate-Protocol state.
   9768   TestCompletionCallback callback_1;
   9769   scoped_ptr<HttpTransaction> trans_1(
   9770       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9771   int rv = trans_1->Start(&request, callback_1.callback(), BoundNetLog());
   9772   EXPECT_EQ(ERR_IO_PENDING, rv);
   9773   EXPECT_EQ(OK, callback_1.WaitForResult());
   9774 
   9775   // Second round should attempt a tunnel connect and get an auth challenge.
   9776   TestCompletionCallback callback_2;
   9777   scoped_ptr<HttpTransaction> trans_2(
   9778       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9779   rv = trans_2->Start(&request, callback_2.callback(), BoundNetLog());
   9780   EXPECT_EQ(ERR_IO_PENDING, rv);
   9781   EXPECT_EQ(OK, callback_2.WaitForResult());
   9782   const HttpResponseInfo* response = trans_2->GetResponseInfo();
   9783   ASSERT_TRUE(response != NULL);
   9784   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   9785 
   9786   // Restart with auth. Tunnel should work and response received.
   9787   TestCompletionCallback callback_3;
   9788   rv = trans_2->RestartWithAuth(
   9789       AuthCredentials(kFoo, kBar), callback_3.callback());
   9790   EXPECT_EQ(ERR_IO_PENDING, rv);
   9791   EXPECT_EQ(OK, callback_3.WaitForResult());
   9792 
   9793   // After all that work, these two lines (or actually, just the scheme) are
   9794   // what this test is all about. Make sure it happens correctly.
   9795   EXPECT_EQ("https", request_url.scheme());
   9796   EXPECT_EQ("www.google.com", request_url.host());
   9797 
   9798   LoadTimingInfo load_timing_info;
   9799   EXPECT_TRUE(trans_2->GetLoadTimingInfo(&load_timing_info));
   9800   TestLoadTimingNotReusedWithPac(load_timing_info,
   9801                                  CONNECT_TIMING_HAS_SSL_TIMES);
   9802 }
   9803 
   9804 // Test that if we cancel the transaction as the connection is completing, that
   9805 // everything tears down correctly.
   9806 TEST_P(HttpNetworkTransactionTest, SimpleCancel) {
   9807   // Setup everything about the connection to complete synchronously, so that
   9808   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
   9809   // for is the callback from the HttpStreamRequest.
   9810   // Then cancel the transaction.
   9811   // Verify that we don't crash.
   9812   MockConnect mock_connect(SYNCHRONOUS, OK);
   9813   MockRead data_reads[] = {
   9814     MockRead(SYNCHRONOUS, "HTTP/1.0 200 OK\r\n\r\n"),
   9815     MockRead(SYNCHRONOUS, "hello world"),
   9816     MockRead(SYNCHRONOUS, OK),
   9817   };
   9818 
   9819   HttpRequestInfo request;
   9820   request.method = "GET";
   9821   request.url = GURL("http://www.google.com/");
   9822   request.load_flags = 0;
   9823 
   9824   session_deps_.host_resolver->set_synchronous_mode(true);
   9825   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9826   scoped_ptr<HttpTransaction> trans(
   9827       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   9828 
   9829   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   9830   data.set_connect_data(mock_connect);
   9831   session_deps_.socket_factory->AddSocketDataProvider(&data);
   9832 
   9833   TestCompletionCallback callback;
   9834 
   9835   CapturingBoundNetLog log;
   9836   int rv = trans->Start(&request, callback.callback(), log.bound());
   9837   EXPECT_EQ(ERR_IO_PENDING, rv);
   9838   trans.reset();  // Cancel the transaction here.
   9839 
   9840   base::MessageLoop::current()->RunUntilIdle();
   9841 }
   9842 
   9843 // Test a basic GET request through a proxy.
   9844 TEST_P(HttpNetworkTransactionTest, ProxyGet) {
   9845   session_deps_.proxy_service.reset(
   9846       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9847   CapturingBoundNetLog log;
   9848   session_deps_.net_log = log.bound().net_log();
   9849   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9850 
   9851   HttpRequestInfo request;
   9852   request.method = "GET";
   9853   request.url = GURL("http://www.google.com/");
   9854 
   9855   MockWrite data_writes1[] = {
   9856     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   9857               "Host: www.google.com\r\n"
   9858               "Proxy-Connection: keep-alive\r\n\r\n"),
   9859   };
   9860 
   9861   MockRead data_reads1[] = {
   9862     MockRead("HTTP/1.1 200 OK\r\n"),
   9863     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   9864     MockRead("Content-Length: 100\r\n\r\n"),
   9865     MockRead(SYNCHRONOUS, OK),
   9866   };
   9867 
   9868   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   9869                                  data_writes1, arraysize(data_writes1));
   9870   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   9871 
   9872   TestCompletionCallback callback1;
   9873 
   9874   scoped_ptr<HttpTransaction> trans(
   9875       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9876 
   9877   int rv = trans->Start(&request, callback1.callback(), log.bound());
   9878   EXPECT_EQ(ERR_IO_PENDING, rv);
   9879 
   9880   rv = callback1.WaitForResult();
   9881   EXPECT_EQ(OK, rv);
   9882 
   9883   const HttpResponseInfo* response = trans->GetResponseInfo();
   9884   ASSERT_TRUE(response != NULL);
   9885 
   9886   EXPECT_TRUE(response->headers->IsKeepAlive());
   9887   EXPECT_EQ(200, response->headers->response_code());
   9888   EXPECT_EQ(100, response->headers->GetContentLength());
   9889   EXPECT_TRUE(response->was_fetched_via_proxy);
   9890   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   9891 
   9892   LoadTimingInfo load_timing_info;
   9893   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   9894   TestLoadTimingNotReusedWithPac(load_timing_info,
   9895                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   9896 }
   9897 
   9898 // Test a basic HTTPS GET request through a proxy.
   9899 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGet) {
   9900   session_deps_.proxy_service.reset(
   9901       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   9902   CapturingBoundNetLog log;
   9903   session_deps_.net_log = log.bound().net_log();
   9904   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9905 
   9906   HttpRequestInfo request;
   9907   request.method = "GET";
   9908   request.url = GURL("https://www.google.com/");
   9909 
   9910   // Since we have proxy, should try to establish tunnel.
   9911   MockWrite data_writes1[] = {
   9912     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9913               "Host: www.google.com\r\n"
   9914               "Proxy-Connection: keep-alive\r\n\r\n"),
   9915 
   9916     MockWrite("GET / HTTP/1.1\r\n"
   9917               "Host: www.google.com\r\n"
   9918               "Connection: keep-alive\r\n\r\n"),
   9919   };
   9920 
   9921   MockRead data_reads1[] = {
   9922     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   9923 
   9924     MockRead("HTTP/1.1 200 OK\r\n"),
   9925     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   9926     MockRead("Content-Length: 100\r\n\r\n"),
   9927     MockRead(SYNCHRONOUS, OK),
   9928   };
   9929 
   9930   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   9931                                  data_writes1, arraysize(data_writes1));
   9932   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   9933   SSLSocketDataProvider ssl(ASYNC, OK);
   9934   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   9935 
   9936   TestCompletionCallback callback1;
   9937 
   9938   scoped_ptr<HttpTransaction> trans(
   9939       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   9940 
   9941   int rv = trans->Start(&request, callback1.callback(), log.bound());
   9942   EXPECT_EQ(ERR_IO_PENDING, rv);
   9943 
   9944   rv = callback1.WaitForResult();
   9945   EXPECT_EQ(OK, rv);
   9946   net::CapturingNetLog::CapturedEntryList entries;
   9947   log.GetEntries(&entries);
   9948   size_t pos = ExpectLogContainsSomewhere(
   9949       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   9950       NetLog::PHASE_NONE);
   9951   ExpectLogContainsSomewhere(
   9952       entries, pos,
   9953       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   9954       NetLog::PHASE_NONE);
   9955 
   9956   const HttpResponseInfo* response = trans->GetResponseInfo();
   9957   ASSERT_TRUE(response != NULL);
   9958 
   9959   EXPECT_TRUE(response->headers->IsKeepAlive());
   9960   EXPECT_EQ(200, response->headers->response_code());
   9961   EXPECT_EQ(100, response->headers->GetContentLength());
   9962   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   9963   EXPECT_TRUE(response->was_fetched_via_proxy);
   9964 
   9965   LoadTimingInfo load_timing_info;
   9966   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   9967   TestLoadTimingNotReusedWithPac(load_timing_info,
   9968                                  CONNECT_TIMING_HAS_SSL_TIMES);
   9969 }
   9970 
   9971 // Test a basic HTTPS GET request through a proxy, but the server hangs up
   9972 // while establishing the tunnel.
   9973 TEST_P(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
   9974   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   9975   CapturingBoundNetLog log;
   9976   session_deps_.net_log = log.bound().net_log();
   9977   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   9978 
   9979   HttpRequestInfo request;
   9980   request.method = "GET";
   9981   request.url = GURL("https://www.google.com/");
   9982 
   9983   // Since we have proxy, should try to establish tunnel.
   9984   MockWrite data_writes1[] = {
   9985     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   9986               "Host: www.google.com\r\n"
   9987               "Proxy-Connection: keep-alive\r\n\r\n"),
   9988 
   9989     MockWrite("GET / HTTP/1.1\r\n"
   9990               "Host: www.google.com\r\n"
   9991               "Connection: keep-alive\r\n\r\n"),
   9992   };
   9993 
   9994   MockRead data_reads1[] = {
   9995     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   9996     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   9997     MockRead(ASYNC, 0, 0),  // EOF
   9998   };
   9999 
   10000   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   10001                                  data_writes1, arraysize(data_writes1));
   10002   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10003   SSLSocketDataProvider ssl(ASYNC, OK);
   10004   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10005 
   10006   TestCompletionCallback callback1;
   10007 
   10008   scoped_ptr<HttpTransaction> trans(
   10009       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10010 
   10011   int rv = trans->Start(&request, callback1.callback(), log.bound());
   10012   EXPECT_EQ(ERR_IO_PENDING, rv);
   10013 
   10014   rv = callback1.WaitForResult();
   10015   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   10016   net::CapturingNetLog::CapturedEntryList entries;
   10017   log.GetEntries(&entries);
   10018   size_t pos = ExpectLogContainsSomewhere(
   10019       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   10020       NetLog::PHASE_NONE);
   10021   ExpectLogContainsSomewhere(
   10022       entries, pos,
   10023       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   10024       NetLog::PHASE_NONE);
   10025 }
   10026 
   10027 // Test for crbug.com/55424.
   10028 TEST_P(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
   10029   scoped_ptr<SpdyFrame> req(
   10030       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10031   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   10032 
   10033   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10034   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10035   MockRead spdy_reads[] = {
   10036     CreateMockRead(*resp),
   10037     CreateMockRead(*data),
   10038     MockRead(ASYNC, 0, 0),
   10039   };
   10040 
   10041   DelayedSocketData spdy_data(
   10042       1,  // wait for one write to finish before reading.
   10043       spdy_reads, arraysize(spdy_reads),
   10044       spdy_writes, arraysize(spdy_writes));
   10045   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10046 
   10047   SSLSocketDataProvider ssl(ASYNC, OK);
   10048   ssl.SetNextProto(GetParam());
   10049   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10050 
   10051   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10052 
   10053   // Set up an initial SpdySession in the pool to reuse.
   10054   HostPortPair host_port_pair("www.google.com", 443);
   10055   SpdySessionKey key(host_port_pair, ProxyServer::Direct(),
   10056                      kPrivacyModeDisabled);
   10057   base::WeakPtr<SpdySession> spdy_session =
   10058       CreateInsecureSpdySession(session, key, BoundNetLog());
   10059 
   10060   HttpRequestInfo request;
   10061   request.method = "GET";
   10062   request.url = GURL("https://www.google.com/");
   10063   request.load_flags = 0;
   10064 
   10065   // This is the important line that marks this as a preconnect.
   10066   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
   10067 
   10068   scoped_ptr<HttpTransaction> trans(
   10069       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10070 
   10071   TestCompletionCallback callback;
   10072   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   10073   EXPECT_EQ(ERR_IO_PENDING, rv);
   10074   EXPECT_EQ(OK, callback.WaitForResult());
   10075 }
   10076 
   10077 // Given a net error, cause that error to be returned from the first Write()
   10078 // call and verify that the HttpTransaction fails with that error.
   10079 void HttpNetworkTransactionTest::CheckErrorIsPassedBack(
   10080     int error, IoMode mode) {
   10081   net::HttpRequestInfo request_info;
   10082   request_info.url = GURL("https://www.example.com/");
   10083   request_info.method = "GET";
   10084   request_info.load_flags = net::LOAD_NORMAL;
   10085 
   10086   SSLSocketDataProvider ssl_data(mode, OK);
   10087   net::MockWrite data_writes[] = {
   10088     net::MockWrite(mode, error),
   10089   };
   10090   net::StaticSocketDataProvider data(NULL, 0,
   10091                                      data_writes, arraysize(data_writes));
   10092   session_deps_.socket_factory->AddSocketDataProvider(&data);
   10093   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data);
   10094 
   10095   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10096   scoped_ptr<HttpTransaction> trans(
   10097       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10098 
   10099   TestCompletionCallback callback;
   10100   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10101   if (rv == net::ERR_IO_PENDING)
   10102     rv = callback.WaitForResult();
   10103   ASSERT_EQ(error, rv);
   10104 }
   10105 
   10106 TEST_P(HttpNetworkTransactionTest, SSLWriteCertError) {
   10107   // Just check a grab bag of cert errors.
   10108   static const int kErrors[] = {
   10109     ERR_CERT_COMMON_NAME_INVALID,
   10110     ERR_CERT_AUTHORITY_INVALID,
   10111     ERR_CERT_DATE_INVALID,
   10112   };
   10113   for (size_t i = 0; i < arraysize(kErrors); i++) {
   10114     CheckErrorIsPassedBack(kErrors[i], ASYNC);
   10115     CheckErrorIsPassedBack(kErrors[i], SYNCHRONOUS);
   10116   }
   10117 }
   10118 
   10119 // Ensure that a client certificate is removed from the SSL client auth
   10120 // cache when:
   10121 //  1) No proxy is involved.
   10122 //  2) TLS False Start is disabled.
   10123 //  3) The initial TLS handshake requests a client certificate.
   10124 //  4) The client supplies an invalid/unacceptable certificate.
   10125 TEST_P(HttpNetworkTransactionTest,
   10126        ClientAuthCertCache_Direct_NoFalseStart) {
   10127   net::HttpRequestInfo request_info;
   10128   request_info.url = GURL("https://www.example.com/");
   10129   request_info.method = "GET";
   10130   request_info.load_flags = net::LOAD_NORMAL;
   10131 
   10132   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10133   cert_request->host_and_port = "www.example.com:443";
   10134 
   10135   // [ssl_]data1 contains the data for the first SSL handshake. When a
   10136   // CertificateRequest is received for the first time, the handshake will
   10137   // be aborted to allow the caller to provide a certificate.
   10138   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10139   ssl_data1.cert_request_info = cert_request.get();
   10140   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10141   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10142   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10143 
   10144   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
   10145   // False Start is not being used, the result of the SSL handshake will be
   10146   // returned as part of the SSLClientSocket::Connect() call. This test
   10147   // matches the result of a server sending a handshake_failure alert,
   10148   // rather than a Finished message, because it requires a client
   10149   // certificate and none was supplied.
   10150   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10151   ssl_data2.cert_request_info = cert_request.get();
   10152   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10153   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10154   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10155 
   10156   // [ssl_]data3 contains the data for the third SSL handshake. When a
   10157   // connection to a server fails during an SSL handshake,
   10158   // HttpNetworkTransaction will attempt to fallback to TLSv1 if the previous
   10159   // connection was attempted with TLSv1.1. This is transparent to the caller
   10160   // of the HttpNetworkTransaction. Because this test failure is due to
   10161   // requiring a client certificate, this fallback handshake should also
   10162   // fail.
   10163   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10164   ssl_data3.cert_request_info = cert_request.get();
   10165   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10166   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10167   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10168 
   10169   // [ssl_]data4 contains the data for the fourth SSL handshake. When a
   10170   // connection to a server fails during an SSL handshake,
   10171   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the previous
   10172   // connection was attempted with TLSv1. This is transparent to the caller
   10173   // of the HttpNetworkTransaction. Because this test failure is due to
   10174   // requiring a client certificate, this fallback handshake should also
   10175   // fail.
   10176   SSLSocketDataProvider ssl_data4(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10177   ssl_data4.cert_request_info = cert_request.get();
   10178   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10179   net::StaticSocketDataProvider data4(NULL, 0, NULL, 0);
   10180   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10181 
   10182   // Need one more if TLSv1.2 is enabled.
   10183   SSLSocketDataProvider ssl_data5(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10184   ssl_data5.cert_request_info = cert_request.get();
   10185   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10186   net::StaticSocketDataProvider data5(NULL, 0, NULL, 0);
   10187   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10188 
   10189   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10190   scoped_ptr<HttpTransaction> trans(
   10191       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10192 
   10193   // Begin the SSL handshake with the peer. This consumes ssl_data1.
   10194   TestCompletionCallback callback;
   10195   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10196   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10197 
   10198   // Complete the SSL handshake, which should abort due to requiring a
   10199   // client certificate.
   10200   rv = callback.WaitForResult();
   10201   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10202 
   10203   // Indicate that no certificate should be supplied. From the perspective
   10204   // of SSLClientCertCache, NULL is just as meaningful as a real
   10205   // certificate, so this is the same as supply a
   10206   // legitimate-but-unacceptable certificate.
   10207   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10208   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10209 
   10210   // Ensure the certificate was added to the client auth cache before
   10211   // allowing the connection to continue restarting.
   10212   scoped_refptr<X509Certificate> client_cert;
   10213   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10214                                                        &client_cert));
   10215   ASSERT_EQ(NULL, client_cert.get());
   10216 
   10217   // Restart the handshake. This will consume ssl_data2, which fails, and
   10218   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10219   // The result code is checked against what ssl_data4 should return.
   10220   rv = callback.WaitForResult();
   10221   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10222 
   10223   // Ensure that the client certificate is removed from the cache on a
   10224   // handshake failure.
   10225   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10226                                                         &client_cert));
   10227 }
   10228 
   10229 // Ensure that a client certificate is removed from the SSL client auth
   10230 // cache when:
   10231 //  1) No proxy is involved.
   10232 //  2) TLS False Start is enabled.
   10233 //  3) The initial TLS handshake requests a client certificate.
   10234 //  4) The client supplies an invalid/unacceptable certificate.
   10235 TEST_P(HttpNetworkTransactionTest,
   10236        ClientAuthCertCache_Direct_FalseStart) {
   10237   net::HttpRequestInfo request_info;
   10238   request_info.url = GURL("https://www.example.com/");
   10239   request_info.method = "GET";
   10240   request_info.load_flags = net::LOAD_NORMAL;
   10241 
   10242   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10243   cert_request->host_and_port = "www.example.com:443";
   10244 
   10245   // When TLS False Start is used, SSLClientSocket::Connect() calls will
   10246   // return successfully after reading up to the peer's Certificate message.
   10247   // This is to allow the caller to call SSLClientSocket::Write(), which can
   10248   // enqueue application data to be sent in the same packet as the
   10249   // ChangeCipherSpec and Finished messages.
   10250   // The actual handshake will be finished when SSLClientSocket::Read() is
   10251   // called, which expects to process the peer's ChangeCipherSpec and
   10252   // Finished messages. If there was an error negotiating with the peer,
   10253   // such as due to the peer requiring a client certificate when none was
   10254   // supplied, the alert sent by the peer won't be processed until Read() is
   10255   // called.
   10256 
   10257   // Like the non-False Start case, when a client certificate is requested by
   10258   // the peer, the handshake is aborted during the Connect() call.
   10259   // [ssl_]data1 represents the initial SSL handshake with the peer.
   10260   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10261   ssl_data1.cert_request_info = cert_request.get();
   10262   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10263   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10264   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10265 
   10266   // When a client certificate is supplied, Connect() will not be aborted
   10267   // when the peer requests the certificate. Instead, the handshake will
   10268   // artificially succeed, allowing the caller to write the HTTP request to
   10269   // the socket. The handshake messages are not processed until Read() is
   10270   // called, which then detects that the handshake was aborted, due to the
   10271   // peer sending a handshake_failure because it requires a client
   10272   // certificate.
   10273   SSLSocketDataProvider ssl_data2(ASYNC, net::OK);
   10274   ssl_data2.cert_request_info = cert_request.get();
   10275   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10276   net::MockRead data2_reads[] = {
   10277     net::MockRead(ASYNC /* async */, net::ERR_SSL_PROTOCOL_ERROR),
   10278   };
   10279   net::StaticSocketDataProvider data2(
   10280       data2_reads, arraysize(data2_reads), NULL, 0);
   10281   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10282 
   10283   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
   10284   // the data for the SSL handshake once the TLSv1.1 connection falls back to
   10285   // TLSv1. It has the same behaviour as [ssl_]data2.
   10286   SSLSocketDataProvider ssl_data3(ASYNC, net::OK);
   10287   ssl_data3.cert_request_info = cert_request.get();
   10288   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10289   net::StaticSocketDataProvider data3(
   10290       data2_reads, arraysize(data2_reads), NULL, 0);
   10291   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10292 
   10293   // [ssl_]data4 is the data for the SSL handshake once the TLSv1 connection
   10294   // falls back to SSLv3. It has the same behaviour as [ssl_]data2.
   10295   SSLSocketDataProvider ssl_data4(ASYNC, net::OK);
   10296   ssl_data4.cert_request_info = cert_request.get();
   10297   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data4);
   10298   net::StaticSocketDataProvider data4(
   10299       data2_reads, arraysize(data2_reads), NULL, 0);
   10300   session_deps_.socket_factory->AddSocketDataProvider(&data4);
   10301 
   10302   // Need one more if TLSv1.2 is enabled.
   10303   SSLSocketDataProvider ssl_data5(ASYNC, net::OK);
   10304   ssl_data5.cert_request_info = cert_request.get();
   10305   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data5);
   10306   net::StaticSocketDataProvider data5(
   10307       data2_reads, arraysize(data2_reads), NULL, 0);
   10308   session_deps_.socket_factory->AddSocketDataProvider(&data5);
   10309 
   10310   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10311   scoped_ptr<HttpTransaction> trans(
   10312       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10313 
   10314   // Begin the initial SSL handshake.
   10315   TestCompletionCallback callback;
   10316   int rv = trans->Start(&request_info, callback.callback(), net::BoundNetLog());
   10317   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10318 
   10319   // Complete the SSL handshake, which should abort due to requiring a
   10320   // client certificate.
   10321   rv = callback.WaitForResult();
   10322   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10323 
   10324   // Indicate that no certificate should be supplied. From the perspective
   10325   // of SSLClientCertCache, NULL is just as meaningful as a real
   10326   // certificate, so this is the same as supply a
   10327   // legitimate-but-unacceptable certificate.
   10328   rv = trans->RestartWithCertificate(NULL, callback.callback());
   10329   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10330 
   10331   // Ensure the certificate was added to the client auth cache before
   10332   // allowing the connection to continue restarting.
   10333   scoped_refptr<X509Certificate> client_cert;
   10334   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10335                                                        &client_cert));
   10336   ASSERT_EQ(NULL, client_cert.get());
   10337 
   10338   // Restart the handshake. This will consume ssl_data2, which fails, and
   10339   // then consume ssl_data3 and ssl_data4, both of which should also fail.
   10340   // The result code is checked against what ssl_data4 should return.
   10341   rv = callback.WaitForResult();
   10342   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   10343 
   10344   // Ensure that the client certificate is removed from the cache on a
   10345   // handshake failure.
   10346   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10347                                                         &client_cert));
   10348 }
   10349 
   10350 // Ensure that a client certificate is removed from the SSL client auth
   10351 // cache when:
   10352 //  1) An HTTPS proxy is involved.
   10353 //  3) The HTTPS proxy requests a client certificate.
   10354 //  4) The client supplies an invalid/unacceptable certificate for the
   10355 //     proxy.
   10356 // The test is repeated twice, first for connecting to an HTTPS endpoint,
   10357 // then for connecting to an HTTP endpoint.
   10358 TEST_P(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
   10359   session_deps_.proxy_service.reset(
   10360       ProxyService::CreateFixed("https://proxy:70"));
   10361   CapturingBoundNetLog log;
   10362   session_deps_.net_log = log.bound().net_log();
   10363 
   10364   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   10365   cert_request->host_and_port = "proxy:70";
   10366 
   10367   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
   10368   // [ssl_]data[1-3]. Rather than represending the endpoint
   10369   // (www.example.com:443), they represent failures with the HTTPS proxy
   10370   // (proxy:70).
   10371   SSLSocketDataProvider ssl_data1(ASYNC, net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   10372   ssl_data1.cert_request_info = cert_request.get();
   10373   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data1);
   10374   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   10375   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10376 
   10377   SSLSocketDataProvider ssl_data2(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10378   ssl_data2.cert_request_info = cert_request.get();
   10379   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data2);
   10380   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   10381   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10382 
   10383   // TODO(wtc): find out why this unit test doesn't need [ssl_]data3.
   10384 #if 0
   10385   SSLSocketDataProvider ssl_data3(ASYNC, net::ERR_SSL_PROTOCOL_ERROR);
   10386   ssl_data3.cert_request_info = cert_request.get();
   10387   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data3);
   10388   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   10389   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   10390 #endif
   10391 
   10392   net::HttpRequestInfo requests[2];
   10393   requests[0].url = GURL("https://www.example.com/");
   10394   requests[0].method = "GET";
   10395   requests[0].load_flags = net::LOAD_NORMAL;
   10396 
   10397   requests[1].url = GURL("http://www.example.com/");
   10398   requests[1].method = "GET";
   10399   requests[1].load_flags = net::LOAD_NORMAL;
   10400 
   10401   for (size_t i = 0; i < arraysize(requests); ++i) {
   10402     session_deps_.socket_factory->ResetNextMockIndexes();
   10403     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10404     scoped_ptr<HttpNetworkTransaction> trans(
   10405         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   10406 
   10407     // Begin the SSL handshake with the proxy.
   10408     TestCompletionCallback callback;
   10409     int rv = trans->Start(
   10410         &requests[i], callback.callback(), net::BoundNetLog());
   10411     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10412 
   10413     // Complete the SSL handshake, which should abort due to requiring a
   10414     // client certificate.
   10415     rv = callback.WaitForResult();
   10416     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   10417 
   10418     // Indicate that no certificate should be supplied. From the perspective
   10419     // of SSLClientCertCache, NULL is just as meaningful as a real
   10420     // certificate, so this is the same as supply a
   10421     // legitimate-but-unacceptable certificate.
   10422     rv = trans->RestartWithCertificate(NULL, callback.callback());
   10423     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   10424 
   10425     // Ensure the certificate was added to the client auth cache before
   10426     // allowing the connection to continue restarting.
   10427     scoped_refptr<X509Certificate> client_cert;
   10428     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   10429                                                          &client_cert));
   10430     ASSERT_EQ(NULL, client_cert.get());
   10431     // Ensure the certificate was NOT cached for the endpoint. This only
   10432     // applies to HTTPS requests, but is fine to check for HTTP requests.
   10433     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10434                                                           &client_cert));
   10435 
   10436     // Restart the handshake. This will consume ssl_data2, which fails, and
   10437     // then consume ssl_data3, which should also fail. The result code is
   10438     // checked against what ssl_data3 should return.
   10439     rv = callback.WaitForResult();
   10440     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
   10441 
   10442     // Now that the new handshake has failed, ensure that the client
   10443     // certificate was removed from the client auth cache.
   10444     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   10445                                                           &client_cert));
   10446     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   10447                                                           &client_cert));
   10448   }
   10449 }
   10450 
   10451 // Unlike TEST/TEST_F, which are macros that expand to further macros,
   10452 // TEST_P is a macro that expands directly to code that stringizes the
   10453 // arguments. As a result, macros passed as parameters (such as prefix
   10454 // or test_case_name) will not be expanded by the preprocessor. To
   10455 // work around this, indirect the macro for TEST_P, so that the
   10456 // pre-processor will expand macros such as MAYBE_test_name before
   10457 // instantiating the test.
   10458 #define WRAPPED_TEST_P(test_case_name, test_name) \
   10459   TEST_P(test_case_name, test_name)
   10460 
   10461 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   10462 #if defined(OS_WIN)
   10463 #define MAYBE_UseIPConnectionPooling DISABLED_UseIPConnectionPooling
   10464 #else
   10465 #define MAYBE_UseIPConnectionPooling UseIPConnectionPooling
   10466 #endif
   10467 WRAPPED_TEST_P(HttpNetworkTransactionTest, MAYBE_UseIPConnectionPooling) {
   10468   HttpStreamFactory::set_use_alternate_protocols(true);
   10469   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10470 
   10471   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   10472   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   10473   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10474   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10475   pool_peer.DisableDomainAuthenticationVerification();
   10476 
   10477   SSLSocketDataProvider ssl(ASYNC, OK);
   10478   ssl.SetNextProto(GetParam());
   10479   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10480 
   10481   scoped_ptr<SpdyFrame> host1_req(
   10482       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10483   scoped_ptr<SpdyFrame> host2_req(
   10484       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10485   MockWrite spdy_writes[] = {
   10486     CreateMockWrite(*host1_req, 1),
   10487     CreateMockWrite(*host2_req, 4),
   10488   };
   10489   scoped_ptr<SpdyFrame> host1_resp(
   10490       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10491   scoped_ptr<SpdyFrame> host1_resp_body(
   10492       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10493   scoped_ptr<SpdyFrame> host2_resp(
   10494       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10495   scoped_ptr<SpdyFrame> host2_resp_body(
   10496       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10497   MockRead spdy_reads[] = {
   10498     CreateMockRead(*host1_resp, 2),
   10499     CreateMockRead(*host1_resp_body, 3),
   10500     CreateMockRead(*host2_resp, 5),
   10501     CreateMockRead(*host2_resp_body, 6),
   10502     MockRead(ASYNC, 0, 7),
   10503   };
   10504 
   10505   IPAddressNumber ip;
   10506   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10507   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10508   MockConnect connect(ASYNC, OK, peer_addr);
   10509   OrderedSocketData spdy_data(
   10510       connect,
   10511       spdy_reads, arraysize(spdy_reads),
   10512       spdy_writes, arraysize(spdy_writes));
   10513   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10514 
   10515   TestCompletionCallback callback;
   10516   HttpRequestInfo request1;
   10517   request1.method = "GET";
   10518   request1.url = GURL("https://www.google.com/");
   10519   request1.load_flags = 0;
   10520   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10521 
   10522   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10523   EXPECT_EQ(ERR_IO_PENDING, rv);
   10524   EXPECT_EQ(OK, callback.WaitForResult());
   10525 
   10526   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10527   ASSERT_TRUE(response != NULL);
   10528   ASSERT_TRUE(response->headers.get() != NULL);
   10529   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10530 
   10531   std::string response_data;
   10532   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10533   EXPECT_EQ("hello!", response_data);
   10534 
   10535   // Preload www.gmail.com into HostCache.
   10536   HostPortPair host_port("www.gmail.com", 443);
   10537   HostResolver::RequestInfo resolve_info(host_port);
   10538   AddressList ignored;
   10539   rv = session_deps_.host_resolver->Resolve(resolve_info,
   10540                                             DEFAULT_PRIORITY,
   10541                                             &ignored,
   10542                                             callback.callback(),
   10543                                             NULL,
   10544                                             BoundNetLog());
   10545   EXPECT_EQ(ERR_IO_PENDING, rv);
   10546   rv = callback.WaitForResult();
   10547   EXPECT_EQ(OK, rv);
   10548 
   10549   HttpRequestInfo request2;
   10550   request2.method = "GET";
   10551   request2.url = GURL("https://www.gmail.com/");
   10552   request2.load_flags = 0;
   10553   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10554 
   10555   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10556   EXPECT_EQ(ERR_IO_PENDING, rv);
   10557   EXPECT_EQ(OK, callback.WaitForResult());
   10558 
   10559   response = trans2.GetResponseInfo();
   10560   ASSERT_TRUE(response != NULL);
   10561   ASSERT_TRUE(response->headers.get() != NULL);
   10562   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10563   EXPECT_TRUE(response->was_fetched_via_spdy);
   10564   EXPECT_TRUE(response->was_npn_negotiated);
   10565   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10566   EXPECT_EQ("hello!", response_data);
   10567 }
   10568 #undef MAYBE_UseIPConnectionPooling
   10569 
   10570 TEST_P(HttpNetworkTransactionTest, UseIPConnectionPoolingAfterResolution) {
   10571   HttpStreamFactory::set_use_alternate_protocols(true);
   10572   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10573 
   10574   // Set up a special HttpNetworkSession with a MockCachingHostResolver.
   10575   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   10576   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10577   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10578   pool_peer.DisableDomainAuthenticationVerification();
   10579 
   10580   SSLSocketDataProvider ssl(ASYNC, OK);
   10581   ssl.SetNextProto(GetParam());
   10582   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10583 
   10584   scoped_ptr<SpdyFrame> host1_req(
   10585       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10586   scoped_ptr<SpdyFrame> host2_req(
   10587       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10588   MockWrite spdy_writes[] = {
   10589     CreateMockWrite(*host1_req, 1),
   10590     CreateMockWrite(*host2_req, 4),
   10591   };
   10592   scoped_ptr<SpdyFrame> host1_resp(
   10593       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10594   scoped_ptr<SpdyFrame> host1_resp_body(
   10595       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10596   scoped_ptr<SpdyFrame> host2_resp(
   10597       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10598   scoped_ptr<SpdyFrame> host2_resp_body(
   10599       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10600   MockRead spdy_reads[] = {
   10601     CreateMockRead(*host1_resp, 2),
   10602     CreateMockRead(*host1_resp_body, 3),
   10603     CreateMockRead(*host2_resp, 5),
   10604     CreateMockRead(*host2_resp_body, 6),
   10605     MockRead(ASYNC, 0, 7),
   10606   };
   10607 
   10608   IPAddressNumber ip;
   10609   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10610   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10611   MockConnect connect(ASYNC, OK, peer_addr);
   10612   OrderedSocketData spdy_data(
   10613       connect,
   10614       spdy_reads, arraysize(spdy_reads),
   10615       spdy_writes, arraysize(spdy_writes));
   10616   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10617 
   10618   TestCompletionCallback callback;
   10619   HttpRequestInfo request1;
   10620   request1.method = "GET";
   10621   request1.url = GURL("https://www.google.com/");
   10622   request1.load_flags = 0;
   10623   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10624 
   10625   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10626   EXPECT_EQ(ERR_IO_PENDING, rv);
   10627   EXPECT_EQ(OK, callback.WaitForResult());
   10628 
   10629   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10630   ASSERT_TRUE(response != NULL);
   10631   ASSERT_TRUE(response->headers.get() != NULL);
   10632   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10633 
   10634   std::string response_data;
   10635   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10636   EXPECT_EQ("hello!", response_data);
   10637 
   10638   HttpRequestInfo request2;
   10639   request2.method = "GET";
   10640   request2.url = GURL("https://www.gmail.com/");
   10641   request2.load_flags = 0;
   10642   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10643 
   10644   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10645   EXPECT_EQ(ERR_IO_PENDING, rv);
   10646   EXPECT_EQ(OK, callback.WaitForResult());
   10647 
   10648   response = trans2.GetResponseInfo();
   10649   ASSERT_TRUE(response != NULL);
   10650   ASSERT_TRUE(response->headers.get() != NULL);
   10651   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10652   EXPECT_TRUE(response->was_fetched_via_spdy);
   10653   EXPECT_TRUE(response->was_npn_negotiated);
   10654   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10655   EXPECT_EQ("hello!", response_data);
   10656 }
   10657 
   10658 class OneTimeCachingHostResolver : public net::HostResolver {
   10659  public:
   10660   explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
   10661       : host_port_(host_port) {}
   10662   virtual ~OneTimeCachingHostResolver() {}
   10663 
   10664   RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
   10665 
   10666   // HostResolver methods:
   10667   virtual int Resolve(const RequestInfo& info,
   10668                       RequestPriority priority,
   10669                       AddressList* addresses,
   10670                       const CompletionCallback& callback,
   10671                       RequestHandle* out_req,
   10672                       const BoundNetLog& net_log) OVERRIDE {
   10673     return host_resolver_.Resolve(
   10674         info, priority, addresses, callback, out_req, net_log);
   10675   }
   10676 
   10677   virtual int ResolveFromCache(const RequestInfo& info,
   10678                                AddressList* addresses,
   10679                                const BoundNetLog& net_log) OVERRIDE {
   10680     int rv = host_resolver_.ResolveFromCache(info, addresses, net_log);
   10681     if (rv == OK && info.host_port_pair().Equals(host_port_))
   10682       host_resolver_.GetHostCache()->clear();
   10683     return rv;
   10684   }
   10685 
   10686   virtual void CancelRequest(RequestHandle req) OVERRIDE {
   10687     host_resolver_.CancelRequest(req);
   10688   }
   10689 
   10690   MockCachingHostResolver* GetMockHostResolver() {
   10691     return &host_resolver_;
   10692   }
   10693 
   10694  private:
   10695   MockCachingHostResolver host_resolver_;
   10696   const HostPortPair host_port_;
   10697 };
   10698 
   10699 // Times out on Win7 dbg(2) bot. http://crbug.com/124776
   10700 #if defined(OS_WIN)
   10701 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   10702     DISABLED_UseIPConnectionPoolingWithHostCacheExpiration
   10703 #else
   10704 #define MAYBE_UseIPConnectionPoolingWithHostCacheExpiration \
   10705     UseIPConnectionPoolingWithHostCacheExpiration
   10706 #endif
   10707 WRAPPED_TEST_P(HttpNetworkTransactionTest,
   10708                MAYBE_UseIPConnectionPoolingWithHostCacheExpiration) {
   10709 // Times out on Win7 dbg(2) bot. http://crbug.com/124776 . (MAYBE_
   10710 // prefix doesn't work with parametrized tests).
   10711 #if defined(OS_WIN)
   10712   return;
   10713 #endif
   10714 
   10715   HttpStreamFactory::set_use_alternate_protocols(true);
   10716   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   10717 
   10718   // Set up a special HttpNetworkSession with a OneTimeCachingHostResolver.
   10719   OneTimeCachingHostResolver host_resolver(HostPortPair("www.gmail.com", 443));
   10720   HttpNetworkSession::Params params =
   10721       SpdySessionDependencies::CreateSessionParams(&session_deps_);
   10722   params.host_resolver = &host_resolver;
   10723   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10724   SpdySessionPoolPeer pool_peer(session->spdy_session_pool());
   10725   pool_peer.DisableDomainAuthenticationVerification();
   10726 
   10727   SSLSocketDataProvider ssl(ASYNC, OK);
   10728   ssl.SetNextProto(GetParam());
   10729   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10730 
   10731   scoped_ptr<SpdyFrame> host1_req(
   10732       spdy_util_.ConstructSpdyGet("https://www.google.com", false, 1, LOWEST));
   10733   scoped_ptr<SpdyFrame> host2_req(
   10734       spdy_util_.ConstructSpdyGet("https://www.gmail.com", false, 3, LOWEST));
   10735   MockWrite spdy_writes[] = {
   10736     CreateMockWrite(*host1_req, 1),
   10737     CreateMockWrite(*host2_req, 4),
   10738   };
   10739   scoped_ptr<SpdyFrame> host1_resp(
   10740       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10741   scoped_ptr<SpdyFrame> host1_resp_body(
   10742       spdy_util_.ConstructSpdyBodyFrame(1, true));
   10743   scoped_ptr<SpdyFrame> host2_resp(
   10744       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10745   scoped_ptr<SpdyFrame> host2_resp_body(
   10746       spdy_util_.ConstructSpdyBodyFrame(3, true));
   10747   MockRead spdy_reads[] = {
   10748     CreateMockRead(*host1_resp, 2),
   10749     CreateMockRead(*host1_resp_body, 3),
   10750     CreateMockRead(*host2_resp, 5),
   10751     CreateMockRead(*host2_resp_body, 6),
   10752     MockRead(ASYNC, 0, 7),
   10753   };
   10754 
   10755   IPAddressNumber ip;
   10756   ASSERT_TRUE(ParseIPLiteralToNumber("127.0.0.1", &ip));
   10757   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   10758   MockConnect connect(ASYNC, OK, peer_addr);
   10759   OrderedSocketData spdy_data(
   10760       connect,
   10761       spdy_reads, arraysize(spdy_reads),
   10762       spdy_writes, arraysize(spdy_writes));
   10763   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   10764 
   10765   TestCompletionCallback callback;
   10766   HttpRequestInfo request1;
   10767   request1.method = "GET";
   10768   request1.url = GURL("https://www.google.com/");
   10769   request1.load_flags = 0;
   10770   HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
   10771 
   10772   int rv = trans1.Start(&request1, callback.callback(), BoundNetLog());
   10773   EXPECT_EQ(ERR_IO_PENDING, rv);
   10774   EXPECT_EQ(OK, callback.WaitForResult());
   10775 
   10776   const HttpResponseInfo* response = trans1.GetResponseInfo();
   10777   ASSERT_TRUE(response != NULL);
   10778   ASSERT_TRUE(response->headers.get() != NULL);
   10779   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10780 
   10781   std::string response_data;
   10782   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   10783   EXPECT_EQ("hello!", response_data);
   10784 
   10785   // Preload cache entries into HostCache.
   10786   HostResolver::RequestInfo resolve_info(HostPortPair("www.gmail.com", 443));
   10787   AddressList ignored;
   10788   rv = host_resolver.Resolve(resolve_info,
   10789                              DEFAULT_PRIORITY,
   10790                              &ignored,
   10791                              callback.callback(),
   10792                              NULL,
   10793                              BoundNetLog());
   10794   EXPECT_EQ(ERR_IO_PENDING, rv);
   10795   rv = callback.WaitForResult();
   10796   EXPECT_EQ(OK, rv);
   10797 
   10798   HttpRequestInfo request2;
   10799   request2.method = "GET";
   10800   request2.url = GURL("https://www.gmail.com/");
   10801   request2.load_flags = 0;
   10802   HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
   10803 
   10804   rv = trans2.Start(&request2, callback.callback(), BoundNetLog());
   10805   EXPECT_EQ(ERR_IO_PENDING, rv);
   10806   EXPECT_EQ(OK, callback.WaitForResult());
   10807 
   10808   response = trans2.GetResponseInfo();
   10809   ASSERT_TRUE(response != NULL);
   10810   ASSERT_TRUE(response->headers.get() != NULL);
   10811   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   10812   EXPECT_TRUE(response->was_fetched_via_spdy);
   10813   EXPECT_TRUE(response->was_npn_negotiated);
   10814   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   10815   EXPECT_EQ("hello!", response_data);
   10816 }
   10817 #undef MAYBE_UseIPConnectionPoolingWithHostCacheExpiration
   10818 
   10819 TEST_P(HttpNetworkTransactionTest, ReadPipelineEvictionFallback) {
   10820   MockRead data_reads1[] = {
   10821     MockRead(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
   10822   };
   10823   MockRead data_reads2[] = {
   10824     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   10825     MockRead("hello world"),
   10826     MockRead(SYNCHRONOUS, OK),
   10827   };
   10828   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1), NULL, 0);
   10829   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2), NULL, 0);
   10830   StaticSocketDataProvider* data[] = { &data1, &data2 };
   10831 
   10832   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
   10833 
   10834   EXPECT_EQ(OK, out.rv);
   10835   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
   10836   EXPECT_EQ("hello world", out.response_data);
   10837 }
   10838 
   10839 TEST_P(HttpNetworkTransactionTest, SendPipelineEvictionFallback) {
   10840   MockWrite data_writes1[] = {
   10841     MockWrite(SYNCHRONOUS, ERR_PIPELINE_EVICTION),
   10842   };
   10843   MockWrite data_writes2[] = {
   10844     MockWrite("GET / HTTP/1.1\r\n"
   10845               "Host: www.google.com\r\n"
   10846               "Connection: keep-alive\r\n\r\n"),
   10847   };
   10848   MockRead data_reads2[] = {
   10849     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   10850     MockRead("hello world"),
   10851     MockRead(SYNCHRONOUS, OK),
   10852   };
   10853   StaticSocketDataProvider data1(NULL, 0,
   10854                                  data_writes1, arraysize(data_writes1));
   10855   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   10856                                  data_writes2, arraysize(data_writes2));
   10857   StaticSocketDataProvider* data[] = { &data1, &data2 };
   10858 
   10859   SimpleGetHelperResult out = SimpleGetHelperForData(data, arraysize(data));
   10860 
   10861   EXPECT_EQ(OK, out.rv);
   10862   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
   10863   EXPECT_EQ("hello world", out.response_data);
   10864 }
   10865 
   10866 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttp) {
   10867   const std::string https_url = "https://www.google.com/";
   10868   const std::string http_url = "http://www.google.com:443/";
   10869 
   10870   // SPDY GET for HTTPS URL
   10871   scoped_ptr<SpdyFrame> req1(
   10872       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   10873 
   10874   MockWrite writes1[] = {
   10875     CreateMockWrite(*req1, 0),
   10876   };
   10877 
   10878   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10879   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10880   MockRead reads1[] = {
   10881     CreateMockRead(*resp1, 1),
   10882     CreateMockRead(*body1, 2),
   10883     MockRead(ASYNC, ERR_IO_PENDING, 3)
   10884   };
   10885 
   10886   DelayedSocketData data1(
   10887       1, reads1, arraysize(reads1),
   10888       writes1, arraysize(writes1));
   10889   MockConnect connect_data1(ASYNC, OK);
   10890   data1.set_connect_data(connect_data1);
   10891 
   10892   // HTTP GET for the HTTP URL
   10893   MockWrite writes2[] = {
   10894     MockWrite(ASYNC, 4,
   10895               "GET / HTTP/1.1\r\n"
   10896               "Host: www.google.com:443\r\n"
   10897               "Connection: keep-alive\r\n\r\n"),
   10898   };
   10899 
   10900   MockRead reads2[] = {
   10901     MockRead(ASYNC, 5, "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   10902     MockRead(ASYNC, 6, "hello"),
   10903     MockRead(ASYNC, 7, OK),
   10904   };
   10905 
   10906   DelayedSocketData data2(
   10907       1, reads2, arraysize(reads2),
   10908       writes2, arraysize(writes2));
   10909 
   10910   SSLSocketDataProvider ssl(ASYNC, OK);
   10911   ssl.SetNextProto(GetParam());
   10912   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   10913   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   10914   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   10915 
   10916   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   10917 
   10918   // Start the first transaction to set up the SpdySession
   10919   HttpRequestInfo request1;
   10920   request1.method = "GET";
   10921   request1.url = GURL(https_url);
   10922   request1.load_flags = 0;
   10923   HttpNetworkTransaction trans1(LOWEST, session.get());
   10924   TestCompletionCallback callback1;
   10925   EXPECT_EQ(ERR_IO_PENDING,
   10926             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   10927   base::MessageLoop::current()->RunUntilIdle();
   10928 
   10929   EXPECT_EQ(OK, callback1.WaitForResult());
   10930   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   10931 
   10932   // Now, start the HTTP request
   10933   HttpRequestInfo request2;
   10934   request2.method = "GET";
   10935   request2.url = GURL(http_url);
   10936   request2.load_flags = 0;
   10937   HttpNetworkTransaction trans2(MEDIUM, session.get());
   10938   TestCompletionCallback callback2;
   10939   EXPECT_EQ(ERR_IO_PENDING,
   10940             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   10941   base::MessageLoop::current()->RunUntilIdle();
   10942 
   10943   EXPECT_EQ(OK, callback2.WaitForResult());
   10944   EXPECT_FALSE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   10945 }
   10946 
   10947 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
   10948   const std::string https_url = "https://www.google.com/";
   10949   const std::string http_url = "http://www.google.com:443/";
   10950 
   10951   // SPDY GET for HTTPS URL (through CONNECT tunnel)
   10952   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   10953                                                                 LOWEST));
   10954   scoped_ptr<SpdyFrame> req1(
   10955       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   10956 
   10957   // SPDY GET for HTTP URL (through the proxy, but not the tunnel)
   10958   scoped_ptr<SpdyFrame> wrapped_req1(
   10959       spdy_util_.ConstructWrappedSpdyFrame(req1, 1));
   10960   const char* const headers[] = {
   10961     spdy_util_.GetMethodKey(), "GET",
   10962     spdy_util_.GetPathKey(), spdy_util_.is_spdy2() ? http_url.c_str() : "/",
   10963     spdy_util_.GetHostKey(),  "www.google.com:443",
   10964     spdy_util_.GetSchemeKey(), "http",
   10965     spdy_util_.GetVersionKey(), "HTTP/1.1"
   10966   };
   10967   scoped_ptr<SpdyFrame> req2(spdy_util_.ConstructSpdyControlFrame(
   10968       NULL, 0, false, 3, MEDIUM, SYN_STREAM, CONTROL_FLAG_FIN,
   10969       headers, arraysize(headers), 0));
   10970 
   10971   MockWrite writes1[] = {
   10972     CreateMockWrite(*connect, 0),
   10973     CreateMockWrite(*wrapped_req1, 2),
   10974     CreateMockWrite(*req2, 5),
   10975   };
   10976 
   10977   scoped_ptr<SpdyFrame> conn_resp(
   10978       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10979   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   10980   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   10981   scoped_ptr<SpdyFrame> wrapped_resp1(
   10982       spdy_util_.ConstructWrappedSpdyFrame(resp1, 1));
   10983   scoped_ptr<SpdyFrame> wrapped_body1(
   10984       spdy_util_.ConstructWrappedSpdyFrame(body1, 1));
   10985   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   10986   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   10987   MockRead reads1[] = {
   10988     CreateMockRead(*conn_resp, 1),
   10989     CreateMockRead(*wrapped_resp1, 3),
   10990     CreateMockRead(*wrapped_body1, 4),
   10991     CreateMockRead(*resp2, 6),
   10992     CreateMockRead(*body2, 7),
   10993     MockRead(ASYNC, ERR_IO_PENDING, 8)
   10994   };
   10995 
   10996   DeterministicSocketData data1(reads1, arraysize(reads1),
   10997                                 writes1, arraysize(writes1));
   10998   MockConnect connect_data1(ASYNC, OK);
   10999   data1.set_connect_data(connect_data1);
   11000 
   11001   session_deps_.proxy_service.reset(
   11002       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   11003   CapturingNetLog log;
   11004   session_deps_.net_log = &log;
   11005   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   11006   ssl1.SetNextProto(GetParam());
   11007   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11008   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   11009   ssl2.SetNextProto(GetParam());
   11010   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11011   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&data1);
   11012 
   11013   scoped_refptr<HttpNetworkSession> session(
   11014       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11015 
   11016   // Start the first transaction to set up the SpdySession
   11017   HttpRequestInfo request1;
   11018   request1.method = "GET";
   11019   request1.url = GURL(https_url);
   11020   request1.load_flags = 0;
   11021   HttpNetworkTransaction trans1(LOWEST, session.get());
   11022   TestCompletionCallback callback1;
   11023   EXPECT_EQ(ERR_IO_PENDING,
   11024             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11025   base::MessageLoop::current()->RunUntilIdle();
   11026   data1.RunFor(4);
   11027 
   11028   EXPECT_EQ(OK, callback1.WaitForResult());
   11029   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11030 
   11031   LoadTimingInfo load_timing_info1;
   11032   EXPECT_TRUE(trans1.GetLoadTimingInfo(&load_timing_info1));
   11033   TestLoadTimingNotReusedWithPac(load_timing_info1,
   11034                                  CONNECT_TIMING_HAS_SSL_TIMES);
   11035 
   11036   // Now, start the HTTP request
   11037   HttpRequestInfo request2;
   11038   request2.method = "GET";
   11039   request2.url = GURL(http_url);
   11040   request2.load_flags = 0;
   11041   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11042   TestCompletionCallback callback2;
   11043   EXPECT_EQ(ERR_IO_PENDING,
   11044             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11045   base::MessageLoop::current()->RunUntilIdle();
   11046   data1.RunFor(3);
   11047 
   11048   EXPECT_EQ(OK, callback2.WaitForResult());
   11049   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11050 
   11051   LoadTimingInfo load_timing_info2;
   11052   EXPECT_TRUE(trans2.GetLoadTimingInfo(&load_timing_info2));
   11053   // The established SPDY sessions is considered reused by the HTTP request.
   11054   TestLoadTimingReusedWithPac(load_timing_info2);
   11055   // HTTP requests over a SPDY session should have a different connection
   11056   // socket_log_id than requests over a tunnel.
   11057   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   11058 }
   11059 
   11060 TEST_P(HttpNetworkTransactionTest, UseSpdySessionForHttpWhenForced) {
   11061   HttpStreamFactory::set_force_spdy_always(true);
   11062   const std::string https_url = "https://www.google.com/";
   11063   const std::string http_url = "http://www.google.com:443/";
   11064 
   11065   // SPDY GET for HTTPS URL
   11066   scoped_ptr<SpdyFrame> req1(
   11067       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
   11068   // SPDY GET for the HTTP URL
   11069   scoped_ptr<SpdyFrame> req2(
   11070       spdy_util_.ConstructSpdyGet(http_url.c_str(), false, 3, MEDIUM));
   11071 
   11072   MockWrite writes[] = {
   11073     CreateMockWrite(*req1, 1),
   11074     CreateMockWrite(*req2, 4),
   11075   };
   11076 
   11077   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11078   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11079   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   11080   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(3, true));
   11081   MockRead reads[] = {
   11082     CreateMockRead(*resp1, 2),
   11083     CreateMockRead(*body1, 3),
   11084     CreateMockRead(*resp2, 5),
   11085     CreateMockRead(*body2, 6),
   11086     MockRead(ASYNC, ERR_IO_PENDING, 7)
   11087   };
   11088 
   11089   OrderedSocketData data(reads, arraysize(reads),
   11090                          writes, arraysize(writes));
   11091 
   11092   SSLSocketDataProvider ssl(ASYNC, OK);
   11093   ssl.SetNextProto(GetParam());
   11094   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   11095   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11096 
   11097   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11098 
   11099   // Start the first transaction to set up the SpdySession
   11100   HttpRequestInfo request1;
   11101   request1.method = "GET";
   11102   request1.url = GURL(https_url);
   11103   request1.load_flags = 0;
   11104   HttpNetworkTransaction trans1(LOWEST, session.get());
   11105   TestCompletionCallback callback1;
   11106   EXPECT_EQ(ERR_IO_PENDING,
   11107             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11108   base::MessageLoop::current()->RunUntilIdle();
   11109 
   11110   EXPECT_EQ(OK, callback1.WaitForResult());
   11111   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11112 
   11113   // Now, start the HTTP request
   11114   HttpRequestInfo request2;
   11115   request2.method = "GET";
   11116   request2.url = GURL(http_url);
   11117   request2.load_flags = 0;
   11118   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11119   TestCompletionCallback callback2;
   11120   EXPECT_EQ(ERR_IO_PENDING,
   11121             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11122   base::MessageLoop::current()->RunUntilIdle();
   11123 
   11124   EXPECT_EQ(OK, callback2.WaitForResult());
   11125   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11126 }
   11127 
   11128 // Test that in the case where we have a SPDY session to a SPDY proxy
   11129 // that we do not pool other origins that resolve to the same IP when
   11130 // the certificate does not match the new origin.
   11131 // http://crbug.com/134690
   11132 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionIfCertDoesNotMatch) {
   11133   const std::string url1 = "http://www.google.com/";
   11134   const std::string url2 = "https://mail.google.com/";
   11135   const std::string ip_addr = "1.2.3.4";
   11136 
   11137   // SPDY GET for HTTP URL (through SPDY proxy)
   11138   scoped_ptr<SpdyHeaderBlock> headers(
   11139       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   11140   scoped_ptr<SpdyFrame> req1(spdy_util_.ConstructSpdyControlFrame(
   11141       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   11142 
   11143   MockWrite writes1[] = {
   11144     CreateMockWrite(*req1, 0),
   11145   };
   11146 
   11147   scoped_ptr<SpdyFrame> resp1(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11148   scoped_ptr<SpdyFrame> body1(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11149   MockRead reads1[] = {
   11150     CreateMockRead(*resp1, 1),
   11151     CreateMockRead(*body1, 2),
   11152     MockRead(ASYNC, OK, 3) // EOF
   11153   };
   11154 
   11155   scoped_ptr<DeterministicSocketData> data1(
   11156       new DeterministicSocketData(reads1, arraysize(reads1),
   11157                                   writes1, arraysize(writes1)));
   11158   IPAddressNumber ip;
   11159   ASSERT_TRUE(ParseIPLiteralToNumber(ip_addr, &ip));
   11160   IPEndPoint peer_addr = IPEndPoint(ip, 443);
   11161   MockConnect connect_data1(ASYNC, OK, peer_addr);
   11162   data1->set_connect_data(connect_data1);
   11163 
   11164   // SPDY GET for HTTPS URL (direct)
   11165   scoped_ptr<SpdyFrame> req2(
   11166       spdy_util_.ConstructSpdyGet(url2.c_str(), false, 1, MEDIUM));
   11167 
   11168   MockWrite writes2[] = {
   11169     CreateMockWrite(*req2, 0),
   11170   };
   11171 
   11172   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11173   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11174   MockRead reads2[] = {
   11175     CreateMockRead(*resp2, 1),
   11176     CreateMockRead(*body2, 2),
   11177     MockRead(ASYNC, OK, 3) // EOF
   11178   };
   11179 
   11180   scoped_ptr<DeterministicSocketData> data2(
   11181       new DeterministicSocketData(reads2, arraysize(reads2),
   11182                                   writes2, arraysize(writes2)));
   11183   MockConnect connect_data2(ASYNC, OK);
   11184   data2->set_connect_data(connect_data2);
   11185 
   11186   // Set up a proxy config that sends HTTP requests to a proxy, and
   11187   // all others direct.
   11188   ProxyConfig proxy_config;
   11189   proxy_config.proxy_rules().ParseFromString("http=https://proxy:443");
   11190   CapturingProxyResolver* capturing_proxy_resolver =
   11191       new CapturingProxyResolver();
   11192   session_deps_.proxy_service.reset(new ProxyService(
   11193       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   11194       NULL));
   11195 
   11196   // Load a valid cert.  Note, that this does not need to
   11197   // be valid for proxy because the MockSSLClientSocket does
   11198   // not actually verify it.  But SpdySession will use this
   11199   // to see if it is valid for the new origin
   11200   base::FilePath certs_dir = GetTestCertsDirectory();
   11201   scoped_refptr<X509Certificate> server_cert(
   11202       ImportCertFromFile(certs_dir, "ok_cert.pem"));
   11203   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
   11204 
   11205   SSLSocketDataProvider ssl1(ASYNC, OK);  // to the proxy
   11206   ssl1.SetNextProto(GetParam());
   11207   ssl1.cert = server_cert;
   11208   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11209   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11210       data1.get());
   11211 
   11212   SSLSocketDataProvider ssl2(ASYNC, OK);  // to the server
   11213   ssl2.SetNextProto(GetParam());
   11214   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11215   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11216       data2.get());
   11217 
   11218   session_deps_.host_resolver.reset(new MockCachingHostResolver());
   11219   session_deps_.host_resolver->rules()->AddRule("mail.google.com", ip_addr);
   11220   session_deps_.host_resolver->rules()->AddRule("proxy", ip_addr);
   11221 
   11222   scoped_refptr<HttpNetworkSession> session(
   11223       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11224 
   11225   // Start the first transaction to set up the SpdySession
   11226   HttpRequestInfo request1;
   11227   request1.method = "GET";
   11228   request1.url = GURL(url1);
   11229   request1.load_flags = 0;
   11230   HttpNetworkTransaction trans1(LOWEST, session.get());
   11231   TestCompletionCallback callback1;
   11232   ASSERT_EQ(ERR_IO_PENDING,
   11233             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11234   data1->RunFor(3);
   11235 
   11236   ASSERT_TRUE(callback1.have_result());
   11237   EXPECT_EQ(OK, callback1.WaitForResult());
   11238   EXPECT_TRUE(trans1.GetResponseInfo()->was_fetched_via_spdy);
   11239 
   11240   // Now, start the HTTP request
   11241   HttpRequestInfo request2;
   11242   request2.method = "GET";
   11243   request2.url = GURL(url2);
   11244   request2.load_flags = 0;
   11245   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11246   TestCompletionCallback callback2;
   11247   EXPECT_EQ(ERR_IO_PENDING,
   11248             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11249   base::MessageLoop::current()->RunUntilIdle();
   11250   data2->RunFor(3);
   11251 
   11252   ASSERT_TRUE(callback2.have_result());
   11253   EXPECT_EQ(OK, callback2.WaitForResult());
   11254   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11255 }
   11256 
   11257 // Test to verify that a failed socket read (due to an ERR_CONNECTION_CLOSED
   11258 // error) in SPDY session, removes the socket from pool and closes the SPDY
   11259 // session. Verify that new url's from the same HttpNetworkSession (and a new
   11260 // SpdySession) do work. http://crbug.com/224701
   11261 TEST_P(HttpNetworkTransactionTest, ErrorSocketNotConnected) {
   11262   const std::string https_url = "https://www.google.com/";
   11263 
   11264   MockRead reads1[] = {
   11265     MockRead(SYNCHRONOUS, ERR_CONNECTION_CLOSED, 0)
   11266   };
   11267 
   11268   scoped_ptr<DeterministicSocketData> data1(
   11269       new DeterministicSocketData(reads1, arraysize(reads1), NULL, 0));
   11270   data1->SetStop(1);
   11271 
   11272   scoped_ptr<SpdyFrame> req2(
   11273       spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, MEDIUM));
   11274   MockWrite writes2[] = {
   11275     CreateMockWrite(*req2, 0),
   11276   };
   11277 
   11278   scoped_ptr<SpdyFrame> resp2(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11279   scoped_ptr<SpdyFrame> body2(spdy_util_.ConstructSpdyBodyFrame(1, true));
   11280   MockRead reads2[] = {
   11281     CreateMockRead(*resp2, 1),
   11282     CreateMockRead(*body2, 2),
   11283     MockRead(ASYNC, OK, 3)  // EOF
   11284   };
   11285 
   11286   scoped_ptr<DeterministicSocketData> data2(
   11287       new DeterministicSocketData(reads2, arraysize(reads2),
   11288                                   writes2, arraysize(writes2)));
   11289 
   11290   SSLSocketDataProvider ssl1(ASYNC, OK);
   11291   ssl1.SetNextProto(GetParam());
   11292   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl1);
   11293   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11294       data1.get());
   11295 
   11296   SSLSocketDataProvider ssl2(ASYNC, OK);
   11297   ssl2.SetNextProto(GetParam());
   11298   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   11299   session_deps_.deterministic_socket_factory->AddSocketDataProvider(
   11300       data2.get());
   11301 
   11302   scoped_refptr<HttpNetworkSession> session(
   11303       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   11304 
   11305   // Start the first transaction to set up the SpdySession and verify that
   11306   // connection was closed.
   11307   HttpRequestInfo request1;
   11308   request1.method = "GET";
   11309   request1.url = GURL(https_url);
   11310   request1.load_flags = 0;
   11311   HttpNetworkTransaction trans1(MEDIUM, session.get());
   11312   TestCompletionCallback callback1;
   11313   EXPECT_EQ(ERR_IO_PENDING,
   11314             trans1.Start(&request1, callback1.callback(), BoundNetLog()));
   11315   base::MessageLoop::current()->RunUntilIdle();
   11316   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback1.WaitForResult());
   11317 
   11318   // Now, start the second request and make sure it succeeds.
   11319   HttpRequestInfo request2;
   11320   request2.method = "GET";
   11321   request2.url = GURL(https_url);
   11322   request2.load_flags = 0;
   11323   HttpNetworkTransaction trans2(MEDIUM, session.get());
   11324   TestCompletionCallback callback2;
   11325   EXPECT_EQ(ERR_IO_PENDING,
   11326             trans2.Start(&request2, callback2.callback(), BoundNetLog()));
   11327   base::MessageLoop::current()->RunUntilIdle();
   11328   data2->RunFor(3);
   11329 
   11330   ASSERT_TRUE(callback2.have_result());
   11331   EXPECT_EQ(OK, callback2.WaitForResult());
   11332   EXPECT_TRUE(trans2.GetResponseInfo()->was_fetched_via_spdy);
   11333 }
   11334 
   11335 TEST_P(HttpNetworkTransactionTest, CloseIdleSpdySessionToOpenNewOne) {
   11336   HttpStreamFactory::SetNextProtos(SpdyNextProtos());
   11337   ClientSocketPoolManager::set_max_sockets_per_group(
   11338       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11339   ClientSocketPoolManager::set_max_sockets_per_pool(
   11340       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   11341 
   11342   // Use two different hosts with different IPs so they don't get pooled.
   11343   session_deps_.host_resolver->rules()->AddRule("www.a.com", "10.0.0.1");
   11344   session_deps_.host_resolver->rules()->AddRule("www.b.com", "10.0.0.2");
   11345   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11346 
   11347   SSLSocketDataProvider ssl1(ASYNC, OK);
   11348   ssl1.SetNextProto(GetParam());
   11349   SSLSocketDataProvider ssl2(ASYNC, OK);
   11350   ssl2.SetNextProto(GetParam());
   11351   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   11352   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   11353 
   11354   scoped_ptr<SpdyFrame> host1_req(spdy_util_.ConstructSpdyGet(
   11355       "https://www.a.com", false, 1, DEFAULT_PRIORITY));
   11356   MockWrite spdy1_writes[] = {
   11357     CreateMockWrite(*host1_req, 1),
   11358   };
   11359   scoped_ptr<SpdyFrame> host1_resp(
   11360       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11361   scoped_ptr<SpdyFrame> host1_resp_body(
   11362       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11363   MockRead spdy1_reads[] = {
   11364     CreateMockRead(*host1_resp, 2),
   11365     CreateMockRead(*host1_resp_body, 3),
   11366     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11367   };
   11368 
   11369   scoped_ptr<OrderedSocketData> spdy1_data(
   11370       new OrderedSocketData(
   11371           spdy1_reads, arraysize(spdy1_reads),
   11372           spdy1_writes, arraysize(spdy1_writes)));
   11373   session_deps_.socket_factory->AddSocketDataProvider(spdy1_data.get());
   11374 
   11375   scoped_ptr<SpdyFrame> host2_req(spdy_util_.ConstructSpdyGet(
   11376       "https://www.b.com", false, 1, DEFAULT_PRIORITY));
   11377   MockWrite spdy2_writes[] = {
   11378     CreateMockWrite(*host2_req, 1),
   11379   };
   11380   scoped_ptr<SpdyFrame> host2_resp(
   11381       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   11382   scoped_ptr<SpdyFrame> host2_resp_body(
   11383       spdy_util_.ConstructSpdyBodyFrame(1, true));
   11384   MockRead spdy2_reads[] = {
   11385     CreateMockRead(*host2_resp, 2),
   11386     CreateMockRead(*host2_resp_body, 3),
   11387     MockRead(ASYNC, ERR_IO_PENDING, 4),
   11388   };
   11389 
   11390   scoped_ptr<OrderedSocketData> spdy2_data(
   11391       new OrderedSocketData(
   11392           spdy2_reads, arraysize(spdy2_reads),
   11393           spdy2_writes, arraysize(spdy2_writes)));
   11394   session_deps_.socket_factory->AddSocketDataProvider(spdy2_data.get());
   11395 
   11396   MockWrite http_write[] = {
   11397     MockWrite("GET / HTTP/1.1\r\n"
   11398               "Host: www.a.com\r\n"
   11399               "Connection: keep-alive\r\n\r\n"),
   11400   };
   11401 
   11402   MockRead http_read[] = {
   11403     MockRead("HTTP/1.1 200 OK\r\n"),
   11404     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   11405     MockRead("Content-Length: 6\r\n\r\n"),
   11406     MockRead("hello!"),
   11407   };
   11408   StaticSocketDataProvider http_data(http_read, arraysize(http_read),
   11409                                      http_write, arraysize(http_write));
   11410   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   11411 
   11412   HostPortPair host_port_pair_a("www.a.com", 443);
   11413   SpdySessionKey spdy_session_key_a(
   11414       host_port_pair_a, ProxyServer::Direct(), kPrivacyModeDisabled);
   11415   EXPECT_FALSE(
   11416       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11417 
   11418   TestCompletionCallback callback;
   11419   HttpRequestInfo request1;
   11420   request1.method = "GET";
   11421   request1.url = GURL("https://www.a.com/");
   11422   request1.load_flags = 0;
   11423   scoped_ptr<HttpNetworkTransaction> trans(
   11424       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11425 
   11426   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   11427   EXPECT_EQ(ERR_IO_PENDING, rv);
   11428   EXPECT_EQ(OK, callback.WaitForResult());
   11429 
   11430   const HttpResponseInfo* response = trans->GetResponseInfo();
   11431   ASSERT_TRUE(response != NULL);
   11432   ASSERT_TRUE(response->headers.get() != NULL);
   11433   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11434   EXPECT_TRUE(response->was_fetched_via_spdy);
   11435   EXPECT_TRUE(response->was_npn_negotiated);
   11436 
   11437   std::string response_data;
   11438   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11439   EXPECT_EQ("hello!", response_data);
   11440   trans.reset();
   11441   EXPECT_TRUE(
   11442       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11443 
   11444   HostPortPair host_port_pair_b("www.b.com", 443);
   11445   SpdySessionKey spdy_session_key_b(
   11446       host_port_pair_b, ProxyServer::Direct(), kPrivacyModeDisabled);
   11447   EXPECT_FALSE(
   11448       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11449   HttpRequestInfo request2;
   11450   request2.method = "GET";
   11451   request2.url = GURL("https://www.b.com/");
   11452   request2.load_flags = 0;
   11453   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11454 
   11455   rv = trans->Start(&request2, callback.callback(), BoundNetLog());
   11456   EXPECT_EQ(ERR_IO_PENDING, rv);
   11457   EXPECT_EQ(OK, callback.WaitForResult());
   11458 
   11459   response = trans->GetResponseInfo();
   11460   ASSERT_TRUE(response != NULL);
   11461   ASSERT_TRUE(response->headers.get() != NULL);
   11462   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11463   EXPECT_TRUE(response->was_fetched_via_spdy);
   11464   EXPECT_TRUE(response->was_npn_negotiated);
   11465   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11466   EXPECT_EQ("hello!", response_data);
   11467   EXPECT_FALSE(
   11468       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11469   EXPECT_TRUE(
   11470       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11471 
   11472   HostPortPair host_port_pair_a1("www.a.com", 80);
   11473   SpdySessionKey spdy_session_key_a1(
   11474       host_port_pair_a1, ProxyServer::Direct(), kPrivacyModeDisabled);
   11475   EXPECT_FALSE(
   11476       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a1));
   11477   HttpRequestInfo request3;
   11478   request3.method = "GET";
   11479   request3.url = GURL("http://www.a.com/");
   11480   request3.load_flags = 0;
   11481   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   11482 
   11483   rv = trans->Start(&request3, callback.callback(), BoundNetLog());
   11484   EXPECT_EQ(ERR_IO_PENDING, rv);
   11485   EXPECT_EQ(OK, callback.WaitForResult());
   11486 
   11487   response = trans->GetResponseInfo();
   11488   ASSERT_TRUE(response != NULL);
   11489   ASSERT_TRUE(response->headers.get() != NULL);
   11490   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   11491   EXPECT_FALSE(response->was_fetched_via_spdy);
   11492   EXPECT_FALSE(response->was_npn_negotiated);
   11493   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   11494   EXPECT_EQ("hello!", response_data);
   11495   EXPECT_FALSE(
   11496       HasSpdySession(session->spdy_session_pool(), spdy_session_key_a));
   11497   EXPECT_FALSE(
   11498       HasSpdySession(session->spdy_session_pool(), spdy_session_key_b));
   11499 }
   11500 
   11501 TEST_P(HttpNetworkTransactionTest, HttpSyncConnectError) {
   11502   HttpRequestInfo request;
   11503   request.method = "GET";
   11504   request.url = GURL("http://www.google.com/");
   11505   request.load_flags = 0;
   11506 
   11507   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11508   scoped_ptr<HttpTransaction> trans(
   11509       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11510 
   11511   MockConnect mock_connect(SYNCHRONOUS, ERR_CONNECTION_REFUSED);
   11512   StaticSocketDataProvider data;
   11513   data.set_connect_data(mock_connect);
   11514   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11515 
   11516   TestCompletionCallback callback;
   11517 
   11518   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11519   EXPECT_EQ(ERR_IO_PENDING, rv);
   11520 
   11521   rv = callback.WaitForResult();
   11522   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   11523 
   11524   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11525 
   11526   // We don't care whether this succeeds or fails, but it shouldn't crash.
   11527   HttpRequestHeaders request_headers;
   11528   trans->GetFullRequestHeaders(&request_headers);
   11529 }
   11530 
   11531 TEST_P(HttpNetworkTransactionTest, HttpAsyncConnectError) {
   11532   HttpRequestInfo request;
   11533   request.method = "GET";
   11534   request.url = GURL("http://www.google.com/");
   11535   request.load_flags = 0;
   11536 
   11537   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11538   scoped_ptr<HttpTransaction> trans(
   11539       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11540 
   11541   MockConnect mock_connect(ASYNC, ERR_CONNECTION_REFUSED);
   11542   StaticSocketDataProvider data;
   11543   data.set_connect_data(mock_connect);
   11544   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11545 
   11546   TestCompletionCallback callback;
   11547 
   11548   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11549   EXPECT_EQ(ERR_IO_PENDING, rv);
   11550 
   11551   rv = callback.WaitForResult();
   11552   EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
   11553 
   11554   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11555 
   11556   // We don't care whether this succeeds or fails, but it shouldn't crash.
   11557   HttpRequestHeaders request_headers;
   11558   trans->GetFullRequestHeaders(&request_headers);
   11559 }
   11560 
   11561 TEST_P(HttpNetworkTransactionTest, HttpSyncWriteError) {
   11562   HttpRequestInfo request;
   11563   request.method = "GET";
   11564   request.url = GURL("http://www.google.com/");
   11565   request.load_flags = 0;
   11566 
   11567   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11568   scoped_ptr<HttpTransaction> trans(
   11569       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11570 
   11571   MockWrite data_writes[] = {
   11572     MockWrite(SYNCHRONOUS, ERR_CONNECTION_RESET),
   11573   };
   11574   MockRead data_reads[] = {
   11575     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   11576   };
   11577 
   11578   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11579                                 data_writes, arraysize(data_writes));
   11580   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11581 
   11582   TestCompletionCallback callback;
   11583 
   11584   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11585   EXPECT_EQ(ERR_IO_PENDING, rv);
   11586 
   11587   rv = callback.WaitForResult();
   11588   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11589 
   11590   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11591 
   11592   HttpRequestHeaders request_headers;
   11593   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11594   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11595 }
   11596 
   11597 TEST_P(HttpNetworkTransactionTest, HttpAsyncWriteError) {
   11598   HttpRequestInfo request;
   11599   request.method = "GET";
   11600   request.url = GURL("http://www.google.com/");
   11601   request.load_flags = 0;
   11602 
   11603   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11604   scoped_ptr<HttpTransaction> trans(
   11605       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11606 
   11607   MockWrite data_writes[] = {
   11608     MockWrite(ASYNC, ERR_CONNECTION_RESET),
   11609   };
   11610   MockRead data_reads[] = {
   11611     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   11612   };
   11613 
   11614   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11615                                 data_writes, arraysize(data_writes));
   11616   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11617 
   11618   TestCompletionCallback callback;
   11619 
   11620   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11621   EXPECT_EQ(ERR_IO_PENDING, rv);
   11622 
   11623   rv = callback.WaitForResult();
   11624   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11625 
   11626   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11627 
   11628   HttpRequestHeaders request_headers;
   11629   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11630   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11631 }
   11632 
   11633 TEST_P(HttpNetworkTransactionTest, HttpSyncReadError) {
   11634   HttpRequestInfo request;
   11635   request.method = "GET";
   11636   request.url = GURL("http://www.google.com/");
   11637   request.load_flags = 0;
   11638 
   11639   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11640   scoped_ptr<HttpTransaction> trans(
   11641       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11642 
   11643   MockWrite data_writes[] = {
   11644     MockWrite("GET / HTTP/1.1\r\n"
   11645               "Host: www.google.com\r\n"
   11646               "Connection: keep-alive\r\n\r\n"),
   11647   };
   11648   MockRead data_reads[] = {
   11649     MockRead(SYNCHRONOUS, ERR_CONNECTION_RESET),
   11650   };
   11651 
   11652   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11653                                 data_writes, arraysize(data_writes));
   11654   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11655 
   11656   TestCompletionCallback callback;
   11657 
   11658   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11659   EXPECT_EQ(ERR_IO_PENDING, rv);
   11660 
   11661   rv = callback.WaitForResult();
   11662   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11663 
   11664   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11665 
   11666   HttpRequestHeaders request_headers;
   11667   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11668   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11669 }
   11670 
   11671 TEST_P(HttpNetworkTransactionTest, HttpAsyncReadError) {
   11672   HttpRequestInfo request;
   11673   request.method = "GET";
   11674   request.url = GURL("http://www.google.com/");
   11675   request.load_flags = 0;
   11676 
   11677   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11678   scoped_ptr<HttpTransaction> trans(
   11679       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11680 
   11681   MockWrite data_writes[] = {
   11682     MockWrite("GET / HTTP/1.1\r\n"
   11683               "Host: www.google.com\r\n"
   11684               "Connection: keep-alive\r\n\r\n"),
   11685   };
   11686   MockRead data_reads[] = {
   11687     MockRead(ASYNC, ERR_CONNECTION_RESET),
   11688   };
   11689 
   11690   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11691                                 data_writes, arraysize(data_writes));
   11692   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11693 
   11694   TestCompletionCallback callback;
   11695 
   11696   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11697   EXPECT_EQ(ERR_IO_PENDING, rv);
   11698 
   11699   rv = callback.WaitForResult();
   11700   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   11701 
   11702   EXPECT_EQ(NULL, trans->GetResponseInfo());
   11703 
   11704   HttpRequestHeaders request_headers;
   11705   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11706   EXPECT_TRUE(request_headers.HasHeader("Host"));
   11707 }
   11708 
   11709 TEST_P(HttpNetworkTransactionTest, GetFullRequestHeadersIncludesExtraHeader) {
   11710   HttpRequestInfo request;
   11711   request.method = "GET";
   11712   request.url = GURL("http://www.google.com/");
   11713   request.load_flags = 0;
   11714   request.extra_headers.SetHeader("X-Foo", "bar");
   11715 
   11716   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   11717   scoped_ptr<HttpTransaction> trans(
   11718       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   11719 
   11720   MockWrite data_writes[] = {
   11721     MockWrite("GET / HTTP/1.1\r\n"
   11722               "Host: www.google.com\r\n"
   11723               "Connection: keep-alive\r\n"
   11724               "X-Foo: bar\r\n\r\n"),
   11725   };
   11726   MockRead data_reads[] = {
   11727     MockRead("HTTP/1.1 200 OK\r\n"
   11728              "Content-Length: 5\r\n\r\n"
   11729              "hello"),
   11730     MockRead(ASYNC, ERR_UNEXPECTED),
   11731   };
   11732 
   11733   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   11734                                 data_writes, arraysize(data_writes));
   11735   session_deps_.socket_factory->AddSocketDataProvider(&data);
   11736 
   11737   TestCompletionCallback callback;
   11738 
   11739   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   11740   EXPECT_EQ(ERR_IO_PENDING, rv);
   11741 
   11742   rv = callback.WaitForResult();
   11743   EXPECT_EQ(OK, rv);
   11744 
   11745   HttpRequestHeaders request_headers;
   11746   EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
   11747   std::string foo;
   11748   EXPECT_TRUE(request_headers.GetHeader("X-Foo", &foo));
   11749   EXPECT_EQ("bar", foo);
   11750 }
   11751 
   11752 namespace {
   11753 
   11754 // Fake HttpStreamBase that simply records calls to SetPriority().
   11755 class FakeStream : public HttpStreamBase,
   11756                    public base::SupportsWeakPtr<FakeStream> {
   11757  public:
   11758   explicit FakeStream(RequestPriority priority) : priority_(priority) {}
   11759   virtual ~FakeStream() {}
   11760 
   11761   RequestPriority priority() const { return priority_; }
   11762 
   11763   virtual int InitializeStream(const HttpRequestInfo* request_info,
   11764                                RequestPriority priority,
   11765                                const BoundNetLog& net_log,
   11766                                const CompletionCallback& callback) OVERRIDE {
   11767     return ERR_IO_PENDING;
   11768   }
   11769 
   11770   virtual int SendRequest(const HttpRequestHeaders& request_headers,
   11771                           HttpResponseInfo* response,
   11772                           const CompletionCallback& callback) OVERRIDE {
   11773     ADD_FAILURE();
   11774     return ERR_UNEXPECTED;
   11775   }
   11776 
   11777   virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE {
   11778     ADD_FAILURE();
   11779     return ERR_UNEXPECTED;
   11780   }
   11781 
   11782   virtual const HttpResponseInfo* GetResponseInfo() const OVERRIDE {
   11783     ADD_FAILURE();
   11784     return NULL;
   11785   }
   11786 
   11787   virtual int ReadResponseBody(IOBuffer* buf, int buf_len,
   11788                                const CompletionCallback& callback) OVERRIDE {
   11789     ADD_FAILURE();
   11790     return ERR_UNEXPECTED;
   11791   }
   11792 
   11793   virtual void Close(bool not_reusable) OVERRIDE {}
   11794 
   11795   virtual bool IsResponseBodyComplete() const OVERRIDE {
   11796     ADD_FAILURE();
   11797     return false;
   11798   }
   11799 
   11800   virtual bool CanFindEndOfResponse() const OVERRIDE {
   11801     return false;
   11802   }
   11803 
   11804   virtual bool IsConnectionReused() const OVERRIDE {
   11805     ADD_FAILURE();
   11806     return false;
   11807   }
   11808 
   11809   virtual void SetConnectionReused() OVERRIDE {
   11810     ADD_FAILURE();
   11811   }
   11812 
   11813   virtual bool IsConnectionReusable() const OVERRIDE {
   11814     ADD_FAILURE();
   11815     return false;
   11816   }
   11817 
   11818   virtual int64 GetTotalReceivedBytes() const OVERRIDE {
   11819     ADD_FAILURE();
   11820     return 0;
   11821   }
   11822 
   11823   virtual bool GetLoadTimingInfo(
   11824       LoadTimingInfo* load_timing_info) const OVERRIDE {
   11825     ADD_FAILURE();
   11826     return false;
   11827   }
   11828 
   11829   virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE {
   11830     ADD_FAILURE();
   11831   }
   11832 
   11833   virtual void GetSSLCertRequestInfo(
   11834       SSLCertRequestInfo* cert_request_info) OVERRIDE {
   11835     ADD_FAILURE();
   11836   }
   11837 
   11838   virtual bool IsSpdyHttpStream() const OVERRIDE {
   11839     ADD_FAILURE();
   11840     return false;
   11841   }
   11842 
   11843   virtual void Drain(HttpNetworkSession* session) OVERRIDE {
   11844     ADD_FAILURE();
   11845   }
   11846 
   11847   virtual void SetPriority(RequestPriority priority) OVERRIDE {
   11848     priority_ = priority;
   11849   }
   11850 
   11851  private:
   11852   RequestPriority priority_;
   11853 
   11854   DISALLOW_COPY_AND_ASSIGN(FakeStream);
   11855 };
   11856 
   11857 // Fake HttpStreamRequest that simply records calls to SetPriority()
   11858 // and vends FakeStreams with its current priority.
   11859 class FakeStreamRequest : public HttpStreamRequest,
   11860                           public base::SupportsWeakPtr<FakeStreamRequest> {
   11861  public:
   11862   FakeStreamRequest(RequestPriority priority,
   11863                     HttpStreamRequest::Delegate* delegate)
   11864       : priority_(priority),
   11865         delegate_(delegate),
   11866         websocket_stream_create_helper_(NULL) {}
   11867 
   11868   FakeStreamRequest(RequestPriority priority,
   11869                     HttpStreamRequest::Delegate* delegate,
   11870                     WebSocketHandshakeStreamBase::CreateHelper* create_helper)
   11871       : priority_(priority),
   11872         delegate_(delegate),
   11873         websocket_stream_create_helper_(create_helper) {}
   11874 
   11875   virtual ~FakeStreamRequest() {}
   11876 
   11877   RequestPriority priority() const { return priority_; }
   11878 
   11879   const WebSocketHandshakeStreamBase::CreateHelper*
   11880   websocket_stream_create_helper() const {
   11881     return websocket_stream_create_helper_;
   11882   }
   11883 
   11884   // Create a new FakeStream and pass it to the request's
   11885   // delegate. Returns a weak pointer to the FakeStream.
   11886   base::WeakPtr<FakeStream> FinishStreamRequest() {
   11887     FakeStream* fake_stream = new FakeStream(priority_);
   11888     // Do this before calling OnStreamReady() as OnStreamReady() may
   11889     // immediately delete |fake_stream|.
   11890     base::WeakPtr<FakeStream> weak_stream = fake_stream->AsWeakPtr();
   11891     delegate_->OnStreamReady(SSLConfig(), ProxyInfo(), fake_stream);
   11892     return weak_stream;
   11893   }
   11894 
   11895   virtual int RestartTunnelWithProxyAuth(
   11896       const AuthCredentials& credentials) OVERRIDE {
   11897     ADD_FAILURE();
   11898     return ERR_UNEXPECTED;
   11899   }
   11900 
   11901   virtual LoadState GetLoadState() const OVERRIDE {
   11902     ADD_FAILURE();
   11903     return LoadState();
   11904   }
   11905 
   11906   virtual void SetPriority(RequestPriority priority) OVERRIDE {
   11907     priority_ = priority;
   11908   }
   11909 
   11910   virtual bool was_npn_negotiated() const OVERRIDE {
   11911     return false;
   11912   }
   11913 
   11914   virtual NextProto protocol_negotiated() const OVERRIDE {
   11915     return kProtoUnknown;
   11916   }
   11917 
   11918   virtual bool using_spdy() const OVERRIDE {
   11919     return false;
   11920   }
   11921 
   11922  private:
   11923   RequestPriority priority_;
   11924   HttpStreamRequest::Delegate* const delegate_;
   11925   WebSocketHandshakeStreamBase::CreateHelper* websocket_stream_create_helper_;
   11926 
   11927   DISALLOW_COPY_AND_ASSIGN(FakeStreamRequest);
   11928 };
   11929 
   11930 // Fake HttpStreamFactory that vends FakeStreamRequests.
   11931 class FakeStreamFactory : public HttpStreamFactory {
   11932  public:
   11933   FakeStreamFactory() {}
   11934   virtual ~FakeStreamFactory() {}
   11935 
   11936   // Returns a WeakPtr<> to the last HttpStreamRequest returned by
   11937   // RequestStream() (which may be NULL if it was destroyed already).
   11938   base::WeakPtr<FakeStreamRequest> last_stream_request() {
   11939     return last_stream_request_;
   11940   }
   11941 
   11942   virtual HttpStreamRequest* RequestStream(
   11943       const HttpRequestInfo& info,
   11944       RequestPriority priority,
   11945       const SSLConfig& server_ssl_config,
   11946       const SSLConfig& proxy_ssl_config,
   11947       HttpStreamRequest::Delegate* delegate,
   11948       const BoundNetLog& net_log) OVERRIDE {
   11949     FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
   11950     last_stream_request_ = fake_request->AsWeakPtr();
   11951     return fake_request;
   11952   }
   11953 
   11954   virtual HttpStreamRequest* RequestWebSocketHandshakeStream(
   11955       const HttpRequestInfo& info,
   11956       RequestPriority priority,
   11957       const SSLConfig& server_ssl_config,
   11958       const SSLConfig& proxy_ssl_config,
   11959       HttpStreamRequest::Delegate* delegate,
   11960       WebSocketHandshakeStreamBase::CreateHelper* create_helper,
   11961       const BoundNetLog& net_log) OVERRIDE {
   11962     FakeStreamRequest* fake_request =
   11963         new FakeStreamRequest(priority, delegate, create_helper);
   11964     last_stream_request_ = fake_request->AsWeakPtr();
   11965     return fake_request;
   11966   }
   11967 
   11968   virtual void PreconnectStreams(int num_streams,
   11969                                  const HttpRequestInfo& info,
   11970                                  RequestPriority priority,
   11971                                  const SSLConfig& server_ssl_config,
   11972                                  const SSLConfig& proxy_ssl_config) OVERRIDE {
   11973     ADD_FAILURE();
   11974   }
   11975 
   11976   virtual base::Value* PipelineInfoToValue() const OVERRIDE {
   11977     ADD_FAILURE();
   11978     return NULL;
   11979   }
   11980 
   11981   virtual const HostMappingRules* GetHostMappingRules() const OVERRIDE {
   11982     ADD_FAILURE();
   11983     return NULL;
   11984   }
   11985 
   11986  private:
   11987   base::WeakPtr<FakeStreamRequest> last_stream_request_;
   11988 
   11989   DISALLOW_COPY_AND_ASSIGN(FakeStreamFactory);
   11990 };
   11991 
   11992 // TODO(yhirano): Split this class out into a net/websockets file, if it is
   11993 // worth doing.
   11994 class FakeWebSocketStreamCreateHelper :
   11995       public WebSocketHandshakeStreamBase::CreateHelper {
   11996  public:
   11997   virtual WebSocketHandshakeStreamBase* CreateBasicStream(
   11998       scoped_ptr<ClientSocketHandle> connection,
   11999       bool using_proxy) OVERRIDE {
   12000     NOTREACHED();
   12001     return NULL;
   12002   }
   12003 
   12004   virtual WebSocketHandshakeStreamBase* CreateSpdyStream(
   12005       const base::WeakPtr<SpdySession>& session,
   12006       bool use_relative_url) OVERRIDE {
   12007     NOTREACHED();
   12008     return NULL;
   12009   };
   12010 
   12011   virtual ~FakeWebSocketStreamCreateHelper() {}
   12012 
   12013   virtual scoped_ptr<WebSocketStream> Upgrade() {
   12014     NOTREACHED();
   12015     return scoped_ptr<WebSocketStream>();
   12016   }
   12017 };
   12018 
   12019 }  // namespace
   12020 
   12021 // Make sure that HttpNetworkTransaction passes on its priority to its
   12022 // stream request on start.
   12023 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriorityOnStart) {
   12024   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12025   HttpNetworkSessionPeer peer(session);
   12026   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12027   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12028 
   12029   HttpNetworkTransaction trans(LOW, session);
   12030 
   12031   ASSERT_TRUE(fake_factory->last_stream_request() == NULL);
   12032 
   12033   HttpRequestInfo request;
   12034   TestCompletionCallback callback;
   12035   EXPECT_EQ(ERR_IO_PENDING,
   12036             trans.Start(&request, callback.callback(), BoundNetLog()));
   12037 
   12038   base::WeakPtr<FakeStreamRequest> fake_request =
   12039       fake_factory->last_stream_request();
   12040   ASSERT_TRUE(fake_request != NULL);
   12041   EXPECT_EQ(LOW, fake_request->priority());
   12042 }
   12043 
   12044 // Make sure that HttpNetworkTransaction passes on its priority
   12045 // updates to its stream request.
   12046 TEST_P(HttpNetworkTransactionTest, SetStreamRequestPriority) {
   12047   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12048   HttpNetworkSessionPeer peer(session);
   12049   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12050   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12051 
   12052   HttpNetworkTransaction trans(LOW, session);
   12053 
   12054   HttpRequestInfo request;
   12055   TestCompletionCallback callback;
   12056   EXPECT_EQ(ERR_IO_PENDING,
   12057             trans.Start(&request, callback.callback(), BoundNetLog()));
   12058 
   12059   base::WeakPtr<FakeStreamRequest> fake_request =
   12060       fake_factory->last_stream_request();
   12061   ASSERT_TRUE(fake_request != NULL);
   12062   EXPECT_EQ(LOW, fake_request->priority());
   12063 
   12064   trans.SetPriority(LOWEST);
   12065   ASSERT_TRUE(fake_request != NULL);
   12066   EXPECT_EQ(LOWEST, fake_request->priority());
   12067 }
   12068 
   12069 // Make sure that HttpNetworkTransaction passes on its priority
   12070 // updates to its stream.
   12071 TEST_P(HttpNetworkTransactionTest, SetStreamPriority) {
   12072   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12073   HttpNetworkSessionPeer peer(session);
   12074   FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12075   peer.SetHttpStreamFactory(scoped_ptr<HttpStreamFactory>(fake_factory));
   12076 
   12077   HttpNetworkTransaction trans(LOW, session);
   12078 
   12079   HttpRequestInfo request;
   12080   TestCompletionCallback callback;
   12081   EXPECT_EQ(ERR_IO_PENDING,
   12082             trans.Start(&request, callback.callback(), BoundNetLog()));
   12083 
   12084   base::WeakPtr<FakeStreamRequest> fake_request =
   12085       fake_factory->last_stream_request();
   12086   ASSERT_TRUE(fake_request != NULL);
   12087   base::WeakPtr<FakeStream> fake_stream = fake_request->FinishStreamRequest();
   12088   ASSERT_TRUE(fake_stream != NULL);
   12089   EXPECT_EQ(LOW, fake_stream->priority());
   12090 
   12091   trans.SetPriority(LOWEST);
   12092   EXPECT_EQ(LOWEST, fake_stream->priority());
   12093 }
   12094 
   12095 TEST_P(HttpNetworkTransactionTest, CreateWebSocketHandshakeStream) {
   12096   // The same logic needs to be tested for both ws: and wss: schemes, but this
   12097   // test is already parameterised on NextProto, so it uses a loop to verify
   12098   // that the different schemes work.
   12099   std::string test_cases[] = {"ws://www.google.com/", "wss://www.google.com/"};
   12100   for (size_t i = 0; i < arraysize(test_cases); ++i) {
   12101     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12102     HttpNetworkSessionPeer peer(session);
   12103     FakeStreamFactory* fake_factory = new FakeStreamFactory();
   12104     FakeWebSocketStreamCreateHelper websocket_stream_create_helper;
   12105     peer.SetHttpStreamFactoryForWebSocket(
   12106         scoped_ptr<HttpStreamFactory>(fake_factory));
   12107 
   12108     HttpNetworkTransaction trans(LOW, session);
   12109     trans.SetWebSocketHandshakeStreamCreateHelper(
   12110         &websocket_stream_create_helper);
   12111 
   12112     HttpRequestInfo request;
   12113     TestCompletionCallback callback;
   12114     request.method = "GET";
   12115     request.url = GURL(test_cases[i]);
   12116 
   12117     EXPECT_EQ(ERR_IO_PENDING,
   12118               trans.Start(&request, callback.callback(), BoundNetLog()));
   12119 
   12120     base::WeakPtr<FakeStreamRequest> fake_request =
   12121         fake_factory->last_stream_request();
   12122     ASSERT_TRUE(fake_request != NULL);
   12123     EXPECT_EQ(&websocket_stream_create_helper,
   12124               fake_request->websocket_stream_create_helper());
   12125   }
   12126 }
   12127 
   12128 // Tests that when a used socket is returned to the SSL socket pool, it's closed
   12129 // if the transport socket pool is stalled on the global socket limit.
   12130 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest) {
   12131   ClientSocketPoolManager::set_max_sockets_per_group(
   12132       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12133   ClientSocketPoolManager::set_max_sockets_per_pool(
   12134       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12135 
   12136   // Set up SSL request.
   12137 
   12138   HttpRequestInfo ssl_request;
   12139   ssl_request.method = "GET";
   12140   ssl_request.url = GURL("https://www.google.com/");
   12141 
   12142   MockWrite ssl_writes[] = {
   12143     MockWrite("GET / HTTP/1.1\r\n"
   12144               "Host: www.google.com\r\n"
   12145               "Connection: keep-alive\r\n\r\n"),
   12146   };
   12147   MockRead ssl_reads[] = {
   12148     MockRead("HTTP/1.1 200 OK\r\n"),
   12149     MockRead("Content-Length: 11\r\n\r\n"),
   12150     MockRead("hello world"),
   12151     MockRead(SYNCHRONOUS, OK),
   12152   };
   12153   StaticSocketDataProvider ssl_data(ssl_reads, arraysize(ssl_reads),
   12154                                     ssl_writes, arraysize(ssl_writes));
   12155   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
   12156 
   12157   SSLSocketDataProvider ssl(ASYNC, OK);
   12158   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   12159 
   12160   // Set up HTTP request.
   12161 
   12162   HttpRequestInfo http_request;
   12163   http_request.method = "GET";
   12164   http_request.url = GURL("http://www.google.com/");
   12165 
   12166   MockWrite http_writes[] = {
   12167     MockWrite("GET / HTTP/1.1\r\n"
   12168               "Host: www.google.com\r\n"
   12169               "Connection: keep-alive\r\n\r\n"),
   12170   };
   12171   MockRead http_reads[] = {
   12172     MockRead("HTTP/1.1 200 OK\r\n"),
   12173     MockRead("Content-Length: 7\r\n\r\n"),
   12174     MockRead("falafel"),
   12175     MockRead(SYNCHRONOUS, OK),
   12176   };
   12177   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
   12178                                      http_writes, arraysize(http_writes));
   12179   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   12180 
   12181   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12182 
   12183   // Start the SSL request.
   12184   TestCompletionCallback ssl_callback;
   12185   scoped_ptr<HttpTransaction> ssl_trans(
   12186       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12187   ASSERT_EQ(ERR_IO_PENDING,
   12188             ssl_trans->Start(&ssl_request, ssl_callback.callback(),
   12189             BoundNetLog()));
   12190 
   12191   // Start the HTTP request.  Pool should stall.
   12192   TestCompletionCallback http_callback;
   12193   scoped_ptr<HttpTransaction> http_trans(
   12194       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12195   ASSERT_EQ(ERR_IO_PENDING,
   12196             http_trans->Start(&http_request, http_callback.callback(),
   12197                               BoundNetLog()));
   12198   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
   12199 
   12200   // Wait for response from SSL request.
   12201   ASSERT_EQ(OK, ssl_callback.WaitForResult());
   12202   std::string response_data;
   12203   ASSERT_EQ(OK, ReadTransaction(ssl_trans.get(), &response_data));
   12204   EXPECT_EQ("hello world", response_data);
   12205 
   12206   // The SSL socket should automatically be closed, so the HTTP request can
   12207   // start.
   12208   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
   12209   ASSERT_FALSE(IsTransportSocketPoolStalled(session));
   12210 
   12211   // The HTTP request can now complete.
   12212   ASSERT_EQ(OK, http_callback.WaitForResult());
   12213   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
   12214   EXPECT_EQ("falafel", response_data);
   12215 
   12216   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
   12217 }
   12218 
   12219 // Tests that when a SSL connection is established but there's no corresponding
   12220 // request that needs it, the new socket is closed if the transport socket pool
   12221 // is stalled on the global socket limit.
   12222 TEST_P(HttpNetworkTransactionTest, CloseSSLSocketOnIdleForHttpRequest2) {
   12223   ClientSocketPoolManager::set_max_sockets_per_group(
   12224       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12225   ClientSocketPoolManager::set_max_sockets_per_pool(
   12226       HttpNetworkSession::NORMAL_SOCKET_POOL, 1);
   12227 
   12228   // Set up an ssl request.
   12229 
   12230   HttpRequestInfo ssl_request;
   12231   ssl_request.method = "GET";
   12232   ssl_request.url = GURL("https://www.foopy.com/");
   12233 
   12234   // No data will be sent on the SSL socket.
   12235   StaticSocketDataProvider ssl_data;
   12236   session_deps_.socket_factory->AddSocketDataProvider(&ssl_data);
   12237 
   12238   SSLSocketDataProvider ssl(ASYNC, OK);
   12239   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   12240 
   12241   // Set up HTTP request.
   12242 
   12243   HttpRequestInfo http_request;
   12244   http_request.method = "GET";
   12245   http_request.url = GURL("http://www.google.com/");
   12246 
   12247   MockWrite http_writes[] = {
   12248     MockWrite("GET / HTTP/1.1\r\n"
   12249               "Host: www.google.com\r\n"
   12250               "Connection: keep-alive\r\n\r\n"),
   12251   };
   12252   MockRead http_reads[] = {
   12253     MockRead("HTTP/1.1 200 OK\r\n"),
   12254     MockRead("Content-Length: 7\r\n\r\n"),
   12255     MockRead("falafel"),
   12256     MockRead(SYNCHRONOUS, OK),
   12257   };
   12258   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
   12259                                      http_writes, arraysize(http_writes));
   12260   session_deps_.socket_factory->AddSocketDataProvider(&http_data);
   12261 
   12262   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   12263 
   12264   // Preconnect an SSL socket.  A preconnect is needed because connect jobs are
   12265   // cancelled when a normal transaction is cancelled.
   12266   net::HttpStreamFactory* http_stream_factory = session->http_stream_factory();
   12267   net::SSLConfig ssl_config;
   12268   session->ssl_config_service()->GetSSLConfig(&ssl_config);
   12269   http_stream_factory->PreconnectStreams(1, ssl_request, DEFAULT_PRIORITY,
   12270                                          ssl_config, ssl_config);
   12271   EXPECT_EQ(0, GetIdleSocketCountInSSLSocketPool(session));
   12272 
   12273   // Start the HTTP request.  Pool should stall.
   12274   TestCompletionCallback http_callback;
   12275   scoped_ptr<HttpTransaction> http_trans(
   12276       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   12277   ASSERT_EQ(ERR_IO_PENDING,
   12278             http_trans->Start(&http_request, http_callback.callback(),
   12279                               BoundNetLog()));
   12280   EXPECT_TRUE(IsTransportSocketPoolStalled(session));
   12281 
   12282   // The SSL connection will automatically be closed once the connection is
   12283   // established, to let the HTTP request start.
   12284   ASSERT_EQ(OK, http_callback.WaitForResult());
   12285   std::string response_data;
   12286   ASSERT_EQ(OK, ReadTransaction(http_trans.get(), &response_data));
   12287   EXPECT_EQ("falafel", response_data);
   12288 
   12289   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session));
   12290 }
   12291 
   12292 }  // namespace net
   12293