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/run_loop.h"
     20 #include "base/strings/string_util.h"
     21 #include "base/strings/utf_string_conversions.h"
     22 #include "base/test/test_file_util.h"
     23 #include "net/base/auth.h"
     24 #include "net/base/capturing_net_log.h"
     25 #include "net/base/completion_callback.h"
     26 #include "net/base/load_timing_info.h"
     27 #include "net/base/load_timing_info_test_util.h"
     28 #include "net/base/net_log.h"
     29 #include "net/base/net_log_unittest.h"
     30 #include "net/base/request_priority.h"
     31 #include "net/base/test_completion_callback.h"
     32 #include "net/base/test_data_directory.h"
     33 #include "net/base/upload_bytes_element_reader.h"
     34 #include "net/base/upload_data_stream.h"
     35 #include "net/base/upload_file_element_reader.h"
     36 #include "net/cert/mock_cert_verifier.h"
     37 #include "net/dns/host_cache.h"
     38 #include "net/dns/mock_host_resolver.h"
     39 #include "net/http/http_auth_challenge_tokenizer.h"
     40 #include "net/http/http_auth_handler_digest.h"
     41 #include "net/http/http_auth_handler_mock.h"
     42 #include "net/http/http_auth_handler_ntlm.h"
     43 #include "net/http/http_basic_stream.h"
     44 #include "net/http/http_network_session.h"
     45 #include "net/http/http_network_session_peer.h"
     46 #include "net/http/http_server_properties_impl.h"
     47 #include "net/http/http_stream.h"
     48 #include "net/http/http_stream_factory.h"
     49 #include "net/http/http_transaction_test_util.h"
     50 #include "net/proxy/proxy_config_service_fixed.h"
     51 #include "net/proxy/proxy_info.h"
     52 #include "net/proxy/proxy_resolver.h"
     53 #include "net/proxy/proxy_service.h"
     54 #include "net/socket/client_socket_factory.h"
     55 #include "net/socket/client_socket_pool_manager.h"
     56 #include "net/socket/mock_client_socket_pool_manager.h"
     57 #include "net/socket/next_proto.h"
     58 #include "net/socket/socket_test_util.h"
     59 #include "net/socket/ssl_client_socket.h"
     60 #include "net/spdy/spdy_framer.h"
     61 #include "net/spdy/spdy_session.h"
     62 #include "net/spdy/spdy_session_pool.h"
     63 #include "net/spdy/spdy_test_util_common.h"
     64 #include "net/ssl/ssl_cert_request_info.h"
     65 #include "net/ssl/ssl_config_service.h"
     66 #include "net/ssl/ssl_config_service_defaults.h"
     67 #include "net/ssl/ssl_info.h"
     68 #include "net/test/cert_test_util.h"
     69 #include "net/websockets/websocket_handshake_stream_base.h"
     70 #include "testing/gtest/include/gtest/gtest.h"
     71 #include "testing/platform_test.h"
     72 #include "url/gurl.h"
     73 
     74 using base::ASCIIToUTF16;
     75 
     76 //-----------------------------------------------------------------------------
     77 
     78 namespace {
     79 
     80 const base::string16 kBar(ASCIIToUTF16("bar"));
     81 const base::string16 kBar2(ASCIIToUTF16("bar2"));
     82 const base::string16 kBar3(ASCIIToUTF16("bar3"));
     83 const base::string16 kBaz(ASCIIToUTF16("baz"));
     84 const base::string16 kFirst(ASCIIToUTF16("first"));
     85 const base::string16 kFoo(ASCIIToUTF16("foo"));
     86 const base::string16 kFoo2(ASCIIToUTF16("foo2"));
     87 const base::string16 kFoo3(ASCIIToUTF16("foo3"));
     88 const base::string16 kFou(ASCIIToUTF16("fou"));
     89 const base::string16 kSecond(ASCIIToUTF16("second"));
     90 const base::string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
     91 const base::string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
     92 
     93 int GetIdleSocketCountInTransportSocketPool(net::HttpNetworkSession* session) {
     94   return session->GetTransportSocketPool(
     95       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
     96 }
     97 
     98 int GetIdleSocketCountInSSLSocketPool(net::HttpNetworkSession* session) {
     99   return session->GetSSLSocketPool(
    100       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IdleSocketCount();
    101 }
    102 
    103 bool IsTransportSocketPoolStalled(net::HttpNetworkSession* session) {
    104   return session->GetTransportSocketPool(
    105       net::HttpNetworkSession::NORMAL_SOCKET_POOL)->IsStalled();
    106 }
    107 
    108 // Takes in a Value created from a NetLogHttpResponseParameter, and returns
    109 // a JSONified list of headers as a single string.  Uses single quotes instead
    110 // of double quotes for easier comparison.  Returns false on failure.
    111 bool GetHeaders(base::DictionaryValue* params, std::string* headers) {
    112   if (!params)
    113     return false;
    114   base::ListValue* header_list;
    115   if (!params->GetList("headers", &header_list))
    116     return false;
    117   std::string double_quote_headers;
    118   base::JSONWriter::Write(header_list, &double_quote_headers);
    119   base::ReplaceChars(double_quote_headers, "\"", "'", headers);
    120   return true;
    121 }
    122 
    123 // Tests LoadTimingInfo in the case a socket is reused and no PAC script is
    124 // used.
    125 void TestLoadTimingReused(const net::LoadTimingInfo& load_timing_info) {
    126   EXPECT_TRUE(load_timing_info.socket_reused);
    127   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    128 
    129   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    130   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    131 
    132   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    133   EXPECT_FALSE(load_timing_info.send_start.is_null());
    134 
    135   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    136 
    137   // Set at a higher level.
    138   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    139   EXPECT_TRUE(load_timing_info.request_start.is_null());
    140   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    141 }
    142 
    143 // Tests LoadTimingInfo in the case a new socket is used and no PAC script is
    144 // used.
    145 void TestLoadTimingNotReused(const net::LoadTimingInfo& load_timing_info,
    146                              int connect_timing_flags) {
    147   EXPECT_FALSE(load_timing_info.socket_reused);
    148   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    149 
    150   EXPECT_TRUE(load_timing_info.proxy_resolve_start.is_null());
    151   EXPECT_TRUE(load_timing_info.proxy_resolve_end.is_null());
    152 
    153   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    154                                    connect_timing_flags);
    155   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    156             load_timing_info.send_start);
    157 
    158   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    159 
    160   // Set at a higher level.
    161   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    162   EXPECT_TRUE(load_timing_info.request_start.is_null());
    163   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    164 }
    165 
    166 // Tests LoadTimingInfo in the case a socket is reused and a PAC script is
    167 // used.
    168 void TestLoadTimingReusedWithPac(const net::LoadTimingInfo& load_timing_info) {
    169   EXPECT_TRUE(load_timing_info.socket_reused);
    170   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    171 
    172   net::ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
    173 
    174   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    175   EXPECT_LE(load_timing_info.proxy_resolve_start,
    176             load_timing_info.proxy_resolve_end);
    177   EXPECT_LE(load_timing_info.proxy_resolve_end,
    178             load_timing_info.send_start);
    179   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    180 
    181   // Set at a higher level.
    182   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    183   EXPECT_TRUE(load_timing_info.request_start.is_null());
    184   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    185 }
    186 
    187 // Tests LoadTimingInfo in the case a new socket is used and a PAC script is
    188 // used.
    189 void TestLoadTimingNotReusedWithPac(const net::LoadTimingInfo& load_timing_info,
    190                                     int connect_timing_flags) {
    191   EXPECT_FALSE(load_timing_info.socket_reused);
    192   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
    193 
    194   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
    195   EXPECT_LE(load_timing_info.proxy_resolve_start,
    196             load_timing_info.proxy_resolve_end);
    197   EXPECT_LE(load_timing_info.proxy_resolve_end,
    198             load_timing_info.connect_timing.connect_start);
    199   net::ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
    200                                    connect_timing_flags);
    201   EXPECT_LE(load_timing_info.connect_timing.connect_end,
    202             load_timing_info.send_start);
    203 
    204   EXPECT_LE(load_timing_info.send_start, load_timing_info.send_end);
    205 
    206   // Set at a higher level.
    207   EXPECT_TRUE(load_timing_info.request_start_time.is_null());
    208   EXPECT_TRUE(load_timing_info.request_start.is_null());
    209   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
    210 }
    211 
    212 }  // namespace
    213 
    214 namespace net {
    215 
    216 namespace {
    217 
    218 HttpNetworkSession* CreateSession(SpdySessionDependencies* session_deps) {
    219   return SpdySessionDependencies::SpdyCreateSession(session_deps);
    220 }
    221 
    222 }  // namespace
    223 
    224 class HttpNetworkTransactionTest
    225     : public PlatformTest,
    226       public ::testing::WithParamInterface<NextProto> {
    227  public:
    228   virtual ~HttpNetworkTransactionTest() {
    229     // Important to restore the per-pool limit first, since the pool limit must
    230     // always be greater than group limit, and the tests reduce both limits.
    231     ClientSocketPoolManager::set_max_sockets_per_pool(
    232         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_pool_sockets_);
    233     ClientSocketPoolManager::set_max_sockets_per_group(
    234         HttpNetworkSession::NORMAL_SOCKET_POOL, old_max_group_sockets_);
    235   }
    236 
    237  protected:
    238   HttpNetworkTransactionTest()
    239       : spdy_util_(GetParam()),
    240         session_deps_(GetParam()),
    241         old_max_group_sockets_(ClientSocketPoolManager::max_sockets_per_group(
    242             HttpNetworkSession::NORMAL_SOCKET_POOL)),
    243         old_max_pool_sockets_(ClientSocketPoolManager::max_sockets_per_pool(
    244             HttpNetworkSession::NORMAL_SOCKET_POOL)) {
    245   }
    246 
    247   struct SimpleGetHelperResult {
    248     int rv;
    249     std::string status_line;
    250     std::string response_data;
    251     int64 totalReceivedBytes;
    252     LoadTimingInfo load_timing_info;
    253   };
    254 
    255   virtual void SetUp() {
    256     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    257     base::MessageLoop::current()->RunUntilIdle();
    258   }
    259 
    260   virtual void TearDown() {
    261     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    262     base::MessageLoop::current()->RunUntilIdle();
    263     // Empty the current queue.
    264     base::MessageLoop::current()->RunUntilIdle();
    265     PlatformTest::TearDown();
    266     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    267     base::MessageLoop::current()->RunUntilIdle();
    268   }
    269 
    270   // This is the expected return from a current server advertising SPDY.
    271   std::string GetAlternateProtocolHttpHeader() {
    272     return
    273         std::string("Alternate-Protocol: 443:") +
    274         AlternateProtocolToString(AlternateProtocolFromNextProto(GetParam())) +
    275         "\r\n\r\n";
    276   }
    277 
    278   // Either |write_failure| specifies a write failure or |read_failure|
    279   // specifies a read failure when using a reused socket.  In either case, the
    280   // failure should cause the network transaction to resend the request, and the
    281   // other argument should be NULL.
    282   void KeepAliveConnectionResendRequestTest(const MockWrite* write_failure,
    283                                             const MockRead* read_failure);
    284 
    285   // Either |write_failure| specifies a write failure or |read_failure|
    286   // specifies a read failure when using a reused socket.  In either case, the
    287   // failure should cause the network transaction to resend the request, and the
    288   // other argument should be NULL.
    289   void PreconnectErrorResendRequestTest(const MockWrite* write_failure,
    290                                         const MockRead* read_failure,
    291                                         bool use_spdy);
    292 
    293   SimpleGetHelperResult SimpleGetHelperForData(StaticSocketDataProvider* data[],
    294                                                size_t data_count) {
    295     SimpleGetHelperResult out;
    296 
    297     HttpRequestInfo request;
    298     request.method = "GET";
    299     request.url = GURL("http://www.google.com/");
    300     request.load_flags = 0;
    301 
    302     CapturingBoundNetLog log;
    303     session_deps_.net_log = log.bound().net_log();
    304     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    305     scoped_ptr<HttpTransaction> trans(
    306         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    307 
    308     for (size_t i = 0; i < data_count; ++i) {
    309       session_deps_.socket_factory->AddSocketDataProvider(data[i]);
    310     }
    311 
    312     TestCompletionCallback callback;
    313 
    314     EXPECT_TRUE(log.bound().IsLogging());
    315     int rv = trans->Start(&request, callback.callback(), log.bound());
    316     EXPECT_EQ(ERR_IO_PENDING, rv);
    317 
    318     out.rv = callback.WaitForResult();
    319 
    320     // Even in the failure cases that use this function, connections are always
    321     // successfully established before the error.
    322     EXPECT_TRUE(trans->GetLoadTimingInfo(&out.load_timing_info));
    323     TestLoadTimingNotReused(out.load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
    324 
    325     if (out.rv != OK)
    326       return out;
    327 
    328     const HttpResponseInfo* response = trans->GetResponseInfo();
    329     // Can't use ASSERT_* inside helper functions like this, so
    330     // return an error.
    331     if (response == NULL || response->headers.get() == NULL) {
    332       out.rv = ERR_UNEXPECTED;
    333       return out;
    334     }
    335     out.status_line = response->headers->GetStatusLine();
    336 
    337     EXPECT_EQ("127.0.0.1", response->socket_address.host());
    338     EXPECT_EQ(80, response->socket_address.port());
    339 
    340     rv = ReadTransaction(trans.get(), &out.response_data);
    341     EXPECT_EQ(OK, rv);
    342 
    343     net::CapturingNetLog::CapturedEntryList entries;
    344     log.GetEntries(&entries);
    345     size_t pos = ExpectLogContainsSomewhere(
    346         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
    347         NetLog::PHASE_NONE);
    348     ExpectLogContainsSomewhere(
    349         entries, pos,
    350         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
    351         NetLog::PHASE_NONE);
    352 
    353     std::string line;
    354     EXPECT_TRUE(entries[pos].GetStringValue("line", &line));
    355     EXPECT_EQ("GET / HTTP/1.1\r\n", line);
    356 
    357     HttpRequestHeaders request_headers;
    358     EXPECT_TRUE(trans->GetFullRequestHeaders(&request_headers));
    359     std::string value;
    360     EXPECT_TRUE(request_headers.GetHeader("Host", &value));
    361     EXPECT_EQ("www.google.com", value);
    362     EXPECT_TRUE(request_headers.GetHeader("Connection", &value));
    363     EXPECT_EQ("keep-alive", value);
    364 
    365     std::string response_headers;
    366     EXPECT_TRUE(GetHeaders(entries[pos].params.get(), &response_headers));
    367     EXPECT_EQ("['Host: www.google.com','Connection: keep-alive']",
    368               response_headers);
    369 
    370     out.totalReceivedBytes = trans->GetTotalReceivedBytes();
    371     return out;
    372   }
    373 
    374   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
    375                                         size_t reads_count) {
    376     StaticSocketDataProvider reads(data_reads, reads_count, NULL, 0);
    377     StaticSocketDataProvider* data[] = { &reads };
    378     return SimpleGetHelperForData(data, 1);
    379   }
    380 
    381   int64 ReadsSize(MockRead data_reads[], size_t reads_count) {
    382     int64 size = 0;
    383     for (size_t i = 0; i < reads_count; ++i)
    384       size += data_reads[i].data_len;
    385     return size;
    386   }
    387 
    388   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    389                                              int expected_status);
    390 
    391   void ConnectStatusHelper(const MockRead& status);
    392 
    393   void BypassHostCacheOnRefreshHelper(int load_flags);
    394 
    395   void CheckErrorIsPassedBack(int error, IoMode mode);
    396 
    397   SpdyTestUtil spdy_util_;
    398   SpdySessionDependencies session_deps_;
    399 
    400   // Original socket limits.  Some tests set these.  Safest to always restore
    401   // them once each test has been run.
    402   int old_max_group_sockets_;
    403   int old_max_pool_sockets_;
    404 };
    405 
    406 INSTANTIATE_TEST_CASE_P(
    407     NextProto,
    408     HttpNetworkTransactionTest,
    409     testing::Values(kProtoDeprecatedSPDY2,
    410                     kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));
    411 
    412 namespace {
    413 
    414 class BeforeNetworkStartHandler {
    415  public:
    416   explicit BeforeNetworkStartHandler(bool defer)
    417       : defer_on_before_network_start_(defer),
    418         observed_before_network_start_(false) {}
    419 
    420   void OnBeforeNetworkStart(bool* defer) {
    421     *defer = defer_on_before_network_start_;
    422     observed_before_network_start_ = true;
    423   }
    424 
    425   bool observed_before_network_start() const {
    426     return observed_before_network_start_;
    427   }
    428 
    429  private:
    430   const bool defer_on_before_network_start_;
    431   bool observed_before_network_start_;
    432 
    433   DISALLOW_COPY_AND_ASSIGN(BeforeNetworkStartHandler);
    434 };
    435 
    436 // Fill |str| with a long header list that consumes >= |size| bytes.
    437 void FillLargeHeadersString(std::string* str, int size) {
    438   const char* row =
    439       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    440   const int sizeof_row = strlen(row);
    441   const int num_rows = static_cast<int>(
    442       ceil(static_cast<float>(size) / sizeof_row));
    443   const int sizeof_data = num_rows * sizeof_row;
    444   DCHECK(sizeof_data >= size);
    445   str->reserve(sizeof_data);
    446 
    447   for (int i = 0; i < num_rows; ++i)
    448     str->append(row, sizeof_row);
    449 }
    450 
    451 // Alternative functions that eliminate randomness and dependency on the local
    452 // host name so that the generated NTLM messages are reproducible.
    453 void MockGenerateRandom1(uint8* output, size_t n) {
    454   static const uint8 bytes[] = {
    455     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    456   };
    457   static size_t current_byte = 0;
    458   for (size_t i = 0; i < n; ++i) {
    459     output[i] = bytes[current_byte++];
    460     current_byte %= arraysize(bytes);
    461   }
    462 }
    463 
    464 void MockGenerateRandom2(uint8* output, size_t n) {
    465   static const uint8 bytes[] = {
    466     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    467     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    468   };
    469   static size_t current_byte = 0;
    470   for (size_t i = 0; i < n; ++i) {
    471     output[i] = bytes[current_byte++];
    472     current_byte %= arraysize(bytes);
    473   }
    474 }
    475 
    476 std::string MockGetHostName() {
    477   return "WTC-WIN7";
    478 }
    479 
    480 template<typename ParentPool>
    481 class CaptureGroupNameSocketPool : public ParentPool {
    482  public:
    483   CaptureGroupNameSocketPool(HostResolver* host_resolver,
    484                              CertVerifier* cert_verifier);
    485 
    486   const std::string last_group_name_received() const {
    487     return last_group_name_;
    488   }
    489 
    490   virtual int RequestSocket(const std::string& group_name,
    491                             const void* socket_params,
    492                             RequestPriority priority,
    493                             ClientSocketHandle* handle,
    494                             const CompletionCallback& callback,
    495                             const BoundNetLog& net_log) {
    496     last_group_name_ = group_name;
    497     return ERR_IO_PENDING;
    498   }
    499   virtual void CancelRequest(const std::string& group_name,
    500                              ClientSocketHandle* handle) {}
    501   virtual void ReleaseSocket(const std::string& group_name,
    502                              scoped_ptr<StreamSocket> socket,
    503                              int id) {}
    504   virtual void CloseIdleSockets() {}
    505   virtual int IdleSocketCount() const {
    506     return 0;
    507   }
    508   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    509     return 0;
    510   }
    511   virtual LoadState GetLoadState(const std::string& group_name,
    512                                  const ClientSocketHandle* handle) const {
    513     return LOAD_STATE_IDLE;
    514   }
    515   virtual base::TimeDelta ConnectionTimeout() const {
    516     return base::TimeDelta();
    517   }
    518 
    519  private:
    520   std::string last_group_name_;
    521 };
    522 
    523 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
    524 CaptureGroupNameTransportSocketPool;
    525 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
    526 CaptureGroupNameHttpProxySocketPool;
    527 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
    528 CaptureGroupNameSOCKSSocketPool;
    529 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
    530 CaptureGroupNameSSLSocketPool;
    531 
    532 template<typename ParentPool>
    533 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
    534     HostResolver* host_resolver,
    535     CertVerifier* /* cert_verifier */)
    536     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
    537 
    538 template<>
    539 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
    540     HostResolver* host_resolver,
    541     CertVerifier* /* cert_verifier */)
    542     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
    543 
    544 template <>
    545 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
    546     HostResolver* host_resolver,
    547     CertVerifier* cert_verifier)
    548     : SSLClientSocketPool(0,
    549                           0,
    550                           NULL,
    551                           host_resolver,
    552                           cert_verifier,
    553                           NULL,
    554                           NULL,
    555                           NULL,
    556                           std::string(),
    557                           NULL,
    558                           NULL,
    559                           NULL,
    560                           NULL,
    561                           NULL,
    562                           NULL) {}
    563 
    564 //-----------------------------------------------------------------------------
    565 
    566 // Helper functions for validating that AuthChallengeInfo's are correctly
    567 // configured for common cases.
    568 bool CheckBasicServerAuth(const AuthChallengeInfo* auth_challenge) {
    569   if (!auth_challenge)
    570     return false;
    571   EXPECT_FALSE(auth_challenge->is_proxy);
    572   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    573   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    574   EXPECT_EQ("basic", auth_challenge->scheme);
    575   return true;
    576 }
    577 
    578 bool CheckBasicProxyAuth(const AuthChallengeInfo* auth_challenge) {
    579   if (!auth_challenge)
    580     return false;
    581   EXPECT_TRUE(auth_challenge->is_proxy);
    582   EXPECT_EQ("myproxy:70", auth_challenge->challenger.ToString());
    583   EXPECT_EQ("MyRealm1", auth_challenge->realm);
    584   EXPECT_EQ("basic", auth_challenge->scheme);
    585   return true;
    586 }
    587 
    588 bool CheckDigestServerAuth(const AuthChallengeInfo* auth_challenge) {
    589   if (!auth_challenge)
    590     return false;
    591   EXPECT_FALSE(auth_challenge->is_proxy);
    592   EXPECT_EQ("www.google.com:80", auth_challenge->challenger.ToString());
    593   EXPECT_EQ("digestive", auth_challenge->realm);
    594   EXPECT_EQ("digest", auth_challenge->scheme);
    595   return true;
    596 }
    597 
    598 bool CheckNTLMServerAuth(const AuthChallengeInfo* auth_challenge) {
    599   if (!auth_challenge)
    600     return false;
    601   EXPECT_FALSE(auth_challenge->is_proxy);
    602   EXPECT_EQ("172.22.68.17:80", auth_challenge->challenger.ToString());
    603   EXPECT_EQ(std::string(), auth_challenge->realm);
    604   EXPECT_EQ("ntlm", auth_challenge->scheme);
    605   return true;
    606 }
    607 
    608 }  // namespace
    609 
    610 TEST_P(HttpNetworkTransactionTest, Basic) {
    611   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    612   scoped_ptr<HttpTransaction> trans(
    613       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    614 }
    615 
    616 TEST_P(HttpNetworkTransactionTest, SimpleGET) {
    617   MockRead data_reads[] = {
    618     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    619     MockRead("hello world"),
    620     MockRead(SYNCHRONOUS, OK),
    621   };
    622   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    623                                               arraysize(data_reads));
    624   EXPECT_EQ(OK, out.rv);
    625   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    626   EXPECT_EQ("hello world", out.response_data);
    627   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    628   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    629 }
    630 
    631 // Response with no status line.
    632 TEST_P(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    633   MockRead data_reads[] = {
    634     MockRead("hello world"),
    635     MockRead(SYNCHRONOUS, OK),
    636   };
    637   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    638                                               arraysize(data_reads));
    639   EXPECT_EQ(OK, out.rv);
    640   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    641   EXPECT_EQ("hello world", out.response_data);
    642   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    643   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    644 }
    645 
    646 // Allow up to 4 bytes of junk to precede status line.
    647 TEST_P(HttpNetworkTransactionTest, StatusLineJunk3Bytes) {
    648   MockRead data_reads[] = {
    649     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    650     MockRead(SYNCHRONOUS, OK),
    651   };
    652   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    653                                               arraysize(data_reads));
    654   EXPECT_EQ(OK, out.rv);
    655   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    656   EXPECT_EQ("DATA", out.response_data);
    657   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    658   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    659 }
    660 
    661 // Allow up to 4 bytes of junk to precede status line.
    662 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    663   MockRead data_reads[] = {
    664     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    665     MockRead(SYNCHRONOUS, OK),
    666   };
    667   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    668                                               arraysize(data_reads));
    669   EXPECT_EQ(OK, out.rv);
    670   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    671   EXPECT_EQ("DATA", out.response_data);
    672   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    673   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    674 }
    675 
    676 // Beyond 4 bytes of slop and it should fail to find a status line.
    677 TEST_P(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    678   MockRead data_reads[] = {
    679     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    680     MockRead(SYNCHRONOUS, OK),
    681   };
    682   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    683                                               arraysize(data_reads));
    684   EXPECT_EQ(OK, out.rv);
    685   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    686   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    687   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    688   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    689 }
    690 
    691 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    692 TEST_P(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    693   MockRead data_reads[] = {
    694     MockRead("\n"),
    695     MockRead("\n"),
    696     MockRead("Q"),
    697     MockRead("J"),
    698     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    699     MockRead(SYNCHRONOUS, OK),
    700   };
    701   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    702                                               arraysize(data_reads));
    703   EXPECT_EQ(OK, out.rv);
    704   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    705   EXPECT_EQ("DATA", out.response_data);
    706   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    707   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    708 }
    709 
    710 // Close the connection before enough bytes to have a status line.
    711 TEST_P(HttpNetworkTransactionTest, StatusLinePartial) {
    712   MockRead data_reads[] = {
    713     MockRead("HTT"),
    714     MockRead(SYNCHRONOUS, OK),
    715   };
    716   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    717                                               arraysize(data_reads));
    718   EXPECT_EQ(OK, out.rv);
    719   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    720   EXPECT_EQ("HTT", out.response_data);
    721   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    722   EXPECT_EQ(reads_size, out.totalReceivedBytes);
    723 }
    724 
    725 // Simulate a 204 response, lacking a Content-Length header, sent over a
    726 // persistent connection.  The response should still terminate since a 204
    727 // cannot have a response body.
    728 TEST_P(HttpNetworkTransactionTest, StopsReading204) {
    729   char junk[] = "junk";
    730   MockRead data_reads[] = {
    731     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    732     MockRead(junk),  // Should not be read!!
    733     MockRead(SYNCHRONOUS, OK),
    734   };
    735   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    736                                               arraysize(data_reads));
    737   EXPECT_EQ(OK, out.rv);
    738   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    739   EXPECT_EQ("", out.response_data);
    740   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    741   int64 response_size = reads_size - strlen(junk);
    742   EXPECT_EQ(response_size, out.totalReceivedBytes);
    743 }
    744 
    745 // A simple request using chunked encoding with some extra data after.
    746 TEST_P(HttpNetworkTransactionTest, ChunkedEncoding) {
    747   std::string final_chunk = "0\r\n\r\n";
    748   std::string extra_data = "HTTP/1.1 200 OK\r\n";
    749   std::string last_read = final_chunk + extra_data;
    750   MockRead data_reads[] = {
    751     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    752     MockRead("5\r\nHello\r\n"),
    753     MockRead("1\r\n"),
    754     MockRead(" \r\n"),
    755     MockRead("5\r\nworld\r\n"),
    756     MockRead(last_read.data()),
    757     MockRead(SYNCHRONOUS, OK),
    758   };
    759   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    760                                               arraysize(data_reads));
    761   EXPECT_EQ(OK, out.rv);
    762   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    763   EXPECT_EQ("Hello world", out.response_data);
    764   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
    765   int64 response_size = reads_size - extra_data.size();
    766   EXPECT_EQ(response_size, out.totalReceivedBytes);
    767 }
    768 
    769 // Next tests deal with http://crbug.com/56344.
    770 
    771 TEST_P(HttpNetworkTransactionTest,
    772        MultipleContentLengthHeadersNoTransferEncoding) {
    773   MockRead data_reads[] = {
    774     MockRead("HTTP/1.1 200 OK\r\n"),
    775     MockRead("Content-Length: 10\r\n"),
    776     MockRead("Content-Length: 5\r\n\r\n"),
    777   };
    778   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    779                                               arraysize(data_reads));
    780   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    781 }
    782 
    783 TEST_P(HttpNetworkTransactionTest,
    784        DuplicateContentLengthHeadersNoTransferEncoding) {
    785   MockRead data_reads[] = {
    786     MockRead("HTTP/1.1 200 OK\r\n"),
    787     MockRead("Content-Length: 5\r\n"),
    788     MockRead("Content-Length: 5\r\n\r\n"),
    789     MockRead("Hello"),
    790   };
    791   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    792                                               arraysize(data_reads));
    793   EXPECT_EQ(OK, out.rv);
    794   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    795   EXPECT_EQ("Hello", out.response_data);
    796 }
    797 
    798 TEST_P(HttpNetworkTransactionTest,
    799        ComplexContentLengthHeadersNoTransferEncoding) {
    800   // More than 2 dupes.
    801   {
    802     MockRead data_reads[] = {
    803       MockRead("HTTP/1.1 200 OK\r\n"),
    804       MockRead("Content-Length: 5\r\n"),
    805       MockRead("Content-Length: 5\r\n"),
    806       MockRead("Content-Length: 5\r\n\r\n"),
    807       MockRead("Hello"),
    808     };
    809     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    810                                                 arraysize(data_reads));
    811     EXPECT_EQ(OK, out.rv);
    812     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    813     EXPECT_EQ("Hello", out.response_data);
    814   }
    815   // HTTP/1.0
    816   {
    817     MockRead data_reads[] = {
    818       MockRead("HTTP/1.0 200 OK\r\n"),
    819       MockRead("Content-Length: 5\r\n"),
    820       MockRead("Content-Length: 5\r\n"),
    821       MockRead("Content-Length: 5\r\n\r\n"),
    822       MockRead("Hello"),
    823     };
    824     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    825                                                 arraysize(data_reads));
    826     EXPECT_EQ(OK, out.rv);
    827     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    828     EXPECT_EQ("Hello", out.response_data);
    829   }
    830   // 2 dupes and one mismatched.
    831   {
    832     MockRead data_reads[] = {
    833       MockRead("HTTP/1.1 200 OK\r\n"),
    834       MockRead("Content-Length: 10\r\n"),
    835       MockRead("Content-Length: 10\r\n"),
    836       MockRead("Content-Length: 5\r\n\r\n"),
    837     };
    838     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    839                                                 arraysize(data_reads));
    840     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    841   }
    842 }
    843 
    844 TEST_P(HttpNetworkTransactionTest,
    845        MultipleContentLengthHeadersTransferEncoding) {
    846   MockRead data_reads[] = {
    847     MockRead("HTTP/1.1 200 OK\r\n"),
    848     MockRead("Content-Length: 666\r\n"),
    849     MockRead("Content-Length: 1337\r\n"),
    850     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
    851     MockRead("5\r\nHello\r\n"),
    852     MockRead("1\r\n"),
    853     MockRead(" \r\n"),
    854     MockRead("5\r\nworld\r\n"),
    855     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    856     MockRead(SYNCHRONOUS, OK),
    857   };
    858   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    859                                               arraysize(data_reads));
    860   EXPECT_EQ(OK, out.rv);
    861   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    862   EXPECT_EQ("Hello world", out.response_data);
    863 }
    864 
    865 // Next tests deal with http://crbug.com/98895.
    866 
    867 // Checks that a single Content-Disposition header results in no error.
    868 TEST_P(HttpNetworkTransactionTest, SingleContentDispositionHeader) {
    869   MockRead data_reads[] = {
    870     MockRead("HTTP/1.1 200 OK\r\n"),
    871     MockRead("Content-Disposition: attachment;filename=\"salutations.txt\"r\n"),
    872     MockRead("Content-Length: 5\r\n\r\n"),
    873     MockRead("Hello"),
    874   };
    875   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    876                                               arraysize(data_reads));
    877   EXPECT_EQ(OK, out.rv);
    878   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    879   EXPECT_EQ("Hello", out.response_data);
    880 }
    881 
    882 // Checks that two identical Content-Disposition headers result in no error.
    883 TEST_P(HttpNetworkTransactionTest,
    884        TwoIdenticalContentDispositionHeaders) {
    885   MockRead data_reads[] = {
    886     MockRead("HTTP/1.1 200 OK\r\n"),
    887     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    888     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    889     MockRead("Content-Length: 5\r\n\r\n"),
    890     MockRead("Hello"),
    891   };
    892   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    893                                               arraysize(data_reads));
    894   EXPECT_EQ(OK, out.rv);
    895   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    896   EXPECT_EQ("Hello", out.response_data);
    897 }
    898 
    899 // Checks that two distinct Content-Disposition headers result in an error.
    900 TEST_P(HttpNetworkTransactionTest, TwoDistinctContentDispositionHeaders) {
    901   MockRead data_reads[] = {
    902     MockRead("HTTP/1.1 200 OK\r\n"),
    903     MockRead("Content-Disposition: attachment;filename=\"greetings.txt\"r\n"),
    904     MockRead("Content-Disposition: attachment;filename=\"hi.txt\"r\n"),
    905     MockRead("Content-Length: 5\r\n\r\n"),
    906     MockRead("Hello"),
    907   };
    908   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    909                                               arraysize(data_reads));
    910   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_DISPOSITION, out.rv);
    911 }
    912 
    913 // Checks that two identical Location headers result in no error.
    914 // Also tests Location header behavior.
    915 TEST_P(HttpNetworkTransactionTest, TwoIdenticalLocationHeaders) {
    916   MockRead data_reads[] = {
    917     MockRead("HTTP/1.1 302 Redirect\r\n"),
    918     MockRead("Location: http://good.com/\r\n"),
    919     MockRead("Location: http://good.com/\r\n"),
    920     MockRead("Content-Length: 0\r\n\r\n"),
    921     MockRead(SYNCHRONOUS, OK),
    922   };
    923 
    924   HttpRequestInfo request;
    925   request.method = "GET";
    926   request.url = GURL("http://redirect.com/");
    927   request.load_flags = 0;
    928 
    929   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    930   scoped_ptr<HttpTransaction> trans(
    931       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    932 
    933   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    934   session_deps_.socket_factory->AddSocketDataProvider(&data);
    935 
    936   TestCompletionCallback callback;
    937 
    938   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
    939   EXPECT_EQ(ERR_IO_PENDING, rv);
    940 
    941   EXPECT_EQ(OK, callback.WaitForResult());
    942 
    943   const HttpResponseInfo* response = trans->GetResponseInfo();
    944   ASSERT_TRUE(response != NULL && response->headers.get() != NULL);
    945   EXPECT_EQ("HTTP/1.1 302 Redirect", response->headers->GetStatusLine());
    946   std::string url;
    947   EXPECT_TRUE(response->headers->IsRedirect(&url));
    948   EXPECT_EQ("http://good.com/", url);
    949   EXPECT_TRUE(response->proxy_server.IsEmpty());
    950 }
    951 
    952 // Checks that two distinct Location headers result in an error.
    953 TEST_P(HttpNetworkTransactionTest, TwoDistinctLocationHeaders) {
    954   MockRead data_reads[] = {
    955     MockRead("HTTP/1.1 302 Redirect\r\n"),
    956     MockRead("Location: http://good.com/\r\n"),
    957     MockRead("Location: http://evil.com/\r\n"),
    958     MockRead("Content-Length: 0\r\n\r\n"),
    959     MockRead(SYNCHRONOUS, OK),
    960   };
    961   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    962                                               arraysize(data_reads));
    963   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION, out.rv);
    964 }
    965 
    966 // Do a request using the HEAD method. Verify that we don't try to read the
    967 // message body (since HEAD has none).
    968 TEST_P(HttpNetworkTransactionTest, Head) {
    969   HttpRequestInfo request;
    970   request.method = "HEAD";
    971   request.url = GURL("http://www.google.com/");
    972   request.load_flags = 0;
    973 
    974   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
    975   scoped_ptr<HttpTransaction> trans(
    976       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
    977 
    978   MockWrite data_writes1[] = {
    979     MockWrite("HEAD / HTTP/1.1\r\n"
    980               "Host: www.google.com\r\n"
    981               "Connection: keep-alive\r\n"
    982               "Content-Length: 0\r\n\r\n"),
    983   };
    984   MockRead data_reads1[] = {
    985     MockRead("HTTP/1.1 404 Not Found\r\n"),
    986     MockRead("Server: Blah\r\n"),
    987     MockRead("Content-Length: 1234\r\n\r\n"),
    988 
    989     // No response body because the test stops reading here.
    990     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
    991   };
    992 
    993   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
    994                                  data_writes1, arraysize(data_writes1));
    995   session_deps_.socket_factory->AddSocketDataProvider(&data1);
    996 
    997   TestCompletionCallback callback1;
    998 
    999   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1000   EXPECT_EQ(ERR_IO_PENDING, rv);
   1001 
   1002   rv = callback1.WaitForResult();
   1003   EXPECT_EQ(OK, rv);
   1004 
   1005   const HttpResponseInfo* response = trans->GetResponseInfo();
   1006   ASSERT_TRUE(response != NULL);
   1007 
   1008   // Check that the headers got parsed.
   1009   EXPECT_TRUE(response->headers.get() != NULL);
   1010   EXPECT_EQ(1234, response->headers->GetContentLength());
   1011   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
   1012   EXPECT_TRUE(response->proxy_server.IsEmpty());
   1013 
   1014   std::string server_header;
   1015   void* iter = NULL;
   1016   bool has_server_header = response->headers->EnumerateHeader(
   1017       &iter, "Server", &server_header);
   1018   EXPECT_TRUE(has_server_header);
   1019   EXPECT_EQ("Blah", server_header);
   1020 
   1021   // Reading should give EOF right away, since there is no message body
   1022   // (despite non-zero content-length).
   1023   std::string response_data;
   1024   rv = ReadTransaction(trans.get(), &response_data);
   1025   EXPECT_EQ(OK, rv);
   1026   EXPECT_EQ("", response_data);
   1027 }
   1028 
   1029 TEST_P(HttpNetworkTransactionTest, ReuseConnection) {
   1030   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1031 
   1032   MockRead data_reads[] = {
   1033     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1034     MockRead("hello"),
   1035     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1036     MockRead("world"),
   1037     MockRead(SYNCHRONOUS, OK),
   1038   };
   1039   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1040   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1041 
   1042   const char* const kExpectedResponseData[] = {
   1043     "hello", "world"
   1044   };
   1045 
   1046   for (int i = 0; i < 2; ++i) {
   1047     HttpRequestInfo request;
   1048     request.method = "GET";
   1049     request.url = GURL("http://www.google.com/");
   1050     request.load_flags = 0;
   1051 
   1052     scoped_ptr<HttpTransaction> trans(
   1053         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1054 
   1055     TestCompletionCallback callback;
   1056 
   1057     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1058     EXPECT_EQ(ERR_IO_PENDING, rv);
   1059 
   1060     rv = callback.WaitForResult();
   1061     EXPECT_EQ(OK, rv);
   1062 
   1063     const HttpResponseInfo* response = trans->GetResponseInfo();
   1064     ASSERT_TRUE(response != NULL);
   1065 
   1066     EXPECT_TRUE(response->headers.get() != NULL);
   1067     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1068     EXPECT_TRUE(response->proxy_server.IsEmpty());
   1069 
   1070     std::string response_data;
   1071     rv = ReadTransaction(trans.get(), &response_data);
   1072     EXPECT_EQ(OK, rv);
   1073     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1074   }
   1075 }
   1076 
   1077 TEST_P(HttpNetworkTransactionTest, Ignores100) {
   1078   ScopedVector<UploadElementReader> element_readers;
   1079   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   1080   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   1081 
   1082   HttpRequestInfo request;
   1083   request.method = "POST";
   1084   request.url = GURL("http://www.foo.com/");
   1085   request.upload_data_stream = &upload_data_stream;
   1086   request.load_flags = 0;
   1087 
   1088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1089   scoped_ptr<HttpTransaction> trans(
   1090       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1091 
   1092   MockRead data_reads[] = {
   1093     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
   1094     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   1095     MockRead("hello world"),
   1096     MockRead(SYNCHRONOUS, OK),
   1097   };
   1098   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1099   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1100 
   1101   TestCompletionCallback callback;
   1102 
   1103   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1104   EXPECT_EQ(ERR_IO_PENDING, rv);
   1105 
   1106   rv = callback.WaitForResult();
   1107   EXPECT_EQ(OK, rv);
   1108 
   1109   const HttpResponseInfo* response = trans->GetResponseInfo();
   1110   ASSERT_TRUE(response != NULL);
   1111 
   1112   EXPECT_TRUE(response->headers.get() != NULL);
   1113   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   1114 
   1115   std::string response_data;
   1116   rv = ReadTransaction(trans.get(), &response_data);
   1117   EXPECT_EQ(OK, rv);
   1118   EXPECT_EQ("hello world", response_data);
   1119 }
   1120 
   1121 // This test is almost the same as Ignores100 above, but the response contains
   1122 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
   1123 // HTTP/1.1 and the two status headers are read in one read.
   1124 TEST_P(HttpNetworkTransactionTest, Ignores1xx) {
   1125   HttpRequestInfo request;
   1126   request.method = "GET";
   1127   request.url = GURL("http://www.foo.com/");
   1128   request.load_flags = 0;
   1129 
   1130   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1131   scoped_ptr<HttpTransaction> trans(
   1132       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1133 
   1134   MockRead data_reads[] = {
   1135     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
   1136              "HTTP/1.1 200 OK\r\n\r\n"),
   1137     MockRead("hello world"),
   1138     MockRead(SYNCHRONOUS, OK),
   1139   };
   1140   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1141   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1142 
   1143   TestCompletionCallback callback;
   1144 
   1145   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1146   EXPECT_EQ(ERR_IO_PENDING, rv);
   1147 
   1148   rv = callback.WaitForResult();
   1149   EXPECT_EQ(OK, rv);
   1150 
   1151   const HttpResponseInfo* response = trans->GetResponseInfo();
   1152   ASSERT_TRUE(response != NULL);
   1153 
   1154   EXPECT_TRUE(response->headers.get() != NULL);
   1155   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1156 
   1157   std::string response_data;
   1158   rv = ReadTransaction(trans.get(), &response_data);
   1159   EXPECT_EQ(OK, rv);
   1160   EXPECT_EQ("hello world", response_data);
   1161 }
   1162 
   1163 TEST_P(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
   1164   HttpRequestInfo request;
   1165   request.method = "POST";
   1166   request.url = GURL("http://www.foo.com/");
   1167   request.load_flags = 0;
   1168 
   1169   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1170   scoped_ptr<HttpTransaction> trans(
   1171       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1172 
   1173   MockRead data_reads[] = {
   1174     MockRead(SYNCHRONOUS, "HTTP/1.0 100 Continue\r\n"),
   1175     MockRead(ASYNC, 0),
   1176   };
   1177   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1178   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1179 
   1180   TestCompletionCallback callback;
   1181 
   1182   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1183   EXPECT_EQ(ERR_IO_PENDING, rv);
   1184 
   1185   rv = callback.WaitForResult();
   1186   EXPECT_EQ(OK, rv);
   1187 
   1188   std::string response_data;
   1189   rv = ReadTransaction(trans.get(), &response_data);
   1190   EXPECT_EQ(OK, rv);
   1191   EXPECT_EQ("", response_data);
   1192 }
   1193 
   1194 TEST_P(HttpNetworkTransactionTest, EmptyResponse) {
   1195   HttpRequestInfo request;
   1196   request.method = "POST";
   1197   request.url = GURL("http://www.foo.com/");
   1198   request.load_flags = 0;
   1199 
   1200   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1201   scoped_ptr<HttpTransaction> trans(
   1202       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1203 
   1204 
   1205   MockRead data_reads[] = {
   1206     MockRead(ASYNC, 0),
   1207   };
   1208   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1209   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1210 
   1211   TestCompletionCallback callback;
   1212 
   1213   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1214   EXPECT_EQ(ERR_IO_PENDING, rv);
   1215 
   1216   rv = callback.WaitForResult();
   1217   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   1218 }
   1219 
   1220 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
   1221     const MockWrite* write_failure,
   1222     const MockRead* read_failure) {
   1223   HttpRequestInfo request;
   1224   request.method = "GET";
   1225   request.url = GURL("http://www.foo.com/");
   1226   request.load_flags = 0;
   1227 
   1228   CapturingNetLog net_log;
   1229   session_deps_.net_log = &net_log;
   1230   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1231 
   1232   // Written data for successfully sending both requests.
   1233   MockWrite data1_writes[] = {
   1234     MockWrite("GET / HTTP/1.1\r\n"
   1235               "Host: www.foo.com\r\n"
   1236               "Connection: keep-alive\r\n\r\n"),
   1237     MockWrite("GET / HTTP/1.1\r\n"
   1238               "Host: www.foo.com\r\n"
   1239               "Connection: keep-alive\r\n\r\n")
   1240   };
   1241 
   1242   // Read results for the first request.
   1243   MockRead data1_reads[] = {
   1244     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1245     MockRead("hello"),
   1246     MockRead(ASYNC, OK),
   1247   };
   1248 
   1249   if (write_failure) {
   1250     ASSERT_FALSE(read_failure);
   1251     data1_writes[1] = *write_failure;
   1252   } else {
   1253     ASSERT_TRUE(read_failure);
   1254     data1_reads[2] = *read_failure;
   1255   }
   1256 
   1257   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads),
   1258                                  data1_writes, arraysize(data1_writes));
   1259   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1260 
   1261   MockRead data2_reads[] = {
   1262     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1263     MockRead("world"),
   1264     MockRead(ASYNC, OK),
   1265   };
   1266   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1267   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1268 
   1269   const char* kExpectedResponseData[] = {
   1270     "hello", "world"
   1271   };
   1272 
   1273   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1274   for (int i = 0; i < 2; ++i) {
   1275     TestCompletionCallback callback;
   1276 
   1277     scoped_ptr<HttpTransaction> trans(
   1278         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   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(OK, rv);
   1285 
   1286     LoadTimingInfo load_timing_info;
   1287     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1288     TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1289     if (i == 0) {
   1290       first_socket_log_id = load_timing_info.socket_log_id;
   1291     } else {
   1292       // The second request should be using a new socket.
   1293       EXPECT_NE(first_socket_log_id, load_timing_info.socket_log_id);
   1294     }
   1295 
   1296     const HttpResponseInfo* response = trans->GetResponseInfo();
   1297     ASSERT_TRUE(response != NULL);
   1298 
   1299     EXPECT_TRUE(response->headers.get() != NULL);
   1300     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1301 
   1302     std::string response_data;
   1303     rv = ReadTransaction(trans.get(), &response_data);
   1304     EXPECT_EQ(OK, rv);
   1305     EXPECT_EQ(kExpectedResponseData[i], response_data);
   1306   }
   1307 }
   1308 
   1309 void HttpNetworkTransactionTest::PreconnectErrorResendRequestTest(
   1310     const MockWrite* write_failure,
   1311     const MockRead* read_failure,
   1312     bool use_spdy) {
   1313   HttpRequestInfo request;
   1314   request.method = "GET";
   1315   request.url = GURL("https://www.foo.com/");
   1316   request.load_flags = 0;
   1317 
   1318   CapturingNetLog net_log;
   1319   session_deps_.net_log = &net_log;
   1320   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1321 
   1322   SSLSocketDataProvider ssl1(ASYNC, OK);
   1323   SSLSocketDataProvider ssl2(ASYNC, OK);
   1324   if (use_spdy) {
   1325     ssl1.SetNextProto(GetParam());
   1326     ssl2.SetNextProto(GetParam());
   1327   }
   1328   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl1);
   1329   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   1330 
   1331   // SPDY versions of the request and response.
   1332   scoped_ptr<SpdyFrame> spdy_request(spdy_util_.ConstructSpdyGet(
   1333       request.url.spec().c_str(), false, 1, DEFAULT_PRIORITY));
   1334   scoped_ptr<SpdyFrame> spdy_response(
   1335       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   1336   scoped_ptr<SpdyFrame> spdy_data(
   1337       spdy_util_.ConstructSpdyBodyFrame(1, "hello", 5, true));
   1338 
   1339   // HTTP/1.1 versions of the request and response.
   1340   const char kHttpRequest[] = "GET / HTTP/1.1\r\n"
   1341       "Host: www.foo.com\r\n"
   1342       "Connection: keep-alive\r\n\r\n";
   1343   const char kHttpResponse[] = "HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n";
   1344   const char kHttpData[] = "hello";
   1345 
   1346   std::vector<MockRead> data1_reads;
   1347   std::vector<MockWrite> data1_writes;
   1348   if (write_failure) {
   1349     ASSERT_FALSE(read_failure);
   1350     data1_writes.push_back(*write_failure);
   1351     data1_reads.push_back(MockRead(ASYNC, OK));
   1352   } else {
   1353     ASSERT_TRUE(read_failure);
   1354     if (use_spdy) {
   1355       data1_writes.push_back(CreateMockWrite(*spdy_request));
   1356     } else {
   1357       data1_writes.push_back(MockWrite(kHttpRequest));
   1358     }
   1359     data1_reads.push_back(*read_failure);
   1360   }
   1361 
   1362   StaticSocketDataProvider data1(&data1_reads[0], data1_reads.size(),
   1363                                  &data1_writes[0], data1_writes.size());
   1364   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1365 
   1366   std::vector<MockRead> data2_reads;
   1367   std::vector<MockWrite> data2_writes;
   1368 
   1369   if (use_spdy) {
   1370     data2_writes.push_back(CreateMockWrite(*spdy_request, 0, ASYNC));
   1371 
   1372     data2_reads.push_back(CreateMockRead(*spdy_response, 1, ASYNC));
   1373     data2_reads.push_back(CreateMockRead(*spdy_data, 2, ASYNC));
   1374     data2_reads.push_back(MockRead(ASYNC, OK, 3));
   1375   } else {
   1376     data2_writes.push_back(
   1377         MockWrite(ASYNC, kHttpRequest, strlen(kHttpRequest), 0));
   1378 
   1379     data2_reads.push_back(
   1380         MockRead(ASYNC, kHttpResponse, strlen(kHttpResponse), 1));
   1381     data2_reads.push_back(MockRead(ASYNC, kHttpData, strlen(kHttpData), 2));
   1382     data2_reads.push_back(MockRead(ASYNC, OK, 3));
   1383   }
   1384   OrderedSocketData data2(&data2_reads[0], data2_reads.size(),
   1385                           &data2_writes[0], data2_writes.size());
   1386   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1387 
   1388   // Preconnect a socket.
   1389   net::SSLConfig ssl_config;
   1390   session->ssl_config_service()->GetSSLConfig(&ssl_config);
   1391   session->GetNextProtos(&ssl_config.next_protos);
   1392   session->http_stream_factory()->PreconnectStreams(
   1393       1, request, DEFAULT_PRIORITY, ssl_config, ssl_config);
   1394   // Wait for the preconnect to complete.
   1395   // TODO(davidben): Some way to wait for an idle socket count might be handy.
   1396   base::RunLoop().RunUntilIdle();
   1397   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   1398 
   1399   // Make the request.
   1400   TestCompletionCallback callback;
   1401 
   1402   scoped_ptr<HttpTransaction> trans(
   1403       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1404 
   1405   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1406   EXPECT_EQ(ERR_IO_PENDING, rv);
   1407 
   1408   rv = callback.WaitForResult();
   1409   EXPECT_EQ(OK, rv);
   1410 
   1411   LoadTimingInfo load_timing_info;
   1412   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1413   TestLoadTimingNotReused(
   1414       load_timing_info,
   1415       CONNECT_TIMING_HAS_DNS_TIMES|CONNECT_TIMING_HAS_SSL_TIMES);
   1416 
   1417   const HttpResponseInfo* response = trans->GetResponseInfo();
   1418   ASSERT_TRUE(response != NULL);
   1419 
   1420   EXPECT_TRUE(response->headers.get() != NULL);
   1421   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1422 
   1423   std::string response_data;
   1424   rv = ReadTransaction(trans.get(), &response_data);
   1425   EXPECT_EQ(OK, rv);
   1426   EXPECT_EQ(kHttpData, response_data);
   1427 }
   1428 
   1429 TEST_P(HttpNetworkTransactionTest,
   1430        KeepAliveConnectionNotConnectedOnWrite) {
   1431   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1432   KeepAliveConnectionResendRequestTest(&write_failure, NULL);
   1433 }
   1434 
   1435 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
   1436   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1437   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1438 }
   1439 
   1440 TEST_P(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
   1441   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1442   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1443 }
   1444 
   1445 // Make sure that on a 408 response (Request Timeout), the request is retried,
   1446 // if the socket was a reused keep alive socket.
   1447 TEST_P(HttpNetworkTransactionTest, KeepAlive408) {
   1448   MockRead read_failure(SYNCHRONOUS,
   1449                         "HTTP/1.1 408 Request Timeout\r\n"
   1450                         "Connection: Keep-Alive\r\n"
   1451                         "Content-Length: 6\r\n\r\n"
   1452                         "Pickle");
   1453   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1454 }
   1455 
   1456 TEST_P(HttpNetworkTransactionTest,
   1457        PreconnectErrorNotConnectedOnWrite) {
   1458   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1459   PreconnectErrorResendRequestTest(&write_failure, NULL, false);
   1460 }
   1461 
   1462 TEST_P(HttpNetworkTransactionTest, PreconnectErrorReset) {
   1463   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1464   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1465 }
   1466 
   1467 TEST_P(HttpNetworkTransactionTest, PreconnectErrorEOF) {
   1468   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1469   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1470 }
   1471 
   1472 TEST_P(HttpNetworkTransactionTest, PreconnectErrorAsyncEOF) {
   1473   MockRead read_failure(ASYNC, OK);  // EOF
   1474   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1475 }
   1476 
   1477 // Make sure that on a 408 response (Request Timeout), the request is retried,
   1478 // if the socket was a preconnected (UNUSED_IDLE) socket.
   1479 TEST_P(HttpNetworkTransactionTest, RetryOnIdle408) {
   1480   MockRead read_failure(SYNCHRONOUS,
   1481                         "HTTP/1.1 408 Request Timeout\r\n"
   1482                         "Connection: Keep-Alive\r\n"
   1483                         "Content-Length: 6\r\n\r\n"
   1484                         "Pickle");
   1485   KeepAliveConnectionResendRequestTest(NULL, &read_failure);
   1486   PreconnectErrorResendRequestTest(NULL, &read_failure, false);
   1487 }
   1488 
   1489 TEST_P(HttpNetworkTransactionTest,
   1490        SpdyPreconnectErrorNotConnectedOnWrite) {
   1491   MockWrite write_failure(ASYNC, ERR_SOCKET_NOT_CONNECTED);
   1492   PreconnectErrorResendRequestTest(&write_failure, NULL, true);
   1493 }
   1494 
   1495 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorReset) {
   1496   MockRead read_failure(ASYNC, ERR_CONNECTION_RESET);
   1497   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1498 }
   1499 
   1500 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorEOF) {
   1501   MockRead read_failure(SYNCHRONOUS, OK);  // EOF
   1502   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1503 }
   1504 
   1505 TEST_P(HttpNetworkTransactionTest, SpdyPreconnectErrorAsyncEOF) {
   1506   MockRead read_failure(ASYNC, OK);  // EOF
   1507   PreconnectErrorResendRequestTest(NULL, &read_failure, true);
   1508 }
   1509 
   1510 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
   1511   HttpRequestInfo request;
   1512   request.method = "GET";
   1513   request.url = GURL("http://www.google.com/");
   1514   request.load_flags = 0;
   1515 
   1516   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1517   scoped_ptr<HttpTransaction> trans(
   1518       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1519 
   1520   MockRead data_reads[] = {
   1521     MockRead(ASYNC, ERR_CONNECTION_RESET),
   1522     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1523     MockRead("hello world"),
   1524     MockRead(SYNCHRONOUS, OK),
   1525   };
   1526   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1527   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1528 
   1529   TestCompletionCallback callback;
   1530 
   1531   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1532   EXPECT_EQ(ERR_IO_PENDING, rv);
   1533 
   1534   rv = callback.WaitForResult();
   1535   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   1536 
   1537   const HttpResponseInfo* response = trans->GetResponseInfo();
   1538   EXPECT_TRUE(response == NULL);
   1539 }
   1540 
   1541 // What do various browsers do when the server closes a non-keepalive
   1542 // connection without sending any response header or body?
   1543 //
   1544 // IE7: error page
   1545 // Safari 3.1.2 (Windows): error page
   1546 // Firefox 3.0.1: blank page
   1547 // Opera 9.52: after five attempts, blank page
   1548 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
   1549 // Us: error page (EMPTY_RESPONSE)
   1550 TEST_P(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
   1551   MockRead data_reads[] = {
   1552     MockRead(SYNCHRONOUS, OK),  // EOF
   1553     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
   1554     MockRead("hello world"),
   1555     MockRead(SYNCHRONOUS, OK),
   1556   };
   1557   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
   1558                                               arraysize(data_reads));
   1559   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
   1560 }
   1561 
   1562 // Test that network access can be deferred and resumed.
   1563 TEST_P(HttpNetworkTransactionTest, ThrottleBeforeNetworkStart) {
   1564   HttpRequestInfo request;
   1565   request.method = "GET";
   1566   request.url = GURL("http://www.google.com/");
   1567   request.load_flags = 0;
   1568 
   1569   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1570   scoped_ptr<HttpTransaction> trans(
   1571       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1572 
   1573   // Defer on OnBeforeNetworkStart.
   1574   BeforeNetworkStartHandler net_start_handler(true);  // defer
   1575   trans->SetBeforeNetworkStartCallback(
   1576       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
   1577                  base::Unretained(&net_start_handler)));
   1578 
   1579   MockRead data_reads[] = {
   1580     MockRead("HTTP/1.0 200 OK\r\n"),
   1581     MockRead("Content-Length: 5\r\n\r\n"),
   1582     MockRead("hello"),
   1583     MockRead(SYNCHRONOUS, 0),
   1584   };
   1585   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1586   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1587 
   1588   TestCompletionCallback callback;
   1589 
   1590   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1591   EXPECT_EQ(ERR_IO_PENDING, rv);
   1592   base::MessageLoop::current()->RunUntilIdle();
   1593 
   1594   // Should have deferred for network start.
   1595   EXPECT_TRUE(net_start_handler.observed_before_network_start());
   1596   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
   1597   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
   1598 
   1599   trans->ResumeNetworkStart();
   1600   rv = callback.WaitForResult();
   1601   EXPECT_EQ(OK, rv);
   1602   EXPECT_TRUE(trans->GetResponseInfo() != NULL);
   1603 
   1604   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1605   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1606   if (rv == ERR_IO_PENDING)
   1607     rv = callback.WaitForResult();
   1608   EXPECT_EQ(5, rv);
   1609   trans.reset();
   1610 }
   1611 
   1612 // Test that network use can be deferred and canceled.
   1613 TEST_P(HttpNetworkTransactionTest, ThrottleAndCancelBeforeNetworkStart) {
   1614   HttpRequestInfo request;
   1615   request.method = "GET";
   1616   request.url = GURL("http://www.google.com/");
   1617   request.load_flags = 0;
   1618 
   1619   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1620   scoped_ptr<HttpTransaction> trans(
   1621       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1622 
   1623   // Defer on OnBeforeNetworkStart.
   1624   BeforeNetworkStartHandler net_start_handler(true);  // defer
   1625   trans->SetBeforeNetworkStartCallback(
   1626       base::Bind(&BeforeNetworkStartHandler::OnBeforeNetworkStart,
   1627                  base::Unretained(&net_start_handler)));
   1628 
   1629   TestCompletionCallback callback;
   1630 
   1631   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1632   EXPECT_EQ(ERR_IO_PENDING, rv);
   1633   base::MessageLoop::current()->RunUntilIdle();
   1634 
   1635   // Should have deferred for network start.
   1636   EXPECT_TRUE(net_start_handler.observed_before_network_start());
   1637   EXPECT_EQ(LOAD_STATE_WAITING_FOR_DELEGATE, trans->GetLoadState());
   1638   EXPECT_TRUE(trans->GetResponseInfo() == NULL);
   1639 }
   1640 
   1641 // Next 2 cases (KeepAliveEarlyClose and KeepAliveEarlyClose2) are regression
   1642 // tests. There was a bug causing HttpNetworkTransaction to hang in the
   1643 // destructor in such situations.
   1644 // See http://crbug.com/154712 and http://crbug.com/156609.
   1645 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose) {
   1646   HttpRequestInfo request;
   1647   request.method = "GET";
   1648   request.url = GURL("http://www.google.com/");
   1649   request.load_flags = 0;
   1650 
   1651   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1652   scoped_ptr<HttpTransaction> trans(
   1653       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1654 
   1655   MockRead data_reads[] = {
   1656     MockRead("HTTP/1.0 200 OK\r\n"),
   1657     MockRead("Connection: keep-alive\r\n"),
   1658     MockRead("Content-Length: 100\r\n\r\n"),
   1659     MockRead("hello"),
   1660     MockRead(SYNCHRONOUS, 0),
   1661   };
   1662   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1663   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1664 
   1665   TestCompletionCallback callback;
   1666 
   1667   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1668   EXPECT_EQ(ERR_IO_PENDING, rv);
   1669 
   1670   rv = callback.WaitForResult();
   1671   EXPECT_EQ(OK, rv);
   1672 
   1673   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1674   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1675   if (rv == ERR_IO_PENDING)
   1676     rv = callback.WaitForResult();
   1677   EXPECT_EQ(5, rv);
   1678   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1679   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1680 
   1681   trans.reset();
   1682   base::MessageLoop::current()->RunUntilIdle();
   1683   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1684 }
   1685 
   1686 TEST_P(HttpNetworkTransactionTest, KeepAliveEarlyClose2) {
   1687   HttpRequestInfo request;
   1688   request.method = "GET";
   1689   request.url = GURL("http://www.google.com/");
   1690   request.load_flags = 0;
   1691 
   1692   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1693   scoped_ptr<HttpTransaction> trans(
   1694       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1695 
   1696   MockRead data_reads[] = {
   1697     MockRead("HTTP/1.0 200 OK\r\n"),
   1698     MockRead("Connection: keep-alive\r\n"),
   1699     MockRead("Content-Length: 100\r\n\r\n"),
   1700     MockRead(SYNCHRONOUS, 0),
   1701   };
   1702   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   1703   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1704 
   1705   TestCompletionCallback callback;
   1706 
   1707   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1708   EXPECT_EQ(ERR_IO_PENDING, rv);
   1709 
   1710   rv = callback.WaitForResult();
   1711   EXPECT_EQ(OK, rv);
   1712 
   1713   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(100));
   1714   rv = trans->Read(io_buf.get(), io_buf->size(), callback.callback());
   1715   if (rv == ERR_IO_PENDING)
   1716     rv = callback.WaitForResult();
   1717   EXPECT_EQ(ERR_CONTENT_LENGTH_MISMATCH, rv);
   1718 
   1719   trans.reset();
   1720   base::MessageLoop::current()->RunUntilIdle();
   1721   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   1722 }
   1723 
   1724 // Test that we correctly reuse a keep-alive connection after not explicitly
   1725 // reading the body.
   1726 TEST_P(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
   1727   HttpRequestInfo request;
   1728   request.method = "GET";
   1729   request.url = GURL("http://www.foo.com/");
   1730   request.load_flags = 0;
   1731 
   1732   CapturingNetLog net_log;
   1733   session_deps_.net_log = &net_log;
   1734   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1735 
   1736   // Note that because all these reads happen in the same
   1737   // StaticSocketDataProvider, it shows that the same socket is being reused for
   1738   // all transactions.
   1739   MockRead data1_reads[] = {
   1740     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
   1741     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
   1742     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
   1743     MockRead("HTTP/1.1 302 Found\r\n"
   1744              "Content-Length: 0\r\n\r\n"),
   1745     MockRead("HTTP/1.1 302 Found\r\n"
   1746              "Content-Length: 5\r\n\r\n"
   1747              "hello"),
   1748     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1749              "Content-Length: 0\r\n\r\n"),
   1750     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
   1751              "Content-Length: 5\r\n\r\n"
   1752              "hello"),
   1753     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
   1754     MockRead("hello"),
   1755   };
   1756   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
   1757   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1758 
   1759   MockRead data2_reads[] = {
   1760     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   1761   };
   1762   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
   1763   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1764 
   1765   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
   1766   std::string response_lines[kNumUnreadBodies];
   1767 
   1768   uint32 first_socket_log_id = NetLog::Source::kInvalidId;
   1769   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
   1770     TestCompletionCallback callback;
   1771 
   1772     scoped_ptr<HttpTransaction> trans(
   1773         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1774 
   1775     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1776     EXPECT_EQ(ERR_IO_PENDING, rv);
   1777 
   1778     rv = callback.WaitForResult();
   1779     EXPECT_EQ(OK, rv);
   1780 
   1781     LoadTimingInfo load_timing_info;
   1782     EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   1783     if (i == 0) {
   1784       TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_DNS_TIMES);
   1785       first_socket_log_id = load_timing_info.socket_log_id;
   1786     } else {
   1787       TestLoadTimingReused(load_timing_info);
   1788       EXPECT_EQ(first_socket_log_id, load_timing_info.socket_log_id);
   1789     }
   1790 
   1791     const HttpResponseInfo* response = trans->GetResponseInfo();
   1792     ASSERT_TRUE(response != NULL);
   1793 
   1794     ASSERT_TRUE(response->headers.get() != NULL);
   1795     response_lines[i] = response->headers->GetStatusLine();
   1796 
   1797     // We intentionally don't read the response bodies.
   1798   }
   1799 
   1800   const char* const kStatusLines[] = {
   1801     "HTTP/1.1 204 No Content",
   1802     "HTTP/1.1 205 Reset Content",
   1803     "HTTP/1.1 304 Not Modified",
   1804     "HTTP/1.1 302 Found",
   1805     "HTTP/1.1 302 Found",
   1806     "HTTP/1.1 301 Moved Permanently",
   1807     "HTTP/1.1 301 Moved Permanently",
   1808   };
   1809 
   1810   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
   1811                  forgot_to_update_kStatusLines);
   1812 
   1813   for (int i = 0; i < kNumUnreadBodies; ++i)
   1814     EXPECT_EQ(kStatusLines[i], response_lines[i]);
   1815 
   1816   TestCompletionCallback callback;
   1817   scoped_ptr<HttpTransaction> trans(
   1818       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   1819   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1820   EXPECT_EQ(ERR_IO_PENDING, rv);
   1821   rv = callback.WaitForResult();
   1822   EXPECT_EQ(OK, rv);
   1823   const HttpResponseInfo* response = trans->GetResponseInfo();
   1824   ASSERT_TRUE(response != NULL);
   1825   ASSERT_TRUE(response->headers.get() != NULL);
   1826   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1827   std::string response_data;
   1828   rv = ReadTransaction(trans.get(), &response_data);
   1829   EXPECT_EQ(OK, rv);
   1830   EXPECT_EQ("hello", response_data);
   1831 }
   1832 
   1833 // Test the request-challenge-retry sequence for basic auth.
   1834 // (basic auth is the easiest to mock, because it has no randomness).
   1835 TEST_P(HttpNetworkTransactionTest, BasicAuth) {
   1836   HttpRequestInfo request;
   1837   request.method = "GET";
   1838   request.url = GURL("http://www.google.com/");
   1839   request.load_flags = 0;
   1840 
   1841   CapturingNetLog log;
   1842   session_deps_.net_log = &log;
   1843   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1844   scoped_ptr<HttpTransaction> trans(
   1845       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1846 
   1847   MockWrite data_writes1[] = {
   1848     MockWrite("GET / HTTP/1.1\r\n"
   1849               "Host: www.google.com\r\n"
   1850               "Connection: keep-alive\r\n\r\n"),
   1851   };
   1852 
   1853   MockRead data_reads1[] = {
   1854     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1855     // Give a couple authenticate options (only the middle one is actually
   1856     // supported).
   1857     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
   1858     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1859     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1860     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1861     // Large content-length -- won't matter, as connection will be reset.
   1862     MockRead("Content-Length: 10000\r\n\r\n"),
   1863     MockRead(SYNCHRONOUS, ERR_FAILED),
   1864   };
   1865 
   1866   // After calling trans->RestartWithAuth(), this is the request we should
   1867   // be issuing -- the final header line contains the credentials.
   1868   MockWrite data_writes2[] = {
   1869     MockWrite("GET / HTTP/1.1\r\n"
   1870               "Host: www.google.com\r\n"
   1871               "Connection: keep-alive\r\n"
   1872               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1873   };
   1874 
   1875   // Lastly, the server responds with the actual content.
   1876   MockRead data_reads2[] = {
   1877     MockRead("HTTP/1.0 200 OK\r\n"),
   1878     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1879     MockRead("Content-Length: 100\r\n\r\n"),
   1880     MockRead(SYNCHRONOUS, OK),
   1881   };
   1882 
   1883   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1884                                  data_writes1, arraysize(data_writes1));
   1885   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1886                                  data_writes2, arraysize(data_writes2));
   1887   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   1888   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   1889 
   1890   TestCompletionCallback callback1;
   1891 
   1892   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   1893   EXPECT_EQ(ERR_IO_PENDING, rv);
   1894 
   1895   rv = callback1.WaitForResult();
   1896   EXPECT_EQ(OK, rv);
   1897 
   1898   LoadTimingInfo load_timing_info1;
   1899   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   1900   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   1901 
   1902   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
   1903   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
   1904 
   1905   const HttpResponseInfo* response = trans->GetResponseInfo();
   1906   ASSERT_TRUE(response != NULL);
   1907   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   1908 
   1909   TestCompletionCallback callback2;
   1910 
   1911   rv = trans->RestartWithAuth(
   1912       AuthCredentials(kFoo, kBar), callback2.callback());
   1913   EXPECT_EQ(ERR_IO_PENDING, rv);
   1914 
   1915   rv = callback2.WaitForResult();
   1916   EXPECT_EQ(OK, rv);
   1917 
   1918   LoadTimingInfo load_timing_info2;
   1919   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   1920   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_DNS_TIMES);
   1921   // The load timing after restart should have a new socket ID, and times after
   1922   // those of the first load timing.
   1923   EXPECT_LE(load_timing_info1.receive_headers_end,
   1924             load_timing_info2.connect_timing.connect_start);
   1925   EXPECT_NE(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   1926 
   1927   int64 reads_size2 = ReadsSize(data_reads2, arraysize(data_reads2));
   1928   EXPECT_EQ(reads_size1 + reads_size2, trans->GetTotalReceivedBytes());
   1929 
   1930   response = trans->GetResponseInfo();
   1931   ASSERT_TRUE(response != NULL);
   1932   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1933   EXPECT_EQ(100, response->headers->GetContentLength());
   1934 }
   1935 
   1936 TEST_P(HttpNetworkTransactionTest, DoNotSendAuth) {
   1937   HttpRequestInfo request;
   1938   request.method = "GET";
   1939   request.url = GURL("http://www.google.com/");
   1940   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1941 
   1942   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1943   scoped_ptr<HttpTransaction> trans(
   1944       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   1945 
   1946   MockWrite data_writes[] = {
   1947     MockWrite("GET / HTTP/1.1\r\n"
   1948               "Host: www.google.com\r\n"
   1949               "Connection: keep-alive\r\n\r\n"),
   1950   };
   1951 
   1952   MockRead data_reads[] = {
   1953     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1954     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1955     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1956     // Large content-length -- won't matter, as connection will be reset.
   1957     MockRead("Content-Length: 10000\r\n\r\n"),
   1958     MockRead(SYNCHRONOUS, ERR_FAILED),
   1959   };
   1960 
   1961   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1962                                 data_writes, arraysize(data_writes));
   1963   session_deps_.socket_factory->AddSocketDataProvider(&data);
   1964   TestCompletionCallback callback;
   1965 
   1966   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   1967   EXPECT_EQ(ERR_IO_PENDING, rv);
   1968 
   1969   rv = callback.WaitForResult();
   1970   EXPECT_EQ(0, rv);
   1971 
   1972   int64 reads_size = ReadsSize(data_reads, arraysize(data_reads));
   1973   EXPECT_EQ(reads_size, trans->GetTotalReceivedBytes());
   1974 
   1975   const HttpResponseInfo* response = trans->GetResponseInfo();
   1976   ASSERT_TRUE(response != NULL);
   1977   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1978 }
   1979 
   1980 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1981 // connection.
   1982 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   1983   HttpRequestInfo request;
   1984   request.method = "GET";
   1985   request.url = GURL("http://www.google.com/");
   1986   request.load_flags = 0;
   1987 
   1988   CapturingNetLog log;
   1989   session_deps_.net_log = &log;
   1990   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   1991 
   1992   MockWrite data_writes1[] = {
   1993     MockWrite("GET / HTTP/1.1\r\n"
   1994               "Host: www.google.com\r\n"
   1995               "Connection: keep-alive\r\n\r\n"),
   1996 
   1997     // After calling trans->RestartWithAuth(), this is the request we should
   1998     // be issuing -- the final header line contains the credentials.
   1999     MockWrite("GET / HTTP/1.1\r\n"
   2000               "Host: www.google.com\r\n"
   2001               "Connection: keep-alive\r\n"
   2002               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2003   };
   2004 
   2005   MockRead data_reads1[] = {
   2006     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2007     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2008     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2009     MockRead("Content-Length: 14\r\n\r\n"),
   2010     MockRead("Unauthorized\r\n"),
   2011 
   2012     // Lastly, the server responds with the actual content.
   2013     MockRead("HTTP/1.1 200 OK\r\n"),
   2014     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2015     MockRead("Content-Length: 5\r\n\r\n"),
   2016     MockRead("Hello"),
   2017   };
   2018 
   2019   // If there is a regression where we disconnect a Keep-Alive
   2020   // connection during an auth roundtrip, we'll end up reading this.
   2021   MockRead data_reads2[] = {
   2022     MockRead(SYNCHRONOUS, ERR_FAILED),
   2023   };
   2024 
   2025   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2026                                  data_writes1, arraysize(data_writes1));
   2027   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2028                                  NULL, 0);
   2029   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2030   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2031 
   2032   TestCompletionCallback callback1;
   2033 
   2034   scoped_ptr<HttpTransaction> trans(
   2035       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2036   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2037   EXPECT_EQ(ERR_IO_PENDING, rv);
   2038 
   2039   rv = callback1.WaitForResult();
   2040   EXPECT_EQ(OK, rv);
   2041 
   2042   LoadTimingInfo load_timing_info1;
   2043   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info1));
   2044   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_DNS_TIMES);
   2045 
   2046   const HttpResponseInfo* response = trans->GetResponseInfo();
   2047   ASSERT_TRUE(response != NULL);
   2048   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2049 
   2050   TestCompletionCallback callback2;
   2051 
   2052   rv = trans->RestartWithAuth(
   2053       AuthCredentials(kFoo, kBar), callback2.callback());
   2054   EXPECT_EQ(ERR_IO_PENDING, rv);
   2055 
   2056   rv = callback2.WaitForResult();
   2057   EXPECT_EQ(OK, rv);
   2058 
   2059   LoadTimingInfo load_timing_info2;
   2060   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info2));
   2061   TestLoadTimingReused(load_timing_info2);
   2062   // The load timing after restart should have the same socket ID, and times
   2063   // those of the first load timing.
   2064   EXPECT_LE(load_timing_info1.receive_headers_end,
   2065             load_timing_info2.send_start);
   2066   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2067 
   2068   response = trans->GetResponseInfo();
   2069   ASSERT_TRUE(response != NULL);
   2070   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2071   EXPECT_EQ(5, response->headers->GetContentLength());
   2072 
   2073   std::string response_data;
   2074   rv = ReadTransaction(trans.get(), &response_data);
   2075   EXPECT_EQ(OK, rv);
   2076   int64 reads_size1 = ReadsSize(data_reads1, arraysize(data_reads1));
   2077   EXPECT_EQ(reads_size1, trans->GetTotalReceivedBytes());
   2078 }
   2079 
   2080 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2081 // connection and with no response body to drain.
   2082 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   2083   HttpRequestInfo request;
   2084   request.method = "GET";
   2085   request.url = GURL("http://www.google.com/");
   2086   request.load_flags = 0;
   2087 
   2088   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2089 
   2090   MockWrite data_writes1[] = {
   2091     MockWrite("GET / HTTP/1.1\r\n"
   2092               "Host: www.google.com\r\n"
   2093               "Connection: keep-alive\r\n\r\n"),
   2094 
   2095     // After calling trans->RestartWithAuth(), this is the request we should
   2096     // be issuing -- the final header line contains the credentials.
   2097     MockWrite("GET / HTTP/1.1\r\n"
   2098               "Host: www.google.com\r\n"
   2099               "Connection: keep-alive\r\n"
   2100               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2101   };
   2102 
   2103   MockRead data_reads1[] = {
   2104     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2105     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2106     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   2107 
   2108     // Lastly, the server responds with the actual content.
   2109     MockRead("HTTP/1.1 200 OK\r\n"),
   2110     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2111     MockRead("Content-Length: 5\r\n\r\n"),
   2112     MockRead("hello"),
   2113   };
   2114 
   2115   // An incorrect reconnect would cause this to be read.
   2116   MockRead data_reads2[] = {
   2117     MockRead(SYNCHRONOUS, ERR_FAILED),
   2118   };
   2119 
   2120   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2121                                  data_writes1, arraysize(data_writes1));
   2122   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2123                                  NULL, 0);
   2124   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2125   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2126 
   2127   TestCompletionCallback callback1;
   2128 
   2129   scoped_ptr<HttpTransaction> trans(
   2130       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2131   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2132   EXPECT_EQ(ERR_IO_PENDING, rv);
   2133 
   2134   rv = callback1.WaitForResult();
   2135   EXPECT_EQ(OK, rv);
   2136 
   2137   const HttpResponseInfo* response = trans->GetResponseInfo();
   2138   ASSERT_TRUE(response != NULL);
   2139   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2140 
   2141   TestCompletionCallback callback2;
   2142 
   2143   rv = trans->RestartWithAuth(
   2144       AuthCredentials(kFoo, kBar), callback2.callback());
   2145   EXPECT_EQ(ERR_IO_PENDING, rv);
   2146 
   2147   rv = callback2.WaitForResult();
   2148   EXPECT_EQ(OK, rv);
   2149 
   2150   response = trans->GetResponseInfo();
   2151   ASSERT_TRUE(response != NULL);
   2152   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2153   EXPECT_EQ(5, response->headers->GetContentLength());
   2154 }
   2155 
   2156 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2157 // connection and with a large response body to drain.
   2158 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   2159   HttpRequestInfo request;
   2160   request.method = "GET";
   2161   request.url = GURL("http://www.google.com/");
   2162   request.load_flags = 0;
   2163 
   2164   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2165 
   2166   MockWrite data_writes1[] = {
   2167     MockWrite("GET / HTTP/1.1\r\n"
   2168               "Host: www.google.com\r\n"
   2169               "Connection: keep-alive\r\n\r\n"),
   2170 
   2171     // After calling trans->RestartWithAuth(), this is the request we should
   2172     // be issuing -- the final header line contains the credentials.
   2173     MockWrite("GET / HTTP/1.1\r\n"
   2174               "Host: www.google.com\r\n"
   2175               "Connection: keep-alive\r\n"
   2176               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2177   };
   2178 
   2179   // Respond with 5 kb of response body.
   2180   std::string large_body_string("Unauthorized");
   2181   large_body_string.append(5 * 1024, ' ');
   2182   large_body_string.append("\r\n");
   2183 
   2184   MockRead data_reads1[] = {
   2185     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2186     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2187     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2188     // 5134 = 12 + 5 * 1024 + 2
   2189     MockRead("Content-Length: 5134\r\n\r\n"),
   2190     MockRead(ASYNC, large_body_string.data(), large_body_string.size()),
   2191 
   2192     // Lastly, the server responds with the actual content.
   2193     MockRead("HTTP/1.1 200 OK\r\n"),
   2194     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2195     MockRead("Content-Length: 5\r\n\r\n"),
   2196     MockRead("hello"),
   2197   };
   2198 
   2199   // An incorrect reconnect would cause this to be read.
   2200   MockRead data_reads2[] = {
   2201     MockRead(SYNCHRONOUS, ERR_FAILED),
   2202   };
   2203 
   2204   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2205                                  data_writes1, arraysize(data_writes1));
   2206   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2207                                  NULL, 0);
   2208   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2209   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2210 
   2211   TestCompletionCallback callback1;
   2212 
   2213   scoped_ptr<HttpTransaction> trans(
   2214       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2215   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2216   EXPECT_EQ(ERR_IO_PENDING, rv);
   2217 
   2218   rv = callback1.WaitForResult();
   2219   EXPECT_EQ(OK, rv);
   2220 
   2221   const HttpResponseInfo* response = trans->GetResponseInfo();
   2222   ASSERT_TRUE(response != NULL);
   2223   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2224 
   2225   TestCompletionCallback callback2;
   2226 
   2227   rv = trans->RestartWithAuth(
   2228       AuthCredentials(kFoo, kBar), callback2.callback());
   2229   EXPECT_EQ(ERR_IO_PENDING, rv);
   2230 
   2231   rv = callback2.WaitForResult();
   2232   EXPECT_EQ(OK, rv);
   2233 
   2234   response = trans->GetResponseInfo();
   2235   ASSERT_TRUE(response != NULL);
   2236   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2237   EXPECT_EQ(5, response->headers->GetContentLength());
   2238 }
   2239 
   2240 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2241 // connection, but the server gets impatient and closes the connection.
   2242 TEST_P(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   2243   HttpRequestInfo request;
   2244   request.method = "GET";
   2245   request.url = GURL("http://www.google.com/");
   2246   request.load_flags = 0;
   2247 
   2248   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2249 
   2250   MockWrite data_writes1[] = {
   2251     MockWrite("GET / HTTP/1.1\r\n"
   2252               "Host: www.google.com\r\n"
   2253               "Connection: keep-alive\r\n\r\n"),
   2254     // This simulates the seemingly successful write to a closed connection
   2255     // if the bug is not fixed.
   2256     MockWrite("GET / HTTP/1.1\r\n"
   2257               "Host: www.google.com\r\n"
   2258               "Connection: keep-alive\r\n"
   2259               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2260   };
   2261 
   2262   MockRead data_reads1[] = {
   2263     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   2264     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2265     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2266     MockRead("Content-Length: 14\r\n\r\n"),
   2267     // Tell MockTCPClientSocket to simulate the server closing the connection.
   2268     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   2269     MockRead("Unauthorized\r\n"),
   2270     MockRead(SYNCHRONOUS, OK),  // The server closes the connection.
   2271   };
   2272 
   2273   // After calling trans->RestartWithAuth(), this is the request we should
   2274   // be issuing -- the final header line contains the credentials.
   2275   MockWrite data_writes2[] = {
   2276     MockWrite("GET / HTTP/1.1\r\n"
   2277               "Host: www.google.com\r\n"
   2278               "Connection: keep-alive\r\n"
   2279               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2280   };
   2281 
   2282   // Lastly, the server responds with the actual content.
   2283   MockRead data_reads2[] = {
   2284     MockRead("HTTP/1.1 200 OK\r\n"),
   2285     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2286     MockRead("Content-Length: 5\r\n\r\n"),
   2287     MockRead("hello"),
   2288   };
   2289 
   2290   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2291                                  data_writes1, arraysize(data_writes1));
   2292   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2293                                  data_writes2, arraysize(data_writes2));
   2294   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2295   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   2296 
   2297   TestCompletionCallback callback1;
   2298 
   2299   scoped_ptr<HttpTransaction> trans(
   2300       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2301   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   2302   EXPECT_EQ(ERR_IO_PENDING, rv);
   2303 
   2304   rv = callback1.WaitForResult();
   2305   EXPECT_EQ(OK, rv);
   2306 
   2307   const HttpResponseInfo* response = trans->GetResponseInfo();
   2308   ASSERT_TRUE(response != NULL);
   2309   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   2310 
   2311   TestCompletionCallback callback2;
   2312 
   2313   rv = trans->RestartWithAuth(
   2314       AuthCredentials(kFoo, kBar), callback2.callback());
   2315   EXPECT_EQ(ERR_IO_PENDING, rv);
   2316 
   2317   rv = callback2.WaitForResult();
   2318   EXPECT_EQ(OK, rv);
   2319 
   2320   response = trans->GetResponseInfo();
   2321   ASSERT_TRUE(response != NULL);
   2322   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2323   EXPECT_EQ(5, response->headers->GetContentLength());
   2324 }
   2325 
   2326 // Test the request-challenge-retry sequence for basic auth, over a connection
   2327 // that requires a restart when setting up an SSL tunnel.
   2328 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
   2329   HttpRequestInfo request;
   2330   request.method = "GET";
   2331   request.url = GURL("https://www.google.com/");
   2332   // when the no authentication data flag is set.
   2333   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2334 
   2335   // Configure against proxy server "myproxy:70".
   2336   session_deps_.proxy_service.reset(
   2337       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2338   CapturingBoundNetLog log;
   2339   session_deps_.net_log = log.bound().net_log();
   2340   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2341 
   2342   // Since we have proxy, should try to establish tunnel.
   2343   MockWrite data_writes1[] = {
   2344     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2345               "Host: www.google.com\r\n"
   2346               "Proxy-Connection: keep-alive\r\n\r\n"),
   2347 
   2348     // After calling trans->RestartWithAuth(), this is the request we should
   2349     // be issuing -- the final header line contains the credentials.
   2350     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2351               "Host: www.google.com\r\n"
   2352               "Proxy-Connection: keep-alive\r\n"
   2353               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2354 
   2355     MockWrite("GET / HTTP/1.1\r\n"
   2356               "Host: www.google.com\r\n"
   2357               "Connection: keep-alive\r\n\r\n"),
   2358   };
   2359 
   2360   // The proxy responds to the connect with a 407, using a persistent
   2361   // connection.
   2362   MockRead data_reads1[] = {
   2363     // No credentials.
   2364     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2365     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2366     MockRead("Proxy-Connection: close\r\n\r\n"),
   2367 
   2368     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2369 
   2370     MockRead("HTTP/1.1 200 OK\r\n"),
   2371     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2372     MockRead("Content-Length: 5\r\n\r\n"),
   2373     MockRead(SYNCHRONOUS, "hello"),
   2374   };
   2375 
   2376   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2377                                  data_writes1, arraysize(data_writes1));
   2378   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2379   SSLSocketDataProvider ssl(ASYNC, OK);
   2380   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2381 
   2382   TestCompletionCallback callback1;
   2383 
   2384   scoped_ptr<HttpTransaction> trans(
   2385       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2386 
   2387   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2388   EXPECT_EQ(ERR_IO_PENDING, rv);
   2389 
   2390   rv = callback1.WaitForResult();
   2391   EXPECT_EQ(OK, rv);
   2392   net::CapturingNetLog::CapturedEntryList entries;
   2393   log.GetEntries(&entries);
   2394   size_t pos = ExpectLogContainsSomewhere(
   2395       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2396       NetLog::PHASE_NONE);
   2397   ExpectLogContainsSomewhere(
   2398       entries, pos,
   2399       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2400       NetLog::PHASE_NONE);
   2401 
   2402   const HttpResponseInfo* response = trans->GetResponseInfo();
   2403   ASSERT_TRUE(response != NULL);
   2404   ASSERT_FALSE(response->headers.get() == NULL);
   2405   EXPECT_EQ(407, response->headers->response_code());
   2406   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2407   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2408 
   2409   LoadTimingInfo load_timing_info;
   2410   // CONNECT requests and responses are handled at the connect job level, so
   2411   // the transaction does not yet have a connection.
   2412   EXPECT_FALSE(trans->GetLoadTimingInfo(&load_timing_info));
   2413 
   2414   TestCompletionCallback callback2;
   2415 
   2416   rv = trans->RestartWithAuth(
   2417       AuthCredentials(kFoo, kBar), callback2.callback());
   2418   EXPECT_EQ(ERR_IO_PENDING, rv);
   2419 
   2420   rv = callback2.WaitForResult();
   2421   EXPECT_EQ(OK, rv);
   2422 
   2423   response = trans->GetResponseInfo();
   2424   ASSERT_TRUE(response != NULL);
   2425 
   2426   EXPECT_TRUE(response->headers->IsKeepAlive());
   2427   EXPECT_EQ(200, response->headers->response_code());
   2428   EXPECT_EQ(5, response->headers->GetContentLength());
   2429   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2430 
   2431   // The password prompt info should not be set.
   2432   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2433 
   2434   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   2435   TestLoadTimingNotReusedWithPac(load_timing_info,
   2436                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2437 
   2438   trans.reset();
   2439   session->CloseAllConnections();
   2440 }
   2441 
   2442 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   2443 // proxy connection, when setting up an SSL tunnel.
   2444 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   2445   HttpRequestInfo request;
   2446   request.method = "GET";
   2447   request.url = GURL("https://www.google.com/");
   2448   // Ensure that proxy authentication is attempted even
   2449   // when the no authentication data flag is set.
   2450   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2451 
   2452   // Configure against proxy server "myproxy:70".
   2453   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2454   CapturingBoundNetLog log;
   2455   session_deps_.net_log = log.bound().net_log();
   2456   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2457 
   2458   scoped_ptr<HttpTransaction> trans(
   2459       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2460 
   2461   // Since we have proxy, should try to establish tunnel.
   2462   MockWrite data_writes1[] = {
   2463     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2464               "Host: www.google.com\r\n"
   2465               "Proxy-Connection: keep-alive\r\n\r\n"),
   2466 
   2467     // After calling trans->RestartWithAuth(), this is the request we should
   2468     // be issuing -- the final header line contains the credentials.
   2469     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2470               "Host: www.google.com\r\n"
   2471               "Proxy-Connection: keep-alive\r\n"
   2472               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   2473   };
   2474 
   2475   // The proxy responds to the connect with a 407, using a persistent
   2476   // connection.
   2477   MockRead data_reads1[] = {
   2478     // No credentials.
   2479     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2480     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2481     MockRead("Content-Length: 10\r\n\r\n"),
   2482     MockRead("0123456789"),
   2483 
   2484     // Wrong credentials (wrong password).
   2485     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2486     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2487     MockRead("Content-Length: 10\r\n\r\n"),
   2488     // No response body because the test stops reading here.
   2489     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2490   };
   2491 
   2492   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2493                                  data_writes1, arraysize(data_writes1));
   2494   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2495 
   2496   TestCompletionCallback callback1;
   2497 
   2498   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2499   EXPECT_EQ(ERR_IO_PENDING, rv);
   2500 
   2501   rv = callback1.WaitForResult();
   2502   EXPECT_EQ(OK, rv);
   2503   net::CapturingNetLog::CapturedEntryList entries;
   2504   log.GetEntries(&entries);
   2505   size_t pos = ExpectLogContainsSomewhere(
   2506       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2507       NetLog::PHASE_NONE);
   2508   ExpectLogContainsSomewhere(
   2509       entries, pos,
   2510       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2511       NetLog::PHASE_NONE);
   2512 
   2513   const HttpResponseInfo* response = trans->GetResponseInfo();
   2514   ASSERT_TRUE(response != NULL);
   2515   ASSERT_FALSE(response->headers.get() == NULL);
   2516   EXPECT_TRUE(response->headers->IsKeepAlive());
   2517   EXPECT_EQ(407, response->headers->response_code());
   2518   EXPECT_EQ(10, response->headers->GetContentLength());
   2519   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2520   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2521 
   2522   TestCompletionCallback callback2;
   2523 
   2524   // Wrong password (should be "bar").
   2525   rv = trans->RestartWithAuth(
   2526       AuthCredentials(kFoo, kBaz), callback2.callback());
   2527   EXPECT_EQ(ERR_IO_PENDING, rv);
   2528 
   2529   rv = callback2.WaitForResult();
   2530   EXPECT_EQ(OK, rv);
   2531 
   2532   response = trans->GetResponseInfo();
   2533   ASSERT_TRUE(response != NULL);
   2534   ASSERT_FALSE(response->headers.get() == NULL);
   2535   EXPECT_TRUE(response->headers->IsKeepAlive());
   2536   EXPECT_EQ(407, response->headers->response_code());
   2537   EXPECT_EQ(10, response->headers->GetContentLength());
   2538   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2539   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   2540 
   2541   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
   2542   // out of scope.
   2543   session->CloseAllConnections();
   2544 }
   2545 
   2546 // Test that we don't read the response body when we fail to establish a tunnel,
   2547 // even if the user cancels the proxy's auth attempt.
   2548 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   2549   HttpRequestInfo request;
   2550   request.method = "GET";
   2551   request.url = GURL("https://www.google.com/");
   2552   request.load_flags = 0;
   2553 
   2554   // Configure against proxy server "myproxy:70".
   2555   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2556 
   2557   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2558 
   2559   scoped_ptr<HttpTransaction> trans(
   2560       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2561 
   2562   // Since we have proxy, should try to establish tunnel.
   2563   MockWrite data_writes[] = {
   2564     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2565               "Host: www.google.com\r\n"
   2566               "Proxy-Connection: keep-alive\r\n\r\n"),
   2567   };
   2568 
   2569   // The proxy responds to the connect with a 407.
   2570   MockRead data_reads[] = {
   2571     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2572     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2573     MockRead("Content-Length: 10\r\n\r\n"),
   2574     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   2575   };
   2576 
   2577   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   2578                                 data_writes, arraysize(data_writes));
   2579   session_deps_.socket_factory->AddSocketDataProvider(&data);
   2580 
   2581   TestCompletionCallback callback;
   2582 
   2583   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2584   EXPECT_EQ(ERR_IO_PENDING, rv);
   2585 
   2586   rv = callback.WaitForResult();
   2587   EXPECT_EQ(OK, rv);
   2588 
   2589   const HttpResponseInfo* response = trans->GetResponseInfo();
   2590   ASSERT_TRUE(response != NULL);
   2591 
   2592   EXPECT_TRUE(response->headers->IsKeepAlive());
   2593   EXPECT_EQ(407, response->headers->response_code());
   2594   EXPECT_EQ(10, response->headers->GetContentLength());
   2595   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2596 
   2597   std::string response_data;
   2598   rv = ReadTransaction(trans.get(), &response_data);
   2599   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   2600 
   2601   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
   2602   session->CloseAllConnections();
   2603 }
   2604 
   2605 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
   2606 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
   2607 TEST_P(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   2608   HttpRequestInfo request;
   2609   request.method = "GET";
   2610   request.url = GURL("http://www.google.com/");
   2611   request.load_flags = 0;
   2612 
   2613   // We are using a DIRECT connection (i.e. no proxy) for this session.
   2614   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2615   scoped_ptr<HttpTransaction> trans(
   2616       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   2617 
   2618   MockWrite data_writes1[] = {
   2619     MockWrite("GET / HTTP/1.1\r\n"
   2620               "Host: www.google.com\r\n"
   2621               "Connection: keep-alive\r\n\r\n"),
   2622   };
   2623 
   2624   MockRead data_reads1[] = {
   2625     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
   2626     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2627     // Large content-length -- won't matter, as connection will be reset.
   2628     MockRead("Content-Length: 10000\r\n\r\n"),
   2629     MockRead(SYNCHRONOUS, ERR_FAILED),
   2630   };
   2631 
   2632   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2633                                  data_writes1, arraysize(data_writes1));
   2634   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2635 
   2636   TestCompletionCallback callback;
   2637 
   2638   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   2639   EXPECT_EQ(ERR_IO_PENDING, rv);
   2640 
   2641   rv = callback.WaitForResult();
   2642   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2643 }
   2644 
   2645 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
   2646 // through a non-authenticating proxy. The request should fail with
   2647 // ERR_UNEXPECTED_PROXY_AUTH.
   2648 // Note that it is impossible to detect if an HTTP server returns a 407 through
   2649 // a non-authenticating proxy - there is nothing to indicate whether the
   2650 // response came from the proxy or the server, so it is treated as if the proxy
   2651 // issued the challenge.
   2652 TEST_P(HttpNetworkTransactionTest,
   2653        HttpsServerRequestsProxyAuthThroughProxy) {
   2654   HttpRequestInfo request;
   2655   request.method = "GET";
   2656   request.url = GURL("https://www.google.com/");
   2657 
   2658   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   2659   CapturingBoundNetLog log;
   2660   session_deps_.net_log = log.bound().net_log();
   2661   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2662 
   2663   // Since we have proxy, should try to establish tunnel.
   2664   MockWrite data_writes1[] = {
   2665     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2666               "Host: www.google.com\r\n"
   2667               "Proxy-Connection: keep-alive\r\n\r\n"),
   2668 
   2669     MockWrite("GET / HTTP/1.1\r\n"
   2670               "Host: www.google.com\r\n"
   2671               "Connection: keep-alive\r\n\r\n"),
   2672   };
   2673 
   2674   MockRead data_reads1[] = {
   2675     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2676 
   2677     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
   2678     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2679     MockRead("\r\n"),
   2680     MockRead(SYNCHRONOUS, OK),
   2681   };
   2682 
   2683   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2684                                  data_writes1, arraysize(data_writes1));
   2685   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2686   SSLSocketDataProvider ssl(ASYNC, OK);
   2687   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2688 
   2689   TestCompletionCallback callback1;
   2690 
   2691   scoped_ptr<HttpTransaction> trans(
   2692       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2693 
   2694   int rv = trans->Start(&request, callback1.callback(), log.bound());
   2695   EXPECT_EQ(ERR_IO_PENDING, rv);
   2696 
   2697   rv = callback1.WaitForResult();
   2698   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   2699   net::CapturingNetLog::CapturedEntryList entries;
   2700   log.GetEntries(&entries);
   2701   size_t pos = ExpectLogContainsSomewhere(
   2702       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   2703       NetLog::PHASE_NONE);
   2704   ExpectLogContainsSomewhere(
   2705       entries, pos,
   2706       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   2707       NetLog::PHASE_NONE);
   2708 }
   2709 
   2710 // Test the load timing for HTTPS requests with an HTTP proxy.
   2711 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingNoPacTwoRequests) {
   2712   HttpRequestInfo request1;
   2713   request1.method = "GET";
   2714   request1.url = GURL("https://www.google.com/1");
   2715 
   2716   HttpRequestInfo request2;
   2717   request2.method = "GET";
   2718   request2.url = GURL("https://www.google.com/2");
   2719 
   2720   // Configure against proxy server "myproxy:70".
   2721   session_deps_.proxy_service.reset(
   2722       ProxyService::CreateFixed("PROXY myproxy:70"));
   2723   CapturingBoundNetLog log;
   2724   session_deps_.net_log = log.bound().net_log();
   2725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2726 
   2727   // Since we have proxy, should try to establish tunnel.
   2728   MockWrite data_writes1[] = {
   2729     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2730               "Host: www.google.com\r\n"
   2731               "Proxy-Connection: keep-alive\r\n\r\n"),
   2732 
   2733     MockWrite("GET /1 HTTP/1.1\r\n"
   2734               "Host: www.google.com\r\n"
   2735               "Connection: keep-alive\r\n\r\n"),
   2736 
   2737     MockWrite("GET /2 HTTP/1.1\r\n"
   2738               "Host: www.google.com\r\n"
   2739               "Connection: keep-alive\r\n\r\n"),
   2740   };
   2741 
   2742   // The proxy responds to the connect with a 407, using a persistent
   2743   // connection.
   2744   MockRead data_reads1[] = {
   2745     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2746 
   2747     MockRead("HTTP/1.1 200 OK\r\n"),
   2748     MockRead("Content-Length: 1\r\n\r\n"),
   2749     MockRead(SYNCHRONOUS, "1"),
   2750 
   2751     MockRead("HTTP/1.1 200 OK\r\n"),
   2752     MockRead("Content-Length: 2\r\n\r\n"),
   2753     MockRead(SYNCHRONOUS, "22"),
   2754   };
   2755 
   2756   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2757                                  data_writes1, arraysize(data_writes1));
   2758   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2759   SSLSocketDataProvider ssl(ASYNC, OK);
   2760   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2761 
   2762   TestCompletionCallback callback1;
   2763   scoped_ptr<HttpTransaction> trans1(
   2764       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2765 
   2766   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2767   EXPECT_EQ(ERR_IO_PENDING, rv);
   2768 
   2769   rv = callback1.WaitForResult();
   2770   EXPECT_EQ(OK, rv);
   2771 
   2772   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2773   ASSERT_TRUE(response1 != NULL);
   2774   ASSERT_TRUE(response1->headers.get() != NULL);
   2775   EXPECT_EQ(1, response1->headers->GetContentLength());
   2776 
   2777   LoadTimingInfo load_timing_info1;
   2778   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2779   TestLoadTimingNotReused(load_timing_info1, CONNECT_TIMING_HAS_SSL_TIMES);
   2780 
   2781   trans1.reset();
   2782 
   2783   TestCompletionCallback callback2;
   2784   scoped_ptr<HttpTransaction> trans2(
   2785       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2786 
   2787   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2788   EXPECT_EQ(ERR_IO_PENDING, rv);
   2789 
   2790   rv = callback2.WaitForResult();
   2791   EXPECT_EQ(OK, rv);
   2792 
   2793   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2794   ASSERT_TRUE(response2 != NULL);
   2795   ASSERT_TRUE(response2->headers.get() != NULL);
   2796   EXPECT_EQ(2, response2->headers->GetContentLength());
   2797 
   2798   LoadTimingInfo load_timing_info2;
   2799   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2800   TestLoadTimingReused(load_timing_info2);
   2801 
   2802   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2803 
   2804   trans2.reset();
   2805   session->CloseAllConnections();
   2806 }
   2807 
   2808 // Test the load timing for HTTPS requests with an HTTP proxy and a PAC script.
   2809 TEST_P(HttpNetworkTransactionTest, HttpProxyLoadTimingWithPacTwoRequests) {
   2810   HttpRequestInfo request1;
   2811   request1.method = "GET";
   2812   request1.url = GURL("https://www.google.com/1");
   2813 
   2814   HttpRequestInfo request2;
   2815   request2.method = "GET";
   2816   request2.url = GURL("https://www.google.com/2");
   2817 
   2818   // Configure against proxy server "myproxy:70".
   2819   session_deps_.proxy_service.reset(
   2820       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
   2821   CapturingBoundNetLog log;
   2822   session_deps_.net_log = log.bound().net_log();
   2823   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2824 
   2825   // Since we have proxy, should try to establish tunnel.
   2826   MockWrite data_writes1[] = {
   2827     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2828               "Host: www.google.com\r\n"
   2829               "Proxy-Connection: keep-alive\r\n\r\n"),
   2830 
   2831     MockWrite("GET /1 HTTP/1.1\r\n"
   2832               "Host: www.google.com\r\n"
   2833               "Connection: keep-alive\r\n\r\n"),
   2834 
   2835     MockWrite("GET /2 HTTP/1.1\r\n"
   2836               "Host: www.google.com\r\n"
   2837               "Connection: keep-alive\r\n\r\n"),
   2838   };
   2839 
   2840   // The proxy responds to the connect with a 407, using a persistent
   2841   // connection.
   2842   MockRead data_reads1[] = {
   2843     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   2844 
   2845     MockRead("HTTP/1.1 200 OK\r\n"),
   2846     MockRead("Content-Length: 1\r\n\r\n"),
   2847     MockRead(SYNCHRONOUS, "1"),
   2848 
   2849     MockRead("HTTP/1.1 200 OK\r\n"),
   2850     MockRead("Content-Length: 2\r\n\r\n"),
   2851     MockRead(SYNCHRONOUS, "22"),
   2852   };
   2853 
   2854   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2855                                  data_writes1, arraysize(data_writes1));
   2856   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2857   SSLSocketDataProvider ssl(ASYNC, OK);
   2858   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2859 
   2860   TestCompletionCallback callback1;
   2861   scoped_ptr<HttpTransaction> trans1(
   2862       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2863 
   2864   int rv = trans1->Start(&request1, callback1.callback(), log.bound());
   2865   EXPECT_EQ(ERR_IO_PENDING, rv);
   2866 
   2867   rv = callback1.WaitForResult();
   2868   EXPECT_EQ(OK, rv);
   2869 
   2870   const HttpResponseInfo* response1 = trans1->GetResponseInfo();
   2871   ASSERT_TRUE(response1 != NULL);
   2872   ASSERT_TRUE(response1->headers.get() != NULL);
   2873   EXPECT_EQ(1, response1->headers->GetContentLength());
   2874 
   2875   LoadTimingInfo load_timing_info1;
   2876   EXPECT_TRUE(trans1->GetLoadTimingInfo(&load_timing_info1));
   2877   TestLoadTimingNotReusedWithPac(load_timing_info1,
   2878                                  CONNECT_TIMING_HAS_SSL_TIMES);
   2879 
   2880   trans1.reset();
   2881 
   2882   TestCompletionCallback callback2;
   2883   scoped_ptr<HttpTransaction> trans2(
   2884       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   2885 
   2886   rv = trans2->Start(&request2, callback2.callback(), log.bound());
   2887   EXPECT_EQ(ERR_IO_PENDING, rv);
   2888 
   2889   rv = callback2.WaitForResult();
   2890   EXPECT_EQ(OK, rv);
   2891 
   2892   const HttpResponseInfo* response2 = trans2->GetResponseInfo();
   2893   ASSERT_TRUE(response2 != NULL);
   2894   ASSERT_TRUE(response2->headers.get() != NULL);
   2895   EXPECT_EQ(2, response2->headers->GetContentLength());
   2896 
   2897   LoadTimingInfo load_timing_info2;
   2898   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   2899   TestLoadTimingReusedWithPac(load_timing_info2);
   2900 
   2901   EXPECT_EQ(load_timing_info1.socket_log_id, load_timing_info2.socket_log_id);
   2902 
   2903   trans2.reset();
   2904   session->CloseAllConnections();
   2905 }
   2906 
   2907 // Test a simple get through an HTTPS Proxy.
   2908 TEST_P(HttpNetworkTransactionTest, HttpsProxyGet) {
   2909   HttpRequestInfo request;
   2910   request.method = "GET";
   2911   request.url = GURL("http://www.google.com/");
   2912 
   2913   // Configure against https proxy server "proxy:70".
   2914   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2915       "https://proxy:70"));
   2916   CapturingBoundNetLog log;
   2917   session_deps_.net_log = log.bound().net_log();
   2918   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2919 
   2920   // Since we have proxy, should use full url
   2921   MockWrite data_writes1[] = {
   2922     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2923               "Host: www.google.com\r\n"
   2924               "Proxy-Connection: keep-alive\r\n\r\n"),
   2925   };
   2926 
   2927   MockRead data_reads1[] = {
   2928     MockRead("HTTP/1.1 200 OK\r\n"),
   2929     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2930     MockRead("Content-Length: 100\r\n\r\n"),
   2931     MockRead(SYNCHRONOUS, OK),
   2932   };
   2933 
   2934   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2935                                  data_writes1, arraysize(data_writes1));
   2936   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   2937   SSLSocketDataProvider ssl(ASYNC, OK);
   2938   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   2939 
   2940   TestCompletionCallback callback1;
   2941 
   2942   scoped_ptr<HttpTransaction> trans(
   2943       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   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,
   2954                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   2955 
   2956   const HttpResponseInfo* response = trans->GetResponseInfo();
   2957   ASSERT_TRUE(response != NULL);
   2958 
   2959   EXPECT_TRUE(response->headers->IsKeepAlive());
   2960   EXPECT_EQ(200, response->headers->response_code());
   2961   EXPECT_EQ(100, response->headers->GetContentLength());
   2962   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2963 
   2964   // The password prompt info should not be set.
   2965   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2966 }
   2967 
   2968 // Test a SPDY get through an HTTPS Proxy.
   2969 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   2970   HttpRequestInfo request;
   2971   request.method = "GET";
   2972   request.url = GURL("http://www.google.com/");
   2973   request.load_flags = 0;
   2974 
   2975   // Configure against https proxy server "proxy:70".
   2976   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   2977       "https://proxy:70"));
   2978   CapturingBoundNetLog log;
   2979   session_deps_.net_log = log.bound().net_log();
   2980   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   2981 
   2982   // fetch http://www.google.com/ via SPDY
   2983   scoped_ptr<SpdyFrame> req(
   2984       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2985   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   2986 
   2987   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   2988   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   2989   MockRead spdy_reads[] = {
   2990     CreateMockRead(*resp),
   2991     CreateMockRead(*data),
   2992     MockRead(ASYNC, 0, 0),
   2993   };
   2994 
   2995   DelayedSocketData spdy_data(
   2996       1,  // wait for one write to finish before reading.
   2997       spdy_reads, arraysize(spdy_reads),
   2998       spdy_writes, arraysize(spdy_writes));
   2999   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3000 
   3001   SSLSocketDataProvider ssl(ASYNC, OK);
   3002   ssl.SetNextProto(GetParam());
   3003   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3004 
   3005   TestCompletionCallback callback1;
   3006 
   3007   scoped_ptr<HttpTransaction> trans(
   3008       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3009 
   3010   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3011   EXPECT_EQ(ERR_IO_PENDING, rv);
   3012 
   3013   rv = callback1.WaitForResult();
   3014   EXPECT_EQ(OK, rv);
   3015 
   3016   LoadTimingInfo load_timing_info;
   3017   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3018   TestLoadTimingNotReused(load_timing_info,
   3019                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3020 
   3021   const HttpResponseInfo* response = trans->GetResponseInfo();
   3022   ASSERT_TRUE(response != NULL);
   3023   ASSERT_TRUE(response->headers.get() != NULL);
   3024   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3025 
   3026   std::string response_data;
   3027   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3028   EXPECT_EQ(kUploadData, response_data);
   3029 }
   3030 
   3031 // Verifies that a session which races and wins against the owning transaction
   3032 // (completing prior to host resolution), doesn't fail the transaction.
   3033 // Regression test for crbug.com/334413.
   3034 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithSessionRace) {
   3035   HttpRequestInfo request;
   3036   request.method = "GET";
   3037   request.url = GURL("http://www.google.com/");
   3038   request.load_flags = 0;
   3039 
   3040   // Configure SPDY proxy server "proxy:70".
   3041   session_deps_.proxy_service.reset(
   3042       ProxyService::CreateFixed("https://proxy:70"));
   3043   CapturingBoundNetLog log;
   3044   session_deps_.net_log = log.bound().net_log();
   3045   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3046 
   3047   // Fetch http://www.google.com/ through the SPDY proxy.
   3048   scoped_ptr<SpdyFrame> req(
   3049       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   3050   MockWrite spdy_writes[] = {CreateMockWrite(*req)};
   3051 
   3052   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3053   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3054   MockRead spdy_reads[] = {
   3055       CreateMockRead(*resp), CreateMockRead(*data), MockRead(ASYNC, 0, 0),
   3056   };
   3057 
   3058   DelayedSocketData spdy_data(
   3059       1,  // wait for one write to finish before reading.
   3060       spdy_reads,
   3061       arraysize(spdy_reads),
   3062       spdy_writes,
   3063       arraysize(spdy_writes));
   3064   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3065 
   3066   SSLSocketDataProvider ssl(ASYNC, OK);
   3067   ssl.SetNextProto(GetParam());
   3068   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3069 
   3070   TestCompletionCallback callback1;
   3071 
   3072   scoped_ptr<HttpTransaction> trans(
   3073       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3074 
   3075   // Stall the hostname resolution begun by the transaction.
   3076   session_deps_.host_resolver->set_synchronous_mode(false);
   3077   session_deps_.host_resolver->set_ondemand_mode(true);
   3078 
   3079   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3080   EXPECT_EQ(ERR_IO_PENDING, rv);
   3081 
   3082   // Race a session to the proxy, which completes first.
   3083   session_deps_.host_resolver->set_ondemand_mode(false);
   3084   SpdySessionKey key(
   3085       HostPortPair("proxy", 70), ProxyServer::Direct(), PRIVACY_MODE_DISABLED);
   3086   base::WeakPtr<SpdySession> spdy_session =
   3087       CreateSecureSpdySession(session, key, log.bound());
   3088 
   3089   // Unstall the resolution begun by the transaction.
   3090   session_deps_.host_resolver->set_ondemand_mode(true);
   3091   session_deps_.host_resolver->ResolveAllPending();
   3092 
   3093   EXPECT_FALSE(callback1.have_result());
   3094   rv = callback1.WaitForResult();
   3095   EXPECT_EQ(OK, rv);
   3096 
   3097   const HttpResponseInfo* response = trans->GetResponseInfo();
   3098   ASSERT_TRUE(response != NULL);
   3099   ASSERT_TRUE(response->headers.get() != NULL);
   3100   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3101 
   3102   std::string response_data;
   3103   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3104   EXPECT_EQ(kUploadData, response_data);
   3105 }
   3106 
   3107 // Test a SPDY get through an HTTPS Proxy.
   3108 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   3109   HttpRequestInfo request;
   3110   request.method = "GET";
   3111   request.url = GURL("http://www.google.com/");
   3112   request.load_flags = 0;
   3113 
   3114   // Configure against https proxy server "myproxy:70".
   3115   session_deps_.proxy_service.reset(
   3116       ProxyService::CreateFixed("https://myproxy:70"));
   3117   CapturingBoundNetLog log;
   3118   session_deps_.net_log = log.bound().net_log();
   3119   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3120 
   3121   // The first request will be a bare GET, the second request will be a
   3122   // GET with a Proxy-Authorization header.
   3123   scoped_ptr<SpdyFrame> req_get(
   3124       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   3125   const char* const kExtraAuthorizationHeaders[] = {
   3126     "proxy-authorization", "Basic Zm9vOmJhcg=="
   3127   };
   3128   scoped_ptr<SpdyFrame> req_get_authorization(
   3129       spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders,
   3130                                   arraysize(kExtraAuthorizationHeaders) / 2,
   3131                                   false,
   3132                                   3,
   3133                                   LOWEST,
   3134                                   false));
   3135   MockWrite spdy_writes[] = {
   3136     CreateMockWrite(*req_get, 1),
   3137     CreateMockWrite(*req_get_authorization, 4),
   3138   };
   3139 
   3140   // The first response is a 407 proxy authentication challenge, and the second
   3141   // response will be a 200 response since the second request includes a valid
   3142   // Authorization header.
   3143   const char* const kExtraAuthenticationHeaders[] = {
   3144     "proxy-authenticate", "Basic realm=\"MyRealm1\""
   3145   };
   3146   scoped_ptr<SpdyFrame> resp_authentication(
   3147       spdy_util_.ConstructSpdySynReplyError(
   3148           "407 Proxy Authentication Required",
   3149           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
   3150           1));
   3151   scoped_ptr<SpdyFrame> body_authentication(
   3152       spdy_util_.ConstructSpdyBodyFrame(1, true));
   3153   scoped_ptr<SpdyFrame> resp_data(
   3154       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3155   scoped_ptr<SpdyFrame> body_data(spdy_util_.ConstructSpdyBodyFrame(3, true));
   3156   MockRead spdy_reads[] = {
   3157     CreateMockRead(*resp_authentication, 2),
   3158     CreateMockRead(*body_authentication, 3),
   3159     CreateMockRead(*resp_data, 5),
   3160     CreateMockRead(*body_data, 6),
   3161     MockRead(ASYNC, 0, 7),
   3162   };
   3163 
   3164   OrderedSocketData data(
   3165       spdy_reads, arraysize(spdy_reads),
   3166       spdy_writes, arraysize(spdy_writes));
   3167   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3168 
   3169   SSLSocketDataProvider ssl(ASYNC, OK);
   3170   ssl.SetNextProto(GetParam());
   3171   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3172 
   3173   TestCompletionCallback callback1;
   3174 
   3175   scoped_ptr<HttpTransaction> trans(
   3176       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3177 
   3178   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3179   EXPECT_EQ(ERR_IO_PENDING, rv);
   3180 
   3181   rv = callback1.WaitForResult();
   3182   EXPECT_EQ(OK, rv);
   3183 
   3184   const HttpResponseInfo* const response = trans->GetResponseInfo();
   3185 
   3186   ASSERT_TRUE(response != NULL);
   3187   ASSERT_TRUE(response->headers.get() != NULL);
   3188   EXPECT_EQ(407, response->headers->response_code());
   3189   EXPECT_TRUE(response->was_fetched_via_spdy);
   3190   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3191 
   3192   TestCompletionCallback callback2;
   3193 
   3194   rv = trans->RestartWithAuth(
   3195       AuthCredentials(kFoo, kBar), callback2.callback());
   3196   EXPECT_EQ(ERR_IO_PENDING, rv);
   3197 
   3198   rv = callback2.WaitForResult();
   3199   EXPECT_EQ(OK, rv);
   3200 
   3201   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   3202 
   3203   ASSERT_TRUE(response_restart != NULL);
   3204   ASSERT_TRUE(response_restart->headers.get() != NULL);
   3205   EXPECT_EQ(200, response_restart->headers->response_code());
   3206   // The password prompt info should not be set.
   3207   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   3208 }
   3209 
   3210 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
   3211 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   3212   HttpRequestInfo request;
   3213   request.method = "GET";
   3214   request.url = GURL("https://www.google.com/");
   3215   request.load_flags = 0;
   3216 
   3217   // Configure against https proxy server "proxy:70".
   3218   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3219       "https://proxy:70"));
   3220   CapturingBoundNetLog log;
   3221   session_deps_.net_log = log.bound().net_log();
   3222   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3223 
   3224   scoped_ptr<HttpTransaction> trans(
   3225       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3226 
   3227   // CONNECT to www.google.com:443 via SPDY
   3228   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3229                                                                 LOWEST));
   3230   // fetch https://www.google.com/ via HTTP
   3231 
   3232   const char get[] = "GET / HTTP/1.1\r\n"
   3233     "Host: www.google.com\r\n"
   3234     "Connection: keep-alive\r\n\r\n";
   3235   scoped_ptr<SpdyFrame> wrapped_get(
   3236       spdy_util_.ConstructSpdyBodyFrame(1, get, strlen(get), false));
   3237   scoped_ptr<SpdyFrame> conn_resp(
   3238       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3239   const char resp[] = "HTTP/1.1 200 OK\r\n"
   3240       "Content-Length: 10\r\n\r\n";
   3241   scoped_ptr<SpdyFrame> wrapped_get_resp(
   3242       spdy_util_.ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
   3243   scoped_ptr<SpdyFrame> wrapped_body(
   3244       spdy_util_.ConstructSpdyBodyFrame(1, "1234567890", 10, false));
   3245   scoped_ptr<SpdyFrame> window_update(
   3246       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   3247 
   3248   MockWrite spdy_writes[] = {
   3249       CreateMockWrite(*connect, 1),
   3250       CreateMockWrite(*wrapped_get, 3),
   3251       CreateMockWrite(*window_update, 5),
   3252   };
   3253 
   3254   MockRead spdy_reads[] = {
   3255     CreateMockRead(*conn_resp, 2, ASYNC),
   3256     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   3257     CreateMockRead(*wrapped_body, 6, ASYNC),
   3258     CreateMockRead(*wrapped_body, 7, ASYNC),
   3259     MockRead(ASYNC, 0, 8),
   3260   };
   3261 
   3262   OrderedSocketData spdy_data(
   3263       spdy_reads, arraysize(spdy_reads),
   3264       spdy_writes, arraysize(spdy_writes));
   3265   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3266 
   3267   SSLSocketDataProvider ssl(ASYNC, OK);
   3268   ssl.SetNextProto(GetParam());
   3269   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3270   SSLSocketDataProvider ssl2(ASYNC, OK);
   3271   ssl2.was_npn_negotiated = false;
   3272   ssl2.protocol_negotiated = kProtoUnknown;
   3273   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3274 
   3275   TestCompletionCallback callback1;
   3276 
   3277   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3278   EXPECT_EQ(ERR_IO_PENDING, rv);
   3279 
   3280   rv = callback1.WaitForResult();
   3281   EXPECT_EQ(OK, rv);
   3282 
   3283   LoadTimingInfo load_timing_info;
   3284   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3285   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3286 
   3287   const HttpResponseInfo* response = trans->GetResponseInfo();
   3288   ASSERT_TRUE(response != NULL);
   3289   ASSERT_TRUE(response->headers.get() != NULL);
   3290   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3291 
   3292   std::string response_data;
   3293   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3294   EXPECT_EQ("1234567890", response_data);
   3295 }
   3296 
   3297 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
   3298 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   3299   HttpRequestInfo request;
   3300   request.method = "GET";
   3301   request.url = GURL("https://www.google.com/");
   3302   request.load_flags = 0;
   3303 
   3304   // Configure against https proxy server "proxy:70".
   3305   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3306       "https://proxy:70"));
   3307   CapturingBoundNetLog log;
   3308   session_deps_.net_log = log.bound().net_log();
   3309   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3310 
   3311   scoped_ptr<HttpTransaction> trans(
   3312       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3313 
   3314   // CONNECT to www.google.com:443 via SPDY
   3315   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3316                                                                 LOWEST));
   3317   // fetch https://www.google.com/ via SPDY
   3318   const char* const kMyUrl = "https://www.google.com/";
   3319   scoped_ptr<SpdyFrame> get(
   3320       spdy_util_.ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   3321   scoped_ptr<SpdyFrame> wrapped_get(
   3322       spdy_util_.ConstructWrappedSpdyFrame(get, 1));
   3323   scoped_ptr<SpdyFrame> conn_resp(
   3324       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3325   scoped_ptr<SpdyFrame> get_resp(
   3326       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3327   scoped_ptr<SpdyFrame> wrapped_get_resp(
   3328       spdy_util_.ConstructWrappedSpdyFrame(get_resp, 1));
   3329   scoped_ptr<SpdyFrame> body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3330   scoped_ptr<SpdyFrame> wrapped_body(
   3331       spdy_util_.ConstructWrappedSpdyFrame(body, 1));
   3332   scoped_ptr<SpdyFrame> window_update_get_resp(
   3333       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp->size()));
   3334   scoped_ptr<SpdyFrame> window_update_body(
   3335       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_body->size()));
   3336 
   3337   MockWrite spdy_writes[] = {
   3338       CreateMockWrite(*connect, 1),
   3339       CreateMockWrite(*wrapped_get, 3),
   3340       CreateMockWrite(*window_update_get_resp, 5),
   3341       CreateMockWrite(*window_update_body, 7),
   3342   };
   3343 
   3344   MockRead spdy_reads[] = {
   3345     CreateMockRead(*conn_resp, 2, ASYNC),
   3346     CreateMockRead(*wrapped_get_resp, 4, ASYNC),
   3347     CreateMockRead(*wrapped_body, 6, ASYNC),
   3348     MockRead(ASYNC, 0, 8),
   3349   };
   3350 
   3351   OrderedSocketData spdy_data(
   3352       spdy_reads, arraysize(spdy_reads),
   3353       spdy_writes, arraysize(spdy_writes));
   3354   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3355 
   3356   SSLSocketDataProvider ssl(ASYNC, OK);
   3357   ssl.SetNextProto(GetParam());
   3358   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3359   SSLSocketDataProvider ssl2(ASYNC, OK);
   3360   ssl2.SetNextProto(GetParam());
   3361   ssl2.protocol_negotiated = GetParam();
   3362   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3363 
   3364   TestCompletionCallback callback1;
   3365 
   3366   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3367   EXPECT_EQ(ERR_IO_PENDING, rv);
   3368 
   3369   rv = callback1.WaitForResult();
   3370   EXPECT_EQ(OK, rv);
   3371 
   3372   LoadTimingInfo load_timing_info;
   3373   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3374   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3375 
   3376   const HttpResponseInfo* response = trans->GetResponseInfo();
   3377   ASSERT_TRUE(response != NULL);
   3378   ASSERT_TRUE(response->headers.get() != NULL);
   3379   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3380 
   3381   std::string response_data;
   3382   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   3383   EXPECT_EQ(kUploadData, response_data);
   3384 }
   3385 
   3386 // Test a SPDY CONNECT failure through an HTTPS Proxy.
   3387 TEST_P(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   3388   HttpRequestInfo request;
   3389   request.method = "GET";
   3390   request.url = GURL("https://www.google.com/");
   3391   request.load_flags = 0;
   3392 
   3393   // Configure against https proxy server "proxy:70".
   3394   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3395       "https://proxy:70"));
   3396   CapturingBoundNetLog log;
   3397   session_deps_.net_log = log.bound().net_log();
   3398   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3399 
   3400   scoped_ptr<HttpTransaction> trans(
   3401       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3402 
   3403   // CONNECT to www.google.com:443 via SPDY
   3404   scoped_ptr<SpdyFrame> connect(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3405                                                                 LOWEST));
   3406   scoped_ptr<SpdyFrame> get(
   3407       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   3408 
   3409   MockWrite spdy_writes[] = {
   3410       CreateMockWrite(*connect, 1),
   3411       CreateMockWrite(*get, 3),
   3412   };
   3413 
   3414   scoped_ptr<SpdyFrame> resp(spdy_util_.ConstructSpdySynReplyError(1));
   3415   scoped_ptr<SpdyFrame> data(spdy_util_.ConstructSpdyBodyFrame(1, true));
   3416   MockRead spdy_reads[] = {
   3417     CreateMockRead(*resp, 2, ASYNC),
   3418     MockRead(ASYNC, 0, 4),
   3419   };
   3420 
   3421   OrderedSocketData spdy_data(
   3422       spdy_reads, arraysize(spdy_reads),
   3423       spdy_writes, arraysize(spdy_writes));
   3424   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   3425 
   3426   SSLSocketDataProvider ssl(ASYNC, OK);
   3427   ssl.SetNextProto(GetParam());
   3428   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3429   SSLSocketDataProvider ssl2(ASYNC, OK);
   3430   ssl2.SetNextProto(GetParam());
   3431   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   3432 
   3433   TestCompletionCallback callback1;
   3434 
   3435   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3436   EXPECT_EQ(ERR_IO_PENDING, rv);
   3437 
   3438   rv = callback1.WaitForResult();
   3439   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3440 
   3441   // TODO(ttuttle): Anything else to check here?
   3442 }
   3443 
   3444 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3445 // HTTPS Proxy to different servers.
   3446 TEST_P(HttpNetworkTransactionTest,
   3447        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsTwoServers) {
   3448   // Configure against https proxy server "proxy:70".
   3449   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3450       "https://proxy:70"));
   3451   CapturingBoundNetLog log;
   3452   session_deps_.net_log = log.bound().net_log();
   3453   scoped_refptr<HttpNetworkSession> session(
   3454       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3455 
   3456   HttpRequestInfo request1;
   3457   request1.method = "GET";
   3458   request1.url = GURL("https://www.google.com/");
   3459   request1.load_flags = 0;
   3460 
   3461   HttpRequestInfo request2;
   3462   request2.method = "GET";
   3463   request2.url = GURL("https://news.google.com/");
   3464   request2.load_flags = 0;
   3465 
   3466   // CONNECT to www.google.com:443 via SPDY.
   3467   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3468                                                                  LOWEST));
   3469   scoped_ptr<SpdyFrame> conn_resp1(
   3470       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3471 
   3472   // Fetch https://www.google.com/ via HTTP.
   3473   const char get1[] = "GET / HTTP/1.1\r\n"
   3474       "Host: www.google.com\r\n"
   3475       "Connection: keep-alive\r\n\r\n";
   3476   scoped_ptr<SpdyFrame> wrapped_get1(
   3477       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3478   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3479       "Content-Length: 1\r\n\r\n";
   3480   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3481       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3482   scoped_ptr<SpdyFrame> wrapped_body1(
   3483       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3484   scoped_ptr<SpdyFrame> window_update(
   3485       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3486 
   3487   // CONNECT to news.google.com:443 via SPDY.
   3488   SpdySynStreamIR connect2_ir(3);
   3489   spdy_util_.SetPriority(LOWEST, &connect2_ir);
   3490   connect2_ir.SetHeader(spdy_util_.GetMethodKey(), "CONNECT");
   3491   connect2_ir.SetHeader(spdy_util_.GetPathKey(), "news.google.com:443");
   3492   connect2_ir.SetHeader(spdy_util_.GetHostKey(), "news.google.com");
   3493   spdy_util_.MaybeAddVersionHeader(&connect2_ir);
   3494   scoped_ptr<SpdyFrame> connect2(
   3495       spdy_util_.CreateFramer(false)->SerializeFrame(connect2_ir));
   3496 
   3497   scoped_ptr<SpdyFrame> conn_resp2(
   3498       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3499 
   3500   // Fetch https://news.google.com/ via HTTP.
   3501   const char get2[] = "GET / HTTP/1.1\r\n"
   3502       "Host: news.google.com\r\n"
   3503       "Connection: keep-alive\r\n\r\n";
   3504   scoped_ptr<SpdyFrame> wrapped_get2(
   3505       spdy_util_.ConstructSpdyBodyFrame(3, get2, strlen(get2), false));
   3506   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3507       "Content-Length: 2\r\n\r\n";
   3508   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3509       spdy_util_.ConstructSpdyBodyFrame(3, resp2, strlen(resp2), false));
   3510   scoped_ptr<SpdyFrame> wrapped_body2(
   3511       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, false));
   3512 
   3513   MockWrite spdy_writes[] = {
   3514       CreateMockWrite(*connect1, 0),
   3515       CreateMockWrite(*wrapped_get1, 2),
   3516       CreateMockWrite(*connect2, 5),
   3517       CreateMockWrite(*wrapped_get2, 7),
   3518   };
   3519 
   3520   MockRead spdy_reads[] = {
   3521     CreateMockRead(*conn_resp1, 1, ASYNC),
   3522     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3523     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3524     CreateMockRead(*conn_resp2, 6, ASYNC),
   3525     CreateMockRead(*wrapped_get_resp2, 8, ASYNC),
   3526     CreateMockRead(*wrapped_body2, 9, ASYNC),
   3527     MockRead(ASYNC, 0, 10),
   3528   };
   3529 
   3530   DeterministicSocketData spdy_data(
   3531       spdy_reads, arraysize(spdy_reads),
   3532       spdy_writes, arraysize(spdy_writes));
   3533   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3534 
   3535   SSLSocketDataProvider ssl(ASYNC, OK);
   3536   ssl.SetNextProto(GetParam());
   3537   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3538   SSLSocketDataProvider ssl2(ASYNC, OK);
   3539   ssl2.was_npn_negotiated = false;
   3540   ssl2.protocol_negotiated = kProtoUnknown;
   3541   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3542   SSLSocketDataProvider ssl3(ASYNC, OK);
   3543   ssl3.was_npn_negotiated = false;
   3544   ssl3.protocol_negotiated = kProtoUnknown;
   3545   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl3);
   3546 
   3547   TestCompletionCallback callback;
   3548 
   3549   scoped_ptr<HttpTransaction> trans(
   3550       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3551   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3552   EXPECT_EQ(ERR_IO_PENDING, rv);
   3553   // The first connect and request, each of their responses, and the body.
   3554   spdy_data.RunFor(5);
   3555 
   3556   rv = callback.WaitForResult();
   3557   EXPECT_EQ(OK, rv);
   3558 
   3559   LoadTimingInfo load_timing_info;
   3560   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3561   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3562 
   3563   const HttpResponseInfo* response = trans->GetResponseInfo();
   3564   ASSERT_TRUE(response != NULL);
   3565   ASSERT_TRUE(response->headers.get() != NULL);
   3566   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3567 
   3568   std::string response_data;
   3569   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3570   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3571 
   3572   scoped_ptr<HttpTransaction> trans2(
   3573       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3574   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3575   EXPECT_EQ(ERR_IO_PENDING, rv);
   3576 
   3577   // The second connect and request, each of their responses, and the body.
   3578   spdy_data.RunFor(5);
   3579   rv = callback.WaitForResult();
   3580   EXPECT_EQ(OK, rv);
   3581 
   3582   LoadTimingInfo load_timing_info2;
   3583   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3584   // Even though the SPDY connection is reused, a new tunnelled connection has
   3585   // to be created, so the socket's load timing looks like a fresh connection.
   3586   TestLoadTimingNotReused(load_timing_info2, CONNECT_TIMING_HAS_SSL_TIMES);
   3587 
   3588   // The requests should have different IDs, since they each are using their own
   3589   // separate stream.
   3590   EXPECT_NE(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3591 
   3592   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3593 }
   3594 
   3595 // Test load timing in the case of two HTTPS (non-SPDY) requests through a SPDY
   3596 // HTTPS Proxy to the same server.
   3597 TEST_P(HttpNetworkTransactionTest,
   3598        HttpsProxySpdyConnectHttpsLoadTimingTwoRequestsSameServer) {
   3599   // Configure against https proxy server "proxy:70".
   3600   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3601       "https://proxy:70"));
   3602   CapturingBoundNetLog log;
   3603   session_deps_.net_log = log.bound().net_log();
   3604   scoped_refptr<HttpNetworkSession> session(
   3605       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3606 
   3607   HttpRequestInfo request1;
   3608   request1.method = "GET";
   3609   request1.url = GURL("https://www.google.com/");
   3610   request1.load_flags = 0;
   3611 
   3612   HttpRequestInfo request2;
   3613   request2.method = "GET";
   3614   request2.url = GURL("https://www.google.com/2");
   3615   request2.load_flags = 0;
   3616 
   3617   // CONNECT to www.google.com:443 via SPDY.
   3618   scoped_ptr<SpdyFrame> connect1(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   3619                                                                  LOWEST));
   3620   scoped_ptr<SpdyFrame> conn_resp1(
   3621       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3622 
   3623   // Fetch https://www.google.com/ via HTTP.
   3624   const char get1[] = "GET / HTTP/1.1\r\n"
   3625       "Host: www.google.com\r\n"
   3626       "Connection: keep-alive\r\n\r\n";
   3627   scoped_ptr<SpdyFrame> wrapped_get1(
   3628       spdy_util_.ConstructSpdyBodyFrame(1, get1, strlen(get1), false));
   3629   const char resp1[] = "HTTP/1.1 200 OK\r\n"
   3630       "Content-Length: 1\r\n\r\n";
   3631   scoped_ptr<SpdyFrame> wrapped_get_resp1(
   3632       spdy_util_.ConstructSpdyBodyFrame(1, resp1, strlen(resp1), false));
   3633   scoped_ptr<SpdyFrame> wrapped_body1(
   3634       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, false));
   3635   scoped_ptr<SpdyFrame> window_update(
   3636       spdy_util_.ConstructSpdyWindowUpdate(1, wrapped_get_resp1->size()));
   3637 
   3638   // Fetch https://www.google.com/2 via HTTP.
   3639   const char get2[] = "GET /2 HTTP/1.1\r\n"
   3640       "Host: www.google.com\r\n"
   3641       "Connection: keep-alive\r\n\r\n";
   3642   scoped_ptr<SpdyFrame> wrapped_get2(
   3643       spdy_util_.ConstructSpdyBodyFrame(1, get2, strlen(get2), false));
   3644   const char resp2[] = "HTTP/1.1 200 OK\r\n"
   3645       "Content-Length: 2\r\n\r\n";
   3646   scoped_ptr<SpdyFrame> wrapped_get_resp2(
   3647       spdy_util_.ConstructSpdyBodyFrame(1, resp2, strlen(resp2), false));
   3648   scoped_ptr<SpdyFrame> wrapped_body2(
   3649       spdy_util_.ConstructSpdyBodyFrame(1, "22", 2, false));
   3650 
   3651   MockWrite spdy_writes[] = {
   3652       CreateMockWrite(*connect1, 0),
   3653       CreateMockWrite(*wrapped_get1, 2),
   3654       CreateMockWrite(*wrapped_get2, 5),
   3655   };
   3656 
   3657   MockRead spdy_reads[] = {
   3658     CreateMockRead(*conn_resp1, 1, ASYNC),
   3659     CreateMockRead(*wrapped_get_resp1, 3, ASYNC),
   3660     CreateMockRead(*wrapped_body1, 4, ASYNC),
   3661     CreateMockRead(*wrapped_get_resp2, 6, ASYNC),
   3662     CreateMockRead(*wrapped_body2, 7, ASYNC),
   3663     MockRead(ASYNC, 0, 8),
   3664   };
   3665 
   3666   DeterministicSocketData spdy_data(
   3667       spdy_reads, arraysize(spdy_reads),
   3668       spdy_writes, arraysize(spdy_writes));
   3669   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3670 
   3671   SSLSocketDataProvider ssl(ASYNC, OK);
   3672   ssl.SetNextProto(GetParam());
   3673   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3674   SSLSocketDataProvider ssl2(ASYNC, OK);
   3675   ssl2.was_npn_negotiated = false;
   3676   ssl2.protocol_negotiated = kProtoUnknown;
   3677   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl2);
   3678 
   3679   TestCompletionCallback callback;
   3680 
   3681   scoped_ptr<HttpTransaction> trans(
   3682       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3683   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3684   EXPECT_EQ(ERR_IO_PENDING, rv);
   3685   // The first connect and request, each of their responses, and the body.
   3686   spdy_data.RunFor(5);
   3687 
   3688   rv = callback.WaitForResult();
   3689   EXPECT_EQ(OK, rv);
   3690 
   3691   LoadTimingInfo load_timing_info;
   3692   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3693   TestLoadTimingNotReused(load_timing_info, CONNECT_TIMING_HAS_SSL_TIMES);
   3694 
   3695   const HttpResponseInfo* response = trans->GetResponseInfo();
   3696   ASSERT_TRUE(response != NULL);
   3697   ASSERT_TRUE(response->headers.get() != NULL);
   3698   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3699 
   3700   std::string response_data;
   3701   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3702   EXPECT_EQ(1, trans->Read(buf.get(), 256, callback.callback()));
   3703   trans.reset();
   3704 
   3705   scoped_ptr<HttpTransaction> trans2(
   3706       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3707   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3708   EXPECT_EQ(ERR_IO_PENDING, rv);
   3709 
   3710   // The second request, response, and body.  There should not be a second
   3711   // connect.
   3712   spdy_data.RunFor(3);
   3713   rv = callback.WaitForResult();
   3714   EXPECT_EQ(OK, rv);
   3715 
   3716   LoadTimingInfo load_timing_info2;
   3717   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3718   TestLoadTimingReused(load_timing_info2);
   3719 
   3720   // The requests should have the same ID.
   3721   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3722 
   3723   EXPECT_EQ(2, trans2->Read(buf.get(), 256, callback.callback()));
   3724 }
   3725 
   3726 // Test load timing in the case of of two HTTP requests through a SPDY HTTPS
   3727 // Proxy to different servers.
   3728 TEST_P(HttpNetworkTransactionTest,
   3729        HttpsProxySpdyLoadTimingTwoHttpRequests) {
   3730   // Configure against https proxy server "proxy:70".
   3731   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   3732       "https://proxy:70"));
   3733   CapturingBoundNetLog log;
   3734   session_deps_.net_log = log.bound().net_log();
   3735   scoped_refptr<HttpNetworkSession> session(
   3736       SpdySessionDependencies::SpdyCreateSessionDeterministic(&session_deps_));
   3737 
   3738   HttpRequestInfo request1;
   3739   request1.method = "GET";
   3740   request1.url = GURL("http://www.google.com/");
   3741   request1.load_flags = 0;
   3742 
   3743   HttpRequestInfo request2;
   3744   request2.method = "GET";
   3745   request2.url = GURL("http://news.google.com/");
   3746   request2.load_flags = 0;
   3747 
   3748   // http://www.google.com/
   3749   scoped_ptr<SpdyHeaderBlock> headers(
   3750       spdy_util_.ConstructGetHeaderBlockForProxy("http://www.google.com/"));
   3751   scoped_ptr<SpdyFrame> get1(spdy_util_.ConstructSpdyControlFrame(
   3752       headers.Pass(), false, 1, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3753   scoped_ptr<SpdyFrame> get_resp1(
   3754       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   3755   scoped_ptr<SpdyFrame> body1(
   3756       spdy_util_.ConstructSpdyBodyFrame(1, "1", 1, true));
   3757 
   3758   // http://news.google.com/
   3759   scoped_ptr<SpdyHeaderBlock> headers2(
   3760       spdy_util_.ConstructGetHeaderBlockForProxy("http://news.google.com/"));
   3761   scoped_ptr<SpdyFrame> get2(spdy_util_.ConstructSpdyControlFrame(
   3762       headers2.Pass(), false, 3, LOWEST, SYN_STREAM, CONTROL_FLAG_FIN, 0));
   3763   scoped_ptr<SpdyFrame> get_resp2(
   3764       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   3765   scoped_ptr<SpdyFrame> body2(
   3766       spdy_util_.ConstructSpdyBodyFrame(3, "22", 2, true));
   3767 
   3768   MockWrite spdy_writes[] = {
   3769       CreateMockWrite(*get1, 0),
   3770       CreateMockWrite(*get2, 3),
   3771   };
   3772 
   3773   MockRead spdy_reads[] = {
   3774     CreateMockRead(*get_resp1, 1, ASYNC),
   3775     CreateMockRead(*body1, 2, ASYNC),
   3776     CreateMockRead(*get_resp2, 4, ASYNC),
   3777     CreateMockRead(*body2, 5, ASYNC),
   3778     MockRead(ASYNC, 0, 6),
   3779   };
   3780 
   3781   DeterministicSocketData spdy_data(
   3782       spdy_reads, arraysize(spdy_reads),
   3783       spdy_writes, arraysize(spdy_writes));
   3784   session_deps_.deterministic_socket_factory->AddSocketDataProvider(&spdy_data);
   3785 
   3786   SSLSocketDataProvider ssl(ASYNC, OK);
   3787   ssl.SetNextProto(GetParam());
   3788   session_deps_.deterministic_socket_factory->AddSSLSocketDataProvider(&ssl);
   3789 
   3790   TestCompletionCallback callback;
   3791 
   3792   scoped_ptr<HttpTransaction> trans(
   3793       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3794   int rv = trans->Start(&request1, callback.callback(), BoundNetLog());
   3795   EXPECT_EQ(ERR_IO_PENDING, rv);
   3796   spdy_data.RunFor(2);
   3797 
   3798   rv = callback.WaitForResult();
   3799   EXPECT_EQ(OK, rv);
   3800 
   3801   LoadTimingInfo load_timing_info;
   3802   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3803   TestLoadTimingNotReused(load_timing_info,
   3804                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3805 
   3806   const HttpResponseInfo* response = trans->GetResponseInfo();
   3807   ASSERT_TRUE(response != NULL);
   3808   ASSERT_TRUE(response->headers.get() != NULL);
   3809   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3810 
   3811   std::string response_data;
   3812   scoped_refptr<net::IOBuffer> buf(new net::IOBuffer(256));
   3813   EXPECT_EQ(ERR_IO_PENDING, trans->Read(buf.get(), 256, callback.callback()));
   3814   spdy_data.RunFor(1);
   3815   EXPECT_EQ(1, callback.WaitForResult());
   3816   // Delete the first request, so the second one can reuse the socket.
   3817   trans.reset();
   3818 
   3819   scoped_ptr<HttpTransaction> trans2(
   3820       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3821   rv = trans2->Start(&request2, callback.callback(), BoundNetLog());
   3822   EXPECT_EQ(ERR_IO_PENDING, rv);
   3823 
   3824   spdy_data.RunFor(2);
   3825   rv = callback.WaitForResult();
   3826   EXPECT_EQ(OK, rv);
   3827 
   3828   LoadTimingInfo load_timing_info2;
   3829   EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2));
   3830   TestLoadTimingReused(load_timing_info2);
   3831 
   3832   // The requests should have the same ID.
   3833   EXPECT_EQ(load_timing_info.socket_log_id, load_timing_info2.socket_log_id);
   3834 
   3835   EXPECT_EQ(ERR_IO_PENDING, trans2->Read(buf.get(), 256, callback.callback()));
   3836   spdy_data.RunFor(1);
   3837   EXPECT_EQ(2, callback.WaitForResult());
   3838 }
   3839 
   3840 // Test the challenge-response-retry sequence through an HTTPS Proxy
   3841 TEST_P(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   3842   HttpRequestInfo request;
   3843   request.method = "GET";
   3844   request.url = GURL("http://www.google.com/");
   3845   // when the no authentication data flag is set.
   3846   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   3847 
   3848   // Configure against https proxy server "myproxy:70".
   3849   session_deps_.proxy_service.reset(
   3850       ProxyService::CreateFixed("https://myproxy:70"));
   3851   CapturingBoundNetLog log;
   3852   session_deps_.net_log = log.bound().net_log();
   3853   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3854 
   3855   // Since we have proxy, should use full url
   3856   MockWrite data_writes1[] = {
   3857     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3858               "Host: www.google.com\r\n"
   3859               "Proxy-Connection: keep-alive\r\n\r\n"),
   3860 
   3861     // After calling trans->RestartWithAuth(), this is the request we should
   3862     // be issuing -- the final header line contains the credentials.
   3863     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   3864               "Host: www.google.com\r\n"
   3865               "Proxy-Connection: keep-alive\r\n"
   3866               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3867   };
   3868 
   3869   // The proxy responds to the GET with a 407, using a persistent
   3870   // connection.
   3871   MockRead data_reads1[] = {
   3872     // No credentials.
   3873     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   3874     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3875     MockRead("Proxy-Connection: keep-alive\r\n"),
   3876     MockRead("Content-Length: 0\r\n\r\n"),
   3877 
   3878     MockRead("HTTP/1.1 200 OK\r\n"),
   3879     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3880     MockRead("Content-Length: 100\r\n\r\n"),
   3881     MockRead(SYNCHRONOUS, OK),
   3882   };
   3883 
   3884   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3885                                  data_writes1, arraysize(data_writes1));
   3886   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   3887   SSLSocketDataProvider ssl(ASYNC, OK);
   3888   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   3889 
   3890   TestCompletionCallback callback1;
   3891 
   3892   scoped_ptr<HttpTransaction> trans(
   3893       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3894 
   3895   int rv = trans->Start(&request, callback1.callback(), log.bound());
   3896   EXPECT_EQ(ERR_IO_PENDING, rv);
   3897 
   3898   rv = callback1.WaitForResult();
   3899   EXPECT_EQ(OK, rv);
   3900 
   3901   LoadTimingInfo load_timing_info;
   3902   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3903   TestLoadTimingNotReused(load_timing_info,
   3904                           CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   3905 
   3906   const HttpResponseInfo* response = trans->GetResponseInfo();
   3907   ASSERT_TRUE(response != NULL);
   3908   ASSERT_FALSE(response->headers.get() == NULL);
   3909   EXPECT_EQ(407, response->headers->response_code());
   3910   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3911   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   3912 
   3913   TestCompletionCallback callback2;
   3914 
   3915   rv = trans->RestartWithAuth(
   3916       AuthCredentials(kFoo, kBar), callback2.callback());
   3917   EXPECT_EQ(ERR_IO_PENDING, rv);
   3918 
   3919   rv = callback2.WaitForResult();
   3920   EXPECT_EQ(OK, rv);
   3921 
   3922   load_timing_info = LoadTimingInfo();
   3923   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   3924   // Retrying with HTTP AUTH is considered to be reusing a socket.
   3925   TestLoadTimingReused(load_timing_info);
   3926 
   3927   response = trans->GetResponseInfo();
   3928   ASSERT_TRUE(response != NULL);
   3929 
   3930   EXPECT_TRUE(response->headers->IsKeepAlive());
   3931   EXPECT_EQ(200, response->headers->response_code());
   3932   EXPECT_EQ(100, response->headers->GetContentLength());
   3933   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   3934 
   3935   // The password prompt info should not be set.
   3936   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3937 }
   3938 
   3939 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   3940     const MockRead& status, int expected_status) {
   3941   HttpRequestInfo request;
   3942   request.method = "GET";
   3943   request.url = GURL("https://www.google.com/");
   3944   request.load_flags = 0;
   3945 
   3946   // Configure against proxy server "myproxy:70".
   3947   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   3948   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   3949 
   3950   // Since we have proxy, should try to establish tunnel.
   3951   MockWrite data_writes[] = {
   3952     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   3953               "Host: www.google.com\r\n"
   3954               "Proxy-Connection: keep-alive\r\n\r\n"),
   3955   };
   3956 
   3957   MockRead data_reads[] = {
   3958     status,
   3959     MockRead("Content-Length: 10\r\n\r\n"),
   3960     // No response body because the test stops reading here.
   3961     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   3962   };
   3963 
   3964   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3965                                 data_writes, arraysize(data_writes));
   3966   session_deps_.socket_factory->AddSocketDataProvider(&data);
   3967 
   3968   TestCompletionCallback callback;
   3969 
   3970   scoped_ptr<HttpTransaction> trans(
   3971       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   3972 
   3973   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   3974   EXPECT_EQ(ERR_IO_PENDING, rv);
   3975 
   3976   rv = callback.WaitForResult();
   3977   EXPECT_EQ(expected_status, rv);
   3978 }
   3979 
   3980 void HttpNetworkTransactionTest::ConnectStatusHelper(
   3981     const MockRead& status) {
   3982   ConnectStatusHelperWithExpectedStatus(
   3983       status, ERR_TUNNEL_CONNECTION_FAILED);
   3984 }
   3985 
   3986 TEST_P(HttpNetworkTransactionTest, ConnectStatus100) {
   3987   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   3988 }
   3989 
   3990 TEST_P(HttpNetworkTransactionTest, ConnectStatus101) {
   3991   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   3992 }
   3993 
   3994 TEST_P(HttpNetworkTransactionTest, ConnectStatus201) {
   3995   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   3996 }
   3997 
   3998 TEST_P(HttpNetworkTransactionTest, ConnectStatus202) {
   3999   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   4000 }
   4001 
   4002 TEST_P(HttpNetworkTransactionTest, ConnectStatus203) {
   4003   ConnectStatusHelper(
   4004       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   4005 }
   4006 
   4007 TEST_P(HttpNetworkTransactionTest, ConnectStatus204) {
   4008   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   4009 }
   4010 
   4011 TEST_P(HttpNetworkTransactionTest, ConnectStatus205) {
   4012   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   4013 }
   4014 
   4015 TEST_P(HttpNetworkTransactionTest, ConnectStatus206) {
   4016   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   4017 }
   4018 
   4019 TEST_P(HttpNetworkTransactionTest, ConnectStatus300) {
   4020   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   4021 }
   4022 
   4023 TEST_P(HttpNetworkTransactionTest, ConnectStatus301) {
   4024   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   4025 }
   4026 
   4027 TEST_P(HttpNetworkTransactionTest, ConnectStatus302) {
   4028   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   4029 }
   4030 
   4031 TEST_P(HttpNetworkTransactionTest, ConnectStatus303) {
   4032   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   4033 }
   4034 
   4035 TEST_P(HttpNetworkTransactionTest, ConnectStatus304) {
   4036   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   4037 }
   4038 
   4039 TEST_P(HttpNetworkTransactionTest, ConnectStatus305) {
   4040   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   4041 }
   4042 
   4043 TEST_P(HttpNetworkTransactionTest, ConnectStatus306) {
   4044   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   4045 }
   4046 
   4047 TEST_P(HttpNetworkTransactionTest, ConnectStatus307) {
   4048   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   4049 }
   4050 
   4051 TEST_P(HttpNetworkTransactionTest, ConnectStatus308) {
   4052   ConnectStatusHelper(MockRead("HTTP/1.1 308 Permanent Redirect\r\n"));
   4053 }
   4054 
   4055 TEST_P(HttpNetworkTransactionTest, ConnectStatus400) {
   4056   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   4057 }
   4058 
   4059 TEST_P(HttpNetworkTransactionTest, ConnectStatus401) {
   4060   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   4061 }
   4062 
   4063 TEST_P(HttpNetworkTransactionTest, ConnectStatus402) {
   4064   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   4065 }
   4066 
   4067 TEST_P(HttpNetworkTransactionTest, ConnectStatus403) {
   4068   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   4069 }
   4070 
   4071 TEST_P(HttpNetworkTransactionTest, ConnectStatus404) {
   4072   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   4073 }
   4074 
   4075 TEST_P(HttpNetworkTransactionTest, ConnectStatus405) {
   4076   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   4077 }
   4078 
   4079 TEST_P(HttpNetworkTransactionTest, ConnectStatus406) {
   4080   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   4081 }
   4082 
   4083 TEST_P(HttpNetworkTransactionTest, ConnectStatus407) {
   4084   ConnectStatusHelperWithExpectedStatus(
   4085       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   4086       ERR_PROXY_AUTH_UNSUPPORTED);
   4087 }
   4088 
   4089 TEST_P(HttpNetworkTransactionTest, ConnectStatus408) {
   4090   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   4091 }
   4092 
   4093 TEST_P(HttpNetworkTransactionTest, ConnectStatus409) {
   4094   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   4095 }
   4096 
   4097 TEST_P(HttpNetworkTransactionTest, ConnectStatus410) {
   4098   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   4099 }
   4100 
   4101 TEST_P(HttpNetworkTransactionTest, ConnectStatus411) {
   4102   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   4103 }
   4104 
   4105 TEST_P(HttpNetworkTransactionTest, ConnectStatus412) {
   4106   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   4107 }
   4108 
   4109 TEST_P(HttpNetworkTransactionTest, ConnectStatus413) {
   4110   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   4111 }
   4112 
   4113 TEST_P(HttpNetworkTransactionTest, ConnectStatus414) {
   4114   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   4115 }
   4116 
   4117 TEST_P(HttpNetworkTransactionTest, ConnectStatus415) {
   4118   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   4119 }
   4120 
   4121 TEST_P(HttpNetworkTransactionTest, ConnectStatus416) {
   4122   ConnectStatusHelper(
   4123       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   4124 }
   4125 
   4126 TEST_P(HttpNetworkTransactionTest, ConnectStatus417) {
   4127   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   4128 }
   4129 
   4130 TEST_P(HttpNetworkTransactionTest, ConnectStatus500) {
   4131   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   4132 }
   4133 
   4134 TEST_P(HttpNetworkTransactionTest, ConnectStatus501) {
   4135   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   4136 }
   4137 
   4138 TEST_P(HttpNetworkTransactionTest, ConnectStatus502) {
   4139   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   4140 }
   4141 
   4142 TEST_P(HttpNetworkTransactionTest, ConnectStatus503) {
   4143   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   4144 }
   4145 
   4146 TEST_P(HttpNetworkTransactionTest, ConnectStatus504) {
   4147   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   4148 }
   4149 
   4150 TEST_P(HttpNetworkTransactionTest, ConnectStatus505) {
   4151   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   4152 }
   4153 
   4154 // Test the flow when both the proxy server AND origin server require
   4155 // authentication. Again, this uses basic auth for both since that is
   4156 // the simplest to mock.
   4157 TEST_P(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   4158   HttpRequestInfo request;
   4159   request.method = "GET";
   4160   request.url = GURL("http://www.google.com/");
   4161   request.load_flags = 0;
   4162 
   4163   // Configure against proxy server "myproxy:70".
   4164   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4165   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4166 
   4167   scoped_ptr<HttpTransaction> trans(
   4168       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4169 
   4170   MockWrite data_writes1[] = {
   4171     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4172               "Host: www.google.com\r\n"
   4173               "Proxy-Connection: keep-alive\r\n\r\n"),
   4174   };
   4175 
   4176   MockRead data_reads1[] = {
   4177     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   4178     // Give a couple authenticate options (only the middle one is actually
   4179     // supported).
   4180     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   4181     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4182     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   4183     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4184     // Large content-length -- won't matter, as connection will be reset.
   4185     MockRead("Content-Length: 10000\r\n\r\n"),
   4186     MockRead(SYNCHRONOUS, ERR_FAILED),
   4187   };
   4188 
   4189   // After calling trans->RestartWithAuth() the first time, this is the
   4190   // request we should be issuing -- the final header line contains the
   4191   // proxy's credentials.
   4192   MockWrite data_writes2[] = {
   4193     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4194               "Host: www.google.com\r\n"
   4195               "Proxy-Connection: keep-alive\r\n"
   4196               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4197   };
   4198 
   4199   // Now the proxy server lets the request pass through to origin server.
   4200   // The origin server responds with a 401.
   4201   MockRead data_reads2[] = {
   4202     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4203     // Note: We are using the same realm-name as the proxy server. This is
   4204     // completely valid, as realms are unique across hosts.
   4205     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4206     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4207     MockRead("Content-Length: 2000\r\n\r\n"),
   4208     MockRead(SYNCHRONOUS, ERR_FAILED),  // Won't be reached.
   4209   };
   4210 
   4211   // After calling trans->RestartWithAuth() the second time, we should send
   4212   // the credentials for both the proxy and origin server.
   4213   MockWrite data_writes3[] = {
   4214     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   4215               "Host: www.google.com\r\n"
   4216               "Proxy-Connection: keep-alive\r\n"
   4217               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   4218               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   4219   };
   4220 
   4221   // Lastly we get the desired content.
   4222   MockRead data_reads3[] = {
   4223     MockRead("HTTP/1.0 200 OK\r\n"),
   4224     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4225     MockRead("Content-Length: 100\r\n\r\n"),
   4226     MockRead(SYNCHRONOUS, OK),
   4227   };
   4228 
   4229   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4230                                  data_writes1, arraysize(data_writes1));
   4231   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4232                                  data_writes2, arraysize(data_writes2));
   4233   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4234                                  data_writes3, arraysize(data_writes3));
   4235   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4236   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4237   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4238 
   4239   TestCompletionCallback callback1;
   4240 
   4241   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4242   EXPECT_EQ(ERR_IO_PENDING, rv);
   4243 
   4244   rv = callback1.WaitForResult();
   4245   EXPECT_EQ(OK, rv);
   4246 
   4247   const HttpResponseInfo* response = trans->GetResponseInfo();
   4248   ASSERT_TRUE(response != NULL);
   4249   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   4250 
   4251   TestCompletionCallback callback2;
   4252 
   4253   rv = trans->RestartWithAuth(
   4254       AuthCredentials(kFoo, kBar), callback2.callback());
   4255   EXPECT_EQ(ERR_IO_PENDING, rv);
   4256 
   4257   rv = callback2.WaitForResult();
   4258   EXPECT_EQ(OK, rv);
   4259 
   4260   response = trans->GetResponseInfo();
   4261   ASSERT_TRUE(response != NULL);
   4262   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   4263 
   4264   TestCompletionCallback callback3;
   4265 
   4266   rv = trans->RestartWithAuth(
   4267       AuthCredentials(kFoo2, kBar2), callback3.callback());
   4268   EXPECT_EQ(ERR_IO_PENDING, rv);
   4269 
   4270   rv = callback3.WaitForResult();
   4271   EXPECT_EQ(OK, rv);
   4272 
   4273   response = trans->GetResponseInfo();
   4274   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4275   EXPECT_EQ(100, response->headers->GetContentLength());
   4276 }
   4277 
   4278 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   4279 // can't hook into its internals to cause it to generate predictable NTLM
   4280 // authorization headers.
   4281 #if defined(NTLM_PORTABLE)
   4282 // The NTLM authentication unit tests were generated by capturing the HTTP
   4283 // requests and responses using Fiddler 2 and inspecting the generated random
   4284 // bytes in the debugger.
   4285 
   4286 // Enter the correct password and authenticate successfully.
   4287 TEST_P(HttpNetworkTransactionTest, NTLMAuth1) {
   4288   HttpRequestInfo request;
   4289   request.method = "GET";
   4290   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   4291 
   4292   // Ensure load is not disrupted by flags which suppress behaviour specific
   4293   // to other auth schemes.
   4294   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   4295 
   4296   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   4297                                                     MockGetHostName);
   4298   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4299 
   4300   MockWrite data_writes1[] = {
   4301     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4302               "Host: 172.22.68.17\r\n"
   4303               "Connection: keep-alive\r\n\r\n"),
   4304   };
   4305 
   4306   MockRead data_reads1[] = {
   4307     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4308     // Negotiate and NTLM are often requested together.  However, we only want
   4309     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4310     // the header that requests Negotiate for this test.
   4311     MockRead("WWW-Authenticate: NTLM\r\n"),
   4312     MockRead("Connection: close\r\n"),
   4313     MockRead("Content-Length: 42\r\n"),
   4314     MockRead("Content-Type: text/html\r\n\r\n"),
   4315     // Missing content -- won't matter, as connection will be reset.
   4316     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4317   };
   4318 
   4319   MockWrite data_writes2[] = {
   4320     // After restarting with a null identity, this is the
   4321     // request we should be issuing -- the final header line contains a Type
   4322     // 1 message.
   4323     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4324               "Host: 172.22.68.17\r\n"
   4325               "Connection: keep-alive\r\n"
   4326               "Authorization: NTLM "
   4327               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4328 
   4329     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4330     // (the credentials for the origin server).  The second request continues
   4331     // on the same connection.
   4332     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4333               "Host: 172.22.68.17\r\n"
   4334               "Connection: keep-alive\r\n"
   4335               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4336               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4337               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   4338               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   4339               "ahlhx5I=\r\n\r\n"),
   4340   };
   4341 
   4342   MockRead data_reads2[] = {
   4343     // The origin server responds with a Type 2 message.
   4344     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4345     MockRead("WWW-Authenticate: NTLM "
   4346              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   4347              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4348              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4349              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4350              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4351              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4352              "BtAAAAAAA=\r\n"),
   4353     MockRead("Content-Length: 42\r\n"),
   4354     MockRead("Content-Type: text/html\r\n\r\n"),
   4355     MockRead("You are not authorized to view this page\r\n"),
   4356 
   4357     // Lastly we get the desired content.
   4358     MockRead("HTTP/1.1 200 OK\r\n"),
   4359     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4360     MockRead("Content-Length: 13\r\n\r\n"),
   4361     MockRead("Please Login\r\n"),
   4362     MockRead(SYNCHRONOUS, OK),
   4363   };
   4364 
   4365   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4366                                  data_writes1, arraysize(data_writes1));
   4367   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4368                                  data_writes2, arraysize(data_writes2));
   4369   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4370   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4371 
   4372   TestCompletionCallback callback1;
   4373 
   4374   scoped_ptr<HttpTransaction> trans(
   4375       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4376 
   4377   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4378   EXPECT_EQ(ERR_IO_PENDING, rv);
   4379 
   4380   rv = callback1.WaitForResult();
   4381   EXPECT_EQ(OK, rv);
   4382 
   4383   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4384 
   4385   const HttpResponseInfo* response = trans->GetResponseInfo();
   4386   ASSERT_FALSE(response == NULL);
   4387   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4388 
   4389   TestCompletionCallback callback2;
   4390 
   4391   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4392                               callback2.callback());
   4393   EXPECT_EQ(ERR_IO_PENDING, rv);
   4394 
   4395   rv = callback2.WaitForResult();
   4396   EXPECT_EQ(OK, rv);
   4397 
   4398   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4399 
   4400   response = trans->GetResponseInfo();
   4401   ASSERT_TRUE(response != NULL);
   4402   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4403 
   4404   TestCompletionCallback callback3;
   4405 
   4406   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4407   EXPECT_EQ(ERR_IO_PENDING, rv);
   4408 
   4409   rv = callback3.WaitForResult();
   4410   EXPECT_EQ(OK, rv);
   4411 
   4412   response = trans->GetResponseInfo();
   4413   ASSERT_TRUE(response != NULL);
   4414   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4415   EXPECT_EQ(13, response->headers->GetContentLength());
   4416 }
   4417 
   4418 // Enter a wrong password, and then the correct one.
   4419 TEST_P(HttpNetworkTransactionTest, NTLMAuth2) {
   4420   HttpRequestInfo request;
   4421   request.method = "GET";
   4422   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   4423   request.load_flags = 0;
   4424 
   4425   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   4426                                                     MockGetHostName);
   4427   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4428 
   4429   MockWrite data_writes1[] = {
   4430     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4431               "Host: 172.22.68.17\r\n"
   4432               "Connection: keep-alive\r\n\r\n"),
   4433   };
   4434 
   4435   MockRead data_reads1[] = {
   4436     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4437     // Negotiate and NTLM are often requested together.  However, we only want
   4438     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   4439     // the header that requests Negotiate for this test.
   4440     MockRead("WWW-Authenticate: NTLM\r\n"),
   4441     MockRead("Connection: close\r\n"),
   4442     MockRead("Content-Length: 42\r\n"),
   4443     MockRead("Content-Type: text/html\r\n\r\n"),
   4444     // Missing content -- won't matter, as connection will be reset.
   4445     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4446   };
   4447 
   4448   MockWrite data_writes2[] = {
   4449     // After restarting with a null identity, this is the
   4450     // request we should be issuing -- the final header line contains a Type
   4451     // 1 message.
   4452     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4453               "Host: 172.22.68.17\r\n"
   4454               "Connection: keep-alive\r\n"
   4455               "Authorization: NTLM "
   4456               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4457 
   4458     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4459     // (the credentials for the origin server).  The second request continues
   4460     // on the same connection.
   4461     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4462               "Host: 172.22.68.17\r\n"
   4463               "Connection: keep-alive\r\n"
   4464               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4465               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4466               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   4467               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   4468               "4Ww7b7E=\r\n\r\n"),
   4469   };
   4470 
   4471   MockRead data_reads2[] = {
   4472     // The origin server responds with a Type 2 message.
   4473     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4474     MockRead("WWW-Authenticate: NTLM "
   4475              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   4476              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4477              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4478              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4479              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4480              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4481              "BtAAAAAAA=\r\n"),
   4482     MockRead("Content-Length: 42\r\n"),
   4483     MockRead("Content-Type: text/html\r\n\r\n"),
   4484     MockRead("You are not authorized to view this page\r\n"),
   4485 
   4486     // Wrong password.
   4487     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4488     MockRead("WWW-Authenticate: NTLM\r\n"),
   4489     MockRead("Connection: close\r\n"),
   4490     MockRead("Content-Length: 42\r\n"),
   4491     MockRead("Content-Type: text/html\r\n\r\n"),
   4492     // Missing content -- won't matter, as connection will be reset.
   4493     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),
   4494   };
   4495 
   4496   MockWrite data_writes3[] = {
   4497     // After restarting with a null identity, this is the
   4498     // request we should be issuing -- the final header line contains a Type
   4499     // 1 message.
   4500     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4501               "Host: 172.22.68.17\r\n"
   4502               "Connection: keep-alive\r\n"
   4503               "Authorization: NTLM "
   4504               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   4505 
   4506     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   4507     // (the credentials for the origin server).  The second request continues
   4508     // on the same connection.
   4509     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   4510               "Host: 172.22.68.17\r\n"
   4511               "Connection: keep-alive\r\n"
   4512               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   4513               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   4514               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   4515               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   4516               "+4MUm7c=\r\n\r\n"),
   4517   };
   4518 
   4519   MockRead data_reads3[] = {
   4520     // The origin server responds with a Type 2 message.
   4521     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   4522     MockRead("WWW-Authenticate: NTLM "
   4523              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   4524              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   4525              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   4526              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   4527              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   4528              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   4529              "BtAAAAAAA=\r\n"),
   4530     MockRead("Content-Length: 42\r\n"),
   4531     MockRead("Content-Type: text/html\r\n\r\n"),
   4532     MockRead("You are not authorized to view this page\r\n"),
   4533 
   4534     // Lastly we get the desired content.
   4535     MockRead("HTTP/1.1 200 OK\r\n"),
   4536     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   4537     MockRead("Content-Length: 13\r\n\r\n"),
   4538     MockRead("Please Login\r\n"),
   4539     MockRead(SYNCHRONOUS, OK),
   4540   };
   4541 
   4542   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4543                                  data_writes1, arraysize(data_writes1));
   4544   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4545                                  data_writes2, arraysize(data_writes2));
   4546   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4547                                  data_writes3, arraysize(data_writes3));
   4548   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4549   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4550   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   4551 
   4552   TestCompletionCallback callback1;
   4553 
   4554   scoped_ptr<HttpTransaction> trans(
   4555       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4556 
   4557   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4558   EXPECT_EQ(ERR_IO_PENDING, rv);
   4559 
   4560   rv = callback1.WaitForResult();
   4561   EXPECT_EQ(OK, rv);
   4562 
   4563   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4564 
   4565   const HttpResponseInfo* response = trans->GetResponseInfo();
   4566   ASSERT_TRUE(response != NULL);
   4567   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4568 
   4569   TestCompletionCallback callback2;
   4570 
   4571   // Enter the wrong password.
   4572   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kWrongPassword),
   4573                               callback2.callback());
   4574   EXPECT_EQ(ERR_IO_PENDING, rv);
   4575 
   4576   rv = callback2.WaitForResult();
   4577   EXPECT_EQ(OK, rv);
   4578 
   4579   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4580   TestCompletionCallback callback3;
   4581   rv = trans->RestartWithAuth(AuthCredentials(), callback3.callback());
   4582   EXPECT_EQ(ERR_IO_PENDING, rv);
   4583   rv = callback3.WaitForResult();
   4584   EXPECT_EQ(OK, rv);
   4585   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4586 
   4587   response = trans->GetResponseInfo();
   4588   ASSERT_FALSE(response == NULL);
   4589   EXPECT_TRUE(CheckNTLMServerAuth(response->auth_challenge.get()));
   4590 
   4591   TestCompletionCallback callback4;
   4592 
   4593   // Now enter the right password.
   4594   rv = trans->RestartWithAuth(AuthCredentials(kTestingNTLM, kTestingNTLM),
   4595                               callback4.callback());
   4596   EXPECT_EQ(ERR_IO_PENDING, rv);
   4597 
   4598   rv = callback4.WaitForResult();
   4599   EXPECT_EQ(OK, rv);
   4600 
   4601   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4602 
   4603   TestCompletionCallback callback5;
   4604 
   4605   // One more roundtrip
   4606   rv = trans->RestartWithAuth(AuthCredentials(), callback5.callback());
   4607   EXPECT_EQ(ERR_IO_PENDING, rv);
   4608 
   4609   rv = callback5.WaitForResult();
   4610   EXPECT_EQ(OK, rv);
   4611 
   4612   response = trans->GetResponseInfo();
   4613   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4614   EXPECT_EQ(13, response->headers->GetContentLength());
   4615 }
   4616 #endif  // NTLM_PORTABLE
   4617 
   4618 // Test reading a server response which has only headers, and no body.
   4619 // After some maximum number of bytes is consumed, the transaction should
   4620 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   4621 TEST_P(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   4622   HttpRequestInfo request;
   4623   request.method = "GET";
   4624   request.url = GURL("http://www.google.com/");
   4625   request.load_flags = 0;
   4626 
   4627   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4628   scoped_ptr<HttpTransaction> trans(
   4629       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   4630 
   4631   // Respond with 300 kb of headers (we should fail after 256 kb).
   4632   std::string large_headers_string;
   4633   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   4634 
   4635   MockRead data_reads[] = {
   4636     MockRead("HTTP/1.0 200 OK\r\n"),
   4637     MockRead(ASYNC, large_headers_string.data(), large_headers_string.size()),
   4638     MockRead("\r\nBODY"),
   4639     MockRead(SYNCHRONOUS, OK),
   4640   };
   4641   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4642   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4643 
   4644   TestCompletionCallback callback;
   4645 
   4646   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4647   EXPECT_EQ(ERR_IO_PENDING, rv);
   4648 
   4649   rv = callback.WaitForResult();
   4650   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   4651 
   4652   const HttpResponseInfo* response = trans->GetResponseInfo();
   4653   EXPECT_TRUE(response == NULL);
   4654 }
   4655 
   4656 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   4657 // establish tunnel.
   4658 // http://code.google.com/p/chromium/issues/detail?id=3772
   4659 TEST_P(HttpNetworkTransactionTest,
   4660        DontRecycleTransportSocketForSSLTunnel) {
   4661   HttpRequestInfo request;
   4662   request.method = "GET";
   4663   request.url = GURL("https://www.google.com/");
   4664   request.load_flags = 0;
   4665 
   4666   // Configure against proxy server "myproxy:70".
   4667   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   4668 
   4669   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4670 
   4671   scoped_ptr<HttpTransaction> trans(
   4672       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4673 
   4674   // Since we have proxy, should try to establish tunnel.
   4675   MockWrite data_writes1[] = {
   4676     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4677               "Host: www.google.com\r\n"
   4678               "Proxy-Connection: keep-alive\r\n\r\n"),
   4679   };
   4680 
   4681   // The proxy responds to the connect with a 404, using a persistent
   4682   // connection. Usually a proxy would return 501 (not implemented),
   4683   // or 200 (tunnel established).
   4684   MockRead data_reads1[] = {
   4685     MockRead("HTTP/1.1 404 Not Found\r\n"),
   4686     MockRead("Content-Length: 10\r\n\r\n"),
   4687     MockRead(SYNCHRONOUS, ERR_UNEXPECTED),  // Should not be reached.
   4688   };
   4689 
   4690   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4691                                  data_writes1, arraysize(data_writes1));
   4692   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   4693 
   4694   TestCompletionCallback callback1;
   4695 
   4696   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   4697   EXPECT_EQ(ERR_IO_PENDING, rv);
   4698 
   4699   rv = callback1.WaitForResult();
   4700   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   4701 
   4702   const HttpResponseInfo* response = trans->GetResponseInfo();
   4703   EXPECT_TRUE(response == NULL);
   4704 
   4705   // Empty the current queue.  This is necessary because idle sockets are
   4706   // added to the connection pool asynchronously with a PostTask.
   4707   base::MessageLoop::current()->RunUntilIdle();
   4708 
   4709   // We now check to make sure the TCPClientSocket was not added back to
   4710   // the pool.
   4711   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4712   trans.reset();
   4713   base::MessageLoop::current()->RunUntilIdle();
   4714   // Make sure that the socket didn't get recycled after calling the destructor.
   4715   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4716 }
   4717 
   4718 // Make sure that we recycle a socket after reading all of the response body.
   4719 TEST_P(HttpNetworkTransactionTest, RecycleSocket) {
   4720   HttpRequestInfo request;
   4721   request.method = "GET";
   4722   request.url = GURL("http://www.google.com/");
   4723   request.load_flags = 0;
   4724 
   4725   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4726 
   4727   scoped_ptr<HttpTransaction> trans(
   4728       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4729 
   4730   MockRead data_reads[] = {
   4731     // A part of the response body is received with the response headers.
   4732     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   4733     // The rest of the response body is received in two parts.
   4734     MockRead("lo"),
   4735     MockRead(" world"),
   4736     MockRead("junk"),  // Should not be read!!
   4737     MockRead(SYNCHRONOUS, OK),
   4738   };
   4739 
   4740   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4741   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4742 
   4743   TestCompletionCallback callback;
   4744 
   4745   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4746   EXPECT_EQ(ERR_IO_PENDING, rv);
   4747 
   4748   rv = callback.WaitForResult();
   4749   EXPECT_EQ(OK, rv);
   4750 
   4751   const HttpResponseInfo* response = trans->GetResponseInfo();
   4752   ASSERT_TRUE(response != NULL);
   4753 
   4754   EXPECT_TRUE(response->headers.get() != NULL);
   4755   std::string status_line = response->headers->GetStatusLine();
   4756   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   4757 
   4758   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4759 
   4760   std::string response_data;
   4761   rv = ReadTransaction(trans.get(), &response_data);
   4762   EXPECT_EQ(OK, rv);
   4763   EXPECT_EQ("hello world", response_data);
   4764 
   4765   // Empty the current queue.  This is necessary because idle sockets are
   4766   // added to the connection pool asynchronously with a PostTask.
   4767   base::MessageLoop::current()->RunUntilIdle();
   4768 
   4769   // We now check to make sure the socket was added back to the pool.
   4770   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4771 }
   4772 
   4773 // Make sure that we recycle a SSL socket after reading all of the response
   4774 // body.
   4775 TEST_P(HttpNetworkTransactionTest, RecycleSSLSocket) {
   4776   HttpRequestInfo request;
   4777   request.method = "GET";
   4778   request.url = GURL("https://www.google.com/");
   4779   request.load_flags = 0;
   4780 
   4781   MockWrite data_writes[] = {
   4782     MockWrite("GET / HTTP/1.1\r\n"
   4783               "Host: www.google.com\r\n"
   4784               "Connection: keep-alive\r\n\r\n"),
   4785   };
   4786 
   4787   MockRead data_reads[] = {
   4788     MockRead("HTTP/1.1 200 OK\r\n"),
   4789     MockRead("Content-Length: 11\r\n\r\n"),
   4790     MockRead("hello world"),
   4791     MockRead(SYNCHRONOUS, OK),
   4792   };
   4793 
   4794   SSLSocketDataProvider ssl(ASYNC, OK);
   4795   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4796 
   4797   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4798                                 data_writes, arraysize(data_writes));
   4799   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4800 
   4801   TestCompletionCallback callback;
   4802 
   4803   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4804   scoped_ptr<HttpTransaction> trans(
   4805       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4806 
   4807   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4808 
   4809   EXPECT_EQ(ERR_IO_PENDING, rv);
   4810   EXPECT_EQ(OK, callback.WaitForResult());
   4811 
   4812   const HttpResponseInfo* response = trans->GetResponseInfo();
   4813   ASSERT_TRUE(response != NULL);
   4814   ASSERT_TRUE(response->headers.get() != NULL);
   4815   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4816 
   4817   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4818 
   4819   std::string response_data;
   4820   rv = ReadTransaction(trans.get(), &response_data);
   4821   EXPECT_EQ(OK, rv);
   4822   EXPECT_EQ("hello world", response_data);
   4823 
   4824   // Empty the current queue.  This is necessary because idle sockets are
   4825   // added to the connection pool asynchronously with a PostTask.
   4826   base::MessageLoop::current()->RunUntilIdle();
   4827 
   4828   // We now check to make sure the socket was added back to the pool.
   4829   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4830 }
   4831 
   4832 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
   4833 // from the pool and make sure that we recover okay.
   4834 TEST_P(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   4835   HttpRequestInfo request;
   4836   request.method = "GET";
   4837   request.url = GURL("https://www.google.com/");
   4838   request.load_flags = 0;
   4839 
   4840   MockWrite data_writes[] = {
   4841     MockWrite("GET / HTTP/1.1\r\n"
   4842               "Host: www.google.com\r\n"
   4843               "Connection: keep-alive\r\n\r\n"),
   4844     MockWrite("GET / HTTP/1.1\r\n"
   4845               "Host: www.google.com\r\n"
   4846               "Connection: keep-alive\r\n\r\n"),
   4847   };
   4848 
   4849   MockRead data_reads[] = {
   4850     MockRead("HTTP/1.1 200 OK\r\n"),
   4851     MockRead("Content-Length: 11\r\n\r\n"),
   4852     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   4853     MockRead("hello world"),
   4854     MockRead(ASYNC, 0, 0)   // EOF
   4855   };
   4856 
   4857   SSLSocketDataProvider ssl(ASYNC, OK);
   4858   SSLSocketDataProvider ssl2(ASYNC, OK);
   4859   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   4860   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl2);
   4861 
   4862   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4863                                 data_writes, arraysize(data_writes));
   4864   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
   4865                                 data_writes, arraysize(data_writes));
   4866   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4867   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   4868 
   4869   TestCompletionCallback callback;
   4870 
   4871   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4872   scoped_ptr<HttpTransaction> trans(
   4873       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4874 
   4875   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4876 
   4877   EXPECT_EQ(ERR_IO_PENDING, rv);
   4878   EXPECT_EQ(OK, callback.WaitForResult());
   4879 
   4880   const HttpResponseInfo* response = trans->GetResponseInfo();
   4881   ASSERT_TRUE(response != NULL);
   4882   ASSERT_TRUE(response->headers.get() != NULL);
   4883   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4884 
   4885   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4886 
   4887   std::string response_data;
   4888   rv = ReadTransaction(trans.get(), &response_data);
   4889   EXPECT_EQ(OK, rv);
   4890   EXPECT_EQ("hello world", response_data);
   4891 
   4892   // Empty the current queue.  This is necessary because idle sockets are
   4893   // added to the connection pool asynchronously with a PostTask.
   4894   base::MessageLoop::current()->RunUntilIdle();
   4895 
   4896   // We now check to make sure the socket was added back to the pool.
   4897   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4898 
   4899   // Now start the second transaction, which should reuse the previous socket.
   4900 
   4901   trans.reset(new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4902 
   4903   rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4904 
   4905   EXPECT_EQ(ERR_IO_PENDING, rv);
   4906   EXPECT_EQ(OK, callback.WaitForResult());
   4907 
   4908   response = trans->GetResponseInfo();
   4909   ASSERT_TRUE(response != NULL);
   4910   ASSERT_TRUE(response->headers.get() != NULL);
   4911   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   4912 
   4913   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4914 
   4915   rv = ReadTransaction(trans.get(), &response_data);
   4916   EXPECT_EQ(OK, rv);
   4917   EXPECT_EQ("hello world", response_data);
   4918 
   4919   // Empty the current queue.  This is necessary because idle sockets are
   4920   // added to the connection pool asynchronously with a PostTask.
   4921   base::MessageLoop::current()->RunUntilIdle();
   4922 
   4923   // We now check to make sure the socket was added back to the pool.
   4924   EXPECT_EQ(1, GetIdleSocketCountInSSLSocketPool(session.get()));
   4925 }
   4926 
   4927 // Make sure that we recycle a socket after a zero-length response.
   4928 // http://crbug.com/9880
   4929 TEST_P(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   4930   HttpRequestInfo request;
   4931   request.method = "GET";
   4932   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   4933                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   4934                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   4935                      "rt=prt.2642,ol.2649,xjs.2951");
   4936   request.load_flags = 0;
   4937 
   4938   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   4939 
   4940   scoped_ptr<HttpTransaction> trans(
   4941       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   4942 
   4943   MockRead data_reads[] = {
   4944     MockRead("HTTP/1.1 204 No Content\r\n"
   4945              "Content-Length: 0\r\n"
   4946              "Content-Type: text/html\r\n\r\n"),
   4947     MockRead("junk"),  // Should not be read!!
   4948     MockRead(SYNCHRONOUS, OK),
   4949   };
   4950 
   4951   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   4952   session_deps_.socket_factory->AddSocketDataProvider(&data);
   4953 
   4954   TestCompletionCallback callback;
   4955 
   4956   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   4957   EXPECT_EQ(ERR_IO_PENDING, rv);
   4958 
   4959   rv = callback.WaitForResult();
   4960   EXPECT_EQ(OK, rv);
   4961 
   4962   const HttpResponseInfo* response = trans->GetResponseInfo();
   4963   ASSERT_TRUE(response != NULL);
   4964 
   4965   EXPECT_TRUE(response->headers.get() != NULL);
   4966   std::string status_line = response->headers->GetStatusLine();
   4967   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   4968 
   4969   EXPECT_EQ(0, GetIdleSocketCountInTransportSocketPool(session.get()));
   4970 
   4971   std::string response_data;
   4972   rv = ReadTransaction(trans.get(), &response_data);
   4973   EXPECT_EQ(OK, rv);
   4974   EXPECT_EQ("", response_data);
   4975 
   4976   // Empty the current queue.  This is necessary because idle sockets are
   4977   // added to the connection pool asynchronously with a PostTask.
   4978   base::MessageLoop::current()->RunUntilIdle();
   4979 
   4980   // We now check to make sure the socket was added back to the pool.
   4981   EXPECT_EQ(1, GetIdleSocketCountInTransportSocketPool(session.get()));
   4982 }
   4983 
   4984 TEST_P(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   4985   ScopedVector<UploadElementReader> element_readers;
   4986   element_readers.push_back(new UploadBytesElementReader("foo", 3));
   4987   UploadDataStream upload_data_stream(element_readers.Pass(), 0);
   4988 
   4989   HttpRequestInfo request[2];
   4990   // Transaction 1: a GET request that succeeds.  The socket is recycled
   4991   // after use.
   4992   request[0].method = "GET";
   4993   request[0].url = GURL("http://www.google.com/");
   4994   request[0].load_flags = 0;
   4995   // Transaction 2: a POST request.  Reuses the socket kept alive from
   4996   // transaction 1.  The first attempts fails when writing the POST data.
   4997   // This causes the transaction to retry with a new socket.  The second
   4998   // attempt succeeds.
   4999   request[1].method = "POST";
   5000   request[1].url = GURL("http://www.google.com/login.cgi");
   5001   request[1].upload_data_stream = &upload_data_stream;
   5002   request[1].load_flags = 0;
   5003 
   5004   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5005 
   5006   // The first socket is used for transaction 1 and the first attempt of
   5007   // transaction 2.
   5008 
   5009   // The response of transaction 1.
   5010   MockRead data_reads1[] = {
   5011     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   5012     MockRead("hello world"),
   5013     MockRead(SYNCHRONOUS, OK),
   5014   };
   5015   // The mock write results of transaction 1 and the first attempt of
   5016   // transaction 2.
   5017   MockWrite data_writes1[] = {
   5018     MockWrite(SYNCHRONOUS, 64),  // GET
   5019     MockWrite(SYNCHRONOUS, 93),  // POST
   5020     MockWrite(SYNCHRONOUS, ERR_CONNECTION_ABORTED),  // POST data
   5021   };
   5022   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5023                                  data_writes1, arraysize(data_writes1));
   5024 
   5025   // The second socket is used for the second attempt of transaction 2.
   5026 
   5027   // The response of transaction 2.
   5028   MockRead data_reads2[] = {
   5029     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   5030     MockRead("welcome"),
   5031     MockRead(SYNCHRONOUS, OK),
   5032   };
   5033   // The mock write results of the second attempt of transaction 2.
   5034   MockWrite data_writes2[] = {
   5035     MockWrite(SYNCHRONOUS, 93),  // POST
   5036     MockWrite(SYNCHRONOUS, 3),  // POST data
   5037   };
   5038   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5039                                  data_writes2, arraysize(data_writes2));
   5040 
   5041   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5042   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5043 
   5044   const char* kExpectedResponseData[] = {
   5045     "hello world", "welcome"
   5046   };
   5047 
   5048   for (int i = 0; i < 2; ++i) {
   5049     scoped_ptr<HttpTransaction> trans(
   5050         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5051 
   5052     TestCompletionCallback callback;
   5053 
   5054     int rv = trans->Start(&request[i], callback.callback(), BoundNetLog());
   5055     EXPECT_EQ(ERR_IO_PENDING, rv);
   5056 
   5057     rv = callback.WaitForResult();
   5058     EXPECT_EQ(OK, rv);
   5059 
   5060     const HttpResponseInfo* response = trans->GetResponseInfo();
   5061     ASSERT_TRUE(response != NULL);
   5062 
   5063     EXPECT_TRUE(response->headers.get() != NULL);
   5064     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   5065 
   5066     std::string response_data;
   5067     rv = ReadTransaction(trans.get(), &response_data);
   5068     EXPECT_EQ(OK, rv);
   5069     EXPECT_EQ(kExpectedResponseData[i], response_data);
   5070   }
   5071 }
   5072 
   5073 // Test the request-challenge-retry sequence for basic auth when there is
   5074 // an identity in the URL. The request should be sent as normal, but when
   5075 // it fails the identity from the URL is used to answer the challenge.
   5076 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURL) {
   5077   HttpRequestInfo request;
   5078   request.method = "GET";
   5079   request.url = GURL("http://foo:b@r@www.google.com/");
   5080   request.load_flags = LOAD_NORMAL;
   5081 
   5082   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5083   scoped_ptr<HttpTransaction> trans(
   5084       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5085 
   5086   // The password contains an escaped character -- for this test to pass it
   5087   // will need to be unescaped by HttpNetworkTransaction.
   5088   EXPECT_EQ("b%40r", request.url.password());
   5089 
   5090   MockWrite data_writes1[] = {
   5091     MockWrite("GET / HTTP/1.1\r\n"
   5092               "Host: www.google.com\r\n"
   5093               "Connection: keep-alive\r\n\r\n"),
   5094   };
   5095 
   5096   MockRead data_reads1[] = {
   5097     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5098     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5099     MockRead("Content-Length: 10\r\n\r\n"),
   5100     MockRead(SYNCHRONOUS, ERR_FAILED),
   5101   };
   5102 
   5103   // After the challenge above, the transaction will be restarted using the
   5104   // identity from the url (foo, b@r) to answer the challenge.
   5105   MockWrite data_writes2[] = {
   5106     MockWrite("GET / HTTP/1.1\r\n"
   5107               "Host: www.google.com\r\n"
   5108               "Connection: keep-alive\r\n"
   5109               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   5110   };
   5111 
   5112   MockRead data_reads2[] = {
   5113     MockRead("HTTP/1.0 200 OK\r\n"),
   5114     MockRead("Content-Length: 100\r\n\r\n"),
   5115     MockRead(SYNCHRONOUS, OK),
   5116   };
   5117 
   5118   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5119                                  data_writes1, arraysize(data_writes1));
   5120   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5121                                  data_writes2, arraysize(data_writes2));
   5122   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5123   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5124 
   5125   TestCompletionCallback callback1;
   5126   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5127   EXPECT_EQ(ERR_IO_PENDING, rv);
   5128   rv = callback1.WaitForResult();
   5129   EXPECT_EQ(OK, rv);
   5130   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5131 
   5132   TestCompletionCallback callback2;
   5133   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5134   EXPECT_EQ(ERR_IO_PENDING, rv);
   5135   rv = callback2.WaitForResult();
   5136   EXPECT_EQ(OK, rv);
   5137   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5138 
   5139   const HttpResponseInfo* response = trans->GetResponseInfo();
   5140   ASSERT_TRUE(response != NULL);
   5141 
   5142   // There is no challenge info, since the identity in URL worked.
   5143   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5144 
   5145   EXPECT_EQ(100, response->headers->GetContentLength());
   5146 
   5147   // Empty the current queue.
   5148   base::MessageLoop::current()->RunUntilIdle();
   5149 }
   5150 
   5151 // Test the request-challenge-retry sequence for basic auth when there is an
   5152 // incorrect identity in the URL. The identity from the URL should be used only
   5153 // once.
   5154 TEST_P(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   5155   HttpRequestInfo request;
   5156   request.method = "GET";
   5157   // Note: the URL has a username:password in it.  The password "baz" is
   5158   // wrong (should be "bar").
   5159   request.url = GURL("http://foo:baz@www.google.com/");
   5160 
   5161   request.load_flags = LOAD_NORMAL;
   5162 
   5163   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5164   scoped_ptr<HttpTransaction> trans(
   5165       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5166 
   5167   MockWrite data_writes1[] = {
   5168     MockWrite("GET / HTTP/1.1\r\n"
   5169               "Host: www.google.com\r\n"
   5170               "Connection: keep-alive\r\n\r\n"),
   5171   };
   5172 
   5173   MockRead data_reads1[] = {
   5174     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5175     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5176     MockRead("Content-Length: 10\r\n\r\n"),
   5177     MockRead(SYNCHRONOUS, ERR_FAILED),
   5178   };
   5179 
   5180   // After the challenge above, the transaction will be restarted using the
   5181   // identity from the url (foo, baz) to answer the challenge.
   5182   MockWrite data_writes2[] = {
   5183     MockWrite("GET / HTTP/1.1\r\n"
   5184               "Host: www.google.com\r\n"
   5185               "Connection: keep-alive\r\n"
   5186               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   5187   };
   5188 
   5189   MockRead data_reads2[] = {
   5190     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5191     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5192     MockRead("Content-Length: 10\r\n\r\n"),
   5193     MockRead(SYNCHRONOUS, ERR_FAILED),
   5194   };
   5195 
   5196   // After the challenge above, the transaction will be restarted using the
   5197   // identity supplied by the user (foo, bar) to answer the challenge.
   5198   MockWrite data_writes3[] = {
   5199     MockWrite("GET / HTTP/1.1\r\n"
   5200               "Host: www.google.com\r\n"
   5201               "Connection: keep-alive\r\n"
   5202               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5203   };
   5204 
   5205   MockRead data_reads3[] = {
   5206     MockRead("HTTP/1.0 200 OK\r\n"),
   5207     MockRead("Content-Length: 100\r\n\r\n"),
   5208     MockRead(SYNCHRONOUS, OK),
   5209   };
   5210 
   5211   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5212                                  data_writes1, arraysize(data_writes1));
   5213   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5214                                  data_writes2, arraysize(data_writes2));
   5215   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5216                                  data_writes3, arraysize(data_writes3));
   5217   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5218   session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5219   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5220 
   5221   TestCompletionCallback callback1;
   5222 
   5223   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5224   EXPECT_EQ(ERR_IO_PENDING, rv);
   5225 
   5226   rv = callback1.WaitForResult();
   5227   EXPECT_EQ(OK, rv);
   5228 
   5229   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5230   TestCompletionCallback callback2;
   5231   rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5232   EXPECT_EQ(ERR_IO_PENDING, rv);
   5233   rv = callback2.WaitForResult();
   5234   EXPECT_EQ(OK, rv);
   5235   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5236 
   5237   const HttpResponseInfo* response = trans->GetResponseInfo();
   5238   ASSERT_TRUE(response != NULL);
   5239   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5240 
   5241   TestCompletionCallback callback3;
   5242   rv = trans->RestartWithAuth(
   5243       AuthCredentials(kFoo, kBar), callback3.callback());
   5244   EXPECT_EQ(ERR_IO_PENDING, rv);
   5245   rv = callback3.WaitForResult();
   5246   EXPECT_EQ(OK, rv);
   5247   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5248 
   5249   response = trans->GetResponseInfo();
   5250   ASSERT_TRUE(response != NULL);
   5251 
   5252   // There is no challenge info, since the identity worked.
   5253   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5254 
   5255   EXPECT_EQ(100, response->headers->GetContentLength());
   5256 
   5257   // Empty the current queue.
   5258   base::MessageLoop::current()->RunUntilIdle();
   5259 }
   5260 
   5261 
   5262 // Test the request-challenge-retry sequence for basic auth when there is a
   5263 // correct identity in the URL, but its use is being suppressed. The identity
   5264 // from the URL should never be used.
   5265 TEST_P(HttpNetworkTransactionTest, AuthIdentityInURLSuppressed) {
   5266   HttpRequestInfo request;
   5267   request.method = "GET";
   5268   request.url = GURL("http://foo:bar@www.google.com/");
   5269   request.load_flags = LOAD_DO_NOT_USE_EMBEDDED_IDENTITY;
   5270 
   5271   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5272   scoped_ptr<HttpTransaction> trans(
   5273       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5274 
   5275   MockWrite data_writes1[] = {
   5276     MockWrite("GET / HTTP/1.1\r\n"
   5277               "Host: www.google.com\r\n"
   5278               "Connection: keep-alive\r\n\r\n"),
   5279   };
   5280 
   5281   MockRead data_reads1[] = {
   5282     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5283     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5284     MockRead("Content-Length: 10\r\n\r\n"),
   5285     MockRead(SYNCHRONOUS, ERR_FAILED),
   5286   };
   5287 
   5288   // After the challenge above, the transaction will be restarted using the
   5289   // identity supplied by the user, not the one in the URL, to answer the
   5290   // challenge.
   5291   MockWrite data_writes3[] = {
   5292     MockWrite("GET / HTTP/1.1\r\n"
   5293               "Host: www.google.com\r\n"
   5294               "Connection: keep-alive\r\n"
   5295               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5296   };
   5297 
   5298   MockRead data_reads3[] = {
   5299     MockRead("HTTP/1.0 200 OK\r\n"),
   5300     MockRead("Content-Length: 100\r\n\r\n"),
   5301     MockRead(SYNCHRONOUS, OK),
   5302   };
   5303 
   5304   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5305                                  data_writes1, arraysize(data_writes1));
   5306   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5307                                  data_writes3, arraysize(data_writes3));
   5308   session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5309   session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5310 
   5311   TestCompletionCallback callback1;
   5312   int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5313   EXPECT_EQ(ERR_IO_PENDING, rv);
   5314   rv = callback1.WaitForResult();
   5315   EXPECT_EQ(OK, rv);
   5316   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5317 
   5318   const HttpResponseInfo* response = trans->GetResponseInfo();
   5319   ASSERT_TRUE(response != NULL);
   5320   EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5321 
   5322   TestCompletionCallback callback3;
   5323   rv = trans->RestartWithAuth(
   5324       AuthCredentials(kFoo, kBar), callback3.callback());
   5325   EXPECT_EQ(ERR_IO_PENDING, rv);
   5326   rv = callback3.WaitForResult();
   5327   EXPECT_EQ(OK, rv);
   5328   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5329 
   5330   response = trans->GetResponseInfo();
   5331   ASSERT_TRUE(response != NULL);
   5332 
   5333   // There is no challenge info, since the identity worked.
   5334   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5335   EXPECT_EQ(100, response->headers->GetContentLength());
   5336 
   5337   // Empty the current queue.
   5338   base::MessageLoop::current()->RunUntilIdle();
   5339 }
   5340 
   5341 // Test that previously tried username/passwords for a realm get re-used.
   5342 TEST_P(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   5343   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5344 
   5345   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5346   {
   5347     HttpRequestInfo request;
   5348     request.method = "GET";
   5349     request.url = GURL("http://www.google.com/x/y/z");
   5350     request.load_flags = 0;
   5351 
   5352     scoped_ptr<HttpTransaction> trans(
   5353         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5354 
   5355     MockWrite data_writes1[] = {
   5356       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5357                 "Host: www.google.com\r\n"
   5358                 "Connection: keep-alive\r\n\r\n"),
   5359     };
   5360 
   5361     MockRead data_reads1[] = {
   5362       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5363       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5364       MockRead("Content-Length: 10000\r\n\r\n"),
   5365       MockRead(SYNCHRONOUS, ERR_FAILED),
   5366     };
   5367 
   5368     // Resend with authorization (username=foo, password=bar)
   5369     MockWrite data_writes2[] = {
   5370       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5371                 "Host: www.google.com\r\n"
   5372                 "Connection: keep-alive\r\n"
   5373                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5374     };
   5375 
   5376     // Sever accepts the authorization.
   5377     MockRead data_reads2[] = {
   5378       MockRead("HTTP/1.0 200 OK\r\n"),
   5379       MockRead("Content-Length: 100\r\n\r\n"),
   5380       MockRead(SYNCHRONOUS, OK),
   5381     };
   5382 
   5383     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5384                                    data_writes1, arraysize(data_writes1));
   5385     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5386                                    data_writes2, arraysize(data_writes2));
   5387     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5388     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5389 
   5390     TestCompletionCallback callback1;
   5391 
   5392     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5393     EXPECT_EQ(ERR_IO_PENDING, rv);
   5394 
   5395     rv = callback1.WaitForResult();
   5396     EXPECT_EQ(OK, rv);
   5397 
   5398     const HttpResponseInfo* response = trans->GetResponseInfo();
   5399     ASSERT_TRUE(response != NULL);
   5400     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5401 
   5402     TestCompletionCallback callback2;
   5403 
   5404     rv = trans->RestartWithAuth(
   5405         AuthCredentials(kFoo, kBar), callback2.callback());
   5406     EXPECT_EQ(ERR_IO_PENDING, rv);
   5407 
   5408     rv = callback2.WaitForResult();
   5409     EXPECT_EQ(OK, rv);
   5410 
   5411     response = trans->GetResponseInfo();
   5412     ASSERT_TRUE(response != NULL);
   5413     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5414     EXPECT_EQ(100, response->headers->GetContentLength());
   5415   }
   5416 
   5417   // ------------------------------------------------------------------------
   5418 
   5419   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   5420   {
   5421     HttpRequestInfo request;
   5422     request.method = "GET";
   5423     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5424     // protection space as MyRealm1.
   5425     request.url = GURL("http://www.google.com/x/y/a/b");
   5426     request.load_flags = 0;
   5427 
   5428     scoped_ptr<HttpTransaction> trans(
   5429         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5430 
   5431     MockWrite data_writes1[] = {
   5432       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5433                 "Host: www.google.com\r\n"
   5434                 "Connection: keep-alive\r\n"
   5435                 // Send preemptive authorization for MyRealm1
   5436                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5437     };
   5438 
   5439     // The server didn't like the preemptive authorization, and
   5440     // challenges us for a different realm (MyRealm2).
   5441     MockRead data_reads1[] = {
   5442       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5443       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   5444       MockRead("Content-Length: 10000\r\n\r\n"),
   5445       MockRead(SYNCHRONOUS, ERR_FAILED),
   5446     };
   5447 
   5448     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   5449     MockWrite data_writes2[] = {
   5450       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5451                 "Host: www.google.com\r\n"
   5452                 "Connection: keep-alive\r\n"
   5453                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   5454     };
   5455 
   5456     // Sever accepts the authorization.
   5457     MockRead data_reads2[] = {
   5458       MockRead("HTTP/1.0 200 OK\r\n"),
   5459       MockRead("Content-Length: 100\r\n\r\n"),
   5460       MockRead(SYNCHRONOUS, OK),
   5461     };
   5462 
   5463     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5464                                    data_writes1, arraysize(data_writes1));
   5465     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5466                                    data_writes2, arraysize(data_writes2));
   5467     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5468     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5469 
   5470     TestCompletionCallback callback1;
   5471 
   5472     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5473     EXPECT_EQ(ERR_IO_PENDING, rv);
   5474 
   5475     rv = callback1.WaitForResult();
   5476     EXPECT_EQ(OK, rv);
   5477 
   5478     const HttpResponseInfo* response = trans->GetResponseInfo();
   5479     ASSERT_TRUE(response != NULL);
   5480     ASSERT_TRUE(response->auth_challenge.get());
   5481     EXPECT_FALSE(response->auth_challenge->is_proxy);
   5482     EXPECT_EQ("www.google.com:80",
   5483               response->auth_challenge->challenger.ToString());
   5484     EXPECT_EQ("MyRealm2", response->auth_challenge->realm);
   5485     EXPECT_EQ("basic", response->auth_challenge->scheme);
   5486 
   5487     TestCompletionCallback callback2;
   5488 
   5489     rv = trans->RestartWithAuth(
   5490         AuthCredentials(kFoo2, kBar2), callback2.callback());
   5491     EXPECT_EQ(ERR_IO_PENDING, rv);
   5492 
   5493     rv = callback2.WaitForResult();
   5494     EXPECT_EQ(OK, rv);
   5495 
   5496     response = trans->GetResponseInfo();
   5497     ASSERT_TRUE(response != NULL);
   5498     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5499     EXPECT_EQ(100, response->headers->GetContentLength());
   5500   }
   5501 
   5502   // ------------------------------------------------------------------------
   5503 
   5504   // Transaction 3: Resend a request in MyRealm's protection space --
   5505   // succeed with preemptive authorization.
   5506   {
   5507     HttpRequestInfo request;
   5508     request.method = "GET";
   5509     request.url = GURL("http://www.google.com/x/y/z2");
   5510     request.load_flags = 0;
   5511 
   5512     scoped_ptr<HttpTransaction> trans(
   5513         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5514 
   5515     MockWrite data_writes1[] = {
   5516       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   5517                 "Host: www.google.com\r\n"
   5518                 "Connection: keep-alive\r\n"
   5519                 // The authorization for MyRealm1 gets sent preemptively
   5520                 // (since the url is in the same protection space)
   5521                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5522     };
   5523 
   5524     // Sever accepts the preemptive authorization
   5525     MockRead data_reads1[] = {
   5526       MockRead("HTTP/1.0 200 OK\r\n"),
   5527       MockRead("Content-Length: 100\r\n\r\n"),
   5528       MockRead(SYNCHRONOUS, OK),
   5529     };
   5530 
   5531     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5532                                    data_writes1, arraysize(data_writes1));
   5533     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5534 
   5535     TestCompletionCallback callback1;
   5536 
   5537     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5538     EXPECT_EQ(ERR_IO_PENDING, rv);
   5539 
   5540     rv = callback1.WaitForResult();
   5541     EXPECT_EQ(OK, rv);
   5542 
   5543     const HttpResponseInfo* response = trans->GetResponseInfo();
   5544     ASSERT_TRUE(response != NULL);
   5545 
   5546     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5547     EXPECT_EQ(100, response->headers->GetContentLength());
   5548   }
   5549 
   5550   // ------------------------------------------------------------------------
   5551 
   5552   // Transaction 4: request another URL in MyRealm (however the
   5553   // url is not known to belong to the protection space, so no pre-auth).
   5554   {
   5555     HttpRequestInfo request;
   5556     request.method = "GET";
   5557     request.url = GURL("http://www.google.com/x/1");
   5558     request.load_flags = 0;
   5559 
   5560     scoped_ptr<HttpTransaction> trans(
   5561         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5562 
   5563     MockWrite data_writes1[] = {
   5564       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5565                 "Host: www.google.com\r\n"
   5566                 "Connection: keep-alive\r\n\r\n"),
   5567     };
   5568 
   5569     MockRead data_reads1[] = {
   5570       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5571       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5572       MockRead("Content-Length: 10000\r\n\r\n"),
   5573       MockRead(SYNCHRONOUS, ERR_FAILED),
   5574     };
   5575 
   5576     // Resend with authorization from MyRealm's cache.
   5577     MockWrite data_writes2[] = {
   5578       MockWrite("GET /x/1 HTTP/1.1\r\n"
   5579                 "Host: www.google.com\r\n"
   5580                 "Connection: keep-alive\r\n"
   5581                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5582     };
   5583 
   5584     // Sever accepts the authorization.
   5585     MockRead data_reads2[] = {
   5586       MockRead("HTTP/1.0 200 OK\r\n"),
   5587       MockRead("Content-Length: 100\r\n\r\n"),
   5588       MockRead(SYNCHRONOUS, OK),
   5589     };
   5590 
   5591     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5592                                    data_writes1, arraysize(data_writes1));
   5593     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5594                                    data_writes2, arraysize(data_writes2));
   5595     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5596     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5597 
   5598     TestCompletionCallback callback1;
   5599 
   5600     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5601     EXPECT_EQ(ERR_IO_PENDING, rv);
   5602 
   5603     rv = callback1.WaitForResult();
   5604     EXPECT_EQ(OK, rv);
   5605 
   5606     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5607     TestCompletionCallback callback2;
   5608     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5609     EXPECT_EQ(ERR_IO_PENDING, rv);
   5610     rv = callback2.WaitForResult();
   5611     EXPECT_EQ(OK, rv);
   5612     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5613 
   5614     const HttpResponseInfo* response = trans->GetResponseInfo();
   5615     ASSERT_TRUE(response != NULL);
   5616     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5617     EXPECT_EQ(100, response->headers->GetContentLength());
   5618   }
   5619 
   5620   // ------------------------------------------------------------------------
   5621 
   5622   // Transaction 5: request a URL in MyRealm, but the server rejects the
   5623   // cached identity. Should invalidate and re-prompt.
   5624   {
   5625     HttpRequestInfo request;
   5626     request.method = "GET";
   5627     request.url = GURL("http://www.google.com/p/q/t");
   5628     request.load_flags = 0;
   5629 
   5630     scoped_ptr<HttpTransaction> trans(
   5631         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5632 
   5633     MockWrite data_writes1[] = {
   5634       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5635                 "Host: www.google.com\r\n"
   5636                 "Connection: keep-alive\r\n\r\n"),
   5637     };
   5638 
   5639     MockRead data_reads1[] = {
   5640       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5641       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5642       MockRead("Content-Length: 10000\r\n\r\n"),
   5643       MockRead(SYNCHRONOUS, ERR_FAILED),
   5644     };
   5645 
   5646     // Resend with authorization from cache for MyRealm.
   5647     MockWrite data_writes2[] = {
   5648       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5649                 "Host: www.google.com\r\n"
   5650                 "Connection: keep-alive\r\n"
   5651                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5652     };
   5653 
   5654     // Sever rejects the authorization.
   5655     MockRead data_reads2[] = {
   5656       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5657       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5658       MockRead("Content-Length: 10000\r\n\r\n"),
   5659       MockRead(SYNCHRONOUS, ERR_FAILED),
   5660     };
   5661 
   5662     // At this point we should prompt for new credentials for MyRealm.
   5663     // Restart with username=foo3, password=foo4.
   5664     MockWrite data_writes3[] = {
   5665       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   5666                 "Host: www.google.com\r\n"
   5667                 "Connection: keep-alive\r\n"
   5668                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   5669     };
   5670 
   5671     // Sever accepts the authorization.
   5672     MockRead data_reads3[] = {
   5673       MockRead("HTTP/1.0 200 OK\r\n"),
   5674       MockRead("Content-Length: 100\r\n\r\n"),
   5675       MockRead(SYNCHRONOUS, OK),
   5676     };
   5677 
   5678     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5679                                    data_writes1, arraysize(data_writes1));
   5680     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5681                                    data_writes2, arraysize(data_writes2));
   5682     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   5683                                    data_writes3, arraysize(data_writes3));
   5684     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5685     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5686     session_deps_.socket_factory->AddSocketDataProvider(&data3);
   5687 
   5688     TestCompletionCallback callback1;
   5689 
   5690     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5691     EXPECT_EQ(ERR_IO_PENDING, rv);
   5692 
   5693     rv = callback1.WaitForResult();
   5694     EXPECT_EQ(OK, rv);
   5695 
   5696     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   5697     TestCompletionCallback callback2;
   5698     rv = trans->RestartWithAuth(AuthCredentials(), callback2.callback());
   5699     EXPECT_EQ(ERR_IO_PENDING, rv);
   5700     rv = callback2.WaitForResult();
   5701     EXPECT_EQ(OK, rv);
   5702     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   5703 
   5704     const HttpResponseInfo* response = trans->GetResponseInfo();
   5705     ASSERT_TRUE(response != NULL);
   5706     EXPECT_TRUE(CheckBasicServerAuth(response->auth_challenge.get()));
   5707 
   5708     TestCompletionCallback callback3;
   5709 
   5710     rv = trans->RestartWithAuth(
   5711         AuthCredentials(kFoo3, kBar3), callback3.callback());
   5712     EXPECT_EQ(ERR_IO_PENDING, rv);
   5713 
   5714     rv = callback3.WaitForResult();
   5715     EXPECT_EQ(OK, rv);
   5716 
   5717     response = trans->GetResponseInfo();
   5718     ASSERT_TRUE(response != NULL);
   5719     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5720     EXPECT_EQ(100, response->headers->GetContentLength());
   5721   }
   5722 }
   5723 
   5724 // Tests that nonce count increments when multiple auth attempts
   5725 // are started with the same nonce.
   5726 TEST_P(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
   5727   HttpAuthHandlerDigest::Factory* digest_factory =
   5728       new HttpAuthHandlerDigest::Factory();
   5729   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
   5730       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
   5731   digest_factory->set_nonce_generator(nonce_generator);
   5732   session_deps_.http_auth_handler_factory.reset(digest_factory);
   5733   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5734 
   5735   // Transaction 1: authenticate (foo, bar) on MyRealm1
   5736   {
   5737     HttpRequestInfo request;
   5738     request.method = "GET";
   5739     request.url = GURL("http://www.google.com/x/y/z");
   5740     request.load_flags = 0;
   5741 
   5742     scoped_ptr<HttpTransaction> trans(
   5743         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5744 
   5745     MockWrite data_writes1[] = {
   5746       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5747                 "Host: www.google.com\r\n"
   5748                 "Connection: keep-alive\r\n\r\n"),
   5749     };
   5750 
   5751     MockRead data_reads1[] = {
   5752       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   5753       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
   5754                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
   5755       MockRead(SYNCHRONOUS, OK),
   5756     };
   5757 
   5758     // Resend with authorization (username=foo, password=bar)
   5759     MockWrite data_writes2[] = {
   5760       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   5761                 "Host: www.google.com\r\n"
   5762                 "Connection: keep-alive\r\n"
   5763                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5764                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
   5765                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
   5766                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5767     };
   5768 
   5769     // Sever accepts the authorization.
   5770     MockRead data_reads2[] = {
   5771       MockRead("HTTP/1.0 200 OK\r\n"),
   5772       MockRead(SYNCHRONOUS, OK),
   5773     };
   5774 
   5775     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5776                                    data_writes1, arraysize(data_writes1));
   5777     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5778                                    data_writes2, arraysize(data_writes2));
   5779     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5780     session_deps_.socket_factory->AddSocketDataProvider(&data2);
   5781 
   5782     TestCompletionCallback callback1;
   5783 
   5784     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5785     EXPECT_EQ(ERR_IO_PENDING, rv);
   5786 
   5787     rv = callback1.WaitForResult();
   5788     EXPECT_EQ(OK, rv);
   5789 
   5790     const HttpResponseInfo* response = trans->GetResponseInfo();
   5791     ASSERT_TRUE(response != NULL);
   5792     EXPECT_TRUE(CheckDigestServerAuth(response->auth_challenge.get()));
   5793 
   5794     TestCompletionCallback callback2;
   5795 
   5796     rv = trans->RestartWithAuth(
   5797         AuthCredentials(kFoo, kBar), callback2.callback());
   5798     EXPECT_EQ(ERR_IO_PENDING, rv);
   5799 
   5800     rv = callback2.WaitForResult();
   5801     EXPECT_EQ(OK, rv);
   5802 
   5803     response = trans->GetResponseInfo();
   5804     ASSERT_TRUE(response != NULL);
   5805     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5806   }
   5807 
   5808   // ------------------------------------------------------------------------
   5809 
   5810   // Transaction 2: Request another resource in digestive's protection space.
   5811   // This will preemptively add an Authorization header which should have an
   5812   // "nc" value of 2 (as compared to 1 in the first use.
   5813   {
   5814     HttpRequestInfo request;
   5815     request.method = "GET";
   5816     // Note that Transaction 1 was at /x/y/z, so this is in the same
   5817     // protection space as digest.
   5818     request.url = GURL("http://www.google.com/x/y/a/b");
   5819     request.load_flags = 0;
   5820 
   5821     scoped_ptr<HttpTransaction> trans(
   5822         new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   5823 
   5824     MockWrite data_writes1[] = {
   5825       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   5826                 "Host: www.google.com\r\n"
   5827                 "Connection: keep-alive\r\n"
   5828                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   5829                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
   5830                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
   5831                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   5832     };
   5833 
   5834     // Sever accepts the authorization.
   5835     MockRead data_reads1[] = {
   5836       MockRead("HTTP/1.0 200 OK\r\n"),
   5837       MockRead("Content-Length: 100\r\n\r\n"),
   5838       MockRead(SYNCHRONOUS, OK),
   5839     };
   5840 
   5841     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5842                                    data_writes1, arraysize(data_writes1));
   5843     session_deps_.socket_factory->AddSocketDataProvider(&data1);
   5844 
   5845     TestCompletionCallback callback1;
   5846 
   5847     int rv = trans->Start(&request, callback1.callback(), BoundNetLog());
   5848     EXPECT_EQ(ERR_IO_PENDING, rv);
   5849 
   5850     rv = callback1.WaitForResult();
   5851     EXPECT_EQ(OK, rv);
   5852 
   5853     const HttpResponseInfo* response = trans->GetResponseInfo();
   5854     ASSERT_TRUE(response != NULL);
   5855     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5856   }
   5857 }
   5858 
   5859 // Test the ResetStateForRestart() private method.
   5860 TEST_P(HttpNetworkTransactionTest, ResetStateForRestart) {
   5861   // Create a transaction (the dependencies aren't important).
   5862   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5863   scoped_ptr<HttpNetworkTransaction> trans(
   5864       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5865 
   5866   // Setup some state (which we expect ResetStateForRestart() will clear).
   5867   trans->read_buf_ = new IOBuffer(15);
   5868   trans->read_buf_len_ = 15;
   5869   trans->request_headers_.SetHeader("Authorization", "NTLM");
   5870 
   5871   // Setup state in response_
   5872   HttpResponseInfo* response = &trans->response_;
   5873   response->auth_challenge = new AuthChallengeInfo();
   5874   response->ssl_info.cert_status = static_cast<CertStatus>(-1);  // Nonsensical.
   5875   response->response_time = base::Time::Now();
   5876   response->was_cached = true;  // (Wouldn't ever actually be true...)
   5877 
   5878   { // Setup state for response_.vary_data
   5879     HttpRequestInfo request;
   5880     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   5881     std::replace(temp.begin(), temp.end(), '\n', '\0');
   5882     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
   5883     request.extra_headers.SetHeader("Foo", "1");
   5884     request.extra_headers.SetHeader("bar", "23");
   5885     EXPECT_TRUE(response->vary_data.Init(request, *headers.get()));
   5886   }
   5887 
   5888   // Cause the above state to be reset.
   5889   trans->ResetStateForRestart();
   5890 
   5891   // Verify that the state that needed to be reset, has been reset.
   5892   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   5893   EXPECT_EQ(0, trans->read_buf_len_);
   5894   EXPECT_TRUE(trans->request_headers_.IsEmpty());
   5895   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   5896   EXPECT_TRUE(response->headers.get() == NULL);
   5897   EXPECT_FALSE(response->was_cached);
   5898   EXPECT_EQ(0U, response->ssl_info.cert_status);
   5899   EXPECT_FALSE(response->vary_data.is_valid());
   5900 }
   5901 
   5902 // Test HTTPS connections to a site with a bad certificate
   5903 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   5904   HttpRequestInfo request;
   5905   request.method = "GET";
   5906   request.url = GURL("https://www.google.com/");
   5907   request.load_flags = 0;
   5908 
   5909   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   5910   scoped_ptr<HttpTransaction> trans(
   5911       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   5912 
   5913   MockWrite data_writes[] = {
   5914     MockWrite("GET / HTTP/1.1\r\n"
   5915               "Host: www.google.com\r\n"
   5916               "Connection: keep-alive\r\n\r\n"),
   5917   };
   5918 
   5919   MockRead data_reads[] = {
   5920     MockRead("HTTP/1.0 200 OK\r\n"),
   5921     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5922     MockRead("Content-Length: 100\r\n\r\n"),
   5923     MockRead(SYNCHRONOUS, OK),
   5924   };
   5925 
   5926   StaticSocketDataProvider ssl_bad_certificate;
   5927   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5928                                 data_writes, arraysize(data_writes));
   5929   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   5930   SSLSocketDataProvider ssl(ASYNC, OK);
   5931 
   5932   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   5933   session_deps_.socket_factory->AddSocketDataProvider(&data);
   5934   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   5935   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   5936 
   5937   TestCompletionCallback callback;
   5938 
   5939   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   5940   EXPECT_EQ(ERR_IO_PENDING, rv);
   5941 
   5942   rv = callback.WaitForResult();
   5943   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   5944 
   5945   rv = trans->RestartIgnoringLastError(callback.callback());
   5946   EXPECT_EQ(ERR_IO_PENDING, rv);
   5947 
   5948   rv = callback.WaitForResult();
   5949   EXPECT_EQ(OK, rv);
   5950 
   5951   const HttpResponseInfo* response = trans->GetResponseInfo();
   5952 
   5953   ASSERT_TRUE(response != NULL);
   5954   EXPECT_EQ(100, response->headers->GetContentLength());
   5955 }
   5956 
   5957 // Test HTTPS connections to a site with a bad certificate, going through a
   5958 // proxy
   5959 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   5960   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   5961 
   5962   HttpRequestInfo request;
   5963   request.method = "GET";
   5964   request.url = GURL("https://www.google.com/");
   5965   request.load_flags = 0;
   5966 
   5967   MockWrite proxy_writes[] = {
   5968     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5969               "Host: www.google.com\r\n"
   5970               "Proxy-Connection: keep-alive\r\n\r\n"),
   5971   };
   5972 
   5973   MockRead proxy_reads[] = {
   5974     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5975     MockRead(SYNCHRONOUS, OK)
   5976   };
   5977 
   5978   MockWrite data_writes[] = {
   5979     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   5980               "Host: www.google.com\r\n"
   5981               "Proxy-Connection: keep-alive\r\n\r\n"),
   5982     MockWrite("GET / HTTP/1.1\r\n"
   5983               "Host: www.google.com\r\n"
   5984               "Connection: keep-alive\r\n\r\n"),
   5985   };
   5986 
   5987   MockRead data_reads[] = {
   5988     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   5989     MockRead("HTTP/1.0 200 OK\r\n"),
   5990     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5991     MockRead("Content-Length: 100\r\n\r\n"),
   5992     MockRead(SYNCHRONOUS, OK),
   5993   };
   5994 
   5995   StaticSocketDataProvider ssl_bad_certificate(
   5996       proxy_reads, arraysize(proxy_reads),
   5997       proxy_writes, arraysize(proxy_writes));
   5998   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5999                                 data_writes, arraysize(data_writes));
   6000   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6001   SSLSocketDataProvider ssl(ASYNC, OK);
   6002 
   6003   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6004   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6005   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6006   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6007 
   6008   TestCompletionCallback callback;
   6009 
   6010   for (int i = 0; i < 2; i++) {
   6011     session_deps_.socket_factory->ResetNextMockIndexes();
   6012 
   6013     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6014     scoped_ptr<HttpTransaction> trans(
   6015         new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6016 
   6017     int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6018     EXPECT_EQ(ERR_IO_PENDING, rv);
   6019 
   6020     rv = callback.WaitForResult();
   6021     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6022 
   6023     rv = trans->RestartIgnoringLastError(callback.callback());
   6024     EXPECT_EQ(ERR_IO_PENDING, rv);
   6025 
   6026     rv = callback.WaitForResult();
   6027     EXPECT_EQ(OK, rv);
   6028 
   6029     const HttpResponseInfo* response = trans->GetResponseInfo();
   6030 
   6031     ASSERT_TRUE(response != NULL);
   6032     EXPECT_EQ(100, response->headers->GetContentLength());
   6033   }
   6034 }
   6035 
   6036 
   6037 // Test HTTPS connections to a site, going through an HTTPS proxy
   6038 TEST_P(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
   6039   session_deps_.proxy_service.reset(
   6040       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   6041   CapturingNetLog net_log;
   6042   session_deps_.net_log = &net_log;
   6043 
   6044   HttpRequestInfo request;
   6045   request.method = "GET";
   6046   request.url = GURL("https://www.google.com/");
   6047   request.load_flags = 0;
   6048 
   6049   MockWrite data_writes[] = {
   6050     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6051               "Host: www.google.com\r\n"
   6052               "Proxy-Connection: keep-alive\r\n\r\n"),
   6053     MockWrite("GET / HTTP/1.1\r\n"
   6054               "Host: www.google.com\r\n"
   6055               "Connection: keep-alive\r\n\r\n"),
   6056   };
   6057 
   6058   MockRead data_reads[] = {
   6059     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6060     MockRead("HTTP/1.1 200 OK\r\n"),
   6061     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6062     MockRead("Content-Length: 100\r\n\r\n"),
   6063     MockRead(SYNCHRONOUS, OK),
   6064   };
   6065 
   6066   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6067                                 data_writes, arraysize(data_writes));
   6068   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6069   SSLSocketDataProvider tunnel_ssl(ASYNC, OK);  // SSL through the tunnel
   6070 
   6071   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6072   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6073   session_deps_.socket_factory->AddSSLSocketDataProvider(&tunnel_ssl);
   6074 
   6075   TestCompletionCallback callback;
   6076 
   6077   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6078   scoped_ptr<HttpTransaction> trans(
   6079       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6080 
   6081   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6082   EXPECT_EQ(ERR_IO_PENDING, rv);
   6083 
   6084   rv = callback.WaitForResult();
   6085   EXPECT_EQ(OK, rv);
   6086   const HttpResponseInfo* response = trans->GetResponseInfo();
   6087 
   6088   ASSERT_TRUE(response != NULL);
   6089 
   6090   EXPECT_TRUE(response->headers->IsKeepAlive());
   6091   EXPECT_EQ(200, response->headers->response_code());
   6092   EXPECT_EQ(100, response->headers->GetContentLength());
   6093   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6094 
   6095   LoadTimingInfo load_timing_info;
   6096   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6097   TestLoadTimingNotReusedWithPac(load_timing_info,
   6098                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6099 }
   6100 
   6101 // Test an HTTPS Proxy's ability to redirect a CONNECT request
   6102 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
   6103   session_deps_.proxy_service.reset(
   6104       ProxyService::CreateFixedFromPacResult("HTTPS proxy:70"));
   6105   CapturingNetLog net_log;
   6106   session_deps_.net_log = &net_log;
   6107 
   6108   HttpRequestInfo request;
   6109   request.method = "GET";
   6110   request.url = GURL("https://www.google.com/");
   6111   request.load_flags = 0;
   6112 
   6113   MockWrite data_writes[] = {
   6114     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6115               "Host: www.google.com\r\n"
   6116               "Proxy-Connection: keep-alive\r\n\r\n"),
   6117   };
   6118 
   6119   MockRead data_reads[] = {
   6120     MockRead("HTTP/1.1 302 Redirect\r\n"),
   6121     MockRead("Location: http://login.example.com/\r\n"),
   6122     MockRead("Content-Length: 0\r\n\r\n"),
   6123     MockRead(SYNCHRONOUS, OK),
   6124   };
   6125 
   6126   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6127                                 data_writes, arraysize(data_writes));
   6128   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6129 
   6130   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6131   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6132 
   6133   TestCompletionCallback callback;
   6134 
   6135   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6136   scoped_ptr<HttpTransaction> trans(
   6137       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6138 
   6139   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6140   EXPECT_EQ(ERR_IO_PENDING, rv);
   6141 
   6142   rv = callback.WaitForResult();
   6143   EXPECT_EQ(OK, rv);
   6144   const HttpResponseInfo* response = trans->GetResponseInfo();
   6145 
   6146   ASSERT_TRUE(response != NULL);
   6147 
   6148   EXPECT_EQ(302, response->headers->response_code());
   6149   std::string url;
   6150   EXPECT_TRUE(response->headers->IsRedirect(&url));
   6151   EXPECT_EQ("http://login.example.com/", url);
   6152 
   6153   // In the case of redirects from proxies, HttpNetworkTransaction returns
   6154   // timing for the proxy connection instead of the connection to the host,
   6155   // and no send / receive times.
   6156   // See HttpNetworkTransaction::OnHttpsProxyTunnelResponse.
   6157   LoadTimingInfo load_timing_info;
   6158   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6159 
   6160   EXPECT_FALSE(load_timing_info.socket_reused);
   6161   EXPECT_NE(net::NetLog::Source::kInvalidId, load_timing_info.socket_log_id);
   6162 
   6163   EXPECT_FALSE(load_timing_info.proxy_resolve_start.is_null());
   6164   EXPECT_LE(load_timing_info.proxy_resolve_start,
   6165             load_timing_info.proxy_resolve_end);
   6166   EXPECT_LE(load_timing_info.proxy_resolve_end,
   6167             load_timing_info.connect_timing.connect_start);
   6168   ExpectConnectTimingHasTimes(
   6169       load_timing_info.connect_timing,
   6170       CONNECT_TIMING_HAS_DNS_TIMES | CONNECT_TIMING_HAS_SSL_TIMES);
   6171 
   6172   EXPECT_TRUE(load_timing_info.send_start.is_null());
   6173   EXPECT_TRUE(load_timing_info.send_end.is_null());
   6174   EXPECT_TRUE(load_timing_info.receive_headers_end.is_null());
   6175 }
   6176 
   6177 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
   6178 TEST_P(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
   6179   session_deps_.proxy_service.reset(
   6180       ProxyService::CreateFixed("https://proxy:70"));
   6181 
   6182   HttpRequestInfo request;
   6183   request.method = "GET";
   6184   request.url = GURL("https://www.google.com/");
   6185   request.load_flags = 0;
   6186 
   6187   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6188                                                              LOWEST));
   6189   scoped_ptr<SpdyFrame> goaway(
   6190       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6191   MockWrite data_writes[] = {
   6192     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   6193     CreateMockWrite(*goaway.get(), 3, SYNCHRONOUS),
   6194   };
   6195 
   6196   static const char* const kExtraHeaders[] = {
   6197     "location",
   6198     "http://login.example.com/",
   6199   };
   6200   scoped_ptr<SpdyFrame> resp(
   6201       spdy_util_.ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
   6202                                  arraysize(kExtraHeaders)/2, 1));
   6203   MockRead data_reads[] = {
   6204     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   6205     MockRead(ASYNC, 0, 2),  // EOF
   6206   };
   6207 
   6208   DelayedSocketData data(
   6209       1,  // wait for one write to finish before reading.
   6210       data_reads, arraysize(data_reads),
   6211       data_writes, arraysize(data_writes));
   6212   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6213   proxy_ssl.SetNextProto(GetParam());
   6214 
   6215   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6216   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6217 
   6218   TestCompletionCallback callback;
   6219 
   6220   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6221   scoped_ptr<HttpTransaction> trans(
   6222       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6223 
   6224   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6225   EXPECT_EQ(ERR_IO_PENDING, rv);
   6226 
   6227   rv = callback.WaitForResult();
   6228   EXPECT_EQ(OK, rv);
   6229   const HttpResponseInfo* response = trans->GetResponseInfo();
   6230 
   6231   ASSERT_TRUE(response != NULL);
   6232 
   6233   EXPECT_EQ(302, response->headers->response_code());
   6234   std::string url;
   6235   EXPECT_TRUE(response->headers->IsRedirect(&url));
   6236   EXPECT_EQ("http://login.example.com/", url);
   6237 }
   6238 
   6239 // Test that an HTTPS proxy's response to a CONNECT request is filtered.
   6240 TEST_P(HttpNetworkTransactionTest,
   6241        ErrorResponseToHttpsConnectViaHttpsProxy) {
   6242   session_deps_.proxy_service.reset(
   6243       ProxyService::CreateFixed("https://proxy:70"));
   6244 
   6245   HttpRequestInfo request;
   6246   request.method = "GET";
   6247   request.url = GURL("https://www.google.com/");
   6248   request.load_flags = 0;
   6249 
   6250   MockWrite data_writes[] = {
   6251     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6252               "Host: www.google.com\r\n"
   6253               "Proxy-Connection: keep-alive\r\n\r\n"),
   6254   };
   6255 
   6256   MockRead data_reads[] = {
   6257     MockRead("HTTP/1.1 404 Not Found\r\n"),
   6258     MockRead("Content-Length: 23\r\n\r\n"),
   6259     MockRead("The host does not exist"),
   6260     MockRead(SYNCHRONOUS, OK),
   6261   };
   6262 
   6263   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6264                                 data_writes, arraysize(data_writes));
   6265   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6266 
   6267   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6268   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6269 
   6270   TestCompletionCallback callback;
   6271 
   6272   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6273   scoped_ptr<HttpTransaction> trans(
   6274       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6275 
   6276   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6277   EXPECT_EQ(ERR_IO_PENDING, rv);
   6278 
   6279   rv = callback.WaitForResult();
   6280   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   6281 
   6282   // TODO(ttuttle): Anything else to check here?
   6283 }
   6284 
   6285 // Test that a SPDY proxy's response to a CONNECT request is filtered.
   6286 TEST_P(HttpNetworkTransactionTest,
   6287        ErrorResponseToHttpsConnectViaSpdyProxy) {
   6288   session_deps_.proxy_service.reset(
   6289      ProxyService::CreateFixed("https://proxy:70"));
   6290 
   6291   HttpRequestInfo request;
   6292   request.method = "GET";
   6293   request.url = GURL("https://www.google.com/");
   6294   request.load_flags = 0;
   6295 
   6296   scoped_ptr<SpdyFrame> conn(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6297                                                              LOWEST));
   6298   scoped_ptr<SpdyFrame> rst(
   6299       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6300   MockWrite data_writes[] = {
   6301     CreateMockWrite(*conn.get(), 0, SYNCHRONOUS),
   6302     CreateMockWrite(*rst.get(), 3, SYNCHRONOUS),
   6303   };
   6304 
   6305   static const char* const kExtraHeaders[] = {
   6306     "location",
   6307     "http://login.example.com/",
   6308   };
   6309   scoped_ptr<SpdyFrame> resp(
   6310       spdy_util_.ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
   6311                                  arraysize(kExtraHeaders)/2, 1));
   6312   scoped_ptr<SpdyFrame> body(
   6313       spdy_util_.ConstructSpdyBodyFrame(
   6314           1, "The host does not exist", 23, true));
   6315   MockRead data_reads[] = {
   6316     CreateMockRead(*resp.get(), 1, SYNCHRONOUS),
   6317     CreateMockRead(*body.get(), 2, SYNCHRONOUS),
   6318     MockRead(ASYNC, 0, 4),  // EOF
   6319   };
   6320 
   6321   DelayedSocketData data(
   6322       1,  // wait for one write to finish before reading.
   6323       data_reads, arraysize(data_reads),
   6324       data_writes, arraysize(data_writes));
   6325   SSLSocketDataProvider proxy_ssl(ASYNC, OK);  // SSL to the proxy
   6326   proxy_ssl.SetNextProto(GetParam());
   6327 
   6328   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6329   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy_ssl);
   6330 
   6331   TestCompletionCallback callback;
   6332 
   6333   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6334   scoped_ptr<HttpTransaction> trans(
   6335       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6336 
   6337   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6338   EXPECT_EQ(ERR_IO_PENDING, rv);
   6339 
   6340   rv = callback.WaitForResult();
   6341   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   6342 
   6343   // TODO(ttuttle): Anything else to check here?
   6344 }
   6345 
   6346 // Test the request-challenge-retry sequence for basic auth, through
   6347 // a SPDY proxy over a single SPDY session.
   6348 TEST_P(HttpNetworkTransactionTest, BasicAuthSpdyProxy) {
   6349   HttpRequestInfo request;
   6350   request.method = "GET";
   6351   request.url = GURL("https://www.google.com/");
   6352   // when the no authentication data flag is set.
   6353   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   6354 
   6355   // Configure against https proxy server "myproxy:70".
   6356   session_deps_.proxy_service.reset(
   6357       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   6358   CapturingBoundNetLog log;
   6359   session_deps_.net_log = log.bound().net_log();
   6360   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6361 
   6362   // Since we have proxy, should try to establish tunnel.
   6363   scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(NULL, 0, 1,
   6364                                                             LOWEST));
   6365   scoped_ptr<SpdyFrame> rst(
   6366       spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL));
   6367 
   6368   // After calling trans->RestartWithAuth(), this is the request we should
   6369   // be issuing -- the final header line contains the credentials.
   6370   const char* const kAuthCredentials[] = {
   6371       "proxy-authorization", "Basic Zm9vOmJhcg==",
   6372   };
   6373   scoped_ptr<SpdyFrame> connect2(spdy_util_.ConstructSpdyConnect(
   6374       kAuthCredentials, arraysize(kAuthCredentials) / 2, 3, LOWEST));
   6375   // fetch https://www.google.com/ via HTTP
   6376   const char get[] = "GET / HTTP/1.1\r\n"
   6377     "Host: www.google.com\r\n"
   6378     "Connection: keep-alive\r\n\r\n";
   6379   scoped_ptr<SpdyFrame> wrapped_get(
   6380       spdy_util_.ConstructSpdyBodyFrame(3, get, strlen(get), false));
   6381 
   6382   MockWrite spdy_writes[] = {
   6383     CreateMockWrite(*req, 1, ASYNC),
   6384     CreateMockWrite(*rst, 4, ASYNC),
   6385     CreateMockWrite(*connect2, 5),
   6386     CreateMockWrite(*wrapped_get, 8),
   6387   };
   6388 
   6389   // The proxy responds to the connect with a 407, using a persistent
   6390   // connection.
   6391   const char* const kAuthChallenge[] = {
   6392     spdy_util_.GetStatusKey(), "407 Proxy Authentication Required",
   6393     spdy_util_.GetVersionKey(), "HTTP/1.1",
   6394     "proxy-authenticate", "Basic realm=\"MyRealm1\"",
   6395   };
   6396 
   6397   scoped_ptr<SpdyFrame> conn_auth_resp(
   6398       spdy_util_.ConstructSpdyControlFrame(NULL,
   6399                                            0,
   6400                                            false,
   6401                                            1,
   6402                                            LOWEST,
   6403                                            SYN_REPLY,
   6404                                            CONTROL_FLAG_NONE,
   6405                                            kAuthChallenge,
   6406                                            arraysize(kAuthChallenge),
   6407                                            0));
   6408 
   6409   scoped_ptr<SpdyFrame> conn_resp(
   6410       spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3));
   6411   const char resp[] = "HTTP/1.1 200 OK\r\n"
   6412       "Content-Length: 5\r\n\r\n";
   6413 
   6414   scoped_ptr<SpdyFrame> wrapped_get_resp(
   6415       spdy_util_.ConstructSpdyBodyFrame(3, resp, strlen(resp), false));
   6416   scoped_ptr<SpdyFrame> wrapped_body(
   6417       spdy_util_.ConstructSpdyBodyFrame(3, "hello", 5, false));
   6418   MockRead spdy_reads[] = {
   6419     CreateMockRead(*conn_auth_resp, 2, ASYNC),
   6420     CreateMockRead(*conn_resp, 6, ASYNC),
   6421     CreateMockRead(*wrapped_get_resp, 9, ASYNC),
   6422     CreateMockRead(*wrapped_body, 10, ASYNC),
   6423     MockRead(ASYNC, OK, 11),  // EOF.  May or may not be read.
   6424   };
   6425 
   6426   OrderedSocketData spdy_data(
   6427       spdy_reads, arraysize(spdy_reads),
   6428       spdy_writes, arraysize(spdy_writes));
   6429   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6430   // Negotiate SPDY to the proxy
   6431   SSLSocketDataProvider proxy(ASYNC, OK);
   6432   proxy.SetNextProto(GetParam());
   6433   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6434   // Vanilla SSL to the server
   6435   SSLSocketDataProvider server(ASYNC, OK);
   6436   session_deps_.socket_factory->AddSSLSocketDataProvider(&server);
   6437 
   6438   TestCompletionCallback callback1;
   6439 
   6440   scoped_ptr<HttpTransaction> trans(
   6441       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6442 
   6443   int rv = trans->Start(&request, callback1.callback(), log.bound());
   6444   EXPECT_EQ(ERR_IO_PENDING, rv);
   6445 
   6446   rv = callback1.WaitForResult();
   6447   EXPECT_EQ(OK, rv);
   6448   net::CapturingNetLog::CapturedEntryList entries;
   6449   log.GetEntries(&entries);
   6450   size_t pos = ExpectLogContainsSomewhere(
   6451       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   6452       NetLog::PHASE_NONE);
   6453   ExpectLogContainsSomewhere(
   6454       entries, pos,
   6455       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   6456       NetLog::PHASE_NONE);
   6457 
   6458   const HttpResponseInfo* response = trans->GetResponseInfo();
   6459   ASSERT_TRUE(response != NULL);
   6460   ASSERT_FALSE(response->headers.get() == NULL);
   6461   EXPECT_EQ(407, response->headers->response_code());
   6462   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6463   EXPECT_TRUE(response->auth_challenge.get() != NULL);
   6464   EXPECT_TRUE(CheckBasicProxyAuth(response->auth_challenge.get()));
   6465 
   6466   TestCompletionCallback callback2;
   6467 
   6468   rv = trans->RestartWithAuth(AuthCredentials(kFoo, kBar),
   6469                               callback2.callback());
   6470   EXPECT_EQ(ERR_IO_PENDING, rv);
   6471 
   6472   rv = callback2.WaitForResult();
   6473   EXPECT_EQ(OK, rv);
   6474 
   6475   response = trans->GetResponseInfo();
   6476   ASSERT_TRUE(response != NULL);
   6477 
   6478   EXPECT_TRUE(response->headers->IsKeepAlive());
   6479   EXPECT_EQ(200, response->headers->response_code());
   6480   EXPECT_EQ(5, response->headers->GetContentLength());
   6481   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6482 
   6483   // The password prompt info should not be set.
   6484   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6485 
   6486   LoadTimingInfo load_timing_info;
   6487   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6488   TestLoadTimingNotReusedWithPac(load_timing_info,
   6489                                  CONNECT_TIMING_HAS_SSL_TIMES);
   6490 
   6491   trans.reset();
   6492   session->CloseAllConnections();
   6493 }
   6494 
   6495 // Test that an explicitly trusted SPDY proxy can push a resource from an
   6496 // origin that is different from that of its associated resource.
   6497 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPush) {
   6498   HttpRequestInfo request;
   6499   HttpRequestInfo push_request;
   6500 
   6501   request.method = "GET";
   6502   request.url = GURL("http://www.google.com/");
   6503   push_request.method = "GET";
   6504   push_request.url = GURL("http://www.another-origin.com/foo.dat");
   6505 
   6506   // Configure against https proxy server "myproxy:70".
   6507   session_deps_.proxy_service.reset(
   6508       ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"));
   6509   CapturingBoundNetLog log;
   6510   session_deps_.net_log = log.bound().net_log();
   6511 
   6512   // Enable cross-origin push.
   6513   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6514 
   6515   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6516 
   6517   scoped_ptr<SpdyFrame> stream1_syn(
   6518       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6519 
   6520   MockWrite spdy_writes[] = {
   6521     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6522   };
   6523 
   6524   scoped_ptr<SpdyFrame>
   6525       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6526 
   6527   scoped_ptr<SpdyFrame>
   6528       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6529 
   6530   scoped_ptr<SpdyFrame>
   6531       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6532                                     0,
   6533                                     2,
   6534                                     1,
   6535                                     "http://www.another-origin.com/foo.dat"));
   6536   const char kPushedData[] = "pushed";
   6537   scoped_ptr<SpdyFrame> stream2_body(
   6538       spdy_util_.ConstructSpdyBodyFrame(
   6539           2, kPushedData, strlen(kPushedData), true));
   6540 
   6541   MockRead spdy_reads[] = {
   6542     CreateMockRead(*stream1_reply, 2, ASYNC),
   6543     CreateMockRead(*stream2_syn, 3, ASYNC),
   6544     CreateMockRead(*stream1_body, 4, ASYNC),
   6545     CreateMockRead(*stream2_body, 5, ASYNC),
   6546     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6547   };
   6548 
   6549   OrderedSocketData spdy_data(
   6550       spdy_reads, arraysize(spdy_reads),
   6551       spdy_writes, arraysize(spdy_writes));
   6552   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6553   // Negotiate SPDY to the proxy
   6554   SSLSocketDataProvider proxy(ASYNC, OK);
   6555   proxy.SetNextProto(GetParam());
   6556   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6557 
   6558   scoped_ptr<HttpTransaction> trans(
   6559       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6560   TestCompletionCallback callback;
   6561   int rv = trans->Start(&request, callback.callback(), log.bound());
   6562   EXPECT_EQ(ERR_IO_PENDING, rv);
   6563 
   6564   rv = callback.WaitForResult();
   6565   EXPECT_EQ(OK, rv);
   6566   const HttpResponseInfo* response = trans->GetResponseInfo();
   6567 
   6568   scoped_ptr<HttpTransaction> push_trans(
   6569       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6570   rv = push_trans->Start(&push_request, callback.callback(), log.bound());
   6571   EXPECT_EQ(ERR_IO_PENDING, rv);
   6572 
   6573   rv = callback.WaitForResult();
   6574   EXPECT_EQ(OK, rv);
   6575   const HttpResponseInfo* push_response = push_trans->GetResponseInfo();
   6576 
   6577   ASSERT_TRUE(response != NULL);
   6578   EXPECT_TRUE(response->headers->IsKeepAlive());
   6579 
   6580   EXPECT_EQ(200, response->headers->response_code());
   6581   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6582 
   6583   std::string response_data;
   6584   rv = ReadTransaction(trans.get(), &response_data);
   6585   EXPECT_EQ(OK, rv);
   6586   EXPECT_EQ("hello!", response_data);
   6587 
   6588   LoadTimingInfo load_timing_info;
   6589   EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info));
   6590   TestLoadTimingNotReusedWithPac(load_timing_info,
   6591                                  CONNECT_TIMING_HAS_CONNECT_TIMES_ONLY);
   6592 
   6593   // Verify the pushed stream.
   6594   EXPECT_TRUE(push_response->headers.get() != NULL);
   6595   EXPECT_EQ(200, push_response->headers->response_code());
   6596 
   6597   rv = ReadTransaction(push_trans.get(), &response_data);
   6598   EXPECT_EQ(OK, rv);
   6599   EXPECT_EQ("pushed", response_data);
   6600 
   6601   LoadTimingInfo push_load_timing_info;
   6602   EXPECT_TRUE(push_trans->GetLoadTimingInfo(&push_load_timing_info));
   6603   TestLoadTimingReusedWithPac(push_load_timing_info);
   6604   // The transactions should share a socket ID, despite being for different
   6605   // origins.
   6606   EXPECT_EQ(load_timing_info.socket_log_id,
   6607             push_load_timing_info.socket_log_id);
   6608 
   6609   trans.reset();
   6610   push_trans.reset();
   6611   session->CloseAllConnections();
   6612 }
   6613 
   6614 // Test that an explicitly trusted SPDY proxy cannot push HTTPS content.
   6615 TEST_P(HttpNetworkTransactionTest, CrossOriginProxyPushCorrectness) {
   6616   HttpRequestInfo request;
   6617 
   6618   request.method = "GET";
   6619   request.url = GURL("http://www.google.com/");
   6620 
   6621   // Configure against https proxy server "myproxy:70".
   6622   session_deps_.proxy_service.reset(
   6623       ProxyService::CreateFixed("https://myproxy:70"));
   6624   CapturingBoundNetLog log;
   6625   session_deps_.net_log = log.bound().net_log();
   6626 
   6627   // Enable cross-origin push.
   6628   session_deps_.trusted_spdy_proxy = "myproxy:70";
   6629 
   6630   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6631 
   6632   scoped_ptr<SpdyFrame> stream1_syn(
   6633       spdy_util_.ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   6634 
   6635   scoped_ptr<SpdyFrame> push_rst(
   6636       spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM));
   6637 
   6638   MockWrite spdy_writes[] = {
   6639     CreateMockWrite(*stream1_syn, 1, ASYNC),
   6640     CreateMockWrite(*push_rst, 4),
   6641   };
   6642 
   6643   scoped_ptr<SpdyFrame>
   6644       stream1_reply(spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1));
   6645 
   6646   scoped_ptr<SpdyFrame>
   6647       stream1_body(spdy_util_.ConstructSpdyBodyFrame(1, true));
   6648 
   6649   scoped_ptr<SpdyFrame>
   6650       stream2_syn(spdy_util_.ConstructSpdyPush(NULL,
   6651                                     0,
   6652                                     2,
   6653                                     1,
   6654                                     "https://www.another-origin.com/foo.dat"));
   6655 
   6656   MockRead spdy_reads[] = {
   6657     CreateMockRead(*stream1_reply, 2, ASYNC),
   6658     CreateMockRead(*stream2_syn, 3, ASYNC),
   6659     CreateMockRead(*stream1_body, 5, ASYNC),
   6660     MockRead(ASYNC, ERR_IO_PENDING, 6),  // Force a pause
   6661   };
   6662 
   6663   OrderedSocketData spdy_data(
   6664       spdy_reads, arraysize(spdy_reads),
   6665       spdy_writes, arraysize(spdy_writes));
   6666   session_deps_.socket_factory->AddSocketDataProvider(&spdy_data);
   6667   // Negotiate SPDY to the proxy
   6668   SSLSocketDataProvider proxy(ASYNC, OK);
   6669   proxy.SetNextProto(GetParam());
   6670   session_deps_.socket_factory->AddSSLSocketDataProvider(&proxy);
   6671 
   6672   scoped_ptr<HttpTransaction> trans(
   6673       new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
   6674   TestCompletionCallback callback;
   6675   int rv = trans->Start(&request, callback.callback(), log.bound());
   6676   EXPECT_EQ(ERR_IO_PENDING, rv);
   6677 
   6678   rv = callback.WaitForResult();
   6679   EXPECT_EQ(OK, rv);
   6680   const HttpResponseInfo* response = trans->GetResponseInfo();
   6681 
   6682   ASSERT_TRUE(response != NULL);
   6683   EXPECT_TRUE(response->headers->IsKeepAlive());
   6684 
   6685   EXPECT_EQ(200, response->headers->response_code());
   6686   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   6687 
   6688   std::string response_data;
   6689   rv = ReadTransaction(trans.get(), &response_data);
   6690   EXPECT_EQ(OK, rv);
   6691   EXPECT_EQ("hello!", response_data);
   6692 
   6693   trans.reset();
   6694   session->CloseAllConnections();
   6695 }
   6696 
   6697 // Test HTTPS connections to a site with a bad certificate, going through an
   6698 // HTTPS proxy
   6699 TEST_P(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
   6700   session_deps_.proxy_service.reset(ProxyService::CreateFixed(
   6701       "https://proxy:70"));
   6702 
   6703   HttpRequestInfo request;
   6704   request.method = "GET";
   6705   request.url = GURL("https://www.google.com/");
   6706   request.load_flags = 0;
   6707 
   6708   // Attempt to fetch the URL from a server with a bad cert
   6709   MockWrite bad_cert_writes[] = {
   6710     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6711               "Host: www.google.com\r\n"
   6712               "Proxy-Connection: keep-alive\r\n\r\n"),
   6713   };
   6714 
   6715   MockRead bad_cert_reads[] = {
   6716     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6717     MockRead(SYNCHRONOUS, OK)
   6718   };
   6719 
   6720   // Attempt to fetch the URL with a good cert
   6721   MockWrite good_data_writes[] = {
   6722     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6723               "Host: www.google.com\r\n"
   6724               "Proxy-Connection: keep-alive\r\n\r\n"),
   6725     MockWrite("GET / HTTP/1.1\r\n"
   6726               "Host: www.google.com\r\n"
   6727               "Connection: keep-alive\r\n\r\n"),
   6728   };
   6729 
   6730   MockRead good_cert_reads[] = {
   6731     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   6732     MockRead("HTTP/1.0 200 OK\r\n"),
   6733     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6734     MockRead("Content-Length: 100\r\n\r\n"),
   6735     MockRead(SYNCHRONOUS, OK),
   6736   };
   6737 
   6738   StaticSocketDataProvider ssl_bad_certificate(
   6739       bad_cert_reads, arraysize(bad_cert_reads),
   6740       bad_cert_writes, arraysize(bad_cert_writes));
   6741   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
   6742                                 good_data_writes, arraysize(good_data_writes));
   6743   SSLSocketDataProvider ssl_bad(ASYNC, ERR_CERT_AUTHORITY_INVALID);
   6744   SSLSocketDataProvider ssl(ASYNC, OK);
   6745 
   6746   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
   6747   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6748   session_deps_.socket_factory->AddSocketDataProvider(&ssl_bad_certificate);
   6749   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_bad);
   6750 
   6751   // SSL to the proxy, then CONNECT request, then valid SSL certificate
   6752   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6753   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6754   session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
   6755 
   6756   TestCompletionCallback callback;
   6757 
   6758   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6759   scoped_ptr<HttpTransaction> trans(
   6760       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6761 
   6762   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6763   EXPECT_EQ(ERR_IO_PENDING, rv);
   6764 
   6765   rv = callback.WaitForResult();
   6766   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   6767 
   6768   rv = trans->RestartIgnoringLastError(callback.callback());
   6769   EXPECT_EQ(ERR_IO_PENDING, rv);
   6770 
   6771   rv = callback.WaitForResult();
   6772   EXPECT_EQ(OK, rv);
   6773 
   6774   const HttpResponseInfo* response = trans->GetResponseInfo();
   6775 
   6776   ASSERT_TRUE(response != NULL);
   6777   EXPECT_EQ(100, response->headers->GetContentLength());
   6778 }
   6779 
   6780 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   6781   HttpRequestInfo request;
   6782   request.method = "GET";
   6783   request.url = GURL("http://www.google.com/");
   6784   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6785                                   "Chromium Ultra Awesome X Edition");
   6786 
   6787   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6788   scoped_ptr<HttpTransaction> trans(
   6789       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6790 
   6791   MockWrite data_writes[] = {
   6792     MockWrite("GET / HTTP/1.1\r\n"
   6793               "Host: www.google.com\r\n"
   6794               "Connection: keep-alive\r\n"
   6795               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6796   };
   6797 
   6798   // Lastly, the server responds with the actual content.
   6799   MockRead data_reads[] = {
   6800     MockRead("HTTP/1.0 200 OK\r\n"),
   6801     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6802     MockRead("Content-Length: 100\r\n\r\n"),
   6803     MockRead(SYNCHRONOUS, OK),
   6804   };
   6805 
   6806   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6807                                 data_writes, arraysize(data_writes));
   6808   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6809 
   6810   TestCompletionCallback callback;
   6811 
   6812   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6813   EXPECT_EQ(ERR_IO_PENDING, rv);
   6814 
   6815   rv = callback.WaitForResult();
   6816   EXPECT_EQ(OK, rv);
   6817 }
   6818 
   6819 TEST_P(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   6820   HttpRequestInfo request;
   6821   request.method = "GET";
   6822   request.url = GURL("https://www.google.com/");
   6823   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   6824                                   "Chromium Ultra Awesome X Edition");
   6825 
   6826   session_deps_.proxy_service.reset(ProxyService::CreateFixed("myproxy:70"));
   6827   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6828   scoped_ptr<HttpTransaction> trans(
   6829       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6830 
   6831   MockWrite data_writes[] = {
   6832     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6833               "Host: www.google.com\r\n"
   6834               "Proxy-Connection: keep-alive\r\n"
   6835               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   6836   };
   6837   MockRead data_reads[] = {
   6838     // Return an error, so the transaction stops here (this test isn't
   6839     // interested in the rest).
   6840     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   6841     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   6842     MockRead("Proxy-Connection: close\r\n\r\n"),
   6843   };
   6844 
   6845   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6846                                 data_writes, arraysize(data_writes));
   6847   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6848 
   6849   TestCompletionCallback callback;
   6850 
   6851   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6852   EXPECT_EQ(ERR_IO_PENDING, rv);
   6853 
   6854   rv = callback.WaitForResult();
   6855   EXPECT_EQ(OK, rv);
   6856 }
   6857 
   6858 TEST_P(HttpNetworkTransactionTest, BuildRequest_Referer) {
   6859   HttpRequestInfo request;
   6860   request.method = "GET";
   6861   request.url = GURL("http://www.google.com/");
   6862   request.load_flags = 0;
   6863   request.extra_headers.SetHeader(HttpRequestHeaders::kReferer,
   6864                                   "http://the.previous.site.com/");
   6865 
   6866   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6867   scoped_ptr<HttpTransaction> trans(
   6868       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6869 
   6870   MockWrite data_writes[] = {
   6871     MockWrite("GET / HTTP/1.1\r\n"
   6872               "Host: www.google.com\r\n"
   6873               "Connection: keep-alive\r\n"
   6874               "Referer: http://the.previous.site.com/\r\n\r\n"),
   6875   };
   6876 
   6877   // Lastly, the server responds with the actual content.
   6878   MockRead data_reads[] = {
   6879     MockRead("HTTP/1.0 200 OK\r\n"),
   6880     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6881     MockRead("Content-Length: 100\r\n\r\n"),
   6882     MockRead(SYNCHRONOUS, OK),
   6883   };
   6884 
   6885   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6886                                 data_writes, arraysize(data_writes));
   6887   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6888 
   6889   TestCompletionCallback callback;
   6890 
   6891   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6892   EXPECT_EQ(ERR_IO_PENDING, rv);
   6893 
   6894   rv = callback.WaitForResult();
   6895   EXPECT_EQ(OK, rv);
   6896 }
   6897 
   6898 TEST_P(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   6899   HttpRequestInfo request;
   6900   request.method = "POST";
   6901   request.url = GURL("http://www.google.com/");
   6902 
   6903   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6904   scoped_ptr<HttpTransaction> trans(
   6905       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6906 
   6907   MockWrite data_writes[] = {
   6908     MockWrite("POST / HTTP/1.1\r\n"
   6909               "Host: www.google.com\r\n"
   6910               "Connection: keep-alive\r\n"
   6911               "Content-Length: 0\r\n\r\n"),
   6912   };
   6913 
   6914   // Lastly, the server responds with the actual content.
   6915   MockRead data_reads[] = {
   6916     MockRead("HTTP/1.0 200 OK\r\n"),
   6917     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6918     MockRead("Content-Length: 100\r\n\r\n"),
   6919     MockRead(SYNCHRONOUS, OK),
   6920   };
   6921 
   6922   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6923                                 data_writes, arraysize(data_writes));
   6924   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6925 
   6926   TestCompletionCallback callback;
   6927 
   6928   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6929   EXPECT_EQ(ERR_IO_PENDING, rv);
   6930 
   6931   rv = callback.WaitForResult();
   6932   EXPECT_EQ(OK, rv);
   6933 }
   6934 
   6935 TEST_P(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   6936   HttpRequestInfo request;
   6937   request.method = "PUT";
   6938   request.url = GURL("http://www.google.com/");
   6939 
   6940   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6941   scoped_ptr<HttpTransaction> trans(
   6942       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6943 
   6944   MockWrite data_writes[] = {
   6945     MockWrite("PUT / HTTP/1.1\r\n"
   6946               "Host: www.google.com\r\n"
   6947               "Connection: keep-alive\r\n"
   6948               "Content-Length: 0\r\n\r\n"),
   6949   };
   6950 
   6951   // Lastly, the server responds with the actual content.
   6952   MockRead data_reads[] = {
   6953     MockRead("HTTP/1.0 200 OK\r\n"),
   6954     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6955     MockRead("Content-Length: 100\r\n\r\n"),
   6956     MockRead(SYNCHRONOUS, OK),
   6957   };
   6958 
   6959   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6960                                 data_writes, arraysize(data_writes));
   6961   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6962 
   6963   TestCompletionCallback callback;
   6964 
   6965   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   6966   EXPECT_EQ(ERR_IO_PENDING, rv);
   6967 
   6968   rv = callback.WaitForResult();
   6969   EXPECT_EQ(OK, rv);
   6970 }
   6971 
   6972 TEST_P(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   6973   HttpRequestInfo request;
   6974   request.method = "HEAD";
   6975   request.url = GURL("http://www.google.com/");
   6976 
   6977   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   6978   scoped_ptr<HttpTransaction> trans(
   6979       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   6980 
   6981   MockWrite data_writes[] = {
   6982     MockWrite("HEAD / HTTP/1.1\r\n"
   6983               "Host: www.google.com\r\n"
   6984               "Connection: keep-alive\r\n"
   6985               "Content-Length: 0\r\n\r\n"),
   6986   };
   6987 
   6988   // Lastly, the server responds with the actual content.
   6989   MockRead data_reads[] = {
   6990     MockRead("HTTP/1.0 200 OK\r\n"),
   6991     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   6992     MockRead("Content-Length: 100\r\n\r\n"),
   6993     MockRead(SYNCHRONOUS, OK),
   6994   };
   6995 
   6996   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   6997                                 data_writes, arraysize(data_writes));
   6998   session_deps_.socket_factory->AddSocketDataProvider(&data);
   6999 
   7000   TestCompletionCallback callback;
   7001 
   7002   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7003   EXPECT_EQ(ERR_IO_PENDING, rv);
   7004 
   7005   rv = callback.WaitForResult();
   7006   EXPECT_EQ(OK, rv);
   7007 }
   7008 
   7009 TEST_P(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   7010   HttpRequestInfo request;
   7011   request.method = "GET";
   7012   request.url = GURL("http://www.google.com/");
   7013   request.load_flags = LOAD_BYPASS_CACHE;
   7014 
   7015   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7016   scoped_ptr<HttpTransaction> trans(
   7017       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7018 
   7019   MockWrite data_writes[] = {
   7020     MockWrite("GET / HTTP/1.1\r\n"
   7021               "Host: www.google.com\r\n"
   7022               "Connection: keep-alive\r\n"
   7023               "Pragma: no-cache\r\n"
   7024               "Cache-Control: no-cache\r\n\r\n"),
   7025   };
   7026 
   7027   // Lastly, the server responds with the actual content.
   7028   MockRead data_reads[] = {
   7029     MockRead("HTTP/1.0 200 OK\r\n"),
   7030     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7031     MockRead("Content-Length: 100\r\n\r\n"),
   7032     MockRead(SYNCHRONOUS, OK),
   7033   };
   7034 
   7035   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7036                                 data_writes, arraysize(data_writes));
   7037   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7038 
   7039   TestCompletionCallback callback;
   7040 
   7041   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7042   EXPECT_EQ(ERR_IO_PENDING, rv);
   7043 
   7044   rv = callback.WaitForResult();
   7045   EXPECT_EQ(OK, rv);
   7046 }
   7047 
   7048 TEST_P(HttpNetworkTransactionTest,
   7049        BuildRequest_CacheControlValidateCache) {
   7050   HttpRequestInfo request;
   7051   request.method = "GET";
   7052   request.url = GURL("http://www.google.com/");
   7053   request.load_flags = LOAD_VALIDATE_CACHE;
   7054 
   7055   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7056   scoped_ptr<HttpTransaction> trans(
   7057       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7058 
   7059   MockWrite data_writes[] = {
   7060     MockWrite("GET / HTTP/1.1\r\n"
   7061               "Host: www.google.com\r\n"
   7062               "Connection: keep-alive\r\n"
   7063               "Cache-Control: max-age=0\r\n\r\n"),
   7064   };
   7065 
   7066   // Lastly, the server responds with the actual content.
   7067   MockRead data_reads[] = {
   7068     MockRead("HTTP/1.0 200 OK\r\n"),
   7069     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7070     MockRead("Content-Length: 100\r\n\r\n"),
   7071     MockRead(SYNCHRONOUS, OK),
   7072   };
   7073 
   7074   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7075                                 data_writes, arraysize(data_writes));
   7076   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7077 
   7078   TestCompletionCallback callback;
   7079 
   7080   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7081   EXPECT_EQ(ERR_IO_PENDING, rv);
   7082 
   7083   rv = callback.WaitForResult();
   7084   EXPECT_EQ(OK, rv);
   7085 }
   7086 
   7087 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   7088   HttpRequestInfo request;
   7089   request.method = "GET";
   7090   request.url = GURL("http://www.google.com/");
   7091   request.extra_headers.SetHeader("FooHeader", "Bar");
   7092 
   7093   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7094   scoped_ptr<HttpTransaction> trans(
   7095       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7096 
   7097   MockWrite data_writes[] = {
   7098     MockWrite("GET / HTTP/1.1\r\n"
   7099               "Host: www.google.com\r\n"
   7100               "Connection: keep-alive\r\n"
   7101               "FooHeader: Bar\r\n\r\n"),
   7102   };
   7103 
   7104   // Lastly, the server responds with the actual content.
   7105   MockRead data_reads[] = {
   7106     MockRead("HTTP/1.0 200 OK\r\n"),
   7107     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   7108     MockRead("Content-Length: 100\r\n\r\n"),
   7109     MockRead(SYNCHRONOUS, OK),
   7110   };
   7111 
   7112   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7113                                 data_writes, arraysize(data_writes));
   7114   session_deps_.socket_factory->AddSocketDataProvider(&data);
   7115 
   7116   TestCompletionCallback callback;
   7117 
   7118   int rv = trans->Start(&request, callback.callback(), BoundNetLog());
   7119   EXPECT_EQ(ERR_IO_PENDING, rv);
   7120 
   7121   rv = callback.WaitForResult();
   7122   EXPECT_EQ(OK, rv);
   7123 }
   7124 
   7125 TEST_P(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   7126   HttpRequestInfo request;
   7127   request.method = "GET";
   7128   request.url = GURL("http://www.google.com/");
   7129   request.extra_headers.SetHeader("referer", "www.foo.com");
   7130   request.extra_headers.SetHeader("hEllo", "Kitty");
   7131   request.extra_headers.SetHeader("FoO", "bar");
   7132 
   7133   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
   7134   scoped_ptr<HttpTransaction> trans(
   7135       new HttpNetworkTransaction(DEFAULT_PRIORITY, session));
   7136