Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2011 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 <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/compiler_specific.h"
     12 #include "base/file_path.h"
     13 #include "base/file_util.h"
     14 #include "base/memory/scoped_ptr.h"
     15 #include "base/utf_string_conversions.h"
     16 #include "net/base/auth.h"
     17 #include "net/base/capturing_net_log.h"
     18 #include "net/base/completion_callback.h"
     19 #include "net/base/mock_host_resolver.h"
     20 #include "net/base/net_log.h"
     21 #include "net/base/net_log_unittest.h"
     22 #include "net/base/request_priority.h"
     23 #include "net/base/ssl_cert_request_info.h"
     24 #include "net/base/ssl_config_service_defaults.h"
     25 #include "net/base/ssl_info.h"
     26 #include "net/base/test_completion_callback.h"
     27 #include "net/base/upload_data.h"
     28 #include "net/http/http_auth_handler_digest.h"
     29 #include "net/http/http_auth_handler_mock.h"
     30 #include "net/http/http_auth_handler_ntlm.h"
     31 #include "net/http/http_basic_stream.h"
     32 #include "net/http/http_net_log_params.h"
     33 #include "net/http/http_network_session.h"
     34 #include "net/http/http_network_session_peer.h"
     35 #include "net/http/http_stream.h"
     36 #include "net/http/http_stream_factory.h"
     37 #include "net/http/http_transaction_unittest.h"
     38 #include "net/proxy/proxy_config_service_fixed.h"
     39 #include "net/proxy/proxy_resolver.h"
     40 #include "net/proxy/proxy_service.h"
     41 #include "net/socket/client_socket_factory.h"
     42 #include "net/socket/socket_test_util.h"
     43 #include "net/socket/ssl_client_socket.h"
     44 #include "net/spdy/spdy_framer.h"
     45 #include "net/spdy/spdy_session.h"
     46 #include "net/spdy/spdy_session_pool.h"
     47 #include "net/spdy/spdy_test_util.h"
     48 #include "testing/gtest/include/gtest/gtest.h"
     49 #include "testing/platform_test.h"
     50 
     51 //-----------------------------------------------------------------------------
     52 
     53 namespace {
     54 
     55 const string16 kBar(ASCIIToUTF16("bar"));
     56 const string16 kBar2(ASCIIToUTF16("bar2"));
     57 const string16 kBar3(ASCIIToUTF16("bar3"));
     58 const string16 kBaz(ASCIIToUTF16("baz"));
     59 const string16 kFirst(ASCIIToUTF16("first"));
     60 const string16 kFoo(ASCIIToUTF16("foo"));
     61 const string16 kFoo2(ASCIIToUTF16("foo2"));
     62 const string16 kFoo3(ASCIIToUTF16("foo3"));
     63 const string16 kFou(ASCIIToUTF16("fou"));
     64 const string16 kSecond(ASCIIToUTF16("second"));
     65 const string16 kTestingNTLM(ASCIIToUTF16("testing-ntlm"));
     66 const string16 kWrongPassword(ASCIIToUTF16("wrongpassword"));
     67 
     68 }  // namespace
     69 
     70 namespace net {
     71 
     72 // Helper to manage the lifetimes of the dependencies for a
     73 // HttpNetworkTransaction.
     74 struct SessionDependencies {
     75   // Default set of dependencies -- "null" proxy service.
     76   SessionDependencies()
     77       : host_resolver(new MockHostResolver),
     78         cert_verifier(new CertVerifier),
     79         proxy_service(ProxyService::CreateDirect()),
     80         ssl_config_service(new SSLConfigServiceDefaults),
     81         http_auth_handler_factory(
     82             HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
     83         net_log(NULL) {}
     84 
     85   // Custom proxy service dependency.
     86   explicit SessionDependencies(ProxyService* proxy_service)
     87       : host_resolver(new MockHostResolver),
     88         cert_verifier(new CertVerifier),
     89         proxy_service(proxy_service),
     90         ssl_config_service(new SSLConfigServiceDefaults),
     91         http_auth_handler_factory(
     92             HttpAuthHandlerFactory::CreateDefault(host_resolver.get())),
     93         net_log(NULL) {}
     94 
     95   scoped_ptr<MockHostResolverBase> host_resolver;
     96   scoped_ptr<CertVerifier> cert_verifier;
     97   scoped_refptr<ProxyService> proxy_service;
     98   scoped_refptr<SSLConfigService> ssl_config_service;
     99   MockClientSocketFactory socket_factory;
    100   scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
    101   NetLog* net_log;
    102 };
    103 
    104 HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
    105   net::HttpNetworkSession::Params params;
    106   params.client_socket_factory = &session_deps->socket_factory;
    107   params.host_resolver = session_deps->host_resolver.get();
    108   params.cert_verifier = session_deps->cert_verifier.get();
    109   params.proxy_service = session_deps->proxy_service;
    110   params.ssl_config_service = session_deps->ssl_config_service;
    111   params.http_auth_handler_factory =
    112       session_deps->http_auth_handler_factory.get();
    113   params.net_log = session_deps->net_log;
    114   return new HttpNetworkSession(params);
    115 }
    116 
    117 class HttpNetworkTransactionTest : public PlatformTest {
    118  public:
    119   virtual void SetUp() {
    120     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    121     MessageLoop::current()->RunAllPending();
    122     spdy::SpdyFramer::set_enable_compression_default(false);
    123   }
    124 
    125   virtual void TearDown() {
    126     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    127     MessageLoop::current()->RunAllPending();
    128     spdy::SpdyFramer::set_enable_compression_default(true);
    129     // Empty the current queue.
    130     MessageLoop::current()->RunAllPending();
    131     PlatformTest::TearDown();
    132     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    133     MessageLoop::current()->RunAllPending();
    134   }
    135 
    136  protected:
    137   void KeepAliveConnectionResendRequestTest(const MockRead& read_failure);
    138 
    139   struct SimpleGetHelperResult {
    140     int rv;
    141     std::string status_line;
    142     std::string response_data;
    143   };
    144 
    145   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[],
    146                                         size_t reads_count) {
    147     SimpleGetHelperResult out;
    148 
    149     HttpRequestInfo request;
    150     request.method = "GET";
    151     request.url = GURL("http://www.google.com/");
    152     request.load_flags = 0;
    153 
    154     SessionDependencies session_deps;
    155     scoped_ptr<HttpTransaction> trans(
    156         new HttpNetworkTransaction(CreateSession(&session_deps)));
    157 
    158     StaticSocketDataProvider data(data_reads, reads_count, NULL, 0);
    159     session_deps.socket_factory.AddSocketDataProvider(&data);
    160 
    161     TestCompletionCallback callback;
    162 
    163     CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
    164     EXPECT_TRUE(log.bound().IsLoggingAllEvents());
    165     int rv = trans->Start(&request, &callback, log.bound());
    166     EXPECT_EQ(ERR_IO_PENDING, rv);
    167 
    168     out.rv = callback.WaitForResult();
    169     if (out.rv != OK)
    170       return out;
    171 
    172     const HttpResponseInfo* response = trans->GetResponseInfo();
    173     EXPECT_TRUE(response != NULL);
    174 
    175     EXPECT_TRUE(response->headers != NULL);
    176     out.status_line = response->headers->GetStatusLine();
    177 
    178     EXPECT_EQ("192.0.2.33", response->socket_address.host());
    179     EXPECT_EQ(0, response->socket_address.port());
    180 
    181     rv = ReadTransaction(trans.get(), &out.response_data);
    182     EXPECT_EQ(OK, rv);
    183 
    184     net::CapturingNetLog::EntryList entries;
    185     log.GetEntries(&entries);
    186     size_t pos = ExpectLogContainsSomewhere(
    187         entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_REQUEST_HEADERS,
    188         NetLog::PHASE_NONE);
    189     ExpectLogContainsSomewhere(
    190         entries, pos,
    191         NetLog::TYPE_HTTP_TRANSACTION_READ_RESPONSE_HEADERS,
    192         NetLog::PHASE_NONE);
    193 
    194     CapturingNetLog::Entry entry = entries[pos];
    195     NetLogHttpRequestParameter* request_params =
    196         static_cast<NetLogHttpRequestParameter*>(entry.extra_parameters.get());
    197     EXPECT_EQ("GET / HTTP/1.1\r\n", request_params->GetLine());
    198     EXPECT_EQ("Host: www.google.com\r\n"
    199               "Connection: keep-alive\r\n\r\n",
    200               request_params->GetHeaders().ToString());
    201 
    202     return out;
    203   }
    204 
    205   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    206                                              int expected_status);
    207 
    208   void ConnectStatusHelper(const MockRead& status);
    209 };
    210 
    211 // Fill |str| with a long header list that consumes >= |size| bytes.
    212 void FillLargeHeadersString(std::string* str, int size) {
    213   const char* row =
    214       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    215   const int sizeof_row = strlen(row);
    216   const int num_rows = static_cast<int>(
    217       ceil(static_cast<float>(size) / sizeof_row));
    218   const int sizeof_data = num_rows * sizeof_row;
    219   DCHECK(sizeof_data >= size);
    220   str->reserve(sizeof_data);
    221 
    222   for (int i = 0; i < num_rows; ++i)
    223     str->append(row, sizeof_row);
    224 }
    225 
    226 // Alternative functions that eliminate randomness and dependency on the local
    227 // host name so that the generated NTLM messages are reproducible.
    228 void MockGenerateRandom1(uint8* output, size_t n) {
    229   static const uint8 bytes[] = {
    230     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    231   };
    232   static size_t current_byte = 0;
    233   for (size_t i = 0; i < n; ++i) {
    234     output[i] = bytes[current_byte++];
    235     current_byte %= arraysize(bytes);
    236   }
    237 }
    238 
    239 void MockGenerateRandom2(uint8* output, size_t n) {
    240   static const uint8 bytes[] = {
    241     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    242     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    243   };
    244   static size_t current_byte = 0;
    245   for (size_t i = 0; i < n; ++i) {
    246     output[i] = bytes[current_byte++];
    247     current_byte %= arraysize(bytes);
    248   }
    249 }
    250 
    251 std::string MockGetHostName() {
    252   return "WTC-WIN7";
    253 }
    254 
    255 template<typename ParentPool>
    256 class CaptureGroupNameSocketPool : public ParentPool {
    257  public:
    258   CaptureGroupNameSocketPool(HostResolver* host_resolver,
    259                              CertVerifier* cert_verifier);
    260 
    261   const std::string last_group_name_received() const {
    262     return last_group_name_;
    263   }
    264 
    265   virtual int RequestSocket(const std::string& group_name,
    266                             const void* socket_params,
    267                             RequestPriority priority,
    268                             ClientSocketHandle* handle,
    269                             CompletionCallback* callback,
    270                             const BoundNetLog& net_log) {
    271     last_group_name_ = group_name;
    272     return ERR_IO_PENDING;
    273   }
    274   virtual void CancelRequest(const std::string& group_name,
    275                              ClientSocketHandle* handle) {}
    276   virtual void ReleaseSocket(const std::string& group_name,
    277                              ClientSocket* socket,
    278                              int id) {}
    279   virtual void CloseIdleSockets() {}
    280   virtual int IdleSocketCount() const {
    281     return 0;
    282   }
    283   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    284     return 0;
    285   }
    286   virtual LoadState GetLoadState(const std::string& group_name,
    287                                  const ClientSocketHandle* handle) const {
    288     return LOAD_STATE_IDLE;
    289   }
    290   virtual base::TimeDelta ConnectionTimeout() const {
    291     return base::TimeDelta();
    292   }
    293 
    294  private:
    295   std::string last_group_name_;
    296 };
    297 
    298 typedef CaptureGroupNameSocketPool<TransportClientSocketPool>
    299 CaptureGroupNameTransportSocketPool;
    300 typedef CaptureGroupNameSocketPool<HttpProxyClientSocketPool>
    301 CaptureGroupNameHttpProxySocketPool;
    302 typedef CaptureGroupNameSocketPool<SOCKSClientSocketPool>
    303 CaptureGroupNameSOCKSSocketPool;
    304 typedef CaptureGroupNameSocketPool<SSLClientSocketPool>
    305 CaptureGroupNameSSLSocketPool;
    306 
    307 template<typename ParentPool>
    308 CaptureGroupNameSocketPool<ParentPool>::CaptureGroupNameSocketPool(
    309     HostResolver* host_resolver,
    310     CertVerifier* /* cert_verifier */)
    311     : ParentPool(0, 0, NULL, host_resolver, NULL, NULL) {}
    312 
    313 template<>
    314 CaptureGroupNameHttpProxySocketPool::CaptureGroupNameSocketPool(
    315     HostResolver* host_resolver,
    316     CertVerifier* /* cert_verifier */)
    317     : HttpProxyClientSocketPool(0, 0, NULL, host_resolver, NULL, NULL, NULL) {}
    318 
    319 template<>
    320 CaptureGroupNameSSLSocketPool::CaptureGroupNameSocketPool(
    321     HostResolver* host_resolver,
    322     CertVerifier* cert_verifier)
    323     : SSLClientSocketPool(0, 0, NULL, host_resolver, cert_verifier, NULL, NULL,
    324                           NULL, NULL, NULL, NULL, NULL, NULL, NULL) {}
    325 
    326 //-----------------------------------------------------------------------------
    327 
    328 // This is the expected list of advertised protocols from the browser's NPN
    329 // list.
    330 static const char kExpectedNPNString[] = "\x08http/1.1\x06spdy/2";
    331 
    332 // This is the expected return from a current server advertising SPDY.
    333 static const char kAlternateProtocolHttpHeader[] =
    334     "Alternate-Protocol: 443:npn-spdy/2\r\n\r\n";
    335 
    336 TEST_F(HttpNetworkTransactionTest, Basic) {
    337   SessionDependencies session_deps;
    338   scoped_ptr<HttpTransaction> trans(
    339       new HttpNetworkTransaction(CreateSession(&session_deps)));
    340 }
    341 
    342 TEST_F(HttpNetworkTransactionTest, SimpleGET) {
    343   MockRead data_reads[] = {
    344     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    345     MockRead("hello world"),
    346     MockRead(false, OK),
    347   };
    348   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    349                                               arraysize(data_reads));
    350   EXPECT_EQ(OK, out.rv);
    351   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    352   EXPECT_EQ("hello world", out.response_data);
    353 }
    354 
    355 // Response with no status line.
    356 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    357   MockRead data_reads[] = {
    358     MockRead("hello world"),
    359     MockRead(false, OK),
    360   };
    361   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    362                                               arraysize(data_reads));
    363   EXPECT_EQ(OK, out.rv);
    364   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    365   EXPECT_EQ("hello world", out.response_data);
    366 }
    367 
    368 // Allow up to 4 bytes of junk to precede status line.
    369 TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) {
    370   MockRead data_reads[] = {
    371     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    372     MockRead(false, OK),
    373   };
    374   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    375                                               arraysize(data_reads));
    376   EXPECT_EQ(OK, out.rv);
    377   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    378   EXPECT_EQ("DATA", out.response_data);
    379 }
    380 
    381 // Allow up to 4 bytes of junk to precede status line.
    382 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    383   MockRead data_reads[] = {
    384     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    385     MockRead(false, OK),
    386   };
    387   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    388                                               arraysize(data_reads));
    389   EXPECT_EQ(OK, out.rv);
    390   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    391   EXPECT_EQ("DATA", out.response_data);
    392 }
    393 
    394 // Beyond 4 bytes of slop and it should fail to find a status line.
    395 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    396   MockRead data_reads[] = {
    397     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    398     MockRead(false, OK),
    399   };
    400   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    401                                               arraysize(data_reads));
    402   EXPECT_EQ(OK, out.rv);
    403   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    404   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    405 }
    406 
    407 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    408 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    409   MockRead data_reads[] = {
    410     MockRead("\n"),
    411     MockRead("\n"),
    412     MockRead("Q"),
    413     MockRead("J"),
    414     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    415     MockRead(false, OK),
    416   };
    417   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    418                                               arraysize(data_reads));
    419   EXPECT_EQ(OK, out.rv);
    420   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    421   EXPECT_EQ("DATA", out.response_data);
    422 }
    423 
    424 // Close the connection before enough bytes to have a status line.
    425 TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
    426   MockRead data_reads[] = {
    427     MockRead("HTT"),
    428     MockRead(false, OK),
    429   };
    430   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    431                                               arraysize(data_reads));
    432   EXPECT_EQ(OK, out.rv);
    433   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    434   EXPECT_EQ("HTT", out.response_data);
    435 }
    436 
    437 // Simulate a 204 response, lacking a Content-Length header, sent over a
    438 // persistent connection.  The response should still terminate since a 204
    439 // cannot have a response body.
    440 TEST_F(HttpNetworkTransactionTest, StopsReading204) {
    441   MockRead data_reads[] = {
    442     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    443     MockRead("junk"),  // Should not be read!!
    444     MockRead(false, OK),
    445   };
    446   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    447                                               arraysize(data_reads));
    448   EXPECT_EQ(OK, out.rv);
    449   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    450   EXPECT_EQ("", out.response_data);
    451 }
    452 
    453 // A simple request using chunked encoding with some extra data after.
    454 // (Like might be seen in a pipelined response.)
    455 TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
    456   MockRead data_reads[] = {
    457     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    458     MockRead("5\r\nHello\r\n"),
    459     MockRead("1\r\n"),
    460     MockRead(" \r\n"),
    461     MockRead("5\r\nworld\r\n"),
    462     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    463     MockRead(false, OK),
    464   };
    465   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    466                                               arraysize(data_reads));
    467   EXPECT_EQ(OK, out.rv);
    468   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    469   EXPECT_EQ("Hello world", out.response_data);
    470 }
    471 
    472 // Next tests deal with http://crbug.com/56344.
    473 
    474 TEST_F(HttpNetworkTransactionTest,
    475        MultipleContentLengthHeadersNoTransferEncoding) {
    476   MockRead data_reads[] = {
    477     MockRead("HTTP/1.1 200 OK\r\n"),
    478     MockRead("Content-Length: 10\r\n"),
    479     MockRead("Content-Length: 5\r\n\r\n"),
    480   };
    481   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    482                                               arraysize(data_reads));
    483   EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    484 }
    485 
    486 TEST_F(HttpNetworkTransactionTest,
    487        DuplicateContentLengthHeadersNoTransferEncoding) {
    488   MockRead data_reads[] = {
    489     MockRead("HTTP/1.1 200 OK\r\n"),
    490     MockRead("Content-Length: 5\r\n"),
    491     MockRead("Content-Length: 5\r\n\r\n"),
    492     MockRead("Hello"),
    493   };
    494   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    495                                               arraysize(data_reads));
    496   EXPECT_EQ(OK, out.rv);
    497   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    498   EXPECT_EQ("Hello", out.response_data);
    499 }
    500 
    501 TEST_F(HttpNetworkTransactionTest,
    502        ComplexContentLengthHeadersNoTransferEncoding) {
    503   // More than 2 dupes.
    504   {
    505     MockRead data_reads[] = {
    506       MockRead("HTTP/1.1 200 OK\r\n"),
    507       MockRead("Content-Length: 5\r\n"),
    508       MockRead("Content-Length: 5\r\n"),
    509       MockRead("Content-Length: 5\r\n\r\n"),
    510       MockRead("Hello"),
    511     };
    512     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    513                                                 arraysize(data_reads));
    514     EXPECT_EQ(OK, out.rv);
    515     EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    516     EXPECT_EQ("Hello", out.response_data);
    517   }
    518   // HTTP/1.0
    519   {
    520     MockRead data_reads[] = {
    521       MockRead("HTTP/1.0 200 OK\r\n"),
    522       MockRead("Content-Length: 5\r\n"),
    523       MockRead("Content-Length: 5\r\n"),
    524       MockRead("Content-Length: 5\r\n\r\n"),
    525       MockRead("Hello"),
    526     };
    527     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    528                                                 arraysize(data_reads));
    529     EXPECT_EQ(OK, out.rv);
    530     EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    531     EXPECT_EQ("Hello", out.response_data);
    532   }
    533   // 2 dupes and one mismatched.
    534   {
    535     MockRead data_reads[] = {
    536       MockRead("HTTP/1.1 200 OK\r\n"),
    537       MockRead("Content-Length: 10\r\n"),
    538       MockRead("Content-Length: 10\r\n"),
    539       MockRead("Content-Length: 5\r\n\r\n"),
    540     };
    541     SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    542                                                 arraysize(data_reads));
    543     EXPECT_EQ(ERR_RESPONSE_HEADERS_MULTIPLE_CONTENT_LENGTH, out.rv);
    544   }
    545 }
    546 
    547 TEST_F(HttpNetworkTransactionTest,
    548        MultipleContentLengthHeadersTransferEncoding) {
    549   MockRead data_reads[] = {
    550     MockRead("HTTP/1.1 200 OK\r\n"),
    551     MockRead("Content-Length: 666\r\n"),
    552     MockRead("Content-Length: 1337\r\n"),
    553     MockRead("Transfer-Encoding: chunked\r\n\r\n"),
    554     MockRead("5\r\nHello\r\n"),
    555     MockRead("1\r\n"),
    556     MockRead(" \r\n"),
    557     MockRead("5\r\nworld\r\n"),
    558     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    559     MockRead(false, OK),
    560   };
    561   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    562                                               arraysize(data_reads));
    563   EXPECT_EQ(OK, out.rv);
    564   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    565   EXPECT_EQ("Hello world", out.response_data);
    566 }
    567 
    568 // Do a request using the HEAD method. Verify that we don't try to read the
    569 // message body (since HEAD has none).
    570 TEST_F(HttpNetworkTransactionTest, Head) {
    571   HttpRequestInfo request;
    572   request.method = "HEAD";
    573   request.url = GURL("http://www.google.com/");
    574   request.load_flags = 0;
    575 
    576   SessionDependencies session_deps;
    577   scoped_ptr<HttpTransaction> trans(
    578       new HttpNetworkTransaction(CreateSession(&session_deps)));
    579 
    580   MockWrite data_writes1[] = {
    581     MockWrite("HEAD / HTTP/1.1\r\n"
    582               "Host: www.google.com\r\n"
    583               "Connection: keep-alive\r\n"
    584               "Content-Length: 0\r\n\r\n"),
    585   };
    586   MockRead data_reads1[] = {
    587     MockRead("HTTP/1.1 404 Not Found\r\n"),
    588     MockRead("Server: Blah\r\n"),
    589     MockRead("Content-Length: 1234\r\n\r\n"),
    590 
    591     // No response body because the test stops reading here.
    592     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
    593   };
    594 
    595   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
    596                                  data_writes1, arraysize(data_writes1));
    597   session_deps.socket_factory.AddSocketDataProvider(&data1);
    598 
    599   TestCompletionCallback callback1;
    600 
    601   int rv = trans->Start(&request, &callback1, BoundNetLog());
    602   EXPECT_EQ(ERR_IO_PENDING, rv);
    603 
    604   rv = callback1.WaitForResult();
    605   EXPECT_EQ(OK, rv);
    606 
    607   const HttpResponseInfo* response = trans->GetResponseInfo();
    608   EXPECT_FALSE(response == NULL);
    609 
    610   // Check that the headers got parsed.
    611   EXPECT_TRUE(response->headers != NULL);
    612   EXPECT_EQ(1234, response->headers->GetContentLength());
    613   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
    614 
    615   std::string server_header;
    616   void* iter = NULL;
    617   bool has_server_header = response->headers->EnumerateHeader(
    618       &iter, "Server", &server_header);
    619   EXPECT_TRUE(has_server_header);
    620   EXPECT_EQ("Blah", server_header);
    621 
    622   // Reading should give EOF right away, since there is no message body
    623   // (despite non-zero content-length).
    624   std::string response_data;
    625   rv = ReadTransaction(trans.get(), &response_data);
    626   EXPECT_EQ(OK, rv);
    627   EXPECT_EQ("", response_data);
    628 }
    629 
    630 TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
    631   SessionDependencies session_deps;
    632   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
    633 
    634   MockRead data_reads[] = {
    635     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    636     MockRead("hello"),
    637     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    638     MockRead("world"),
    639     MockRead(false, OK),
    640   };
    641   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    642   session_deps.socket_factory.AddSocketDataProvider(&data);
    643 
    644   const char* const kExpectedResponseData[] = {
    645     "hello", "world"
    646   };
    647 
    648   for (int i = 0; i < 2; ++i) {
    649     HttpRequestInfo request;
    650     request.method = "GET";
    651     request.url = GURL("http://www.google.com/");
    652     request.load_flags = 0;
    653 
    654     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    655 
    656     TestCompletionCallback callback;
    657 
    658     int rv = trans->Start(&request, &callback, BoundNetLog());
    659     EXPECT_EQ(ERR_IO_PENDING, rv);
    660 
    661     rv = callback.WaitForResult();
    662     EXPECT_EQ(OK, rv);
    663 
    664     const HttpResponseInfo* response = trans->GetResponseInfo();
    665     EXPECT_TRUE(response != NULL);
    666 
    667     EXPECT_TRUE(response->headers != NULL);
    668     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    669 
    670     std::string response_data;
    671     rv = ReadTransaction(trans.get(), &response_data);
    672     EXPECT_EQ(OK, rv);
    673     EXPECT_EQ(kExpectedResponseData[i], response_data);
    674   }
    675 }
    676 
    677 TEST_F(HttpNetworkTransactionTest, Ignores100) {
    678   HttpRequestInfo request;
    679   request.method = "POST";
    680   request.url = GURL("http://www.foo.com/");
    681   request.upload_data = new UploadData;
    682   request.upload_data->AppendBytes("foo", 3);
    683   request.load_flags = 0;
    684 
    685   SessionDependencies session_deps;
    686   scoped_ptr<HttpTransaction> trans(
    687       new HttpNetworkTransaction(CreateSession(&session_deps)));
    688 
    689   MockRead data_reads[] = {
    690     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
    691     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    692     MockRead("hello world"),
    693     MockRead(false, OK),
    694   };
    695   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    696   session_deps.socket_factory.AddSocketDataProvider(&data);
    697 
    698   TestCompletionCallback callback;
    699 
    700   int rv = trans->Start(&request, &callback, BoundNetLog());
    701   EXPECT_EQ(ERR_IO_PENDING, rv);
    702 
    703   rv = callback.WaitForResult();
    704   EXPECT_EQ(OK, rv);
    705 
    706   const HttpResponseInfo* response = trans->GetResponseInfo();
    707   EXPECT_TRUE(response != NULL);
    708 
    709   EXPECT_TRUE(response->headers != NULL);
    710   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
    711 
    712   std::string response_data;
    713   rv = ReadTransaction(trans.get(), &response_data);
    714   EXPECT_EQ(OK, rv);
    715   EXPECT_EQ("hello world", response_data);
    716 }
    717 
    718 // This test is almost the same as Ignores100 above, but the response contains
    719 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
    720 // HTTP/1.1 and the two status headers are read in one read.
    721 TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
    722   HttpRequestInfo request;
    723   request.method = "GET";
    724   request.url = GURL("http://www.foo.com/");
    725   request.load_flags = 0;
    726 
    727   SessionDependencies session_deps;
    728   scoped_ptr<HttpTransaction> trans(
    729       new HttpNetworkTransaction(CreateSession(&session_deps)));
    730 
    731   MockRead data_reads[] = {
    732     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
    733              "HTTP/1.1 200 OK\r\n\r\n"),
    734     MockRead("hello world"),
    735     MockRead(false, OK),
    736   };
    737   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    738   session_deps.socket_factory.AddSocketDataProvider(&data);
    739 
    740   TestCompletionCallback callback;
    741 
    742   int rv = trans->Start(&request, &callback, BoundNetLog());
    743   EXPECT_EQ(ERR_IO_PENDING, rv);
    744 
    745   rv = callback.WaitForResult();
    746   EXPECT_EQ(OK, rv);
    747 
    748   const HttpResponseInfo* response = trans->GetResponseInfo();
    749   EXPECT_TRUE(response != NULL);
    750 
    751   EXPECT_TRUE(response->headers != NULL);
    752   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    753 
    754   std::string response_data;
    755   rv = ReadTransaction(trans.get(), &response_data);
    756   EXPECT_EQ(OK, rv);
    757   EXPECT_EQ("hello world", response_data);
    758 }
    759 
    760 TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
    761   HttpRequestInfo request;
    762   request.method = "POST";
    763   request.url = GURL("http://www.foo.com/");
    764   request.load_flags = 0;
    765 
    766   SessionDependencies session_deps;
    767   scoped_ptr<HttpTransaction> trans(
    768       new HttpNetworkTransaction(CreateSession(&session_deps)));
    769 
    770   MockRead data_reads[] = {
    771     MockRead(false, "HTTP/1.0 100 Continue\r\n"),
    772     MockRead(true, 0),
    773   };
    774   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    775   session_deps.socket_factory.AddSocketDataProvider(&data);
    776 
    777   TestCompletionCallback callback;
    778 
    779   int rv = trans->Start(&request, &callback, BoundNetLog());
    780   EXPECT_EQ(ERR_IO_PENDING, rv);
    781 
    782   rv = callback.WaitForResult();
    783   EXPECT_EQ(OK, rv);
    784 
    785   std::string response_data;
    786   rv = ReadTransaction(trans.get(), &response_data);
    787   EXPECT_EQ(OK, rv);
    788   EXPECT_EQ("", response_data);
    789 }
    790 
    791 TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
    792   HttpRequestInfo request;
    793   request.method = "POST";
    794   request.url = GURL("http://www.foo.com/");
    795   request.load_flags = 0;
    796 
    797   SessionDependencies session_deps;
    798   scoped_ptr<HttpTransaction> trans(
    799       new HttpNetworkTransaction(CreateSession(&session_deps)));
    800 
    801   MockRead data_reads[] = {
    802     MockRead(true, 0),
    803   };
    804   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    805   session_deps.socket_factory.AddSocketDataProvider(&data);
    806 
    807   TestCompletionCallback callback;
    808 
    809   int rv = trans->Start(&request, &callback, BoundNetLog());
    810   EXPECT_EQ(ERR_IO_PENDING, rv);
    811 
    812   rv = callback.WaitForResult();
    813   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
    814 }
    815 
    816 // read_failure specifies a read failure that should cause the network
    817 // transaction to resend the request.
    818 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
    819     const MockRead& read_failure) {
    820   HttpRequestInfo request;
    821   request.method = "GET";
    822   request.url = GURL("http://www.foo.com/");
    823   request.load_flags = 0;
    824 
    825   SessionDependencies session_deps;
    826   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
    827 
    828   MockRead data1_reads[] = {
    829     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    830     MockRead("hello"),
    831     read_failure,  // Now, we reuse the connection and fail the first read.
    832   };
    833   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
    834   session_deps.socket_factory.AddSocketDataProvider(&data1);
    835 
    836   MockRead data2_reads[] = {
    837     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    838     MockRead("world"),
    839     MockRead(true, OK),
    840   };
    841   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
    842   session_deps.socket_factory.AddSocketDataProvider(&data2);
    843 
    844   const char* kExpectedResponseData[] = {
    845     "hello", "world"
    846   };
    847 
    848   for (int i = 0; i < 2; ++i) {
    849     TestCompletionCallback callback;
    850 
    851     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    852 
    853     int rv = trans->Start(&request, &callback, BoundNetLog());
    854     EXPECT_EQ(ERR_IO_PENDING, rv);
    855 
    856     rv = callback.WaitForResult();
    857     EXPECT_EQ(OK, rv);
    858 
    859     const HttpResponseInfo* response = trans->GetResponseInfo();
    860     EXPECT_TRUE(response != NULL);
    861 
    862     EXPECT_TRUE(response->headers != NULL);
    863     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    864 
    865     std::string response_data;
    866     rv = ReadTransaction(trans.get(), &response_data);
    867     EXPECT_EQ(OK, rv);
    868     EXPECT_EQ(kExpectedResponseData[i], response_data);
    869   }
    870 }
    871 
    872 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
    873   MockRead read_failure(true, ERR_CONNECTION_RESET);
    874   KeepAliveConnectionResendRequestTest(read_failure);
    875 }
    876 
    877 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
    878   MockRead read_failure(false, OK);  // EOF
    879   KeepAliveConnectionResendRequestTest(read_failure);
    880 }
    881 
    882 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
    883   HttpRequestInfo request;
    884   request.method = "GET";
    885   request.url = GURL("http://www.google.com/");
    886   request.load_flags = 0;
    887 
    888   SessionDependencies session_deps;
    889   scoped_ptr<HttpTransaction> trans(
    890       new HttpNetworkTransaction(CreateSession(&session_deps)));
    891 
    892   MockRead data_reads[] = {
    893     MockRead(true, ERR_CONNECTION_RESET),
    894     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
    895     MockRead("hello world"),
    896     MockRead(false, OK),
    897   };
    898   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
    899   session_deps.socket_factory.AddSocketDataProvider(&data);
    900 
    901   TestCompletionCallback callback;
    902 
    903   int rv = trans->Start(&request, &callback, BoundNetLog());
    904   EXPECT_EQ(ERR_IO_PENDING, rv);
    905 
    906   rv = callback.WaitForResult();
    907   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
    908 
    909   const HttpResponseInfo* response = trans->GetResponseInfo();
    910   EXPECT_TRUE(response == NULL);
    911 }
    912 
    913 // What do various browsers do when the server closes a non-keepalive
    914 // connection without sending any response header or body?
    915 //
    916 // IE7: error page
    917 // Safari 3.1.2 (Windows): error page
    918 // Firefox 3.0.1: blank page
    919 // Opera 9.52: after five attempts, blank page
    920 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
    921 // Us: error page (EMPTY_RESPONSE)
    922 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
    923   MockRead data_reads[] = {
    924     MockRead(false, OK),  // EOF
    925     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
    926     MockRead("hello world"),
    927     MockRead(false, OK),
    928   };
    929   SimpleGetHelperResult out = SimpleGetHelper(data_reads,
    930                                               arraysize(data_reads));
    931   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
    932 }
    933 
    934 // Test that we correctly reuse a keep-alive connection after not explicitly
    935 // reading the body.
    936 TEST_F(HttpNetworkTransactionTest, KeepAliveAfterUnreadBody) {
    937   HttpRequestInfo request;
    938   request.method = "GET";
    939   request.url = GURL("http://www.foo.com/");
    940   request.load_flags = 0;
    941 
    942   SessionDependencies session_deps;
    943   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
    944 
    945   // Note that because all these reads happen in the same
    946   // StaticSocketDataProvider, it shows that the same socket is being reused for
    947   // all transactions.
    948   MockRead data1_reads[] = {
    949     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    950     MockRead("HTTP/1.1 205 Reset Content\r\n\r\n"),
    951     MockRead("HTTP/1.1 304 Not Modified\r\n\r\n"),
    952     MockRead("HTTP/1.1 302 Found\r\n"
    953              "Content-Length: 0\r\n\r\n"),
    954     MockRead("HTTP/1.1 302 Found\r\n"
    955              "Content-Length: 5\r\n\r\n"
    956              "hello"),
    957     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
    958              "Content-Length: 0\r\n\r\n"),
    959     MockRead("HTTP/1.1 301 Moved Permanently\r\n"
    960              "Content-Length: 5\r\n\r\n"
    961              "hello"),
    962     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    963     MockRead("hello"),
    964   };
    965   StaticSocketDataProvider data1(data1_reads, arraysize(data1_reads), NULL, 0);
    966   session_deps.socket_factory.AddSocketDataProvider(&data1);
    967 
    968   MockRead data2_reads[] = {
    969     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
    970   };
    971   StaticSocketDataProvider data2(data2_reads, arraysize(data2_reads), NULL, 0);
    972   session_deps.socket_factory.AddSocketDataProvider(&data2);
    973 
    974   const int kNumUnreadBodies = arraysize(data1_reads) - 2;
    975   std::string response_lines[kNumUnreadBodies];
    976 
    977   for (size_t i = 0; i < arraysize(data1_reads) - 2; ++i) {
    978     TestCompletionCallback callback;
    979 
    980     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    981 
    982     int rv = trans->Start(&request, &callback, BoundNetLog());
    983     EXPECT_EQ(ERR_IO_PENDING, rv);
    984 
    985     rv = callback.WaitForResult();
    986     EXPECT_EQ(OK, rv);
    987 
    988     const HttpResponseInfo* response = trans->GetResponseInfo();
    989     ASSERT_TRUE(response != NULL);
    990 
    991     ASSERT_TRUE(response->headers != NULL);
    992     response_lines[i] = response->headers->GetStatusLine();
    993 
    994     // We intentionally don't read the response bodies.
    995   }
    996 
    997   const char* const kStatusLines[] = {
    998     "HTTP/1.1 204 No Content",
    999     "HTTP/1.1 205 Reset Content",
   1000     "HTTP/1.1 304 Not Modified",
   1001     "HTTP/1.1 302 Found",
   1002     "HTTP/1.1 302 Found",
   1003     "HTTP/1.1 301 Moved Permanently",
   1004     "HTTP/1.1 301 Moved Permanently",
   1005   };
   1006 
   1007   COMPILE_ASSERT(kNumUnreadBodies == arraysize(kStatusLines),
   1008                  forgot_to_update_kStatusLines);
   1009 
   1010   for (int i = 0; i < kNumUnreadBodies; ++i)
   1011     EXPECT_EQ(kStatusLines[i], response_lines[i]);
   1012 
   1013   TestCompletionCallback callback;
   1014   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1015   int rv = trans->Start(&request, &callback, BoundNetLog());
   1016   EXPECT_EQ(ERR_IO_PENDING, rv);
   1017   rv = callback.WaitForResult();
   1018   EXPECT_EQ(OK, rv);
   1019   const HttpResponseInfo* response = trans->GetResponseInfo();
   1020   ASSERT_TRUE(response != NULL);
   1021   ASSERT_TRUE(response->headers != NULL);
   1022   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1023   std::string response_data;
   1024   rv = ReadTransaction(trans.get(), &response_data);
   1025   EXPECT_EQ(OK, rv);
   1026   EXPECT_EQ("hello", response_data);
   1027 }
   1028 
   1029 // Test the request-challenge-retry sequence for basic auth.
   1030 // (basic auth is the easiest to mock, because it has no randomness).
   1031 TEST_F(HttpNetworkTransactionTest, BasicAuth) {
   1032   HttpRequestInfo request;
   1033   request.method = "GET";
   1034   request.url = GURL("http://www.google.com/");
   1035   request.load_flags = 0;
   1036 
   1037   SessionDependencies session_deps;
   1038   scoped_ptr<HttpTransaction> trans(
   1039       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1040 
   1041   MockWrite data_writes1[] = {
   1042     MockWrite("GET / HTTP/1.1\r\n"
   1043               "Host: www.google.com\r\n"
   1044               "Connection: keep-alive\r\n\r\n"),
   1045   };
   1046 
   1047   MockRead data_reads1[] = {
   1048     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1049     // Give a couple authenticate options (only the middle one is actually
   1050     // supported).
   1051     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
   1052     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1053     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1054     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1055     // Large content-length -- won't matter, as connection will be reset.
   1056     MockRead("Content-Length: 10000\r\n\r\n"),
   1057     MockRead(false, ERR_FAILED),
   1058   };
   1059 
   1060   // After calling trans->RestartWithAuth(), this is the request we should
   1061   // be issuing -- the final header line contains the credentials.
   1062   MockWrite data_writes2[] = {
   1063     MockWrite("GET / HTTP/1.1\r\n"
   1064               "Host: www.google.com\r\n"
   1065               "Connection: keep-alive\r\n"
   1066               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1067   };
   1068 
   1069   // Lastly, the server responds with the actual content.
   1070   MockRead data_reads2[] = {
   1071     MockRead("HTTP/1.0 200 OK\r\n"),
   1072     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1073     MockRead("Content-Length: 100\r\n\r\n"),
   1074     MockRead(false, OK),
   1075   };
   1076 
   1077   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1078                                  data_writes1, arraysize(data_writes1));
   1079   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1080                                  data_writes2, arraysize(data_writes2));
   1081   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1082   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1083 
   1084   TestCompletionCallback callback1;
   1085 
   1086   int rv = trans->Start(&request, &callback1, BoundNetLog());
   1087   EXPECT_EQ(ERR_IO_PENDING, rv);
   1088 
   1089   rv = callback1.WaitForResult();
   1090   EXPECT_EQ(OK, rv);
   1091 
   1092   const HttpResponseInfo* response = trans->GetResponseInfo();
   1093   EXPECT_FALSE(response == NULL);
   1094 
   1095   // The password prompt info should have been set in response->auth_challenge.
   1096   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1097 
   1098   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1099   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1100   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1101 
   1102   TestCompletionCallback callback2;
   1103 
   1104   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1105   EXPECT_EQ(ERR_IO_PENDING, rv);
   1106 
   1107   rv = callback2.WaitForResult();
   1108   EXPECT_EQ(OK, rv);
   1109 
   1110   response = trans->GetResponseInfo();
   1111   EXPECT_FALSE(response == NULL);
   1112   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1113   EXPECT_EQ(100, response->headers->GetContentLength());
   1114 }
   1115 
   1116 TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
   1117   HttpRequestInfo request;
   1118   request.method = "GET";
   1119   request.url = GURL("http://www.google.com/");
   1120   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1121 
   1122   SessionDependencies session_deps;
   1123   scoped_ptr<HttpTransaction> trans(
   1124       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1125 
   1126   MockWrite data_writes[] = {
   1127     MockWrite("GET / HTTP/1.1\r\n"
   1128               "Host: www.google.com\r\n"
   1129               "Connection: keep-alive\r\n\r\n"),
   1130   };
   1131 
   1132   MockRead data_reads[] = {
   1133     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1134     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1135     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1136     // Large content-length -- won't matter, as connection will be reset.
   1137     MockRead("Content-Length: 10000\r\n\r\n"),
   1138     MockRead(false, ERR_FAILED),
   1139   };
   1140 
   1141   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1142                                 data_writes, arraysize(data_writes));
   1143   session_deps.socket_factory.AddSocketDataProvider(&data);
   1144   TestCompletionCallback callback;
   1145 
   1146   int rv = trans->Start(&request, &callback, BoundNetLog());
   1147   EXPECT_EQ(ERR_IO_PENDING, rv);
   1148 
   1149   rv = callback.WaitForResult();
   1150   EXPECT_EQ(0, rv);
   1151 
   1152   const HttpResponseInfo* response = trans->GetResponseInfo();
   1153   ASSERT_FALSE(response == NULL);
   1154   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1155 }
   1156 
   1157 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1158 // connection.
   1159 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
   1160   HttpRequestInfo request;
   1161   request.method = "GET";
   1162   request.url = GURL("http://www.google.com/");
   1163   request.load_flags = 0;
   1164 
   1165   SessionDependencies session_deps;
   1166   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1167 
   1168   MockWrite data_writes1[] = {
   1169     MockWrite("GET / HTTP/1.1\r\n"
   1170               "Host: www.google.com\r\n"
   1171               "Connection: keep-alive\r\n\r\n"),
   1172 
   1173     // After calling trans->RestartWithAuth(), this is the request we should
   1174     // be issuing -- the final header line contains the credentials.
   1175     MockWrite("GET / HTTP/1.1\r\n"
   1176               "Host: www.google.com\r\n"
   1177               "Connection: keep-alive\r\n"
   1178               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1179   };
   1180 
   1181   MockRead data_reads1[] = {
   1182     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1183     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1184     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1185     MockRead("Content-Length: 14\r\n\r\n"),
   1186     MockRead("Unauthorized\r\n"),
   1187 
   1188     // Lastly, the server responds with the actual content.
   1189     MockRead("HTTP/1.1 200 OK\r\n"),
   1190     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1191     MockRead("Content-Length: 5\r\n\r\n"),
   1192     MockRead("Hello"),
   1193   };
   1194 
   1195   // If there is a regression where we disconnect a Keep-Alive
   1196   // connection during an auth roundtrip, we'll end up reading this.
   1197   MockRead data_reads2[] = {
   1198     MockRead(false, ERR_FAILED),
   1199   };
   1200 
   1201   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1202                                  data_writes1, arraysize(data_writes1));
   1203   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1204                                  NULL, 0);
   1205   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1206   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1207 
   1208   TestCompletionCallback callback1;
   1209 
   1210   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1211   int rv = trans->Start(&request, &callback1, BoundNetLog());
   1212   EXPECT_EQ(ERR_IO_PENDING, rv);
   1213 
   1214   rv = callback1.WaitForResult();
   1215   EXPECT_EQ(OK, rv);
   1216 
   1217   const HttpResponseInfo* response = trans->GetResponseInfo();
   1218   EXPECT_FALSE(response == NULL);
   1219 
   1220   // The password prompt info should have been set in response->auth_challenge.
   1221   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1222 
   1223   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1224   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1225   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1226 
   1227   TestCompletionCallback callback2;
   1228 
   1229   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1230   EXPECT_EQ(ERR_IO_PENDING, rv);
   1231 
   1232   rv = callback2.WaitForResult();
   1233   EXPECT_EQ(OK, rv);
   1234 
   1235   response = trans->GetResponseInfo();
   1236   ASSERT_FALSE(response == NULL);
   1237   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1238   EXPECT_EQ(5, response->headers->GetContentLength());
   1239 }
   1240 
   1241 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1242 // connection and with no response body to drain.
   1243 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
   1244   HttpRequestInfo request;
   1245   request.method = "GET";
   1246   request.url = GURL("http://www.google.com/");
   1247   request.load_flags = 0;
   1248 
   1249   SessionDependencies session_deps;
   1250   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1251 
   1252   MockWrite data_writes1[] = {
   1253     MockWrite("GET / HTTP/1.1\r\n"
   1254               "Host: www.google.com\r\n"
   1255               "Connection: keep-alive\r\n\r\n"),
   1256 
   1257     // After calling trans->RestartWithAuth(), this is the request we should
   1258     // be issuing -- the final header line contains the credentials.
   1259     MockWrite("GET / HTTP/1.1\r\n"
   1260               "Host: www.google.com\r\n"
   1261               "Connection: keep-alive\r\n"
   1262               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1263   };
   1264 
   1265   MockRead data_reads1[] = {
   1266     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1267     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1268     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   1269 
   1270     // Lastly, the server responds with the actual content.
   1271     MockRead("HTTP/1.1 200 OK\r\n"),
   1272     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1273     MockRead("Content-Length: 5\r\n\r\n"),
   1274     MockRead("hello"),
   1275   };
   1276 
   1277   // An incorrect reconnect would cause this to be read.
   1278   MockRead data_reads2[] = {
   1279     MockRead(false, ERR_FAILED),
   1280   };
   1281 
   1282   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1283                                  data_writes1, arraysize(data_writes1));
   1284   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1285                                  NULL, 0);
   1286   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1287   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1288 
   1289   TestCompletionCallback callback1;
   1290 
   1291   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1292   int rv = trans->Start(&request, &callback1, BoundNetLog());
   1293   EXPECT_EQ(ERR_IO_PENDING, rv);
   1294 
   1295   rv = callback1.WaitForResult();
   1296   EXPECT_EQ(OK, rv);
   1297 
   1298   const HttpResponseInfo* response = trans->GetResponseInfo();
   1299   EXPECT_FALSE(response == NULL);
   1300 
   1301   // The password prompt info should have been set in response->auth_challenge.
   1302   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1303 
   1304   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1305   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1306   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1307 
   1308   TestCompletionCallback callback2;
   1309 
   1310   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1311   EXPECT_EQ(ERR_IO_PENDING, rv);
   1312 
   1313   rv = callback2.WaitForResult();
   1314   EXPECT_EQ(OK, rv);
   1315 
   1316   response = trans->GetResponseInfo();
   1317   ASSERT_FALSE(response == NULL);
   1318   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1319   EXPECT_EQ(5, response->headers->GetContentLength());
   1320 }
   1321 
   1322 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1323 // connection and with a large response body to drain.
   1324 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
   1325   HttpRequestInfo request;
   1326   request.method = "GET";
   1327   request.url = GURL("http://www.google.com/");
   1328   request.load_flags = 0;
   1329 
   1330   SessionDependencies session_deps;
   1331   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1332 
   1333   MockWrite data_writes1[] = {
   1334     MockWrite("GET / HTTP/1.1\r\n"
   1335               "Host: www.google.com\r\n"
   1336               "Connection: keep-alive\r\n\r\n"),
   1337 
   1338     // After calling trans->RestartWithAuth(), this is the request we should
   1339     // be issuing -- the final header line contains the credentials.
   1340     MockWrite("GET / HTTP/1.1\r\n"
   1341               "Host: www.google.com\r\n"
   1342               "Connection: keep-alive\r\n"
   1343               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1344   };
   1345 
   1346   // Respond with 5 kb of response body.
   1347   std::string large_body_string("Unauthorized");
   1348   large_body_string.append(5 * 1024, ' ');
   1349   large_body_string.append("\r\n");
   1350 
   1351   MockRead data_reads1[] = {
   1352     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1353     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1354     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1355     // 5134 = 12 + 5 * 1024 + 2
   1356     MockRead("Content-Length: 5134\r\n\r\n"),
   1357     MockRead(true, large_body_string.data(), large_body_string.size()),
   1358 
   1359     // Lastly, the server responds with the actual content.
   1360     MockRead("HTTP/1.1 200 OK\r\n"),
   1361     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1362     MockRead("Content-Length: 5\r\n\r\n"),
   1363     MockRead("hello"),
   1364   };
   1365 
   1366   // An incorrect reconnect would cause this to be read.
   1367   MockRead data_reads2[] = {
   1368     MockRead(false, ERR_FAILED),
   1369   };
   1370 
   1371   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1372                                  data_writes1, arraysize(data_writes1));
   1373   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1374                                  NULL, 0);
   1375   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1376   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1377 
   1378   TestCompletionCallback callback1;
   1379 
   1380   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1381   int rv = trans->Start(&request, &callback1, BoundNetLog());
   1382   EXPECT_EQ(ERR_IO_PENDING, rv);
   1383 
   1384   rv = callback1.WaitForResult();
   1385   EXPECT_EQ(OK, rv);
   1386 
   1387   const HttpResponseInfo* response = trans->GetResponseInfo();
   1388   EXPECT_FALSE(response == NULL);
   1389 
   1390   // The password prompt info should have been set in response->auth_challenge.
   1391   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1392 
   1393   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1394   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1395   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1396 
   1397   TestCompletionCallback callback2;
   1398 
   1399   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1400   EXPECT_EQ(ERR_IO_PENDING, rv);
   1401 
   1402   rv = callback2.WaitForResult();
   1403   EXPECT_EQ(OK, rv);
   1404 
   1405   response = trans->GetResponseInfo();
   1406   ASSERT_FALSE(response == NULL);
   1407   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1408   EXPECT_EQ(5, response->headers->GetContentLength());
   1409 }
   1410 
   1411 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1412 // connection, but the server gets impatient and closes the connection.
   1413 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   1414   HttpRequestInfo request;
   1415   request.method = "GET";
   1416   request.url = GURL("http://www.google.com/");
   1417   request.load_flags = 0;
   1418 
   1419   SessionDependencies session_deps;
   1420   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1421 
   1422   MockWrite data_writes1[] = {
   1423     MockWrite("GET / HTTP/1.1\r\n"
   1424               "Host: www.google.com\r\n"
   1425               "Connection: keep-alive\r\n\r\n"),
   1426     // This simulates the seemingly successful write to a closed connection
   1427     // if the bug is not fixed.
   1428     MockWrite("GET / HTTP/1.1\r\n"
   1429               "Host: www.google.com\r\n"
   1430               "Connection: keep-alive\r\n"
   1431               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1432   };
   1433 
   1434   MockRead data_reads1[] = {
   1435     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1436     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1437     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1438     MockRead("Content-Length: 14\r\n\r\n"),
   1439     // Tell MockTCPClientSocket to simulate the server closing the connection.
   1440     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   1441     MockRead("Unauthorized\r\n"),
   1442     MockRead(false, OK),  // The server closes the connection.
   1443   };
   1444 
   1445   // After calling trans->RestartWithAuth(), this is the request we should
   1446   // be issuing -- the final header line contains the credentials.
   1447   MockWrite data_writes2[] = {
   1448     MockWrite("GET / HTTP/1.1\r\n"
   1449               "Host: www.google.com\r\n"
   1450               "Connection: keep-alive\r\n"
   1451               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1452   };
   1453 
   1454   // Lastly, the server responds with the actual content.
   1455   MockRead data_reads2[] = {
   1456     MockRead("HTTP/1.1 200 OK\r\n"),
   1457     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1458     MockRead("Content-Length: 5\r\n\r\n"),
   1459     MockRead("hello"),
   1460   };
   1461 
   1462   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1463                                  data_writes1, arraysize(data_writes1));
   1464   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   1465                                  data_writes2, arraysize(data_writes2));
   1466   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1467   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1468 
   1469   TestCompletionCallback callback1;
   1470 
   1471   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1472   int rv = trans->Start(&request, &callback1, BoundNetLog());
   1473   EXPECT_EQ(ERR_IO_PENDING, rv);
   1474 
   1475   rv = callback1.WaitForResult();
   1476   EXPECT_EQ(OK, rv);
   1477 
   1478   const HttpResponseInfo* response = trans->GetResponseInfo();
   1479   EXPECT_FALSE(response == NULL);
   1480 
   1481   // The password prompt info should have been set in response->auth_challenge.
   1482   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1483 
   1484   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1485   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1486   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1487 
   1488   TestCompletionCallback callback2;
   1489 
   1490   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1491   EXPECT_EQ(ERR_IO_PENDING, rv);
   1492 
   1493   rv = callback2.WaitForResult();
   1494   EXPECT_EQ(OK, rv);
   1495 
   1496   response = trans->GetResponseInfo();
   1497   ASSERT_FALSE(response == NULL);
   1498   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1499   EXPECT_EQ(5, response->headers->GetContentLength());
   1500 }
   1501 
   1502 // Test the request-challenge-retry sequence for basic auth, over a connection
   1503 // that requires a restart when setting up an SSL tunnel.
   1504 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyNoKeepAlive) {
   1505   HttpRequestInfo request;
   1506   request.method = "GET";
   1507   request.url = GURL("https://www.google.com/");
   1508   // when the no authentication data flag is set.
   1509   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1510 
   1511   // Configure against proxy server "myproxy:70".
   1512   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   1513   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   1514   session_deps.net_log = log.bound().net_log();
   1515   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1516 
   1517   // Since we have proxy, should try to establish tunnel.
   1518   MockWrite data_writes1[] = {
   1519     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1520               "Host: www.google.com\r\n"
   1521               "Proxy-Connection: keep-alive\r\n\r\n"),
   1522 
   1523     // After calling trans->RestartWithAuth(), this is the request we should
   1524     // be issuing -- the final header line contains the credentials.
   1525     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1526               "Host: www.google.com\r\n"
   1527               "Proxy-Connection: keep-alive\r\n"
   1528               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1529 
   1530     MockWrite("GET / HTTP/1.1\r\n"
   1531               "Host: www.google.com\r\n"
   1532               "Connection: keep-alive\r\n\r\n"),
   1533   };
   1534 
   1535   // The proxy responds to the connect with a 407, using a persistent
   1536   // connection.
   1537   MockRead data_reads1[] = {
   1538     // No credentials.
   1539     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1540     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1541     MockRead("Proxy-Connection: close\r\n\r\n"),
   1542 
   1543     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   1544 
   1545     MockRead("HTTP/1.1 200 OK\r\n"),
   1546     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1547     MockRead("Content-Length: 5\r\n\r\n"),
   1548     MockRead(false, "hello"),
   1549   };
   1550 
   1551   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1552                                  data_writes1, arraysize(data_writes1));
   1553   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1554   SSLSocketDataProvider ssl(true, OK);
   1555   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   1556 
   1557   TestCompletionCallback callback1;
   1558 
   1559   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1560 
   1561   int rv = trans->Start(&request, &callback1, log.bound());
   1562   EXPECT_EQ(ERR_IO_PENDING, rv);
   1563 
   1564   rv = callback1.WaitForResult();
   1565   EXPECT_EQ(OK, rv);
   1566   net::CapturingNetLog::EntryList entries;
   1567   log.GetEntries(&entries);
   1568   size_t pos = ExpectLogContainsSomewhere(
   1569       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   1570       NetLog::PHASE_NONE);
   1571   ExpectLogContainsSomewhere(
   1572       entries, pos,
   1573       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   1574       NetLog::PHASE_NONE);
   1575 
   1576   const HttpResponseInfo* response = trans->GetResponseInfo();
   1577   ASSERT_FALSE(response == NULL);
   1578 
   1579   EXPECT_EQ(407, response->headers->response_code());
   1580   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1581 
   1582   // The password prompt info should have been set in response->auth_challenge.
   1583   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   1584 
   1585   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1586   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1587   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1588 
   1589   TestCompletionCallback callback2;
   1590 
   1591   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   1592   EXPECT_EQ(ERR_IO_PENDING, rv);
   1593 
   1594   rv = callback2.WaitForResult();
   1595   EXPECT_EQ(OK, rv);
   1596 
   1597   response = trans->GetResponseInfo();
   1598   ASSERT_FALSE(response == NULL);
   1599 
   1600   EXPECT_TRUE(response->headers->IsKeepAlive());
   1601   EXPECT_EQ(200, response->headers->response_code());
   1602   EXPECT_EQ(5, response->headers->GetContentLength());
   1603   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1604 
   1605   // The password prompt info should not be set.
   1606   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1607 
   1608   trans.reset();
   1609   session->CloseAllConnections();
   1610 }
   1611 
   1612 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1613 // proxy connection, when setting up an SSL tunnel.
   1614 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   1615   HttpRequestInfo request;
   1616   request.method = "GET";
   1617   request.url = GURL("https://www.google.com/");
   1618   // Ensure that proxy authentication is attempted even
   1619   // when the no authentication data flag is set.
   1620   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1621 
   1622   // Configure against proxy server "myproxy:70".
   1623   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   1624   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   1625   session_deps.net_log = log.bound().net_log();
   1626   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1627 
   1628   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1629 
   1630   // Since we have proxy, should try to establish tunnel.
   1631   MockWrite data_writes1[] = {
   1632     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1633               "Host: www.google.com\r\n"
   1634               "Proxy-Connection: keep-alive\r\n\r\n"),
   1635 
   1636     // After calling trans->RestartWithAuth(), this is the request we should
   1637     // be issuing -- the final header line contains the credentials.
   1638     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1639               "Host: www.google.com\r\n"
   1640               "Proxy-Connection: keep-alive\r\n"
   1641               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   1642   };
   1643 
   1644   // The proxy responds to the connect with a 407, using a persistent
   1645   // connection.
   1646   MockRead data_reads1[] = {
   1647     // No credentials.
   1648     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1649     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1650     MockRead("Content-Length: 10\r\n\r\n"),
   1651     MockRead("0123456789"),
   1652 
   1653     // Wrong credentials (wrong password).
   1654     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1655     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1656     MockRead("Content-Length: 10\r\n\r\n"),
   1657     // No response body because the test stops reading here.
   1658     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   1659   };
   1660 
   1661   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1662                                  data_writes1, arraysize(data_writes1));
   1663   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1664 
   1665   TestCompletionCallback callback1;
   1666 
   1667   int rv = trans->Start(&request, &callback1, log.bound());
   1668   EXPECT_EQ(ERR_IO_PENDING, rv);
   1669 
   1670   rv = callback1.WaitForResult();
   1671   EXPECT_EQ(OK, rv);
   1672   net::CapturingNetLog::EntryList entries;
   1673   log.GetEntries(&entries);
   1674   size_t pos = ExpectLogContainsSomewhere(
   1675       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   1676       NetLog::PHASE_NONE);
   1677   ExpectLogContainsSomewhere(
   1678       entries, pos,
   1679       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   1680       NetLog::PHASE_NONE);
   1681 
   1682   const HttpResponseInfo* response = trans->GetResponseInfo();
   1683   EXPECT_FALSE(response == NULL);
   1684 
   1685   EXPECT_TRUE(response->headers->IsKeepAlive());
   1686   EXPECT_EQ(407, response->headers->response_code());
   1687   EXPECT_EQ(10, response->headers->GetContentLength());
   1688   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1689 
   1690   // The password prompt info should have been set in response->auth_challenge.
   1691   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1692 
   1693   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1694   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1695   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1696 
   1697   TestCompletionCallback callback2;
   1698 
   1699   // Wrong password (should be "bar").
   1700   rv = trans->RestartWithAuth(kFoo, kBaz, &callback2);
   1701   EXPECT_EQ(ERR_IO_PENDING, rv);
   1702 
   1703   rv = callback2.WaitForResult();
   1704   EXPECT_EQ(OK, rv);
   1705 
   1706   response = trans->GetResponseInfo();
   1707   EXPECT_FALSE(response == NULL);
   1708 
   1709   EXPECT_TRUE(response->headers->IsKeepAlive());
   1710   EXPECT_EQ(407, response->headers->response_code());
   1711   EXPECT_EQ(10, response->headers->GetContentLength());
   1712   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1713 
   1714   // The password prompt info should have been set in response->auth_challenge.
   1715   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1716 
   1717   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1718   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1719   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1720 
   1721   // Flush the idle socket before the NetLog and HttpNetworkTransaction go
   1722   // out of scope.
   1723   session->CloseAllConnections();
   1724 }
   1725 
   1726 // Test that we don't read the response body when we fail to establish a tunnel,
   1727 // even if the user cancels the proxy's auth attempt.
   1728 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   1729   HttpRequestInfo request;
   1730   request.method = "GET";
   1731   request.url = GURL("https://www.google.com/");
   1732   request.load_flags = 0;
   1733 
   1734   // Configure against proxy server "myproxy:70".
   1735   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   1736 
   1737   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1738 
   1739   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1740 
   1741   // Since we have proxy, should try to establish tunnel.
   1742   MockWrite data_writes[] = {
   1743     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1744               "Host: www.google.com\r\n"
   1745               "Proxy-Connection: keep-alive\r\n\r\n"),
   1746   };
   1747 
   1748   // The proxy responds to the connect with a 407.
   1749   MockRead data_reads[] = {
   1750     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1751     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1752     MockRead("Content-Length: 10\r\n\r\n"),
   1753     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   1754   };
   1755 
   1756   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   1757                                 data_writes, arraysize(data_writes));
   1758   session_deps.socket_factory.AddSocketDataProvider(&data);
   1759 
   1760   TestCompletionCallback callback;
   1761 
   1762   int rv = trans->Start(&request, &callback, BoundNetLog());
   1763   EXPECT_EQ(ERR_IO_PENDING, rv);
   1764 
   1765   rv = callback.WaitForResult();
   1766   EXPECT_EQ(OK, rv);
   1767 
   1768   const HttpResponseInfo* response = trans->GetResponseInfo();
   1769   EXPECT_FALSE(response == NULL);
   1770 
   1771   EXPECT_TRUE(response->headers->IsKeepAlive());
   1772   EXPECT_EQ(407, response->headers->response_code());
   1773   EXPECT_EQ(10, response->headers->GetContentLength());
   1774   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1775 
   1776   std::string response_data;
   1777   rv = ReadTransaction(trans.get(), &response_data);
   1778   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   1779 
   1780   // Flush the idle socket before the HttpNetworkTransaction goes out of scope.
   1781   session->CloseAllConnections();
   1782 }
   1783 
   1784 // Test when a server (non-proxy) returns a 407 (proxy-authenticate).
   1785 // The request should fail with ERR_UNEXPECTED_PROXY_AUTH.
   1786 TEST_F(HttpNetworkTransactionTest, UnexpectedProxyAuth) {
   1787   HttpRequestInfo request;
   1788   request.method = "GET";
   1789   request.url = GURL("http://www.google.com/");
   1790   request.load_flags = 0;
   1791 
   1792   // We are using a DIRECT connection (i.e. no proxy) for this session.
   1793   SessionDependencies session_deps;
   1794   scoped_ptr<HttpTransaction> trans(
   1795       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1796 
   1797   MockWrite data_writes1[] = {
   1798     MockWrite("GET / HTTP/1.1\r\n"
   1799               "Host: www.google.com\r\n"
   1800               "Connection: keep-alive\r\n\r\n"),
   1801   };
   1802 
   1803   MockRead data_reads1[] = {
   1804     MockRead("HTTP/1.0 407 Proxy Auth required\r\n"),
   1805     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1806     // Large content-length -- won't matter, as connection will be reset.
   1807     MockRead("Content-Length: 10000\r\n\r\n"),
   1808     MockRead(false, ERR_FAILED),
   1809   };
   1810 
   1811   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1812                                  data_writes1, arraysize(data_writes1));
   1813   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1814 
   1815   TestCompletionCallback callback;
   1816 
   1817   int rv = trans->Start(&request, &callback, BoundNetLog());
   1818   EXPECT_EQ(ERR_IO_PENDING, rv);
   1819 
   1820   rv = callback.WaitForResult();
   1821   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   1822 }
   1823 
   1824 // Tests when an HTTPS server (non-proxy) returns a 407 (proxy-authentication)
   1825 // through a non-authenticating proxy. The request should fail with
   1826 // ERR_UNEXPECTED_PROXY_AUTH.
   1827 // Note that it is impossible to detect if an HTTP server returns a 407 through
   1828 // a non-authenticating proxy - there is nothing to indicate whether the
   1829 // response came from the proxy or the server, so it is treated as if the proxy
   1830 // issued the challenge.
   1831 TEST_F(HttpNetworkTransactionTest, HttpsServerRequestsProxyAuthThroughProxy) {
   1832   HttpRequestInfo request;
   1833   request.method = "GET";
   1834   request.url = GURL("https://www.google.com/");
   1835 
   1836   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   1837   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   1838   session_deps.net_log = log.bound().net_log();
   1839   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1840 
   1841   // Since we have proxy, should try to establish tunnel.
   1842   MockWrite data_writes1[] = {
   1843     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1844               "Host: www.google.com\r\n"
   1845               "Proxy-Connection: keep-alive\r\n\r\n"),
   1846 
   1847     MockWrite("GET / HTTP/1.1\r\n"
   1848               "Host: www.google.com\r\n"
   1849               "Connection: keep-alive\r\n\r\n"),
   1850   };
   1851 
   1852   MockRead data_reads1[] = {
   1853     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   1854 
   1855     MockRead("HTTP/1.1 407 Unauthorized\r\n"),
   1856     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1857     MockRead("\r\n"),
   1858     MockRead(false, OK),
   1859   };
   1860 
   1861   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1862                                  data_writes1, arraysize(data_writes1));
   1863   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1864   SSLSocketDataProvider ssl(true, OK);
   1865   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   1866 
   1867   TestCompletionCallback callback1;
   1868 
   1869   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1870 
   1871   int rv = trans->Start(&request, &callback1, log.bound());
   1872   EXPECT_EQ(ERR_IO_PENDING, rv);
   1873 
   1874   rv = callback1.WaitForResult();
   1875   EXPECT_EQ(ERR_UNEXPECTED_PROXY_AUTH, rv);
   1876   net::CapturingNetLog::EntryList entries;
   1877   log.GetEntries(&entries);
   1878   size_t pos = ExpectLogContainsSomewhere(
   1879       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   1880       NetLog::PHASE_NONE);
   1881   ExpectLogContainsSomewhere(
   1882       entries, pos,
   1883       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   1884       NetLog::PHASE_NONE);
   1885 }
   1886 
   1887 // Test a simple get through an HTTPS Proxy.
   1888 TEST_F(HttpNetworkTransactionTest, HttpsProxyGet) {
   1889   HttpRequestInfo request;
   1890   request.method = "GET";
   1891   request.url = GURL("http://www.google.com/");
   1892 
   1893   // Configure against https proxy server "proxy:70".
   1894   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   1895   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   1896   session_deps.net_log = log.bound().net_log();
   1897   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1898 
   1899   // Since we have proxy, should use full url
   1900   MockWrite data_writes1[] = {
   1901     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   1902               "Host: www.google.com\r\n"
   1903               "Proxy-Connection: keep-alive\r\n\r\n"),
   1904   };
   1905 
   1906   MockRead data_reads1[] = {
   1907     MockRead("HTTP/1.1 200 OK\r\n"),
   1908     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1909     MockRead("Content-Length: 100\r\n\r\n"),
   1910     MockRead(false, OK),
   1911   };
   1912 
   1913   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   1914                                  data_writes1, arraysize(data_writes1));
   1915   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1916   SSLSocketDataProvider ssl(true, OK);
   1917   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   1918 
   1919   TestCompletionCallback callback1;
   1920 
   1921   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1922 
   1923   int rv = trans->Start(&request, &callback1, log.bound());
   1924   EXPECT_EQ(ERR_IO_PENDING, rv);
   1925 
   1926   rv = callback1.WaitForResult();
   1927   EXPECT_EQ(OK, rv);
   1928 
   1929   const HttpResponseInfo* response = trans->GetResponseInfo();
   1930   ASSERT_FALSE(response == NULL);
   1931 
   1932   EXPECT_TRUE(response->headers->IsKeepAlive());
   1933   EXPECT_EQ(200, response->headers->response_code());
   1934   EXPECT_EQ(100, response->headers->GetContentLength());
   1935   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1936 
   1937   // The password prompt info should not be set.
   1938   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1939 }
   1940 
   1941 // Test a SPDY get through an HTTPS Proxy.
   1942 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGet) {
   1943   HttpRequestInfo request;
   1944   request.method = "GET";
   1945   request.url = GURL("http://www.google.com/");
   1946   request.load_flags = 0;
   1947 
   1948   // Configure against https proxy server "proxy:70".
   1949   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   1950   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   1951   session_deps.net_log = log.bound().net_log();
   1952   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1953 
   1954   // fetch http://www.google.com/ via SPDY
   1955   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST,
   1956                                                    false));
   1957   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   1958 
   1959   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   1960   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   1961   MockRead spdy_reads[] = {
   1962     CreateMockRead(*resp),
   1963     CreateMockRead(*data),
   1964     MockRead(true, 0, 0),
   1965   };
   1966 
   1967   scoped_refptr<DelayedSocketData> spdy_data(
   1968       new DelayedSocketData(
   1969           1,  // wait for one write to finish before reading.
   1970           spdy_reads, arraysize(spdy_reads),
   1971           spdy_writes, arraysize(spdy_writes)));
   1972   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   1973 
   1974   SSLSocketDataProvider ssl(true, OK);
   1975   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   1976   ssl.next_proto = "spdy/2";
   1977   ssl.was_npn_negotiated = true;
   1978   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   1979 
   1980   TestCompletionCallback callback1;
   1981 
   1982   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1983 
   1984   int rv = trans->Start(&request, &callback1, log.bound());
   1985   EXPECT_EQ(ERR_IO_PENDING, rv);
   1986 
   1987   rv = callback1.WaitForResult();
   1988   EXPECT_EQ(OK, rv);
   1989 
   1990   const HttpResponseInfo* response = trans->GetResponseInfo();
   1991   ASSERT_TRUE(response != NULL);
   1992   ASSERT_TRUE(response->headers != NULL);
   1993   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   1994 
   1995   std::string response_data;
   1996   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   1997   EXPECT_EQ(net::kUploadData, response_data);
   1998 }
   1999 
   2000 // Test a SPDY get through an HTTPS Proxy.
   2001 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyGetWithProxyAuth) {
   2002   HttpRequestInfo request;
   2003   request.method = "GET";
   2004   request.url = GURL("http://www.google.com/");
   2005   request.load_flags = 0;
   2006 
   2007   // Configure against https proxy server "proxy:70".
   2008   SessionDependencies session_deps(
   2009       ProxyService::CreateFixed("https://proxy:70"));
   2010   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   2011   session_deps.net_log = log.bound().net_log();
   2012   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2013 
   2014   // The first request will be a bare GET, the second request will be a
   2015   // GET with a Proxy-Authorization header.
   2016   scoped_ptr<spdy::SpdyFrame> req_get(
   2017       ConstructSpdyGet(NULL, 0, false, 1, LOWEST, false));
   2018   const char* const kExtraAuthorizationHeaders[] = {
   2019     "proxy-authorization",
   2020     "Basic Zm9vOmJhcg==",
   2021   };
   2022   scoped_ptr<spdy::SpdyFrame> req_get_authorization(
   2023       ConstructSpdyGet(
   2024           kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders)/2,
   2025           false, 3, LOWEST, false));
   2026   MockWrite spdy_writes[] = {
   2027     CreateMockWrite(*req_get, 1),
   2028     CreateMockWrite(*req_get_authorization, 4),
   2029   };
   2030 
   2031   // The first response is a 407 proxy authentication challenge, and the second
   2032   // response will be a 200 response since the second request includes a valid
   2033   // Authorization header.
   2034   const char* const kExtraAuthenticationHeaders[] = {
   2035     "Proxy-Authenticate",
   2036     "Basic realm=\"MyRealm1\""
   2037   };
   2038   scoped_ptr<spdy::SpdyFrame> resp_authentication(
   2039       ConstructSpdySynReplyError(
   2040           "407 Proxy Authentication Required",
   2041           kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders)/2,
   2042           1));
   2043   scoped_ptr<spdy::SpdyFrame> body_authentication(
   2044       ConstructSpdyBodyFrame(1, true));
   2045   scoped_ptr<spdy::SpdyFrame> resp_data(ConstructSpdyGetSynReply(NULL, 0, 3));
   2046   scoped_ptr<spdy::SpdyFrame> body_data(ConstructSpdyBodyFrame(3, true));
   2047   MockRead spdy_reads[] = {
   2048     CreateMockRead(*resp_authentication, 2),
   2049     CreateMockRead(*body_authentication, 3),
   2050     CreateMockRead(*resp_data, 5),
   2051     CreateMockRead(*body_data, 6),
   2052     MockRead(true, 0, 7),
   2053   };
   2054 
   2055   scoped_refptr<OrderedSocketData> data(
   2056       new OrderedSocketData(spdy_reads, arraysize(spdy_reads),
   2057                             spdy_writes, arraysize(spdy_writes)));
   2058   session_deps.socket_factory.AddSocketDataProvider(data);
   2059 
   2060   SSLSocketDataProvider ssl(true, OK);
   2061   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2062   ssl.next_proto = "spdy/2";
   2063   ssl.was_npn_negotiated = true;
   2064   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2065 
   2066   TestCompletionCallback callback1;
   2067 
   2068   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2069 
   2070   int rv = trans->Start(&request, &callback1, log.bound());
   2071   EXPECT_EQ(ERR_IO_PENDING, rv);
   2072 
   2073   rv = callback1.WaitForResult();
   2074   EXPECT_EQ(OK, rv);
   2075 
   2076   const HttpResponseInfo* const response = trans->GetResponseInfo();
   2077 
   2078   ASSERT_TRUE(response != NULL);
   2079   ASSERT_TRUE(response->headers != NULL);
   2080   EXPECT_EQ(407, response->headers->response_code());
   2081   EXPECT_TRUE(response->was_fetched_via_spdy);
   2082 
   2083   // The password prompt info should have been set in response->auth_challenge.
   2084   ASSERT_TRUE(response->auth_challenge.get() != NULL);
   2085   EXPECT_TRUE(response->auth_challenge->is_proxy);
   2086   EXPECT_EQ(L"proxy:70", response->auth_challenge->host_and_port);
   2087   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2088   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2089 
   2090   TestCompletionCallback callback2;
   2091 
   2092   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   2093   EXPECT_EQ(ERR_IO_PENDING, rv);
   2094 
   2095   rv = callback2.WaitForResult();
   2096   EXPECT_EQ(OK, rv);
   2097 
   2098   const HttpResponseInfo* const response_restart = trans->GetResponseInfo();
   2099 
   2100   ASSERT_TRUE(response_restart != NULL);
   2101   ASSERT_TRUE(response_restart->headers != NULL);
   2102   EXPECT_EQ(200, response_restart->headers->response_code());
   2103   // The password prompt info should not be set.
   2104   EXPECT_TRUE(response_restart->auth_challenge.get() == NULL);
   2105 }
   2106 
   2107 // Test a SPDY CONNECT through an HTTPS Proxy to an HTTPS (non-SPDY) Server.
   2108 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectHttps) {
   2109   HttpRequestInfo request;
   2110   request.method = "GET";
   2111   request.url = GURL("https://www.google.com/");
   2112   request.load_flags = 0;
   2113 
   2114   // Configure against https proxy server "proxy:70".
   2115   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   2116   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   2117   session_deps.net_log = log.bound().net_log();
   2118   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2119 
   2120   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2121 
   2122   // CONNECT to www.google.com:443 via SPDY
   2123   scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
   2124   // fetch https://www.google.com/ via HTTP
   2125 
   2126   const char get[] = "GET / HTTP/1.1\r\n"
   2127     "Host: www.google.com\r\n"
   2128     "Connection: keep-alive\r\n\r\n";
   2129   scoped_ptr<spdy::SpdyFrame> wrapped_get(
   2130       ConstructSpdyBodyFrame(1, get, strlen(get), false));
   2131   MockWrite spdy_writes[] = {
   2132       CreateMockWrite(*connect, 1),
   2133       CreateMockWrite(*wrapped_get, 3)
   2134   };
   2135 
   2136   scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2137   const char resp[] = "HTTP/1.1 200 OK\r\n"
   2138       "Content-Length: 10\r\n\r\n";
   2139 
   2140   scoped_ptr<spdy::SpdyFrame> wrapped_get_resp(
   2141       ConstructSpdyBodyFrame(1, resp, strlen(resp), false));
   2142   scoped_ptr<spdy::SpdyFrame> wrapped_body(
   2143       ConstructSpdyBodyFrame(1, "1234567890", 10, false));
   2144   MockRead spdy_reads[] = {
   2145     CreateMockRead(*conn_resp, 2, true),
   2146     CreateMockRead(*wrapped_get_resp, 4, true),
   2147     CreateMockRead(*wrapped_body, 5, true),
   2148     CreateMockRead(*wrapped_body, 6, true),
   2149     MockRead(true, 0, 7),
   2150   };
   2151 
   2152   scoped_refptr<OrderedSocketData> spdy_data(
   2153       new OrderedSocketData(
   2154           spdy_reads, arraysize(spdy_reads),
   2155           spdy_writes, arraysize(spdy_writes)));
   2156   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   2157 
   2158   SSLSocketDataProvider ssl(true, OK);
   2159   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2160   ssl.next_proto = "spdy/2";
   2161   ssl.was_npn_negotiated = true;
   2162   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2163   SSLSocketDataProvider ssl2(true, OK);
   2164   ssl2.was_npn_negotiated = false;
   2165   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
   2166 
   2167   TestCompletionCallback callback1;
   2168 
   2169   int rv = trans->Start(&request, &callback1, log.bound());
   2170   EXPECT_EQ(ERR_IO_PENDING, rv);
   2171 
   2172   rv = callback1.WaitForResult();
   2173   EXPECT_EQ(OK, rv);
   2174 
   2175   const HttpResponseInfo* response = trans->GetResponseInfo();
   2176   ASSERT_TRUE(response != NULL);
   2177   ASSERT_TRUE(response->headers != NULL);
   2178   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2179 
   2180   std::string response_data;
   2181   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2182   EXPECT_EQ("1234567890", response_data);
   2183 }
   2184 
   2185 // Test a SPDY CONNECT through an HTTPS Proxy to a SPDY server.
   2186 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectSpdy) {
   2187   HttpRequestInfo request;
   2188   request.method = "GET";
   2189   request.url = GURL("https://www.google.com/");
   2190   request.load_flags = 0;
   2191 
   2192   // Configure against https proxy server "proxy:70".
   2193   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   2194   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   2195   session_deps.net_log = log.bound().net_log();
   2196   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2197 
   2198   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2199 
   2200   // CONNECT to www.google.com:443 via SPDY
   2201   scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
   2202   // fetch https://www.google.com/ via SPDY
   2203   const char* const kMyUrl = "https://www.google.com/";
   2204   scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyGet(kMyUrl, false, 1, LOWEST));
   2205   scoped_ptr<spdy::SpdyFrame> wrapped_get(ConstructWrappedSpdyFrame(get, 1));
   2206   MockWrite spdy_writes[] = {
   2207       CreateMockWrite(*connect, 1),
   2208       CreateMockWrite(*wrapped_get, 3)
   2209   };
   2210 
   2211   scoped_ptr<spdy::SpdyFrame> conn_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2212   scoped_ptr<spdy::SpdyFrame> get_resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   2213   scoped_ptr<spdy::SpdyFrame> wrapped_get_resp(
   2214       ConstructWrappedSpdyFrame(get_resp, 1));
   2215   scoped_ptr<spdy::SpdyFrame> body(ConstructSpdyBodyFrame(1, true));
   2216   scoped_ptr<spdy::SpdyFrame> wrapped_body(ConstructWrappedSpdyFrame(body, 1));
   2217   MockRead spdy_reads[] = {
   2218     CreateMockRead(*conn_resp, 2, true),
   2219     CreateMockRead(*wrapped_get_resp, 4, true),
   2220     CreateMockRead(*wrapped_body, 5, true),
   2221     MockRead(true, 0, 1),
   2222   };
   2223 
   2224   scoped_refptr<OrderedSocketData> spdy_data(
   2225       new OrderedSocketData(
   2226           spdy_reads, arraysize(spdy_reads),
   2227           spdy_writes, arraysize(spdy_writes)));
   2228   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   2229 
   2230   SSLSocketDataProvider ssl(true, OK);
   2231   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2232   ssl.next_proto = "spdy/2";
   2233   ssl.was_npn_negotiated = true;
   2234   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2235   SSLSocketDataProvider ssl2(true, OK);
   2236   ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2237   ssl2.next_proto = "spdy/2";
   2238   ssl2.was_npn_negotiated = true;
   2239   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
   2240 
   2241   TestCompletionCallback callback1;
   2242 
   2243   int rv = trans->Start(&request, &callback1, log.bound());
   2244   EXPECT_EQ(ERR_IO_PENDING, rv);
   2245 
   2246   rv = callback1.WaitForResult();
   2247   EXPECT_EQ(OK, rv);
   2248 
   2249   const HttpResponseInfo* response = trans->GetResponseInfo();
   2250   ASSERT_TRUE(response != NULL);
   2251   ASSERT_TRUE(response->headers != NULL);
   2252   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2253 
   2254   std::string response_data;
   2255   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   2256   EXPECT_EQ(net::kUploadData, response_data);
   2257 }
   2258 
   2259 // Test a SPDY CONNECT failure through an HTTPS Proxy.
   2260 TEST_F(HttpNetworkTransactionTest, HttpsProxySpdyConnectFailure) {
   2261   HttpRequestInfo request;
   2262   request.method = "GET";
   2263   request.url = GURL("https://www.google.com/");
   2264   request.load_flags = 0;
   2265 
   2266   // Configure against https proxy server "proxy:70".
   2267   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   2268   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   2269   session_deps.net_log = log.bound().net_log();
   2270   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2271 
   2272   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2273 
   2274   // CONNECT to www.google.com:443 via SPDY
   2275   scoped_ptr<spdy::SpdyFrame> connect(ConstructSpdyConnect(NULL, 0, 1));
   2276   scoped_ptr<spdy::SpdyFrame> get(ConstructSpdyRstStream(1, spdy::CANCEL));
   2277 
   2278   MockWrite spdy_writes[] = {
   2279       CreateMockWrite(*connect, 1),
   2280       CreateMockWrite(*get, 3),
   2281   };
   2282 
   2283   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdySynReplyError(1));
   2284   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   2285   MockRead spdy_reads[] = {
   2286     CreateMockRead(*resp, 2, true),
   2287     MockRead(true, 0, 4),
   2288   };
   2289 
   2290   scoped_refptr<OrderedSocketData> spdy_data(
   2291       new OrderedSocketData(
   2292           spdy_reads, arraysize(spdy_reads),
   2293           spdy_writes, arraysize(spdy_writes)));
   2294   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   2295 
   2296   SSLSocketDataProvider ssl(true, OK);
   2297   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2298   ssl.next_proto = "spdy/2";
   2299   ssl.was_npn_negotiated = true;
   2300   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2301   SSLSocketDataProvider ssl2(true, OK);
   2302   ssl2.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   2303   ssl2.next_proto = "spdy/2";
   2304   ssl2.was_npn_negotiated = true;
   2305   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
   2306 
   2307   TestCompletionCallback callback1;
   2308 
   2309   int rv = trans->Start(&request, &callback1, log.bound());
   2310   EXPECT_EQ(ERR_IO_PENDING, rv);
   2311 
   2312   rv = callback1.WaitForResult();
   2313   EXPECT_EQ(OK, rv);
   2314 
   2315   const HttpResponseInfo* response = trans->GetResponseInfo();
   2316   ASSERT_FALSE(response == NULL);
   2317   EXPECT_EQ(500, response->headers->response_code());
   2318 }
   2319 
   2320 // Test the challenge-response-retry sequence through an HTTPS Proxy
   2321 TEST_F(HttpNetworkTransactionTest, HttpsProxyAuthRetry) {
   2322   HttpRequestInfo request;
   2323   request.method = "GET";
   2324   request.url = GURL("http://www.google.com/");
   2325   // when the no authentication data flag is set.
   2326   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   2327 
   2328   // Configure against https proxy server "proxy:70".
   2329   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   2330   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   2331   session_deps.net_log = log.bound().net_log();
   2332   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2333 
   2334   // Since we have proxy, should use full url
   2335   MockWrite data_writes1[] = {
   2336     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2337               "Host: www.google.com\r\n"
   2338               "Proxy-Connection: keep-alive\r\n\r\n"),
   2339 
   2340     // After calling trans->RestartWithAuth(), this is the request we should
   2341     // be issuing -- the final header line contains the credentials.
   2342     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2343               "Host: www.google.com\r\n"
   2344               "Proxy-Connection: keep-alive\r\n"
   2345               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2346   };
   2347 
   2348   // The proxy responds to the GET with a 407, using a persistent
   2349   // connection.
   2350   MockRead data_reads1[] = {
   2351     // No credentials.
   2352     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2353     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2354     MockRead("Proxy-Connection: keep-alive\r\n"),
   2355     MockRead("Content-Length: 0\r\n\r\n"),
   2356 
   2357     MockRead("HTTP/1.1 200 OK\r\n"),
   2358     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2359     MockRead("Content-Length: 100\r\n\r\n"),
   2360     MockRead(false, OK),
   2361   };
   2362 
   2363   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2364                                  data_writes1, arraysize(data_writes1));
   2365   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2366   SSLSocketDataProvider ssl(true, OK);
   2367   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2368 
   2369   TestCompletionCallback callback1;
   2370 
   2371   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2372 
   2373   int rv = trans->Start(&request, &callback1, log.bound());
   2374   EXPECT_EQ(ERR_IO_PENDING, rv);
   2375 
   2376   rv = callback1.WaitForResult();
   2377   EXPECT_EQ(OK, rv);
   2378 
   2379   const HttpResponseInfo* response = trans->GetResponseInfo();
   2380   ASSERT_FALSE(response == NULL);
   2381 
   2382   EXPECT_EQ(407, response->headers->response_code());
   2383   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2384 
   2385   // The password prompt info should have been set in response->auth_challenge.
   2386   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   2387 
   2388   EXPECT_EQ(L"proxy:70", response->auth_challenge->host_and_port);
   2389   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2390   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2391 
   2392   TestCompletionCallback callback2;
   2393 
   2394   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   2395   EXPECT_EQ(ERR_IO_PENDING, rv);
   2396 
   2397   rv = callback2.WaitForResult();
   2398   EXPECT_EQ(OK, rv);
   2399 
   2400   response = trans->GetResponseInfo();
   2401   ASSERT_FALSE(response == NULL);
   2402 
   2403   EXPECT_TRUE(response->headers->IsKeepAlive());
   2404   EXPECT_EQ(200, response->headers->response_code());
   2405   EXPECT_EQ(100, response->headers->GetContentLength());
   2406   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   2407 
   2408   // The password prompt info should not be set.
   2409   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2410 }
   2411 
   2412 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   2413     const MockRead& status, int expected_status) {
   2414   HttpRequestInfo request;
   2415   request.method = "GET";
   2416   request.url = GURL("https://www.google.com/");
   2417   request.load_flags = 0;
   2418 
   2419   // Configure against proxy server "myproxy:70".
   2420   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   2421 
   2422   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2423 
   2424   // Since we have proxy, should try to establish tunnel.
   2425   MockWrite data_writes[] = {
   2426     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2427               "Host: www.google.com\r\n"
   2428               "Proxy-Connection: keep-alive\r\n\r\n"),
   2429   };
   2430 
   2431   MockRead data_reads[] = {
   2432     status,
   2433     MockRead("Content-Length: 10\r\n\r\n"),
   2434     // No response body because the test stops reading here.
   2435     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   2436   };
   2437 
   2438   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   2439                                 data_writes, arraysize(data_writes));
   2440   session_deps.socket_factory.AddSocketDataProvider(&data);
   2441 
   2442   TestCompletionCallback callback;
   2443 
   2444   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2445 
   2446   int rv = trans->Start(&request, &callback, BoundNetLog());
   2447   EXPECT_EQ(ERR_IO_PENDING, rv);
   2448 
   2449   rv = callback.WaitForResult();
   2450   EXPECT_EQ(expected_status, rv);
   2451 }
   2452 
   2453 void HttpNetworkTransactionTest::ConnectStatusHelper(const MockRead& status) {
   2454   ConnectStatusHelperWithExpectedStatus(
   2455       status, ERR_TUNNEL_CONNECTION_FAILED);
   2456 }
   2457 
   2458 TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
   2459   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   2460 }
   2461 
   2462 TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
   2463   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   2464 }
   2465 
   2466 TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
   2467   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   2468 }
   2469 
   2470 TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
   2471   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   2472 }
   2473 
   2474 TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
   2475   ConnectStatusHelper(
   2476       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   2477 }
   2478 
   2479 TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
   2480   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   2481 }
   2482 
   2483 TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
   2484   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   2485 }
   2486 
   2487 TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
   2488   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   2489 }
   2490 
   2491 TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
   2492   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   2493 }
   2494 
   2495 TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
   2496   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   2497 }
   2498 
   2499 TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
   2500   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   2501 }
   2502 
   2503 TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
   2504   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   2505 }
   2506 
   2507 TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
   2508   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   2509 }
   2510 
   2511 TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
   2512   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   2513 }
   2514 
   2515 TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
   2516   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   2517 }
   2518 
   2519 TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
   2520   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   2521 }
   2522 
   2523 TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
   2524   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   2525 }
   2526 
   2527 TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
   2528   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   2529 }
   2530 
   2531 TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
   2532   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   2533 }
   2534 
   2535 TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
   2536   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   2537 }
   2538 
   2539 TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
   2540   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   2541 }
   2542 
   2543 TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
   2544   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   2545 }
   2546 
   2547 TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
   2548   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   2549 }
   2550 
   2551 TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
   2552   ConnectStatusHelperWithExpectedStatus(
   2553       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   2554       ERR_PROXY_AUTH_UNSUPPORTED);
   2555 }
   2556 
   2557 TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
   2558   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   2559 }
   2560 
   2561 TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
   2562   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   2563 }
   2564 
   2565 TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
   2566   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   2567 }
   2568 
   2569 TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
   2570   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   2571 }
   2572 
   2573 TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
   2574   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   2575 }
   2576 
   2577 TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
   2578   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   2579 }
   2580 
   2581 TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
   2582   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   2583 }
   2584 
   2585 TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
   2586   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   2587 }
   2588 
   2589 TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
   2590   ConnectStatusHelper(
   2591       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   2592 }
   2593 
   2594 TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
   2595   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   2596 }
   2597 
   2598 TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
   2599   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   2600 }
   2601 
   2602 TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
   2603   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   2604 }
   2605 
   2606 TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
   2607   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   2608 }
   2609 
   2610 TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
   2611   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   2612 }
   2613 
   2614 TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
   2615   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   2616 }
   2617 
   2618 TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
   2619   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   2620 }
   2621 
   2622 // Test the flow when both the proxy server AND origin server require
   2623 // authentication. Again, this uses basic auth for both since that is
   2624 // the simplest to mock.
   2625 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   2626   HttpRequestInfo request;
   2627   request.method = "GET";
   2628   request.url = GURL("http://www.google.com/");
   2629   request.load_flags = 0;
   2630 
   2631   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   2632 
   2633   // Configure against proxy server "myproxy:70".
   2634   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   2635       CreateSession(&session_deps)));
   2636 
   2637   MockWrite data_writes1[] = {
   2638     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2639               "Host: www.google.com\r\n"
   2640               "Proxy-Connection: keep-alive\r\n\r\n"),
   2641   };
   2642 
   2643   MockRead data_reads1[] = {
   2644     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   2645     // Give a couple authenticate options (only the middle one is actually
   2646     // supported).
   2647     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   2648     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2649     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   2650     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2651     // Large content-length -- won't matter, as connection will be reset.
   2652     MockRead("Content-Length: 10000\r\n\r\n"),
   2653     MockRead(false, ERR_FAILED),
   2654   };
   2655 
   2656   // After calling trans->RestartWithAuth() the first time, this is the
   2657   // request we should be issuing -- the final header line contains the
   2658   // proxy's credentials.
   2659   MockWrite data_writes2[] = {
   2660     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2661               "Host: www.google.com\r\n"
   2662               "Proxy-Connection: keep-alive\r\n"
   2663               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2664   };
   2665 
   2666   // Now the proxy server lets the request pass through to origin server.
   2667   // The origin server responds with a 401.
   2668   MockRead data_reads2[] = {
   2669     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2670     // Note: We are using the same realm-name as the proxy server. This is
   2671     // completely valid, as realms are unique across hosts.
   2672     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2673     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2674     MockRead("Content-Length: 2000\r\n\r\n"),
   2675     MockRead(false, ERR_FAILED),  // Won't be reached.
   2676   };
   2677 
   2678   // After calling trans->RestartWithAuth() the second time, we should send
   2679   // the credentials for both the proxy and origin server.
   2680   MockWrite data_writes3[] = {
   2681     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   2682               "Host: www.google.com\r\n"
   2683               "Proxy-Connection: keep-alive\r\n"
   2684               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   2685               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   2686   };
   2687 
   2688   // Lastly we get the desired content.
   2689   MockRead data_reads3[] = {
   2690     MockRead("HTTP/1.0 200 OK\r\n"),
   2691     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2692     MockRead("Content-Length: 100\r\n\r\n"),
   2693     MockRead(false, OK),
   2694   };
   2695 
   2696   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2697                                  data_writes1, arraysize(data_writes1));
   2698   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2699                                  data_writes2, arraysize(data_writes2));
   2700   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   2701                                  data_writes3, arraysize(data_writes3));
   2702   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2703   session_deps.socket_factory.AddSocketDataProvider(&data2);
   2704   session_deps.socket_factory.AddSocketDataProvider(&data3);
   2705 
   2706   TestCompletionCallback callback1;
   2707 
   2708   int rv = trans->Start(&request, &callback1, BoundNetLog());
   2709   EXPECT_EQ(ERR_IO_PENDING, rv);
   2710 
   2711   rv = callback1.WaitForResult();
   2712   EXPECT_EQ(OK, rv);
   2713 
   2714   const HttpResponseInfo* response = trans->GetResponseInfo();
   2715   EXPECT_FALSE(response == NULL);
   2716 
   2717   // The password prompt info should have been set in response->auth_challenge.
   2718   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2719 
   2720   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   2721   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2722   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2723 
   2724   TestCompletionCallback callback2;
   2725 
   2726   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   2727   EXPECT_EQ(ERR_IO_PENDING, rv);
   2728 
   2729   rv = callback2.WaitForResult();
   2730   EXPECT_EQ(OK, rv);
   2731 
   2732   response = trans->GetResponseInfo();
   2733   EXPECT_FALSE(response == NULL);
   2734   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2735 
   2736   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   2737   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2738   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2739 
   2740   TestCompletionCallback callback3;
   2741 
   2742   rv = trans->RestartWithAuth(kFoo2, kBar2, &callback3);
   2743   EXPECT_EQ(ERR_IO_PENDING, rv);
   2744 
   2745   rv = callback3.WaitForResult();
   2746   EXPECT_EQ(OK, rv);
   2747 
   2748   response = trans->GetResponseInfo();
   2749   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2750   EXPECT_EQ(100, response->headers->GetContentLength());
   2751 }
   2752 
   2753 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   2754 // can't hook into its internals to cause it to generate predictable NTLM
   2755 // authorization headers.
   2756 #if defined(NTLM_PORTABLE)
   2757 // The NTLM authentication unit tests were generated by capturing the HTTP
   2758 // requests and responses using Fiddler 2 and inspecting the generated random
   2759 // bytes in the debugger.
   2760 
   2761 // Enter the correct password and authenticate successfully.
   2762 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
   2763   HttpRequestInfo request;
   2764   request.method = "GET";
   2765   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   2766   request.load_flags = 0;
   2767 
   2768   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   2769                                                     MockGetHostName);
   2770   SessionDependencies session_deps;
   2771   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2772 
   2773   MockWrite data_writes1[] = {
   2774     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2775               "Host: 172.22.68.17\r\n"
   2776               "Connection: keep-alive\r\n\r\n"),
   2777   };
   2778 
   2779   MockRead data_reads1[] = {
   2780     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   2781     // Negotiate and NTLM are often requested together.  However, we only want
   2782     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   2783     // the header that requests Negotiate for this test.
   2784     MockRead("WWW-Authenticate: NTLM\r\n"),
   2785     MockRead("Connection: close\r\n"),
   2786     MockRead("Content-Length: 42\r\n"),
   2787     MockRead("Content-Type: text/html\r\n\r\n"),
   2788     // Missing content -- won't matter, as connection will be reset.
   2789     MockRead(false, ERR_UNEXPECTED),
   2790   };
   2791 
   2792   MockWrite data_writes2[] = {
   2793     // After restarting with a null identity, this is the
   2794     // request we should be issuing -- the final header line contains a Type
   2795     // 1 message.
   2796     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2797               "Host: 172.22.68.17\r\n"
   2798               "Connection: keep-alive\r\n"
   2799               "Authorization: NTLM "
   2800               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   2801 
   2802     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   2803     // (the credentials for the origin server).  The second request continues
   2804     // on the same connection.
   2805     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2806               "Host: 172.22.68.17\r\n"
   2807               "Connection: keep-alive\r\n"
   2808               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   2809               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   2810               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   2811               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   2812               "ahlhx5I=\r\n\r\n"),
   2813   };
   2814 
   2815   MockRead data_reads2[] = {
   2816     // The origin server responds with a Type 2 message.
   2817     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   2818     MockRead("WWW-Authenticate: NTLM "
   2819              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   2820              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   2821              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   2822              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   2823              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   2824              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   2825              "BtAAAAAAA=\r\n"),
   2826     MockRead("Content-Length: 42\r\n"),
   2827     MockRead("Content-Type: text/html\r\n\r\n"),
   2828     MockRead("You are not authorized to view this page\r\n"),
   2829 
   2830     // Lastly we get the desired content.
   2831     MockRead("HTTP/1.1 200 OK\r\n"),
   2832     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   2833     MockRead("Content-Length: 13\r\n\r\n"),
   2834     MockRead("Please Login\r\n"),
   2835     MockRead(false, OK),
   2836   };
   2837 
   2838   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   2839                                  data_writes1, arraysize(data_writes1));
   2840   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   2841                                  data_writes2, arraysize(data_writes2));
   2842   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2843   session_deps.socket_factory.AddSocketDataProvider(&data2);
   2844 
   2845   TestCompletionCallback callback1;
   2846 
   2847   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2848 
   2849   int rv = trans->Start(&request, &callback1, BoundNetLog());
   2850   EXPECT_EQ(ERR_IO_PENDING, rv);
   2851 
   2852   rv = callback1.WaitForResult();
   2853   EXPECT_EQ(OK, rv);
   2854 
   2855   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2856 
   2857   const HttpResponseInfo* response = trans->GetResponseInfo();
   2858   ASSERT_TRUE(response != NULL);
   2859 
   2860   // The password prompt info should have been set in
   2861   // response->auth_challenge.
   2862   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   2863 
   2864   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   2865   EXPECT_EQ(L"", response->auth_challenge->realm);
   2866   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   2867 
   2868   TestCompletionCallback callback2;
   2869 
   2870   rv = trans->RestartWithAuth(kTestingNTLM, kTestingNTLM, &callback2);
   2871   EXPECT_EQ(ERR_IO_PENDING, rv);
   2872 
   2873   rv = callback2.WaitForResult();
   2874   EXPECT_EQ(OK, rv);
   2875 
   2876   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   2877 
   2878   response = trans->GetResponseInfo();
   2879   ASSERT_TRUE(response != NULL);
   2880 
   2881   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2882 
   2883   TestCompletionCallback callback3;
   2884 
   2885   rv = trans->RestartWithAuth(string16(), string16(), &callback3);
   2886   EXPECT_EQ(ERR_IO_PENDING, rv);
   2887 
   2888   rv = callback3.WaitForResult();
   2889   EXPECT_EQ(OK, rv);
   2890 
   2891   response = trans->GetResponseInfo();
   2892   ASSERT_FALSE(response == NULL);
   2893   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2894   EXPECT_EQ(13, response->headers->GetContentLength());
   2895 }
   2896 
   2897 // Enter a wrong password, and then the correct one.
   2898 TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
   2899   HttpRequestInfo request;
   2900   request.method = "GET";
   2901   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   2902   request.load_flags = 0;
   2903 
   2904   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   2905                                                     MockGetHostName);
   2906   SessionDependencies session_deps;
   2907   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2908 
   2909   MockWrite data_writes1[] = {
   2910     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2911               "Host: 172.22.68.17\r\n"
   2912               "Connection: keep-alive\r\n\r\n"),
   2913   };
   2914 
   2915   MockRead data_reads1[] = {
   2916     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   2917     // Negotiate and NTLM are often requested together.  However, we only want
   2918     // to test NTLM. Since Negotiate is preferred over NTLM, we have to skip
   2919     // the header that requests Negotiate for this test.
   2920     MockRead("WWW-Authenticate: NTLM\r\n"),
   2921     MockRead("Connection: close\r\n"),
   2922     MockRead("Content-Length: 42\r\n"),
   2923     MockRead("Content-Type: text/html\r\n\r\n"),
   2924     // Missing content -- won't matter, as connection will be reset.
   2925     MockRead(false, ERR_UNEXPECTED),
   2926   };
   2927 
   2928   MockWrite data_writes2[] = {
   2929     // After restarting with a null identity, this is the
   2930     // request we should be issuing -- the final header line contains a Type
   2931     // 1 message.
   2932     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2933               "Host: 172.22.68.17\r\n"
   2934               "Connection: keep-alive\r\n"
   2935               "Authorization: NTLM "
   2936               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   2937 
   2938     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   2939     // (the credentials for the origin server).  The second request continues
   2940     // on the same connection.
   2941     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2942               "Host: 172.22.68.17\r\n"
   2943               "Connection: keep-alive\r\n"
   2944               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   2945               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   2946               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   2947               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   2948               "4Ww7b7E=\r\n\r\n"),
   2949   };
   2950 
   2951   MockRead data_reads2[] = {
   2952     // The origin server responds with a Type 2 message.
   2953     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   2954     MockRead("WWW-Authenticate: NTLM "
   2955              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   2956              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   2957              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   2958              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   2959              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   2960              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   2961              "BtAAAAAAA=\r\n"),
   2962     MockRead("Content-Length: 42\r\n"),
   2963     MockRead("Content-Type: text/html\r\n\r\n"),
   2964     MockRead("You are not authorized to view this page\r\n"),
   2965 
   2966     // Wrong password.
   2967     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   2968     MockRead("WWW-Authenticate: NTLM\r\n"),
   2969     MockRead("Connection: close\r\n"),
   2970     MockRead("Content-Length: 42\r\n"),
   2971     MockRead("Content-Type: text/html\r\n\r\n"),
   2972     // Missing content -- won't matter, as connection will be reset.
   2973     MockRead(false, ERR_UNEXPECTED),
   2974   };
   2975 
   2976   MockWrite data_writes3[] = {
   2977     // After restarting with a null identity, this is the
   2978     // request we should be issuing -- the final header line contains a Type
   2979     // 1 message.
   2980     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2981               "Host: 172.22.68.17\r\n"
   2982               "Connection: keep-alive\r\n"
   2983               "Authorization: NTLM "
   2984               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   2985 
   2986     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   2987     // (the credentials for the origin server).  The second request continues
   2988     // on the same connection.
   2989     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   2990               "Host: 172.22.68.17\r\n"
   2991               "Connection: keep-alive\r\n"
   2992               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   2993               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   2994               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   2995               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   2996               "+4MUm7c=\r\n\r\n"),
   2997   };
   2998 
   2999   MockRead data_reads3[] = {
   3000     // The origin server responds with a Type 2 message.
   3001     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   3002     MockRead("WWW-Authenticate: NTLM "
   3003              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   3004              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   3005              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   3006              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   3007              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   3008              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   3009              "BtAAAAAAA=\r\n"),
   3010     MockRead("Content-Length: 42\r\n"),
   3011     MockRead("Content-Type: text/html\r\n\r\n"),
   3012     MockRead("You are not authorized to view this page\r\n"),
   3013 
   3014     // Lastly we get the desired content.
   3015     MockRead("HTTP/1.1 200 OK\r\n"),
   3016     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   3017     MockRead("Content-Length: 13\r\n\r\n"),
   3018     MockRead("Please Login\r\n"),
   3019     MockRead(false, OK),
   3020   };
   3021 
   3022   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3023                                  data_writes1, arraysize(data_writes1));
   3024   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3025                                  data_writes2, arraysize(data_writes2));
   3026   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   3027                                  data_writes3, arraysize(data_writes3));
   3028   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3029   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3030   session_deps.socket_factory.AddSocketDataProvider(&data3);
   3031 
   3032   TestCompletionCallback callback1;
   3033 
   3034   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3035 
   3036   int rv = trans->Start(&request, &callback1, BoundNetLog());
   3037   EXPECT_EQ(ERR_IO_PENDING, rv);
   3038 
   3039   rv = callback1.WaitForResult();
   3040   EXPECT_EQ(OK, rv);
   3041 
   3042   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3043 
   3044   const HttpResponseInfo* response = trans->GetResponseInfo();
   3045   EXPECT_FALSE(response == NULL);
   3046 
   3047   // The password prompt info should have been set in response->auth_challenge.
   3048   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3049 
   3050   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   3051   EXPECT_EQ(L"", response->auth_challenge->realm);
   3052   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   3053 
   3054   TestCompletionCallback callback2;
   3055 
   3056   // Enter the wrong password.
   3057   rv = trans->RestartWithAuth(kTestingNTLM, kWrongPassword, &callback2);
   3058   EXPECT_EQ(ERR_IO_PENDING, rv);
   3059 
   3060   rv = callback2.WaitForResult();
   3061   EXPECT_EQ(OK, rv);
   3062 
   3063   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3064   TestCompletionCallback callback3;
   3065   rv = trans->RestartWithAuth(string16(), string16(), &callback3);
   3066   EXPECT_EQ(ERR_IO_PENDING, rv);
   3067   rv = callback3.WaitForResult();
   3068   EXPECT_EQ(OK, rv);
   3069   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3070 
   3071   response = trans->GetResponseInfo();
   3072   ASSERT_TRUE(response != NULL);
   3073 
   3074   // The password prompt info should have been set in response->auth_challenge.
   3075   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3076 
   3077   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   3078   EXPECT_EQ(L"", response->auth_challenge->realm);
   3079   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   3080 
   3081   TestCompletionCallback callback4;
   3082 
   3083   // Now enter the right password.
   3084   rv = trans->RestartWithAuth(kTestingNTLM, kTestingNTLM, &callback4);
   3085   EXPECT_EQ(ERR_IO_PENDING, rv);
   3086 
   3087   rv = callback4.WaitForResult();
   3088   EXPECT_EQ(OK, rv);
   3089 
   3090   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3091 
   3092   TestCompletionCallback callback5;
   3093 
   3094   // One more roundtrip
   3095   rv = trans->RestartWithAuth(string16(), string16(), &callback5);
   3096   EXPECT_EQ(ERR_IO_PENDING, rv);
   3097 
   3098   rv = callback5.WaitForResult();
   3099   EXPECT_EQ(OK, rv);
   3100 
   3101   response = trans->GetResponseInfo();
   3102   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3103   EXPECT_EQ(13, response->headers->GetContentLength());
   3104 }
   3105 #endif  // NTLM_PORTABLE
   3106 
   3107 // Test reading a server response which has only headers, and no body.
   3108 // After some maximum number of bytes is consumed, the transaction should
   3109 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   3110 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   3111   HttpRequestInfo request;
   3112   request.method = "GET";
   3113   request.url = GURL("http://www.google.com/");
   3114   request.load_flags = 0;
   3115 
   3116   SessionDependencies session_deps;
   3117   scoped_ptr<HttpTransaction> trans(
   3118       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3119 
   3120   // Respond with 300 kb of headers (we should fail after 256 kb).
   3121   std::string large_headers_string;
   3122   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   3123 
   3124   MockRead data_reads[] = {
   3125     MockRead("HTTP/1.0 200 OK\r\n"),
   3126     MockRead(true, large_headers_string.data(), large_headers_string.size()),
   3127     MockRead("\r\nBODY"),
   3128     MockRead(false, OK),
   3129   };
   3130   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   3131   session_deps.socket_factory.AddSocketDataProvider(&data);
   3132 
   3133   TestCompletionCallback callback;
   3134 
   3135   int rv = trans->Start(&request, &callback, BoundNetLog());
   3136   EXPECT_EQ(ERR_IO_PENDING, rv);
   3137 
   3138   rv = callback.WaitForResult();
   3139   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   3140 
   3141   const HttpResponseInfo* response = trans->GetResponseInfo();
   3142   EXPECT_TRUE(response == NULL);
   3143 }
   3144 
   3145 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   3146 // establish tunnel.
   3147 // http://code.google.com/p/chromium/issues/detail?id=3772
   3148 TEST_F(HttpNetworkTransactionTest, DontRecycleTransportSocketForSSLTunnel) {
   3149   HttpRequestInfo request;
   3150   request.method = "GET";
   3151   request.url = GURL("https://www.google.com/");
   3152   request.load_flags = 0;
   3153 
   3154   // Configure against proxy server "myproxy:70".
   3155   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   3156 
   3157   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3158 
   3159   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3160 
   3161   // Since we have proxy, should try to establish tunnel.
   3162   MockWrite data_writes1[] = {
   3163     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   3164               "Host: www.google.com\r\n"
   3165               "Proxy-Connection: keep-alive\r\n\r\n"),
   3166   };
   3167 
   3168   // The proxy responds to the connect with a 404, using a persistent
   3169   // connection. Usually a proxy would return 501 (not implemented),
   3170   // or 200 (tunnel established).
   3171   MockRead data_reads1[] = {
   3172     MockRead("HTTP/1.1 404 Not Found\r\n"),
   3173     MockRead("Content-Length: 10\r\n\r\n"),
   3174     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   3175   };
   3176 
   3177   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3178                                  data_writes1, arraysize(data_writes1));
   3179   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3180 
   3181   TestCompletionCallback callback1;
   3182 
   3183   int rv = trans->Start(&request, &callback1, BoundNetLog());
   3184   EXPECT_EQ(ERR_IO_PENDING, rv);
   3185 
   3186   rv = callback1.WaitForResult();
   3187   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3188 
   3189   const HttpResponseInfo* response = trans->GetResponseInfo();
   3190   EXPECT_TRUE(response == NULL);
   3191 
   3192   // Empty the current queue.  This is necessary because idle sockets are
   3193   // added to the connection pool asynchronously with a PostTask.
   3194   MessageLoop::current()->RunAllPending();
   3195 
   3196   // We now check to make sure the TCPClientSocket was not added back to
   3197   // the pool.
   3198   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3199   trans.reset();
   3200   MessageLoop::current()->RunAllPending();
   3201   // Make sure that the socket didn't get recycled after calling the destructor.
   3202   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3203 }
   3204 
   3205 // Make sure that we recycle a socket after reading all of the response body.
   3206 TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
   3207   HttpRequestInfo request;
   3208   request.method = "GET";
   3209   request.url = GURL("http://www.google.com/");
   3210   request.load_flags = 0;
   3211 
   3212   SessionDependencies session_deps;
   3213   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3214 
   3215   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3216 
   3217   MockRead data_reads[] = {
   3218     // A part of the response body is received with the response headers.
   3219     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   3220     // The rest of the response body is received in two parts.
   3221     MockRead("lo"),
   3222     MockRead(" world"),
   3223     MockRead("junk"),  // Should not be read!!
   3224     MockRead(false, OK),
   3225   };
   3226 
   3227   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   3228   session_deps.socket_factory.AddSocketDataProvider(&data);
   3229 
   3230   TestCompletionCallback callback;
   3231 
   3232   int rv = trans->Start(&request, &callback, BoundNetLog());
   3233   EXPECT_EQ(ERR_IO_PENDING, rv);
   3234 
   3235   rv = callback.WaitForResult();
   3236   EXPECT_EQ(OK, rv);
   3237 
   3238   const HttpResponseInfo* response = trans->GetResponseInfo();
   3239   EXPECT_TRUE(response != NULL);
   3240 
   3241   EXPECT_TRUE(response->headers != NULL);
   3242   std::string status_line = response->headers->GetStatusLine();
   3243   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   3244 
   3245   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3246 
   3247   std::string response_data;
   3248   rv = ReadTransaction(trans.get(), &response_data);
   3249   EXPECT_EQ(OK, rv);
   3250   EXPECT_EQ("hello world", response_data);
   3251 
   3252   // Empty the current queue.  This is necessary because idle sockets are
   3253   // added to the connection pool asynchronously with a PostTask.
   3254   MessageLoop::current()->RunAllPending();
   3255 
   3256   // We now check to make sure the socket was added back to the pool.
   3257   EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount());
   3258 }
   3259 
   3260 // Make sure that we recycle a SSL socket after reading all of the response
   3261 // body.
   3262 TEST_F(HttpNetworkTransactionTest, RecycleSSLSocket) {
   3263   SessionDependencies session_deps;
   3264   HttpRequestInfo request;
   3265   request.method = "GET";
   3266   request.url = GURL("https://www.google.com/");
   3267   request.load_flags = 0;
   3268 
   3269   MockWrite data_writes[] = {
   3270     MockWrite("GET / HTTP/1.1\r\n"
   3271               "Host: www.google.com\r\n"
   3272               "Connection: keep-alive\r\n\r\n"),
   3273   };
   3274 
   3275   MockRead data_reads[] = {
   3276     MockRead("HTTP/1.1 200 OK\r\n"),
   3277     MockRead("Content-Length: 11\r\n\r\n"),
   3278     MockRead("hello world"),
   3279     MockRead(false, OK),
   3280   };
   3281 
   3282   SSLSocketDataProvider ssl(true, OK);
   3283   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   3284 
   3285   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3286                                 data_writes, arraysize(data_writes));
   3287   session_deps.socket_factory.AddSocketDataProvider(&data);
   3288 
   3289   TestCompletionCallback callback;
   3290 
   3291   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3292   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3293 
   3294   int rv = trans->Start(&request, &callback, BoundNetLog());
   3295 
   3296   EXPECT_EQ(ERR_IO_PENDING, rv);
   3297   EXPECT_EQ(OK, callback.WaitForResult());
   3298 
   3299   const HttpResponseInfo* response = trans->GetResponseInfo();
   3300   ASSERT_TRUE(response != NULL);
   3301   ASSERT_TRUE(response->headers != NULL);
   3302   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3303 
   3304   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3305 
   3306   std::string response_data;
   3307   rv = ReadTransaction(trans.get(), &response_data);
   3308   EXPECT_EQ(OK, rv);
   3309   EXPECT_EQ("hello world", response_data);
   3310 
   3311   // Empty the current queue.  This is necessary because idle sockets are
   3312   // added to the connection pool asynchronously with a PostTask.
   3313   MessageLoop::current()->RunAllPending();
   3314 
   3315   // We now check to make sure the socket was added back to the pool.
   3316   EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount());
   3317 }
   3318 
   3319 // Grab a SSL socket, use it, and put it back into the pool.  Then, reuse it
   3320 // from the pool and make sure that we recover okay.
   3321 TEST_F(HttpNetworkTransactionTest, RecycleDeadSSLSocket) {
   3322   SessionDependencies session_deps;
   3323   HttpRequestInfo request;
   3324   request.method = "GET";
   3325   request.url = GURL("https://www.google.com/");
   3326   request.load_flags = 0;
   3327 
   3328   MockWrite data_writes[] = {
   3329     MockWrite("GET / HTTP/1.1\r\n"
   3330               "Host: www.google.com\r\n"
   3331               "Connection: keep-alive\r\n\r\n"),
   3332     MockWrite("GET / HTTP/1.1\r\n"
   3333               "Host: www.google.com\r\n"
   3334               "Connection: keep-alive\r\n\r\n"),
   3335   };
   3336 
   3337   MockRead data_reads[] = {
   3338     MockRead("HTTP/1.1 200 OK\r\n"),
   3339     MockRead("Content-Length: 11\r\n\r\n"),
   3340     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   3341     MockRead("hello world"),
   3342     MockRead(true, 0, 0)   // EOF
   3343   };
   3344 
   3345   SSLSocketDataProvider ssl(true, OK);
   3346   SSLSocketDataProvider ssl2(true, OK);
   3347   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   3348   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl2);
   3349 
   3350   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   3351                                 data_writes, arraysize(data_writes));
   3352   StaticSocketDataProvider data2(data_reads, arraysize(data_reads),
   3353                                 data_writes, arraysize(data_writes));
   3354   session_deps.socket_factory.AddSocketDataProvider(&data);
   3355   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3356 
   3357   TestCompletionCallback callback;
   3358 
   3359   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3360   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3361 
   3362   int rv = trans->Start(&request, &callback, BoundNetLog());
   3363 
   3364   EXPECT_EQ(ERR_IO_PENDING, rv);
   3365   EXPECT_EQ(OK, callback.WaitForResult());
   3366 
   3367   const HttpResponseInfo* response = trans->GetResponseInfo();
   3368   ASSERT_TRUE(response != NULL);
   3369   ASSERT_TRUE(response->headers != NULL);
   3370   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3371 
   3372   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3373 
   3374   std::string response_data;
   3375   rv = ReadTransaction(trans.get(), &response_data);
   3376   EXPECT_EQ(OK, rv);
   3377   EXPECT_EQ("hello world", response_data);
   3378 
   3379   // Empty the current queue.  This is necessary because idle sockets are
   3380   // added to the connection pool asynchronously with a PostTask.
   3381   MessageLoop::current()->RunAllPending();
   3382 
   3383   // We now check to make sure the socket was added back to the pool.
   3384   EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount());
   3385 
   3386   // Now start the second transaction, which should reuse the previous socket.
   3387 
   3388   trans.reset(new HttpNetworkTransaction(session));
   3389 
   3390   rv = trans->Start(&request, &callback, BoundNetLog());
   3391 
   3392   EXPECT_EQ(ERR_IO_PENDING, rv);
   3393   EXPECT_EQ(OK, callback.WaitForResult());
   3394 
   3395   response = trans->GetResponseInfo();
   3396   ASSERT_TRUE(response != NULL);
   3397   ASSERT_TRUE(response->headers != NULL);
   3398   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3399 
   3400   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3401 
   3402   rv = ReadTransaction(trans.get(), &response_data);
   3403   EXPECT_EQ(OK, rv);
   3404   EXPECT_EQ("hello world", response_data);
   3405 
   3406   // Empty the current queue.  This is necessary because idle sockets are
   3407   // added to the connection pool asynchronously with a PostTask.
   3408   MessageLoop::current()->RunAllPending();
   3409 
   3410   // We now check to make sure the socket was added back to the pool.
   3411   EXPECT_EQ(1, session->ssl_socket_pool()->IdleSocketCount());
   3412 }
   3413 
   3414 // Make sure that we recycle a socket after a zero-length response.
   3415 // http://crbug.com/9880
   3416 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   3417   HttpRequestInfo request;
   3418   request.method = "GET";
   3419   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   3420                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   3421                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   3422                      "rt=prt.2642,ol.2649,xjs.2951");
   3423   request.load_flags = 0;
   3424 
   3425   SessionDependencies session_deps;
   3426   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3427 
   3428   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3429 
   3430   MockRead data_reads[] = {
   3431     MockRead("HTTP/1.1 204 No Content\r\n"
   3432              "Content-Length: 0\r\n"
   3433              "Content-Type: text/html\r\n\r\n"),
   3434     MockRead("junk"),  // Should not be read!!
   3435     MockRead(false, OK),
   3436   };
   3437 
   3438   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   3439   session_deps.socket_factory.AddSocketDataProvider(&data);
   3440 
   3441   TestCompletionCallback callback;
   3442 
   3443   int rv = trans->Start(&request, &callback, BoundNetLog());
   3444   EXPECT_EQ(ERR_IO_PENDING, rv);
   3445 
   3446   rv = callback.WaitForResult();
   3447   EXPECT_EQ(OK, rv);
   3448 
   3449   const HttpResponseInfo* response = trans->GetResponseInfo();
   3450   EXPECT_TRUE(response != NULL);
   3451 
   3452   EXPECT_TRUE(response->headers != NULL);
   3453   std::string status_line = response->headers->GetStatusLine();
   3454   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   3455 
   3456   EXPECT_EQ(0, session->transport_socket_pool()->IdleSocketCount());
   3457 
   3458   std::string response_data;
   3459   rv = ReadTransaction(trans.get(), &response_data);
   3460   EXPECT_EQ(OK, rv);
   3461   EXPECT_EQ("", response_data);
   3462 
   3463   // Empty the current queue.  This is necessary because idle sockets are
   3464   // added to the connection pool asynchronously with a PostTask.
   3465   MessageLoop::current()->RunAllPending();
   3466 
   3467   // We now check to make sure the socket was added back to the pool.
   3468   EXPECT_EQ(1, session->transport_socket_pool()->IdleSocketCount());
   3469 }
   3470 
   3471 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   3472   HttpRequestInfo request[2];
   3473   // Transaction 1: a GET request that succeeds.  The socket is recycled
   3474   // after use.
   3475   request[0].method = "GET";
   3476   request[0].url = GURL("http://www.google.com/");
   3477   request[0].load_flags = 0;
   3478   // Transaction 2: a POST request.  Reuses the socket kept alive from
   3479   // transaction 1.  The first attempts fails when writing the POST data.
   3480   // This causes the transaction to retry with a new socket.  The second
   3481   // attempt succeeds.
   3482   request[1].method = "POST";
   3483   request[1].url = GURL("http://www.google.com/login.cgi");
   3484   request[1].upload_data = new UploadData;
   3485   request[1].upload_data->AppendBytes("foo", 3);
   3486   request[1].load_flags = 0;
   3487 
   3488   SessionDependencies session_deps;
   3489   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3490 
   3491   // The first socket is used for transaction 1 and the first attempt of
   3492   // transaction 2.
   3493 
   3494   // The response of transaction 1.
   3495   MockRead data_reads1[] = {
   3496     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   3497     MockRead("hello world"),
   3498     MockRead(false, OK),
   3499   };
   3500   // The mock write results of transaction 1 and the first attempt of
   3501   // transaction 2.
   3502   MockWrite data_writes1[] = {
   3503     MockWrite(false, 64),  // GET
   3504     MockWrite(false, 93),  // POST
   3505     MockWrite(false, ERR_CONNECTION_ABORTED),  // POST data
   3506   };
   3507   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3508                                  data_writes1, arraysize(data_writes1));
   3509 
   3510   // The second socket is used for the second attempt of transaction 2.
   3511 
   3512   // The response of transaction 2.
   3513   MockRead data_reads2[] = {
   3514     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   3515     MockRead("welcome"),
   3516     MockRead(false, OK),
   3517   };
   3518   // The mock write results of the second attempt of transaction 2.
   3519   MockWrite data_writes2[] = {
   3520     MockWrite(false, 93),  // POST
   3521     MockWrite(false, 3),  // POST data
   3522   };
   3523   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3524                                  data_writes2, arraysize(data_writes2));
   3525 
   3526   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3527   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3528 
   3529   const char* kExpectedResponseData[] = {
   3530     "hello world", "welcome"
   3531   };
   3532 
   3533   for (int i = 0; i < 2; ++i) {
   3534     scoped_ptr<HttpTransaction> trans(
   3535         new HttpNetworkTransaction(session));
   3536 
   3537     TestCompletionCallback callback;
   3538 
   3539     int rv = trans->Start(&request[i], &callback, BoundNetLog());
   3540     EXPECT_EQ(ERR_IO_PENDING, rv);
   3541 
   3542     rv = callback.WaitForResult();
   3543     EXPECT_EQ(OK, rv);
   3544 
   3545     const HttpResponseInfo* response = trans->GetResponseInfo();
   3546     EXPECT_TRUE(response != NULL);
   3547 
   3548     EXPECT_TRUE(response->headers != NULL);
   3549     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   3550 
   3551     std::string response_data;
   3552     rv = ReadTransaction(trans.get(), &response_data);
   3553     EXPECT_EQ(OK, rv);
   3554     EXPECT_EQ(kExpectedResponseData[i], response_data);
   3555   }
   3556 }
   3557 
   3558 // Test the request-challenge-retry sequence for basic auth when there is
   3559 // an identity in the URL. The request should be sent as normal, but when
   3560 // it fails the identity from the URL is used to answer the challenge.
   3561 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
   3562   HttpRequestInfo request;
   3563   request.method = "GET";
   3564   // Note: the URL has a username:password in it.
   3565   request.url = GURL("http://foo:b@r@www.google.com/");
   3566 
   3567   SessionDependencies session_deps;
   3568   scoped_ptr<HttpTransaction> trans(
   3569       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3570 
   3571   // The password contains an escaped character -- for this test to pass it
   3572   // will need to be unescaped by HttpNetworkTransaction.
   3573   EXPECT_EQ("b%40r", request.url.password());
   3574 
   3575   request.load_flags = LOAD_NORMAL;
   3576 
   3577   MockWrite data_writes1[] = {
   3578     MockWrite("GET / HTTP/1.1\r\n"
   3579               "Host: www.google.com\r\n"
   3580               "Connection: keep-alive\r\n\r\n"),
   3581   };
   3582 
   3583   MockRead data_reads1[] = {
   3584     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3585     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3586     MockRead("Content-Length: 10\r\n\r\n"),
   3587     MockRead(false, ERR_FAILED),
   3588   };
   3589 
   3590   // After the challenge above, the transaction will be restarted using the
   3591   // identity from the url (foo, b@r) to answer the challenge.
   3592   MockWrite data_writes2[] = {
   3593     MockWrite("GET / HTTP/1.1\r\n"
   3594               "Host: www.google.com\r\n"
   3595               "Connection: keep-alive\r\n"
   3596               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   3597   };
   3598 
   3599   MockRead data_reads2[] = {
   3600     MockRead("HTTP/1.0 200 OK\r\n"),
   3601     MockRead("Content-Length: 100\r\n\r\n"),
   3602     MockRead(false, OK),
   3603   };
   3604 
   3605   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3606                                  data_writes1, arraysize(data_writes1));
   3607   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3608                                  data_writes2, arraysize(data_writes2));
   3609   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3610   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3611 
   3612   TestCompletionCallback callback1;
   3613 
   3614   int rv = trans->Start(&request, &callback1, BoundNetLog());
   3615   EXPECT_EQ(ERR_IO_PENDING, rv);
   3616 
   3617   rv = callback1.WaitForResult();
   3618   EXPECT_EQ(OK, rv);
   3619 
   3620   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3621   TestCompletionCallback callback2;
   3622   rv = trans->RestartWithAuth(string16(), string16(), &callback2);
   3623   EXPECT_EQ(ERR_IO_PENDING, rv);
   3624   rv = callback2.WaitForResult();
   3625   EXPECT_EQ(OK, rv);
   3626   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3627 
   3628   const HttpResponseInfo* response = trans->GetResponseInfo();
   3629   EXPECT_FALSE(response == NULL);
   3630 
   3631   // There is no challenge info, since the identity in URL worked.
   3632   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3633 
   3634   EXPECT_EQ(100, response->headers->GetContentLength());
   3635 
   3636   // Empty the current queue.
   3637   MessageLoop::current()->RunAllPending();
   3638 }
   3639 
   3640 // Test the request-challenge-retry sequence for basic auth when there is
   3641 // an incorrect identity in the URL. The identity from the URL should be used
   3642 // only once.
   3643 TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   3644   HttpRequestInfo request;
   3645   request.method = "GET";
   3646   // Note: the URL has a username:password in it.  The password "baz" is
   3647   // wrong (should be "bar").
   3648   request.url = GURL("http://foo:baz@www.google.com/");
   3649 
   3650   request.load_flags = LOAD_NORMAL;
   3651 
   3652   SessionDependencies session_deps;
   3653   scoped_ptr<HttpTransaction> trans(
   3654       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3655 
   3656   MockWrite data_writes1[] = {
   3657     MockWrite("GET / HTTP/1.1\r\n"
   3658               "Host: www.google.com\r\n"
   3659               "Connection: keep-alive\r\n\r\n"),
   3660   };
   3661 
   3662   MockRead data_reads1[] = {
   3663     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3664     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3665     MockRead("Content-Length: 10\r\n\r\n"),
   3666     MockRead(false, ERR_FAILED),
   3667   };
   3668 
   3669   // After the challenge above, the transaction will be restarted using the
   3670   // identity from the url (foo, baz) to answer the challenge.
   3671   MockWrite data_writes2[] = {
   3672     MockWrite("GET / HTTP/1.1\r\n"
   3673               "Host: www.google.com\r\n"
   3674               "Connection: keep-alive\r\n"
   3675               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   3676   };
   3677 
   3678   MockRead data_reads2[] = {
   3679     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3680     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3681     MockRead("Content-Length: 10\r\n\r\n"),
   3682     MockRead(false, ERR_FAILED),
   3683   };
   3684 
   3685   // After the challenge above, the transaction will be restarted using the
   3686   // identity supplied by the user (foo, bar) to answer the challenge.
   3687   MockWrite data_writes3[] = {
   3688     MockWrite("GET / HTTP/1.1\r\n"
   3689               "Host: www.google.com\r\n"
   3690               "Connection: keep-alive\r\n"
   3691               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3692   };
   3693 
   3694   MockRead data_reads3[] = {
   3695     MockRead("HTTP/1.0 200 OK\r\n"),
   3696     MockRead("Content-Length: 100\r\n\r\n"),
   3697     MockRead(false, OK),
   3698   };
   3699 
   3700   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3701                                  data_writes1, arraysize(data_writes1));
   3702   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3703                                  data_writes2, arraysize(data_writes2));
   3704   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   3705                                  data_writes3, arraysize(data_writes3));
   3706   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3707   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3708   session_deps.socket_factory.AddSocketDataProvider(&data3);
   3709 
   3710   TestCompletionCallback callback1;
   3711 
   3712   int rv = trans->Start(&request, &callback1, BoundNetLog());
   3713   EXPECT_EQ(ERR_IO_PENDING, rv);
   3714 
   3715   rv = callback1.WaitForResult();
   3716   EXPECT_EQ(OK, rv);
   3717 
   3718   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   3719   TestCompletionCallback callback2;
   3720   rv = trans->RestartWithAuth(string16(), string16(), &callback2);
   3721   EXPECT_EQ(ERR_IO_PENDING, rv);
   3722   rv = callback2.WaitForResult();
   3723   EXPECT_EQ(OK, rv);
   3724   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3725 
   3726   const HttpResponseInfo* response = trans->GetResponseInfo();
   3727   EXPECT_FALSE(response == NULL);
   3728   // The password prompt info should have been set in response->auth_challenge.
   3729   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3730 
   3731   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   3732   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   3733   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   3734 
   3735   TestCompletionCallback callback3;
   3736   rv = trans->RestartWithAuth(kFoo, kBar, &callback3);
   3737   EXPECT_EQ(ERR_IO_PENDING, rv);
   3738   rv = callback3.WaitForResult();
   3739   EXPECT_EQ(OK, rv);
   3740   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   3741 
   3742   response = trans->GetResponseInfo();
   3743   EXPECT_FALSE(response == NULL);
   3744 
   3745   // There is no challenge info, since the identity worked.
   3746   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3747 
   3748   EXPECT_EQ(100, response->headers->GetContentLength());
   3749 
   3750   // Empty the current queue.
   3751   MessageLoop::current()->RunAllPending();
   3752 }
   3753 
   3754 // Test that previously tried username/passwords for a realm get re-used.
   3755 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   3756   SessionDependencies session_deps;
   3757   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3758 
   3759   // Transaction 1: authenticate (foo, bar) on MyRealm1
   3760   {
   3761     HttpRequestInfo request;
   3762     request.method = "GET";
   3763     request.url = GURL("http://www.google.com/x/y/z");
   3764     request.load_flags = 0;
   3765 
   3766     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3767 
   3768     MockWrite data_writes1[] = {
   3769       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   3770                 "Host: www.google.com\r\n"
   3771                 "Connection: keep-alive\r\n\r\n"),
   3772     };
   3773 
   3774     MockRead data_reads1[] = {
   3775       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3776       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3777       MockRead("Content-Length: 10000\r\n\r\n"),
   3778       MockRead(false, ERR_FAILED),
   3779     };
   3780 
   3781     // Resend with authorization (username=foo, password=bar)
   3782     MockWrite data_writes2[] = {
   3783       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   3784                 "Host: www.google.com\r\n"
   3785                 "Connection: keep-alive\r\n"
   3786                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3787     };
   3788 
   3789     // Sever accepts the authorization.
   3790     MockRead data_reads2[] = {
   3791       MockRead("HTTP/1.0 200 OK\r\n"),
   3792       MockRead("Content-Length: 100\r\n\r\n"),
   3793       MockRead(false, OK),
   3794     };
   3795 
   3796     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3797                                    data_writes1, arraysize(data_writes1));
   3798     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3799                                    data_writes2, arraysize(data_writes2));
   3800     session_deps.socket_factory.AddSocketDataProvider(&data1);
   3801     session_deps.socket_factory.AddSocketDataProvider(&data2);
   3802 
   3803     TestCompletionCallback callback1;
   3804 
   3805     int rv = trans->Start(&request, &callback1, BoundNetLog());
   3806     EXPECT_EQ(ERR_IO_PENDING, rv);
   3807 
   3808     rv = callback1.WaitForResult();
   3809     EXPECT_EQ(OK, rv);
   3810 
   3811     const HttpResponseInfo* response = trans->GetResponseInfo();
   3812     EXPECT_FALSE(response == NULL);
   3813 
   3814     // The password prompt info should have been set in
   3815     // response->auth_challenge.
   3816     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3817 
   3818     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   3819     EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   3820     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   3821 
   3822     TestCompletionCallback callback2;
   3823 
   3824     rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   3825     EXPECT_EQ(ERR_IO_PENDING, rv);
   3826 
   3827     rv = callback2.WaitForResult();
   3828     EXPECT_EQ(OK, rv);
   3829 
   3830     response = trans->GetResponseInfo();
   3831     EXPECT_FALSE(response == NULL);
   3832     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3833     EXPECT_EQ(100, response->headers->GetContentLength());
   3834   }
   3835 
   3836   // ------------------------------------------------------------------------
   3837 
   3838   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   3839   {
   3840     HttpRequestInfo request;
   3841     request.method = "GET";
   3842     // Note that Transaction 1 was at /x/y/z, so this is in the same
   3843     // protection space as MyRealm1.
   3844     request.url = GURL("http://www.google.com/x/y/a/b");
   3845     request.load_flags = 0;
   3846 
   3847     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3848 
   3849     MockWrite data_writes1[] = {
   3850       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   3851                 "Host: www.google.com\r\n"
   3852                 "Connection: keep-alive\r\n"
   3853                 // Send preemptive authorization for MyRealm1
   3854                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3855     };
   3856 
   3857     // The server didn't like the preemptive authorization, and
   3858     // challenges us for a different realm (MyRealm2).
   3859     MockRead data_reads1[] = {
   3860       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3861       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   3862       MockRead("Content-Length: 10000\r\n\r\n"),
   3863       MockRead(false, ERR_FAILED),
   3864     };
   3865 
   3866     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   3867     MockWrite data_writes2[] = {
   3868       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   3869                 "Host: www.google.com\r\n"
   3870                 "Connection: keep-alive\r\n"
   3871                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   3872     };
   3873 
   3874     // Sever accepts the authorization.
   3875     MockRead data_reads2[] = {
   3876       MockRead("HTTP/1.0 200 OK\r\n"),
   3877       MockRead("Content-Length: 100\r\n\r\n"),
   3878       MockRead(false, OK),
   3879     };
   3880 
   3881     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3882                                    data_writes1, arraysize(data_writes1));
   3883     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   3884                                    data_writes2, arraysize(data_writes2));
   3885     session_deps.socket_factory.AddSocketDataProvider(&data1);
   3886     session_deps.socket_factory.AddSocketDataProvider(&data2);
   3887 
   3888     TestCompletionCallback callback1;
   3889 
   3890     int rv = trans->Start(&request, &callback1, BoundNetLog());
   3891     EXPECT_EQ(ERR_IO_PENDING, rv);
   3892 
   3893     rv = callback1.WaitForResult();
   3894     EXPECT_EQ(OK, rv);
   3895 
   3896     const HttpResponseInfo* response = trans->GetResponseInfo();
   3897     EXPECT_FALSE(response == NULL);
   3898 
   3899     // The password prompt info should have been set in
   3900     // response->auth_challenge.
   3901     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3902 
   3903     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   3904     EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm);
   3905     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   3906 
   3907     TestCompletionCallback callback2;
   3908 
   3909     rv = trans->RestartWithAuth(kFoo2, kBar2, &callback2);
   3910     EXPECT_EQ(ERR_IO_PENDING, rv);
   3911 
   3912     rv = callback2.WaitForResult();
   3913     EXPECT_EQ(OK, rv);
   3914 
   3915     response = trans->GetResponseInfo();
   3916     EXPECT_FALSE(response == NULL);
   3917     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3918     EXPECT_EQ(100, response->headers->GetContentLength());
   3919   }
   3920 
   3921   // ------------------------------------------------------------------------
   3922 
   3923   // Transaction 3: Resend a request in MyRealm's protection space --
   3924   // succeed with preemptive authorization.
   3925   {
   3926     HttpRequestInfo request;
   3927     request.method = "GET";
   3928     request.url = GURL("http://www.google.com/x/y/z2");
   3929     request.load_flags = 0;
   3930 
   3931     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3932 
   3933     MockWrite data_writes1[] = {
   3934       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   3935                 "Host: www.google.com\r\n"
   3936                 "Connection: keep-alive\r\n"
   3937                 // The authorization for MyRealm1 gets sent preemptively
   3938                 // (since the url is in the same protection space)
   3939                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3940     };
   3941 
   3942     // Sever accepts the preemptive authorization
   3943     MockRead data_reads1[] = {
   3944       MockRead("HTTP/1.0 200 OK\r\n"),
   3945       MockRead("Content-Length: 100\r\n\r\n"),
   3946       MockRead(false, OK),
   3947     };
   3948 
   3949     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   3950                                    data_writes1, arraysize(data_writes1));
   3951     session_deps.socket_factory.AddSocketDataProvider(&data1);
   3952 
   3953     TestCompletionCallback callback1;
   3954 
   3955     int rv = trans->Start(&request, &callback1, BoundNetLog());
   3956     EXPECT_EQ(ERR_IO_PENDING, rv);
   3957 
   3958     rv = callback1.WaitForResult();
   3959     EXPECT_EQ(OK, rv);
   3960 
   3961     const HttpResponseInfo* response = trans->GetResponseInfo();
   3962     EXPECT_FALSE(response == NULL);
   3963 
   3964     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3965     EXPECT_EQ(100, response->headers->GetContentLength());
   3966   }
   3967 
   3968   // ------------------------------------------------------------------------
   3969 
   3970   // Transaction 4: request another URL in MyRealm (however the
   3971   // url is not known to belong to the protection space, so no pre-auth).
   3972   {
   3973     HttpRequestInfo request;
   3974     request.method = "GET";
   3975     request.url = GURL("http://www.google.com/x/1");
   3976     request.load_flags = 0;
   3977 
   3978     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3979 
   3980     MockWrite data_writes1[] = {
   3981       MockWrite("GET /x/1 HTTP/1.1\r\n"
   3982                 "Host: www.google.com\r\n"
   3983                 "Connection: keep-alive\r\n\r\n"),
   3984     };
   3985 
   3986     MockRead data_reads1[] = {
   3987       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   3988       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3989       MockRead("Content-Length: 10000\r\n\r\n"),
   3990       MockRead(false, ERR_FAILED),
   3991     };
   3992 
   3993     // Resend with authorization from MyRealm's cache.
   3994     MockWrite data_writes2[] = {
   3995       MockWrite("GET /x/1 HTTP/1.1\r\n"
   3996                 "Host: www.google.com\r\n"
   3997                 "Connection: keep-alive\r\n"
   3998                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3999     };
   4000 
   4001     // Sever accepts the authorization.
   4002     MockRead data_reads2[] = {
   4003       MockRead("HTTP/1.0 200 OK\r\n"),
   4004       MockRead("Content-Length: 100\r\n\r\n"),
   4005       MockRead(false, OK),
   4006     };
   4007 
   4008     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4009                                    data_writes1, arraysize(data_writes1));
   4010     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4011                                    data_writes2, arraysize(data_writes2));
   4012     session_deps.socket_factory.AddSocketDataProvider(&data1);
   4013     session_deps.socket_factory.AddSocketDataProvider(&data2);
   4014 
   4015     TestCompletionCallback callback1;
   4016 
   4017     int rv = trans->Start(&request, &callback1, BoundNetLog());
   4018     EXPECT_EQ(ERR_IO_PENDING, rv);
   4019 
   4020     rv = callback1.WaitForResult();
   4021     EXPECT_EQ(OK, rv);
   4022 
   4023     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4024     TestCompletionCallback callback2;
   4025     rv = trans->RestartWithAuth(string16(), string16(), &callback2);
   4026     EXPECT_EQ(ERR_IO_PENDING, rv);
   4027     rv = callback2.WaitForResult();
   4028     EXPECT_EQ(OK, rv);
   4029     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4030 
   4031     const HttpResponseInfo* response = trans->GetResponseInfo();
   4032     EXPECT_FALSE(response == NULL);
   4033     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4034     EXPECT_EQ(100, response->headers->GetContentLength());
   4035   }
   4036 
   4037   // ------------------------------------------------------------------------
   4038 
   4039   // Transaction 5: request a URL in MyRealm, but the server rejects the
   4040   // cached identity. Should invalidate and re-prompt.
   4041   {
   4042     HttpRequestInfo request;
   4043     request.method = "GET";
   4044     request.url = GURL("http://www.google.com/p/q/t");
   4045     request.load_flags = 0;
   4046 
   4047     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   4048 
   4049     MockWrite data_writes1[] = {
   4050       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   4051                 "Host: www.google.com\r\n"
   4052                 "Connection: keep-alive\r\n\r\n"),
   4053     };
   4054 
   4055     MockRead data_reads1[] = {
   4056       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4057       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4058       MockRead("Content-Length: 10000\r\n\r\n"),
   4059       MockRead(false, ERR_FAILED),
   4060     };
   4061 
   4062     // Resend with authorization from cache for MyRealm.
   4063     MockWrite data_writes2[] = {
   4064       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   4065                 "Host: www.google.com\r\n"
   4066                 "Connection: keep-alive\r\n"
   4067                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   4068     };
   4069 
   4070     // Sever rejects the authorization.
   4071     MockRead data_reads2[] = {
   4072       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4073       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4074       MockRead("Content-Length: 10000\r\n\r\n"),
   4075       MockRead(false, ERR_FAILED),
   4076     };
   4077 
   4078     // At this point we should prompt for new credentials for MyRealm.
   4079     // Restart with username=foo3, password=foo4.
   4080     MockWrite data_writes3[] = {
   4081       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   4082                 "Host: www.google.com\r\n"
   4083                 "Connection: keep-alive\r\n"
   4084                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   4085     };
   4086 
   4087     // Sever accepts the authorization.
   4088     MockRead data_reads3[] = {
   4089       MockRead("HTTP/1.0 200 OK\r\n"),
   4090       MockRead("Content-Length: 100\r\n\r\n"),
   4091       MockRead(false, OK),
   4092     };
   4093 
   4094     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4095                                    data_writes1, arraysize(data_writes1));
   4096     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4097                                    data_writes2, arraysize(data_writes2));
   4098     StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   4099                                    data_writes3, arraysize(data_writes3));
   4100     session_deps.socket_factory.AddSocketDataProvider(&data1);
   4101     session_deps.socket_factory.AddSocketDataProvider(&data2);
   4102     session_deps.socket_factory.AddSocketDataProvider(&data3);
   4103 
   4104     TestCompletionCallback callback1;
   4105 
   4106     int rv = trans->Start(&request, &callback1, BoundNetLog());
   4107     EXPECT_EQ(ERR_IO_PENDING, rv);
   4108 
   4109     rv = callback1.WaitForResult();
   4110     EXPECT_EQ(OK, rv);
   4111 
   4112     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   4113     TestCompletionCallback callback2;
   4114     rv = trans->RestartWithAuth(string16(), string16(), &callback2);
   4115     EXPECT_EQ(ERR_IO_PENDING, rv);
   4116     rv = callback2.WaitForResult();
   4117     EXPECT_EQ(OK, rv);
   4118     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   4119 
   4120     const HttpResponseInfo* response = trans->GetResponseInfo();
   4121     EXPECT_FALSE(response == NULL);
   4122 
   4123     // The password prompt info should have been set in
   4124     // response->auth_challenge.
   4125     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   4126 
   4127     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   4128     EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   4129     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   4130 
   4131     TestCompletionCallback callback3;
   4132 
   4133     rv = trans->RestartWithAuth(kFoo3, kBar3, &callback3);
   4134     EXPECT_EQ(ERR_IO_PENDING, rv);
   4135 
   4136     rv = callback3.WaitForResult();
   4137     EXPECT_EQ(OK, rv);
   4138 
   4139     response = trans->GetResponseInfo();
   4140     EXPECT_FALSE(response == NULL);
   4141     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4142     EXPECT_EQ(100, response->headers->GetContentLength());
   4143   }
   4144 }
   4145 
   4146 // Tests that nonce count increments when multiple auth attempts
   4147 // are started with the same nonce.
   4148 TEST_F(HttpNetworkTransactionTest, DigestPreAuthNonceCount) {
   4149   SessionDependencies session_deps;
   4150   HttpAuthHandlerDigest::Factory* digest_factory =
   4151       new HttpAuthHandlerDigest::Factory();
   4152   HttpAuthHandlerDigest::FixedNonceGenerator* nonce_generator =
   4153       new HttpAuthHandlerDigest::FixedNonceGenerator("0123456789abcdef");
   4154   digest_factory->set_nonce_generator(nonce_generator);
   4155   session_deps.http_auth_handler_factory.reset(digest_factory);
   4156   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   4157 
   4158   // Transaction 1: authenticate (foo, bar) on MyRealm1
   4159   {
   4160     HttpRequestInfo request;
   4161     request.method = "GET";
   4162     request.url = GURL("http://www.google.com/x/y/z");
   4163     request.load_flags = 0;
   4164 
   4165     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   4166 
   4167     MockWrite data_writes1[] = {
   4168       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4169                 "Host: www.google.com\r\n"
   4170                 "Connection: keep-alive\r\n\r\n"),
   4171     };
   4172 
   4173     MockRead data_reads1[] = {
   4174       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   4175       MockRead("WWW-Authenticate: Digest realm=\"digestive\", nonce=\"OU812\", "
   4176                "algorithm=MD5, qop=\"auth\"\r\n\r\n"),
   4177       MockRead(false, OK),
   4178     };
   4179 
   4180     // Resend with authorization (username=foo, password=bar)
   4181     MockWrite data_writes2[] = {
   4182       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   4183                 "Host: www.google.com\r\n"
   4184                 "Connection: keep-alive\r\n"
   4185                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   4186                 "nonce=\"OU812\", uri=\"/x/y/z\", algorithm=MD5, "
   4187                 "response=\"03ffbcd30add722589c1de345d7a927f\", qop=auth, "
   4188                 "nc=00000001, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   4189     };
   4190 
   4191     // Sever accepts the authorization.
   4192     MockRead data_reads2[] = {
   4193       MockRead("HTTP/1.0 200 OK\r\n"),
   4194       MockRead(false, OK),
   4195     };
   4196 
   4197     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4198                                    data_writes1, arraysize(data_writes1));
   4199     StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   4200                                    data_writes2, arraysize(data_writes2));
   4201     session_deps.socket_factory.AddSocketDataProvider(&data1);
   4202     session_deps.socket_factory.AddSocketDataProvider(&data2);
   4203 
   4204     TestCompletionCallback callback1;
   4205 
   4206     int rv = trans->Start(&request, &callback1, BoundNetLog());
   4207     EXPECT_EQ(ERR_IO_PENDING, rv);
   4208 
   4209     rv = callback1.WaitForResult();
   4210     EXPECT_EQ(OK, rv);
   4211 
   4212     const HttpResponseInfo* response = trans->GetResponseInfo();
   4213     ASSERT_FALSE(response == NULL);
   4214 
   4215     // The password prompt info should have been set in
   4216     // response->auth_challenge.
   4217     ASSERT_FALSE(response->auth_challenge.get() == NULL);
   4218 
   4219     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   4220     EXPECT_EQ(L"digestive", response->auth_challenge->realm);
   4221     EXPECT_EQ(L"digest", response->auth_challenge->scheme);
   4222 
   4223     TestCompletionCallback callback2;
   4224 
   4225     rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   4226     EXPECT_EQ(ERR_IO_PENDING, rv);
   4227 
   4228     rv = callback2.WaitForResult();
   4229     EXPECT_EQ(OK, rv);
   4230 
   4231     response = trans->GetResponseInfo();
   4232     ASSERT_FALSE(response == NULL);
   4233     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4234   }
   4235 
   4236   // ------------------------------------------------------------------------
   4237 
   4238   // Transaction 2: Request another resource in digestive's protection space.
   4239   // This will preemptively add an Authorization header which should have an
   4240   // "nc" value of 2 (as compared to 1 in the first use.
   4241   {
   4242     HttpRequestInfo request;
   4243     request.method = "GET";
   4244     // Note that Transaction 1 was at /x/y/z, so this is in the same
   4245     // protection space as digest.
   4246     request.url = GURL("http://www.google.com/x/y/a/b");
   4247     request.load_flags = 0;
   4248 
   4249     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   4250 
   4251     MockWrite data_writes1[] = {
   4252       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   4253                 "Host: www.google.com\r\n"
   4254                 "Connection: keep-alive\r\n"
   4255                 "Authorization: Digest username=\"foo\", realm=\"digestive\", "
   4256                 "nonce=\"OU812\", uri=\"/x/y/a/b\", algorithm=MD5, "
   4257                 "response=\"d6f9a2c07d1c5df7b89379dca1269b35\", qop=auth, "
   4258                 "nc=00000002, cnonce=\"0123456789abcdef\"\r\n\r\n"),
   4259     };
   4260 
   4261     // Sever accepts the authorization.
   4262     MockRead data_reads1[] = {
   4263       MockRead("HTTP/1.0 200 OK\r\n"),
   4264       MockRead("Content-Length: 100\r\n\r\n"),
   4265       MockRead(false, OK),
   4266     };
   4267 
   4268     StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   4269                                    data_writes1, arraysize(data_writes1));
   4270     session_deps.socket_factory.AddSocketDataProvider(&data1);
   4271 
   4272     TestCompletionCallback callback1;
   4273 
   4274     int rv = trans->Start(&request, &callback1, BoundNetLog());
   4275     EXPECT_EQ(ERR_IO_PENDING, rv);
   4276 
   4277     rv = callback1.WaitForResult();
   4278     EXPECT_EQ(OK, rv);
   4279 
   4280     const HttpResponseInfo* response = trans->GetResponseInfo();
   4281     ASSERT_FALSE(response == NULL);
   4282     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4283   }
   4284 }
   4285 
   4286 // Test the ResetStateForRestart() private method.
   4287 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
   4288   // Create a transaction (the dependencies aren't important).
   4289   SessionDependencies session_deps;
   4290   scoped_ptr<HttpNetworkTransaction> trans(
   4291       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4292 
   4293   // Setup some state (which we expect ResetStateForRestart() will clear).
   4294   trans->read_buf_ = new IOBuffer(15);
   4295   trans->read_buf_len_ = 15;
   4296   trans->request_headers_.SetHeader("Authorization", "NTLM");
   4297 
   4298   // Setup state in response_
   4299   HttpResponseInfo* response = &trans->response_;
   4300   response->auth_challenge = new AuthChallengeInfo();
   4301   response->ssl_info.cert_status = -15;
   4302   response->response_time = base::Time::Now();
   4303   response->was_cached = true;  // (Wouldn't ever actually be true...)
   4304 
   4305   { // Setup state for response_.vary_data
   4306     HttpRequestInfo request;
   4307     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   4308     std::replace(temp.begin(), temp.end(), '\n', '\0');
   4309     scoped_refptr<HttpResponseHeaders> headers(new HttpResponseHeaders(temp));
   4310     request.extra_headers.SetHeader("Foo", "1");
   4311     request.extra_headers.SetHeader("bar", "23");
   4312     EXPECT_TRUE(response->vary_data.Init(request, *headers));
   4313   }
   4314 
   4315   // Cause the above state to be reset.
   4316   trans->ResetStateForRestart();
   4317 
   4318   // Verify that the state that needed to be reset, has been reset.
   4319   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   4320   EXPECT_EQ(0, trans->read_buf_len_);
   4321   EXPECT_TRUE(trans->request_headers_.IsEmpty());
   4322   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   4323   EXPECT_TRUE(response->headers.get() == NULL);
   4324   EXPECT_FALSE(response->was_cached);
   4325   EXPECT_EQ(0, response->ssl_info.cert_status);
   4326   EXPECT_FALSE(response->vary_data.is_valid());
   4327 }
   4328 
   4329 // Test HTTPS connections to a site with a bad certificate
   4330 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   4331   HttpRequestInfo request;
   4332   request.method = "GET";
   4333   request.url = GURL("https://www.google.com/");
   4334   request.load_flags = 0;
   4335 
   4336   SessionDependencies session_deps;
   4337   scoped_ptr<HttpTransaction> trans(
   4338       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4339 
   4340   MockWrite data_writes[] = {
   4341     MockWrite("GET / HTTP/1.1\r\n"
   4342               "Host: www.google.com\r\n"
   4343               "Connection: keep-alive\r\n\r\n"),
   4344   };
   4345 
   4346   MockRead data_reads[] = {
   4347     MockRead("HTTP/1.0 200 OK\r\n"),
   4348     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4349     MockRead("Content-Length: 100\r\n\r\n"),
   4350     MockRead(false, OK),
   4351   };
   4352 
   4353   StaticSocketDataProvider ssl_bad_certificate;
   4354   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4355                                 data_writes, arraysize(data_writes));
   4356   SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
   4357   SSLSocketDataProvider ssl(true, OK);
   4358 
   4359   session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
   4360   session_deps.socket_factory.AddSocketDataProvider(&data);
   4361   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
   4362   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   4363 
   4364   TestCompletionCallback callback;
   4365 
   4366   int rv = trans->Start(&request, &callback, BoundNetLog());
   4367   EXPECT_EQ(ERR_IO_PENDING, rv);
   4368 
   4369   rv = callback.WaitForResult();
   4370   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   4371 
   4372   rv = trans->RestartIgnoringLastError(&callback);
   4373   EXPECT_EQ(ERR_IO_PENDING, rv);
   4374 
   4375   rv = callback.WaitForResult();
   4376   EXPECT_EQ(OK, rv);
   4377 
   4378   const HttpResponseInfo* response = trans->GetResponseInfo();
   4379 
   4380   EXPECT_FALSE(response == NULL);
   4381   EXPECT_EQ(100, response->headers->GetContentLength());
   4382 }
   4383 
   4384 // Test HTTPS connections to a site with a bad certificate, going through a
   4385 // proxy
   4386 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   4387   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   4388 
   4389   HttpRequestInfo request;
   4390   request.method = "GET";
   4391   request.url = GURL("https://www.google.com/");
   4392   request.load_flags = 0;
   4393 
   4394   MockWrite proxy_writes[] = {
   4395     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4396               "Host: www.google.com\r\n"
   4397               "Proxy-Connection: keep-alive\r\n\r\n"),
   4398   };
   4399 
   4400   MockRead proxy_reads[] = {
   4401     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   4402     MockRead(false, OK)
   4403   };
   4404 
   4405   MockWrite data_writes[] = {
   4406     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4407               "Host: www.google.com\r\n"
   4408               "Proxy-Connection: keep-alive\r\n\r\n"),
   4409     MockWrite("GET / HTTP/1.1\r\n"
   4410               "Host: www.google.com\r\n"
   4411               "Connection: keep-alive\r\n\r\n"),
   4412   };
   4413 
   4414   MockRead data_reads[] = {
   4415     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   4416     MockRead("HTTP/1.0 200 OK\r\n"),
   4417     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4418     MockRead("Content-Length: 100\r\n\r\n"),
   4419     MockRead(false, OK),
   4420   };
   4421 
   4422   StaticSocketDataProvider ssl_bad_certificate(
   4423       proxy_reads, arraysize(proxy_reads),
   4424       proxy_writes, arraysize(proxy_writes));
   4425   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4426                                 data_writes, arraysize(data_writes));
   4427   SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
   4428   SSLSocketDataProvider ssl(true, OK);
   4429 
   4430   session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
   4431   session_deps.socket_factory.AddSocketDataProvider(&data);
   4432   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
   4433   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   4434 
   4435   TestCompletionCallback callback;
   4436 
   4437   for (int i = 0; i < 2; i++) {
   4438     session_deps.socket_factory.ResetNextMockIndexes();
   4439 
   4440     scoped_ptr<HttpTransaction> trans(
   4441         new HttpNetworkTransaction(CreateSession(&session_deps)));
   4442 
   4443     int rv = trans->Start(&request, &callback, BoundNetLog());
   4444     EXPECT_EQ(ERR_IO_PENDING, rv);
   4445 
   4446     rv = callback.WaitForResult();
   4447     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   4448 
   4449     rv = trans->RestartIgnoringLastError(&callback);
   4450     EXPECT_EQ(ERR_IO_PENDING, rv);
   4451 
   4452     rv = callback.WaitForResult();
   4453     EXPECT_EQ(OK, rv);
   4454 
   4455     const HttpResponseInfo* response = trans->GetResponseInfo();
   4456 
   4457     EXPECT_FALSE(response == NULL);
   4458     EXPECT_EQ(100, response->headers->GetContentLength());
   4459   }
   4460 }
   4461 
   4462 
   4463 // Test HTTPS connections to a site, going through an HTTPS proxy
   4464 TEST_F(HttpNetworkTransactionTest, HTTPSViaHttpsProxy) {
   4465   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   4466 
   4467   HttpRequestInfo request;
   4468   request.method = "GET";
   4469   request.url = GURL("https://www.google.com/");
   4470   request.load_flags = 0;
   4471 
   4472   MockWrite data_writes[] = {
   4473     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4474               "Host: www.google.com\r\n"
   4475               "Proxy-Connection: keep-alive\r\n\r\n"),
   4476     MockWrite("GET / HTTP/1.1\r\n"
   4477               "Host: www.google.com\r\n"
   4478               "Connection: keep-alive\r\n\r\n"),
   4479   };
   4480 
   4481   MockRead data_reads[] = {
   4482     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   4483     MockRead("HTTP/1.1 200 OK\r\n"),
   4484     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4485     MockRead("Content-Length: 100\r\n\r\n"),
   4486     MockRead(false, OK),
   4487   };
   4488 
   4489   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4490                                 data_writes, arraysize(data_writes));
   4491   SSLSocketDataProvider proxy_ssl(true, OK);  // SSL to the proxy
   4492   SSLSocketDataProvider tunnel_ssl(true, OK);  // SSL through the tunnel
   4493 
   4494   session_deps.socket_factory.AddSocketDataProvider(&data);
   4495   session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
   4496   session_deps.socket_factory.AddSSLSocketDataProvider(&tunnel_ssl);
   4497 
   4498   TestCompletionCallback callback;
   4499 
   4500   scoped_ptr<HttpTransaction> trans(
   4501       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4502 
   4503   int rv = trans->Start(&request, &callback, BoundNetLog());
   4504   EXPECT_EQ(ERR_IO_PENDING, rv);
   4505 
   4506   rv = callback.WaitForResult();
   4507   EXPECT_EQ(OK, rv);
   4508   const HttpResponseInfo* response = trans->GetResponseInfo();
   4509 
   4510   ASSERT_FALSE(response == NULL);
   4511 
   4512   EXPECT_TRUE(response->headers->IsKeepAlive());
   4513   EXPECT_EQ(200, response->headers->response_code());
   4514   EXPECT_EQ(100, response->headers->GetContentLength());
   4515   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   4516 }
   4517 
   4518 // Test an HTTPS Proxy's ability to redirect a CONNECT request
   4519 TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaHttpsProxy) {
   4520   SessionDependencies session_deps(
   4521       ProxyService::CreateFixed("https://proxy:70"));
   4522 
   4523   HttpRequestInfo request;
   4524   request.method = "GET";
   4525   request.url = GURL("https://www.google.com/");
   4526   request.load_flags = 0;
   4527 
   4528   MockWrite data_writes[] = {
   4529     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4530               "Host: www.google.com\r\n"
   4531               "Proxy-Connection: keep-alive\r\n\r\n"),
   4532   };
   4533 
   4534   MockRead data_reads[] = {
   4535     MockRead("HTTP/1.1 302 Redirect\r\n"),
   4536     MockRead("Location: http://login.example.com/\r\n"),
   4537     MockRead("Content-Length: 0\r\n\r\n"),
   4538     MockRead(false, OK),
   4539   };
   4540 
   4541   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4542                                 data_writes, arraysize(data_writes));
   4543   SSLSocketDataProvider proxy_ssl(true, OK);  // SSL to the proxy
   4544 
   4545   session_deps.socket_factory.AddSocketDataProvider(&data);
   4546   session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
   4547 
   4548   TestCompletionCallback callback;
   4549 
   4550   scoped_ptr<HttpTransaction> trans(
   4551       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4552 
   4553   int rv = trans->Start(&request, &callback, BoundNetLog());
   4554   EXPECT_EQ(ERR_IO_PENDING, rv);
   4555 
   4556   rv = callback.WaitForResult();
   4557   EXPECT_EQ(OK, rv);
   4558   const HttpResponseInfo* response = trans->GetResponseInfo();
   4559 
   4560   ASSERT_FALSE(response == NULL);
   4561 
   4562   EXPECT_EQ(302, response->headers->response_code());
   4563   std::string url;
   4564   EXPECT_TRUE(response->headers->IsRedirect(&url));
   4565   EXPECT_EQ("http://login.example.com/", url);
   4566 }
   4567 
   4568 // Test an HTTPS (SPDY) Proxy's ability to redirect a CONNECT request
   4569 TEST_F(HttpNetworkTransactionTest, RedirectOfHttpsConnectViaSpdyProxy) {
   4570   SessionDependencies session_deps(
   4571       ProxyService::CreateFixed("https://proxy:70"));
   4572 
   4573   HttpRequestInfo request;
   4574   request.method = "GET";
   4575   request.url = GURL("https://www.google.com/");
   4576   request.load_flags = 0;
   4577 
   4578   scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1));
   4579   scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL));
   4580   MockWrite data_writes[] = {
   4581     CreateMockWrite(*conn.get(), 0, false),
   4582   };
   4583 
   4584   static const char* const kExtraHeaders[] = {
   4585     "location",
   4586     "http://login.example.com/",
   4587   };
   4588   scoped_ptr<spdy::SpdyFrame> resp(
   4589       ConstructSpdySynReplyError("302 Redirect", kExtraHeaders,
   4590                                  arraysize(kExtraHeaders)/2, 1));
   4591   MockRead data_reads[] = {
   4592     CreateMockRead(*resp.get(), 1, false),
   4593     MockRead(true, 0, 2),  // EOF
   4594   };
   4595 
   4596   scoped_refptr<DelayedSocketData> data(
   4597       new DelayedSocketData(
   4598           1,  // wait for one write to finish before reading.
   4599           data_reads, arraysize(data_reads),
   4600           data_writes, arraysize(data_writes)));
   4601   SSLSocketDataProvider proxy_ssl(true, OK);  // SSL to the proxy
   4602   proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   4603   proxy_ssl.next_proto = "spdy/2";
   4604   proxy_ssl.was_npn_negotiated = true;
   4605 
   4606   session_deps.socket_factory.AddSocketDataProvider(data.get());
   4607   session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
   4608 
   4609   TestCompletionCallback callback;
   4610 
   4611   scoped_ptr<HttpTransaction> trans(
   4612       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4613 
   4614   int rv = trans->Start(&request, &callback, BoundNetLog());
   4615   EXPECT_EQ(ERR_IO_PENDING, rv);
   4616 
   4617   rv = callback.WaitForResult();
   4618   EXPECT_EQ(OK, rv);
   4619   const HttpResponseInfo* response = trans->GetResponseInfo();
   4620 
   4621   ASSERT_FALSE(response == NULL);
   4622 
   4623   EXPECT_EQ(302, response->headers->response_code());
   4624   std::string url;
   4625   EXPECT_TRUE(response->headers->IsRedirect(&url));
   4626   EXPECT_EQ("http://login.example.com/", url);
   4627 }
   4628 
   4629 // Test an HTTPS Proxy's ability to provide a response to a CONNECT request
   4630 TEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaHttpsProxy) {
   4631   SessionDependencies session_deps(
   4632       ProxyService::CreateFixed("https://proxy:70"));
   4633 
   4634   HttpRequestInfo request;
   4635   request.method = "GET";
   4636   request.url = GURL("https://www.google.com/");
   4637   request.load_flags = 0;
   4638 
   4639   MockWrite data_writes[] = {
   4640     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4641               "Host: www.google.com\r\n"
   4642               "Proxy-Connection: keep-alive\r\n\r\n"),
   4643   };
   4644 
   4645   MockRead data_reads[] = {
   4646     MockRead("HTTP/1.1 404 Not Found\r\n"),
   4647     MockRead("Content-Length: 23\r\n\r\n"),
   4648     MockRead("The host does not exist"),
   4649     MockRead(false, OK),
   4650   };
   4651 
   4652   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4653                                 data_writes, arraysize(data_writes));
   4654   SSLSocketDataProvider proxy_ssl(true, OK);  // SSL to the proxy
   4655 
   4656   session_deps.socket_factory.AddSocketDataProvider(&data);
   4657   session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
   4658 
   4659   TestCompletionCallback callback;
   4660 
   4661   scoped_ptr<HttpTransaction> trans(
   4662       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4663 
   4664   int rv = trans->Start(&request, &callback, BoundNetLog());
   4665   EXPECT_EQ(ERR_IO_PENDING, rv);
   4666 
   4667   rv = callback.WaitForResult();
   4668   EXPECT_EQ(OK, rv);
   4669   const HttpResponseInfo* response = trans->GetResponseInfo();
   4670 
   4671   ASSERT_FALSE(response == NULL);
   4672 
   4673   EXPECT_EQ(404, response->headers->response_code());
   4674   EXPECT_EQ(23, response->headers->GetContentLength());
   4675   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   4676   EXPECT_FALSE(response->ssl_info.is_valid());
   4677 
   4678   std::string response_data;
   4679   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   4680   EXPECT_EQ("The host does not exist", response_data);
   4681 }
   4682 
   4683 // Test an HTTPS (SPDY) Proxy's ability to provide a response to a CONNECT
   4684 // request
   4685 TEST_F(HttpNetworkTransactionTest, ErrorResponseTofHttpsConnectViaSpdyProxy) {
   4686   SessionDependencies session_deps(
   4687       ProxyService::CreateFixed("https://proxy:70"));
   4688 
   4689   HttpRequestInfo request;
   4690   request.method = "GET";
   4691   request.url = GURL("https://www.google.com/");
   4692   request.load_flags = 0;
   4693 
   4694   scoped_ptr<spdy::SpdyFrame> conn(ConstructSpdyConnect(NULL, 0, 1));
   4695   scoped_ptr<spdy::SpdyFrame> goaway(ConstructSpdyRstStream(1, spdy::CANCEL));
   4696   MockWrite data_writes[] = {
   4697     CreateMockWrite(*conn.get(), 0, false),
   4698   };
   4699 
   4700   static const char* const kExtraHeaders[] = {
   4701     "location",
   4702     "http://login.example.com/",
   4703   };
   4704   scoped_ptr<spdy::SpdyFrame> resp(
   4705       ConstructSpdySynReplyError("404 Not Found", kExtraHeaders,
   4706                                  arraysize(kExtraHeaders)/2, 1));
   4707   scoped_ptr<spdy::SpdyFrame> body(
   4708       ConstructSpdyBodyFrame(1, "The host does not exist", 23, true));
   4709   MockRead data_reads[] = {
   4710     CreateMockRead(*resp.get(), 1, false),
   4711     CreateMockRead(*body.get(), 2, false),
   4712     MockRead(true, 0, 3),  // EOF
   4713   };
   4714 
   4715   scoped_refptr<DelayedSocketData> data(
   4716       new DelayedSocketData(
   4717           1,  // wait for one write to finish before reading.
   4718           data_reads, arraysize(data_reads),
   4719           data_writes, arraysize(data_writes)));
   4720   SSLSocketDataProvider proxy_ssl(true, OK);  // SSL to the proxy
   4721   proxy_ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   4722   proxy_ssl.next_proto = "spdy/2";
   4723   proxy_ssl.was_npn_negotiated = true;
   4724 
   4725   session_deps.socket_factory.AddSocketDataProvider(data.get());
   4726   session_deps.socket_factory.AddSSLSocketDataProvider(&proxy_ssl);
   4727 
   4728   TestCompletionCallback callback;
   4729 
   4730   scoped_ptr<HttpTransaction> trans(
   4731       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4732 
   4733   int rv = trans->Start(&request, &callback, BoundNetLog());
   4734   EXPECT_EQ(ERR_IO_PENDING, rv);
   4735 
   4736   rv = callback.WaitForResult();
   4737   EXPECT_EQ(OK, rv);
   4738   const HttpResponseInfo* response = trans->GetResponseInfo();
   4739 
   4740   ASSERT_FALSE(response == NULL);
   4741 
   4742   EXPECT_EQ(404, response->headers->response_code());
   4743   EXPECT_FALSE(response->ssl_info.is_valid());
   4744 
   4745   std::string response_data;
   4746   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   4747   EXPECT_EQ("The host does not exist", response_data);
   4748 }
   4749 
   4750 // Test HTTPS connections to a site with a bad certificate, going through an
   4751 // HTTPS proxy
   4752 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaHttpsProxy) {
   4753   SessionDependencies session_deps(ProxyService::CreateFixed("https://proxy:70"));
   4754 
   4755   HttpRequestInfo request;
   4756   request.method = "GET";
   4757   request.url = GURL("https://www.google.com/");
   4758   request.load_flags = 0;
   4759 
   4760   // Attempt to fetch the URL from a server with a bad cert
   4761   MockWrite bad_cert_writes[] = {
   4762     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4763               "Host: www.google.com\r\n"
   4764               "Proxy-Connection: keep-alive\r\n\r\n"),
   4765   };
   4766 
   4767   MockRead bad_cert_reads[] = {
   4768     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   4769     MockRead(false, OK)
   4770   };
   4771 
   4772   // Attempt to fetch the URL with a good cert
   4773   MockWrite good_data_writes[] = {
   4774     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4775               "Host: www.google.com\r\n"
   4776               "Proxy-Connection: keep-alive\r\n\r\n"),
   4777     MockWrite("GET / HTTP/1.1\r\n"
   4778               "Host: www.google.com\r\n"
   4779               "Connection: keep-alive\r\n\r\n"),
   4780   };
   4781 
   4782   MockRead good_cert_reads[] = {
   4783     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   4784     MockRead("HTTP/1.0 200 OK\r\n"),
   4785     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4786     MockRead("Content-Length: 100\r\n\r\n"),
   4787     MockRead(false, OK),
   4788   };
   4789 
   4790   StaticSocketDataProvider ssl_bad_certificate(
   4791       bad_cert_reads, arraysize(bad_cert_reads),
   4792       bad_cert_writes, arraysize(bad_cert_writes));
   4793   StaticSocketDataProvider data(good_cert_reads, arraysize(good_cert_reads),
   4794                                 good_data_writes, arraysize(good_data_writes));
   4795   SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
   4796   SSLSocketDataProvider ssl(true, OK);
   4797 
   4798   // SSL to the proxy, then CONNECT request, then SSL with bad certificate
   4799   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   4800   session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
   4801   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
   4802 
   4803   // SSL to the proxy, then CONNECT request, then valid SSL certificate
   4804   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   4805   session_deps.socket_factory.AddSocketDataProvider(&data);
   4806   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   4807 
   4808   TestCompletionCallback callback;
   4809 
   4810   scoped_ptr<HttpTransaction> trans(
   4811       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4812 
   4813   int rv = trans->Start(&request, &callback, BoundNetLog());
   4814   EXPECT_EQ(ERR_IO_PENDING, rv);
   4815 
   4816   rv = callback.WaitForResult();
   4817   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   4818 
   4819   rv = trans->RestartIgnoringLastError(&callback);
   4820   EXPECT_EQ(ERR_IO_PENDING, rv);
   4821 
   4822   rv = callback.WaitForResult();
   4823   EXPECT_EQ(OK, rv);
   4824 
   4825   const HttpResponseInfo* response = trans->GetResponseInfo();
   4826 
   4827   EXPECT_FALSE(response == NULL);
   4828   EXPECT_EQ(100, response->headers->GetContentLength());
   4829 }
   4830 
   4831 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   4832   HttpRequestInfo request;
   4833   request.method = "GET";
   4834   request.url = GURL("http://www.google.com/");
   4835   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   4836                                   "Chromium Ultra Awesome X Edition");
   4837 
   4838   SessionDependencies session_deps;
   4839   scoped_ptr<HttpTransaction> trans(
   4840       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4841 
   4842   MockWrite data_writes[] = {
   4843     MockWrite("GET / HTTP/1.1\r\n"
   4844               "Host: www.google.com\r\n"
   4845               "Connection: keep-alive\r\n"
   4846               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   4847   };
   4848 
   4849   // Lastly, the server responds with the actual content.
   4850   MockRead data_reads[] = {
   4851     MockRead("HTTP/1.0 200 OK\r\n"),
   4852     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4853     MockRead("Content-Length: 100\r\n\r\n"),
   4854     MockRead(false, OK),
   4855   };
   4856 
   4857   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4858                                 data_writes, arraysize(data_writes));
   4859   session_deps.socket_factory.AddSocketDataProvider(&data);
   4860 
   4861   TestCompletionCallback callback;
   4862 
   4863   int rv = trans->Start(&request, &callback, BoundNetLog());
   4864   EXPECT_EQ(ERR_IO_PENDING, rv);
   4865 
   4866   rv = callback.WaitForResult();
   4867   EXPECT_EQ(OK, rv);
   4868 }
   4869 
   4870 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgentOverTunnel) {
   4871   HttpRequestInfo request;
   4872   request.method = "GET";
   4873   request.url = GURL("https://www.google.com/");
   4874   request.extra_headers.SetHeader(HttpRequestHeaders::kUserAgent,
   4875                                   "Chromium Ultra Awesome X Edition");
   4876 
   4877   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   4878   scoped_ptr<HttpTransaction> trans(
   4879       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4880 
   4881   MockWrite data_writes[] = {
   4882     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   4883               "Host: www.google.com\r\n"
   4884               "Proxy-Connection: keep-alive\r\n"
   4885               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   4886   };
   4887   MockRead data_reads[] = {
   4888     // Return an error, so the transaction stops here (this test isn't
   4889     // interested in the rest).
   4890     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   4891     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   4892     MockRead("Proxy-Connection: close\r\n\r\n"),
   4893   };
   4894 
   4895   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4896                                 data_writes, arraysize(data_writes));
   4897   session_deps.socket_factory.AddSocketDataProvider(&data);
   4898 
   4899   TestCompletionCallback callback;
   4900 
   4901   int rv = trans->Start(&request, &callback, BoundNetLog());
   4902   EXPECT_EQ(ERR_IO_PENDING, rv);
   4903 
   4904   rv = callback.WaitForResult();
   4905   EXPECT_EQ(OK, rv);
   4906 }
   4907 
   4908 TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
   4909   HttpRequestInfo request;
   4910   request.method = "GET";
   4911   request.url = GURL("http://www.google.com/");
   4912   request.load_flags = 0;
   4913   request.referrer = GURL("http://the.previous.site.com/");
   4914 
   4915   SessionDependencies session_deps;
   4916   scoped_ptr<HttpTransaction> trans(
   4917       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4918 
   4919   MockWrite data_writes[] = {
   4920     MockWrite("GET / HTTP/1.1\r\n"
   4921               "Host: www.google.com\r\n"
   4922               "Connection: keep-alive\r\n"
   4923               "Referer: http://the.previous.site.com/\r\n\r\n"),
   4924   };
   4925 
   4926   // Lastly, the server responds with the actual content.
   4927   MockRead data_reads[] = {
   4928     MockRead("HTTP/1.0 200 OK\r\n"),
   4929     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4930     MockRead("Content-Length: 100\r\n\r\n"),
   4931     MockRead(false, OK),
   4932   };
   4933 
   4934   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4935                                 data_writes, arraysize(data_writes));
   4936   session_deps.socket_factory.AddSocketDataProvider(&data);
   4937 
   4938   TestCompletionCallback callback;
   4939 
   4940   int rv = trans->Start(&request, &callback, BoundNetLog());
   4941   EXPECT_EQ(ERR_IO_PENDING, rv);
   4942 
   4943   rv = callback.WaitForResult();
   4944   EXPECT_EQ(OK, rv);
   4945 }
   4946 
   4947 TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   4948   HttpRequestInfo request;
   4949   request.method = "POST";
   4950   request.url = GURL("http://www.google.com/");
   4951 
   4952   SessionDependencies session_deps;
   4953   scoped_ptr<HttpTransaction> trans(
   4954       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4955 
   4956   MockWrite data_writes[] = {
   4957     MockWrite("POST / HTTP/1.1\r\n"
   4958               "Host: www.google.com\r\n"
   4959               "Connection: keep-alive\r\n"
   4960               "Content-Length: 0\r\n\r\n"),
   4961   };
   4962 
   4963   // Lastly, the server responds with the actual content.
   4964   MockRead data_reads[] = {
   4965     MockRead("HTTP/1.0 200 OK\r\n"),
   4966     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   4967     MockRead("Content-Length: 100\r\n\r\n"),
   4968     MockRead(false, OK),
   4969   };
   4970 
   4971   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   4972                                 data_writes, arraysize(data_writes));
   4973   session_deps.socket_factory.AddSocketDataProvider(&data);
   4974 
   4975   TestCompletionCallback callback;
   4976 
   4977   int rv = trans->Start(&request, &callback, BoundNetLog());
   4978   EXPECT_EQ(ERR_IO_PENDING, rv);
   4979 
   4980   rv = callback.WaitForResult();
   4981   EXPECT_EQ(OK, rv);
   4982 }
   4983 
   4984 TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   4985   HttpRequestInfo request;
   4986   request.method = "PUT";
   4987   request.url = GURL("http://www.google.com/");
   4988 
   4989   SessionDependencies session_deps;
   4990   scoped_ptr<HttpTransaction> trans(
   4991       new HttpNetworkTransaction(CreateSession(&session_deps)));
   4992 
   4993   MockWrite data_writes[] = {
   4994     MockWrite("PUT / HTTP/1.1\r\n"
   4995               "Host: www.google.com\r\n"
   4996               "Connection: keep-alive\r\n"
   4997               "Content-Length: 0\r\n\r\n"),
   4998   };
   4999 
   5000   // Lastly, the server responds with the actual content.
   5001   MockRead data_reads[] = {
   5002     MockRead("HTTP/1.0 200 OK\r\n"),
   5003     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5004     MockRead("Content-Length: 100\r\n\r\n"),
   5005     MockRead(false, OK),
   5006   };
   5007 
   5008   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5009                                 data_writes, arraysize(data_writes));
   5010   session_deps.socket_factory.AddSocketDataProvider(&data);
   5011 
   5012   TestCompletionCallback callback;
   5013 
   5014   int rv = trans->Start(&request, &callback, BoundNetLog());
   5015   EXPECT_EQ(ERR_IO_PENDING, rv);
   5016 
   5017   rv = callback.WaitForResult();
   5018   EXPECT_EQ(OK, rv);
   5019 }
   5020 
   5021 TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   5022   HttpRequestInfo request;
   5023   request.method = "HEAD";
   5024   request.url = GURL("http://www.google.com/");
   5025 
   5026   SessionDependencies session_deps;
   5027   scoped_ptr<HttpTransaction> trans(
   5028       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5029 
   5030   MockWrite data_writes[] = {
   5031     MockWrite("HEAD / HTTP/1.1\r\n"
   5032               "Host: www.google.com\r\n"
   5033               "Connection: keep-alive\r\n"
   5034               "Content-Length: 0\r\n\r\n"),
   5035   };
   5036 
   5037   // Lastly, the server responds with the actual content.
   5038   MockRead data_reads[] = {
   5039     MockRead("HTTP/1.0 200 OK\r\n"),
   5040     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5041     MockRead("Content-Length: 100\r\n\r\n"),
   5042     MockRead(false, OK),
   5043   };
   5044 
   5045   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5046                                 data_writes, arraysize(data_writes));
   5047   session_deps.socket_factory.AddSocketDataProvider(&data);
   5048 
   5049   TestCompletionCallback callback;
   5050 
   5051   int rv = trans->Start(&request, &callback, BoundNetLog());
   5052   EXPECT_EQ(ERR_IO_PENDING, rv);
   5053 
   5054   rv = callback.WaitForResult();
   5055   EXPECT_EQ(OK, rv);
   5056 }
   5057 
   5058 TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   5059   HttpRequestInfo request;
   5060   request.method = "GET";
   5061   request.url = GURL("http://www.google.com/");
   5062   request.load_flags = LOAD_BYPASS_CACHE;
   5063 
   5064   SessionDependencies session_deps;
   5065   scoped_ptr<HttpTransaction> trans(
   5066       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5067 
   5068   MockWrite data_writes[] = {
   5069     MockWrite("GET / HTTP/1.1\r\n"
   5070               "Host: www.google.com\r\n"
   5071               "Connection: keep-alive\r\n"
   5072               "Pragma: no-cache\r\n"
   5073               "Cache-Control: no-cache\r\n\r\n"),
   5074   };
   5075 
   5076   // Lastly, the server responds with the actual content.
   5077   MockRead data_reads[] = {
   5078     MockRead("HTTP/1.0 200 OK\r\n"),
   5079     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5080     MockRead("Content-Length: 100\r\n\r\n"),
   5081     MockRead(false, OK),
   5082   };
   5083 
   5084   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5085                                 data_writes, arraysize(data_writes));
   5086   session_deps.socket_factory.AddSocketDataProvider(&data);
   5087 
   5088   TestCompletionCallback callback;
   5089 
   5090   int rv = trans->Start(&request, &callback, BoundNetLog());
   5091   EXPECT_EQ(ERR_IO_PENDING, rv);
   5092 
   5093   rv = callback.WaitForResult();
   5094   EXPECT_EQ(OK, rv);
   5095 }
   5096 
   5097 TEST_F(HttpNetworkTransactionTest,
   5098        BuildRequest_CacheControlValidateCache) {
   5099   HttpRequestInfo request;
   5100   request.method = "GET";
   5101   request.url = GURL("http://www.google.com/");
   5102   request.load_flags = LOAD_VALIDATE_CACHE;
   5103 
   5104   SessionDependencies session_deps;
   5105   scoped_ptr<HttpTransaction> trans(
   5106       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5107 
   5108   MockWrite data_writes[] = {
   5109     MockWrite("GET / HTTP/1.1\r\n"
   5110               "Host: www.google.com\r\n"
   5111               "Connection: keep-alive\r\n"
   5112               "Cache-Control: max-age=0\r\n\r\n"),
   5113   };
   5114 
   5115   // Lastly, the server responds with the actual content.
   5116   MockRead data_reads[] = {
   5117     MockRead("HTTP/1.0 200 OK\r\n"),
   5118     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5119     MockRead("Content-Length: 100\r\n\r\n"),
   5120     MockRead(false, OK),
   5121   };
   5122 
   5123   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5124                                 data_writes, arraysize(data_writes));
   5125   session_deps.socket_factory.AddSocketDataProvider(&data);
   5126 
   5127   TestCompletionCallback callback;
   5128 
   5129   int rv = trans->Start(&request, &callback, BoundNetLog());
   5130   EXPECT_EQ(ERR_IO_PENDING, rv);
   5131 
   5132   rv = callback.WaitForResult();
   5133   EXPECT_EQ(OK, rv);
   5134 }
   5135 
   5136 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   5137   HttpRequestInfo request;
   5138   request.method = "GET";
   5139   request.url = GURL("http://www.google.com/");
   5140   request.extra_headers.SetHeader("FooHeader", "Bar");
   5141 
   5142   SessionDependencies session_deps;
   5143   scoped_ptr<HttpTransaction> trans(
   5144       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5145 
   5146   MockWrite data_writes[] = {
   5147     MockWrite("GET / HTTP/1.1\r\n"
   5148               "Host: www.google.com\r\n"
   5149               "Connection: keep-alive\r\n"
   5150               "FooHeader: Bar\r\n\r\n"),
   5151   };
   5152 
   5153   // Lastly, the server responds with the actual content.
   5154   MockRead data_reads[] = {
   5155     MockRead("HTTP/1.0 200 OK\r\n"),
   5156     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5157     MockRead("Content-Length: 100\r\n\r\n"),
   5158     MockRead(false, OK),
   5159   };
   5160 
   5161   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5162                                 data_writes, arraysize(data_writes));
   5163   session_deps.socket_factory.AddSocketDataProvider(&data);
   5164 
   5165   TestCompletionCallback callback;
   5166 
   5167   int rv = trans->Start(&request, &callback, BoundNetLog());
   5168   EXPECT_EQ(ERR_IO_PENDING, rv);
   5169 
   5170   rv = callback.WaitForResult();
   5171   EXPECT_EQ(OK, rv);
   5172 }
   5173 
   5174 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeadersStripped) {
   5175   HttpRequestInfo request;
   5176   request.method = "GET";
   5177   request.url = GURL("http://www.google.com/");
   5178   request.extra_headers.SetHeader("referer", "www.foo.com");
   5179   request.extra_headers.SetHeader("hEllo", "Kitty");
   5180   request.extra_headers.SetHeader("FoO", "bar");
   5181 
   5182   SessionDependencies session_deps;
   5183   scoped_ptr<HttpTransaction> trans(
   5184       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5185 
   5186   MockWrite data_writes[] = {
   5187     MockWrite("GET / HTTP/1.1\r\n"
   5188               "Host: www.google.com\r\n"
   5189               "Connection: keep-alive\r\n"
   5190               "hEllo: Kitty\r\n"
   5191               "FoO: bar\r\n\r\n"),
   5192   };
   5193 
   5194   // Lastly, the server responds with the actual content.
   5195   MockRead data_reads[] = {
   5196     MockRead("HTTP/1.0 200 OK\r\n"),
   5197     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5198     MockRead("Content-Length: 100\r\n\r\n"),
   5199     MockRead(false, OK),
   5200   };
   5201 
   5202   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5203                                 data_writes, arraysize(data_writes));
   5204   session_deps.socket_factory.AddSocketDataProvider(&data);
   5205 
   5206   TestCompletionCallback callback;
   5207 
   5208   int rv = trans->Start(&request, &callback, BoundNetLog());
   5209   EXPECT_EQ(ERR_IO_PENDING, rv);
   5210 
   5211   rv = callback.WaitForResult();
   5212   EXPECT_EQ(OK, rv);
   5213 }
   5214 
   5215 TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   5216   HttpRequestInfo request;
   5217   request.method = "GET";
   5218   request.url = GURL("http://www.google.com/");
   5219   request.load_flags = 0;
   5220 
   5221   SessionDependencies session_deps(
   5222       ProxyService::CreateFixed("socks4://myproxy:1080"));
   5223 
   5224   scoped_ptr<HttpTransaction> trans(
   5225       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5226 
   5227   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   5228   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   5229 
   5230   MockWrite data_writes[] = {
   5231     MockWrite(true, write_buffer, arraysize(write_buffer)),
   5232     MockWrite("GET / HTTP/1.1\r\n"
   5233               "Host: www.google.com\r\n"
   5234               "Connection: keep-alive\r\n\r\n")
   5235   };
   5236 
   5237   MockRead data_reads[] = {
   5238     MockRead(true, read_buffer, arraysize(read_buffer)),
   5239     MockRead("HTTP/1.0 200 OK\r\n"),
   5240     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   5241     MockRead("Payload"),
   5242     MockRead(false, OK)
   5243   };
   5244 
   5245   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5246                                 data_writes, arraysize(data_writes));
   5247   session_deps.socket_factory.AddSocketDataProvider(&data);
   5248 
   5249   TestCompletionCallback callback;
   5250 
   5251   int rv = trans->Start(&request, &callback, BoundNetLog());
   5252   EXPECT_EQ(ERR_IO_PENDING, rv);
   5253 
   5254   rv = callback.WaitForResult();
   5255   EXPECT_EQ(OK, rv);
   5256 
   5257   const HttpResponseInfo* response = trans->GetResponseInfo();
   5258   EXPECT_FALSE(response == NULL);
   5259 
   5260   std::string response_text;
   5261   rv = ReadTransaction(trans.get(), &response_text);
   5262   EXPECT_EQ(OK, rv);
   5263   EXPECT_EQ("Payload", response_text);
   5264 }
   5265 
   5266 TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   5267   HttpRequestInfo request;
   5268   request.method = "GET";
   5269   request.url = GURL("https://www.google.com/");
   5270   request.load_flags = 0;
   5271 
   5272   SessionDependencies session_deps(
   5273       ProxyService::CreateFixed("socks4://myproxy:1080"));
   5274 
   5275   scoped_ptr<HttpTransaction> trans(
   5276       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5277 
   5278   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
   5279   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   5280 
   5281   MockWrite data_writes[] = {
   5282     MockWrite(true, reinterpret_cast<char*>(write_buffer),
   5283               arraysize(write_buffer)),
   5284     MockWrite("GET / HTTP/1.1\r\n"
   5285               "Host: www.google.com\r\n"
   5286               "Connection: keep-alive\r\n\r\n")
   5287   };
   5288 
   5289   MockRead data_reads[] = {
   5290     MockWrite(true, reinterpret_cast<char*>(read_buffer),
   5291               arraysize(read_buffer)),
   5292     MockRead("HTTP/1.0 200 OK\r\n"),
   5293     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   5294     MockRead("Payload"),
   5295     MockRead(false, OK)
   5296   };
   5297 
   5298   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5299                                 data_writes, arraysize(data_writes));
   5300   session_deps.socket_factory.AddSocketDataProvider(&data);
   5301 
   5302   SSLSocketDataProvider ssl(true, OK);
   5303   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   5304 
   5305   TestCompletionCallback callback;
   5306 
   5307   int rv = trans->Start(&request, &callback, BoundNetLog());
   5308   EXPECT_EQ(ERR_IO_PENDING, rv);
   5309 
   5310   rv = callback.WaitForResult();
   5311   EXPECT_EQ(OK, rv);
   5312 
   5313   const HttpResponseInfo* response = trans->GetResponseInfo();
   5314   EXPECT_FALSE(response == NULL);
   5315 
   5316   std::string response_text;
   5317   rv = ReadTransaction(trans.get(), &response_text);
   5318   EXPECT_EQ(OK, rv);
   5319   EXPECT_EQ("Payload", response_text);
   5320 }
   5321 
   5322 TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   5323   HttpRequestInfo request;
   5324   request.method = "GET";
   5325   request.url = GURL("http://www.google.com/");
   5326   request.load_flags = 0;
   5327 
   5328   SessionDependencies session_deps(
   5329       ProxyService::CreateFixed("socks5://myproxy:1080"));
   5330 
   5331   scoped_ptr<HttpTransaction> trans(
   5332       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5333 
   5334   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   5335   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   5336   const char kSOCKS5OkRequest[] = {
   5337     0x05,  // Version
   5338     0x01,  // Command (CONNECT)
   5339     0x00,  // Reserved.
   5340     0x03,  // Address type (DOMAINNAME).
   5341     0x0E,  // Length of domain (14)
   5342     // Domain string:
   5343     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   5344     0x00, 0x50,  // 16-bit port (80)
   5345   };
   5346   const char kSOCKS5OkResponse[] =
   5347       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
   5348 
   5349   MockWrite data_writes[] = {
   5350     MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   5351     MockWrite(true, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
   5352     MockWrite("GET / HTTP/1.1\r\n"
   5353               "Host: www.google.com\r\n"
   5354               "Connection: keep-alive\r\n\r\n")
   5355   };
   5356 
   5357   MockRead data_reads[] = {
   5358     MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   5359     MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   5360     MockRead("HTTP/1.0 200 OK\r\n"),
   5361     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   5362     MockRead("Payload"),
   5363     MockRead(false, OK)
   5364   };
   5365 
   5366   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5367                                 data_writes, arraysize(data_writes));
   5368   session_deps.socket_factory.AddSocketDataProvider(&data);
   5369 
   5370   TestCompletionCallback callback;
   5371 
   5372   int rv = trans->Start(&request, &callback, BoundNetLog());
   5373   EXPECT_EQ(ERR_IO_PENDING, rv);
   5374 
   5375   rv = callback.WaitForResult();
   5376   EXPECT_EQ(OK, rv);
   5377 
   5378   const HttpResponseInfo* response = trans->GetResponseInfo();
   5379   EXPECT_FALSE(response == NULL);
   5380 
   5381   std::string response_text;
   5382   rv = ReadTransaction(trans.get(), &response_text);
   5383   EXPECT_EQ(OK, rv);
   5384   EXPECT_EQ("Payload", response_text);
   5385 }
   5386 
   5387 TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   5388   HttpRequestInfo request;
   5389   request.method = "GET";
   5390   request.url = GURL("https://www.google.com/");
   5391   request.load_flags = 0;
   5392 
   5393   SessionDependencies session_deps(
   5394       ProxyService::CreateFixed("socks5://myproxy:1080"));
   5395 
   5396   scoped_ptr<HttpTransaction> trans(
   5397       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5398 
   5399   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   5400   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   5401   const unsigned char kSOCKS5OkRequest[] = {
   5402     0x05,  // Version
   5403     0x01,  // Command (CONNECT)
   5404     0x00,  // Reserved.
   5405     0x03,  // Address type (DOMAINNAME).
   5406     0x0E,  // Length of domain (14)
   5407     // Domain string:
   5408     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   5409     0x01, 0xBB,  // 16-bit port (443)
   5410   };
   5411 
   5412   const char kSOCKS5OkResponse[] =
   5413       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
   5414 
   5415   MockWrite data_writes[] = {
   5416     MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   5417     MockWrite(true, reinterpret_cast<const char*>(kSOCKS5OkRequest),
   5418               arraysize(kSOCKS5OkRequest)),
   5419     MockWrite("GET / HTTP/1.1\r\n"
   5420               "Host: www.google.com\r\n"
   5421               "Connection: keep-alive\r\n\r\n")
   5422   };
   5423 
   5424   MockRead data_reads[] = {
   5425     MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   5426     MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   5427     MockRead("HTTP/1.0 200 OK\r\n"),
   5428     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   5429     MockRead("Payload"),
   5430     MockRead(false, OK)
   5431   };
   5432 
   5433   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   5434                                 data_writes, arraysize(data_writes));
   5435   session_deps.socket_factory.AddSocketDataProvider(&data);
   5436 
   5437   SSLSocketDataProvider ssl(true, OK);
   5438   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   5439 
   5440   TestCompletionCallback callback;
   5441 
   5442   int rv = trans->Start(&request, &callback, BoundNetLog());
   5443   EXPECT_EQ(ERR_IO_PENDING, rv);
   5444 
   5445   rv = callback.WaitForResult();
   5446   EXPECT_EQ(OK, rv);
   5447 
   5448   const HttpResponseInfo* response = trans->GetResponseInfo();
   5449   EXPECT_FALSE(response == NULL);
   5450 
   5451   std::string response_text;
   5452   rv = ReadTransaction(trans.get(), &response_text);
   5453   EXPECT_EQ(OK, rv);
   5454   EXPECT_EQ("Payload", response_text);
   5455 }
   5456 
   5457 // Tests that for connection endpoints the group names are correctly set.
   5458 
   5459 struct GroupNameTest {
   5460   std::string proxy_server;
   5461   std::string url;
   5462   std::string expected_group_name;
   5463   bool ssl;
   5464 };
   5465 
   5466 scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests(
   5467     SessionDependencies* session_deps) {
   5468   scoped_refptr<HttpNetworkSession> session(CreateSession(session_deps));
   5469 
   5470   HttpAlternateProtocols* alternate_protocols =
   5471       session->mutable_alternate_protocols();
   5472   alternate_protocols->SetAlternateProtocolFor(
   5473       HostPortPair("host.with.alternate", 80), 443,
   5474       HttpAlternateProtocols::NPN_SPDY_2);
   5475 
   5476   return session;
   5477 }
   5478 
   5479 int GroupNameTransactionHelper(
   5480     const std::string& url,
   5481     const scoped_refptr<HttpNetworkSession>& session) {
   5482   HttpRequestInfo request;
   5483   request.method = "GET";
   5484   request.url = GURL(url);
   5485   request.load_flags = 0;
   5486 
   5487   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   5488 
   5489   TestCompletionCallback callback;
   5490 
   5491   // We do not complete this request, the dtor will clean the transaction up.
   5492   return trans->Start(&request, &callback, BoundNetLog());
   5493 }
   5494 
   5495 TEST_F(HttpNetworkTransactionTest, GroupNameForDirectConnections) {
   5496   const GroupNameTest tests[] = {
   5497     {
   5498       "",  // unused
   5499       "http://www.google.com/direct",
   5500       "www.google.com:80",
   5501       false,
   5502     },
   5503     {
   5504       "",  // unused
   5505       "http://[2001:1418:13:1::25]/direct",
   5506       "[2001:1418:13:1::25]:80",
   5507       false,
   5508     },
   5509 
   5510     // SSL Tests
   5511     {
   5512       "",  // unused
   5513       "https://www.google.com/direct_ssl",
   5514       "ssl/www.google.com:443",
   5515       true,
   5516     },
   5517     {
   5518       "",  // unused
   5519       "https://[2001:1418:13:1::25]/direct",
   5520       "ssl/[2001:1418:13:1::25]:443",
   5521       true,
   5522     },
   5523     {
   5524       "",  // unused
   5525       "http://host.with.alternate/direct",
   5526       "ssl/host.with.alternate:443",
   5527       true,
   5528     },
   5529   };
   5530 
   5531   HttpStreamFactory::set_use_alternate_protocols(true);
   5532 
   5533   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   5534     SessionDependencies session_deps(
   5535         ProxyService::CreateFixed(tests[i].proxy_server));
   5536     scoped_refptr<HttpNetworkSession> session(
   5537         SetupSessionForGroupNameTests(&session_deps));
   5538 
   5539     HttpNetworkSessionPeer peer(session);
   5540     CaptureGroupNameTransportSocketPool* transport_conn_pool =
   5541         new CaptureGroupNameTransportSocketPool(NULL, NULL);
   5542     peer.SetTransportSocketPool(transport_conn_pool);
   5543     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   5544         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   5545     peer.SetSSLSocketPool(ssl_conn_pool);
   5546 
   5547     EXPECT_EQ(ERR_IO_PENDING,
   5548               GroupNameTransactionHelper(tests[i].url, session));
   5549     if (tests[i].ssl)
   5550       EXPECT_EQ(tests[i].expected_group_name,
   5551                 ssl_conn_pool->last_group_name_received());
   5552     else
   5553       EXPECT_EQ(tests[i].expected_group_name,
   5554                 transport_conn_pool->last_group_name_received());
   5555   }
   5556 
   5557   HttpStreamFactory::set_use_alternate_protocols(false);
   5558 }
   5559 
   5560 TEST_F(HttpNetworkTransactionTest, GroupNameForHTTPProxyConnections) {
   5561   const GroupNameTest tests[] = {
   5562     {
   5563       "http_proxy",
   5564       "http://www.google.com/http_proxy_normal",
   5565       "www.google.com:80",
   5566       false,
   5567     },
   5568 
   5569     // SSL Tests
   5570     {
   5571       "http_proxy",
   5572       "https://www.google.com/http_connect_ssl",
   5573       "ssl/www.google.com:443",
   5574       true,
   5575     },
   5576 
   5577     {
   5578       "http_proxy",
   5579       "http://host.with.alternate/direct",
   5580       "ssl/host.with.alternate:443",
   5581       true,
   5582     },
   5583   };
   5584 
   5585   HttpStreamFactory::set_use_alternate_protocols(true);
   5586 
   5587   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   5588     SessionDependencies session_deps(
   5589         ProxyService::CreateFixed(tests[i].proxy_server));
   5590     scoped_refptr<HttpNetworkSession> session(
   5591         SetupSessionForGroupNameTests(&session_deps));
   5592 
   5593     HttpNetworkSessionPeer peer(session);
   5594 
   5595     HostPortPair proxy_host("http_proxy", 80);
   5596     CaptureGroupNameHttpProxySocketPool* http_proxy_pool =
   5597         new CaptureGroupNameHttpProxySocketPool(NULL, NULL);
   5598     peer.SetSocketPoolForHTTPProxy(proxy_host, http_proxy_pool);
   5599     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   5600         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   5601     peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   5602 
   5603     EXPECT_EQ(ERR_IO_PENDING,
   5604               GroupNameTransactionHelper(tests[i].url, session));
   5605     if (tests[i].ssl)
   5606       EXPECT_EQ(tests[i].expected_group_name,
   5607                 ssl_conn_pool->last_group_name_received());
   5608     else
   5609       EXPECT_EQ(tests[i].expected_group_name,
   5610                 http_proxy_pool->last_group_name_received());
   5611   }
   5612 
   5613   HttpStreamFactory::set_use_alternate_protocols(false);
   5614 }
   5615 
   5616 TEST_F(HttpNetworkTransactionTest, GroupNameForSOCKSConnections) {
   5617   const GroupNameTest tests[] = {
   5618     {
   5619       "socks4://socks_proxy:1080",
   5620       "http://www.google.com/socks4_direct",
   5621       "socks4/www.google.com:80",
   5622       false,
   5623     },
   5624     {
   5625       "socks5://socks_proxy:1080",
   5626       "http://www.google.com/socks5_direct",
   5627       "socks5/www.google.com:80",
   5628       false,
   5629     },
   5630 
   5631     // SSL Tests
   5632     {
   5633       "socks4://socks_proxy:1080",
   5634       "https://www.google.com/socks4_ssl",
   5635       "socks4/ssl/www.google.com:443",
   5636       true,
   5637     },
   5638     {
   5639       "socks5://socks_proxy:1080",
   5640       "https://www.google.com/socks5_ssl",
   5641       "socks5/ssl/www.google.com:443",
   5642       true,
   5643     },
   5644 
   5645     {
   5646       "socks4://socks_proxy:1080",
   5647       "http://host.with.alternate/direct",
   5648       "socks4/ssl/host.with.alternate:443",
   5649       true,
   5650     },
   5651   };
   5652 
   5653   HttpStreamFactory::set_use_alternate_protocols(true);
   5654 
   5655   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   5656     SessionDependencies session_deps(
   5657         ProxyService::CreateFixed(tests[i].proxy_server));
   5658     scoped_refptr<HttpNetworkSession> session(
   5659         SetupSessionForGroupNameTests(&session_deps));
   5660 
   5661     HttpNetworkSessionPeer peer(session);
   5662 
   5663     HostPortPair proxy_host("socks_proxy", 1080);
   5664     CaptureGroupNameSOCKSSocketPool* socks_conn_pool =
   5665         new CaptureGroupNameSOCKSSocketPool(NULL, NULL);
   5666     peer.SetSocketPoolForSOCKSProxy(proxy_host, socks_conn_pool);
   5667     CaptureGroupNameSSLSocketPool* ssl_conn_pool =
   5668         new CaptureGroupNameSSLSocketPool(NULL, NULL);
   5669     peer.SetSocketPoolForSSLWithProxy(proxy_host, ssl_conn_pool);
   5670 
   5671     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   5672 
   5673     EXPECT_EQ(ERR_IO_PENDING,
   5674               GroupNameTransactionHelper(tests[i].url, session));
   5675     if (tests[i].ssl)
   5676       EXPECT_EQ(tests[i].expected_group_name,
   5677                 ssl_conn_pool->last_group_name_received());
   5678     else
   5679       EXPECT_EQ(tests[i].expected_group_name,
   5680                 socks_conn_pool->last_group_name_received());
   5681   }
   5682 
   5683   HttpStreamFactory::set_use_alternate_protocols(false);
   5684 }
   5685 
   5686 TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   5687   HttpRequestInfo request;
   5688   request.method = "GET";
   5689   request.url = GURL("http://www.google.com/");
   5690 
   5691   SessionDependencies session_deps(
   5692       ProxyService::CreateFixed("myproxy:70;foobar:80"));
   5693 
   5694   // This simulates failure resolving all hostnames; that means we will fail
   5695   // connecting to both proxies (myproxy:70 and foobar:80).
   5696   session_deps.host_resolver->rules()->AddSimulatedFailure("*");
   5697 
   5698   scoped_ptr<HttpTransaction> trans(
   5699       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5700 
   5701   TestCompletionCallback callback;
   5702 
   5703   int rv = trans->Start(&request, &callback, BoundNetLog());
   5704   EXPECT_EQ(ERR_IO_PENDING, rv);
   5705 
   5706   rv = callback.WaitForResult();
   5707   EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
   5708 }
   5709 
   5710 // Host resolution observer used by
   5711 // HttpNetworkTransactionTest.ResolveMadeWithReferrer to check that host
   5712 // resovle requests are issued with a referrer of |expected_referrer|.
   5713 class ResolutionReferrerObserver : public HostResolver::Observer {
   5714  public:
   5715   explicit ResolutionReferrerObserver(const GURL& expected_referrer)
   5716       : expected_referrer_(expected_referrer),
   5717         called_start_with_referrer_(false),
   5718         called_finish_with_referrer_(false) {
   5719   }
   5720 
   5721   virtual void OnStartResolution(int id,
   5722                                  const HostResolver::RequestInfo& info) {
   5723     if (info.referrer() == expected_referrer_)
   5724       called_start_with_referrer_ = true;
   5725   }
   5726 
   5727   virtual void OnFinishResolutionWithStatus(
   5728       int id, bool was_resolved, const HostResolver::RequestInfo& info ) {
   5729     if (info.referrer() == expected_referrer_)
   5730       called_finish_with_referrer_ = true;
   5731   }
   5732 
   5733   virtual void OnCancelResolution(int id,
   5734                                   const HostResolver::RequestInfo& info ) {
   5735     FAIL() << "Should not be cancelling any requests!";
   5736   }
   5737 
   5738   bool did_complete_with_expected_referrer() const {
   5739     return called_start_with_referrer_ && called_finish_with_referrer_;
   5740   }
   5741 
   5742  private:
   5743   GURL expected_referrer_;
   5744   bool called_start_with_referrer_;
   5745   bool called_finish_with_referrer_;
   5746 
   5747   DISALLOW_COPY_AND_ASSIGN(ResolutionReferrerObserver);
   5748 };
   5749 
   5750 // Make sure that when HostResolver::Resolve() is invoked, it passes through
   5751 // the "referrer". This is depended on by the DNS prefetch observer.
   5752 TEST_F(HttpNetworkTransactionTest, ResolveMadeWithReferrer) {
   5753   GURL referrer = GURL("http://expected-referrer/");
   5754   EXPECT_TRUE(referrer.is_valid());
   5755   ResolutionReferrerObserver resolution_observer(referrer);
   5756 
   5757   // Issue a request, containing an HTTP referrer.
   5758   HttpRequestInfo request;
   5759   request.method = "GET";
   5760   request.referrer = referrer;
   5761   request.url = GURL("http://www.google.com/");
   5762 
   5763   SessionDependencies session_deps;
   5764   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   5765       CreateSession(&session_deps)));
   5766 
   5767   // Attach an observer to watch the host resolutions being made.
   5768   session_deps.host_resolver->AddObserver(&resolution_observer);
   5769 
   5770   // Connect up a mock socket which will fail when reading.
   5771   MockRead data_reads[] = {
   5772     MockRead(false, ERR_FAILED),
   5773   };
   5774   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   5775   session_deps.socket_factory.AddSocketDataProvider(&data);
   5776 
   5777   // Run the request until it fails reading from the socket.
   5778   TestCompletionCallback callback;
   5779   int rv = trans->Start(&request, &callback, BoundNetLog());
   5780   EXPECT_EQ(ERR_IO_PENDING, rv);
   5781   rv = callback.WaitForResult();
   5782   EXPECT_EQ(ERR_FAILED, rv);
   5783 
   5784   // Check that the host resolution observer saw |referrer|.
   5785   EXPECT_TRUE(resolution_observer.did_complete_with_expected_referrer());
   5786 }
   5787 
   5788 // Base test to make sure that when the load flags for a request specify to
   5789 // bypass the cache, the DNS cache is not used.
   5790 void BypassHostCacheOnRefreshHelper(int load_flags) {
   5791   // Issue a request, asking to bypass the cache(s).
   5792   HttpRequestInfo request;
   5793   request.method = "GET";
   5794   request.load_flags = load_flags;
   5795   request.url = GURL("http://www.google.com/");
   5796 
   5797   SessionDependencies session_deps;
   5798 
   5799   // Select a host resolver that does caching.
   5800   session_deps.host_resolver.reset(new MockCachingHostResolver);
   5801 
   5802   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   5803       CreateSession(&session_deps)));
   5804 
   5805   // Warm up the host cache so it has an entry for "www.google.com" (by doing
   5806   // a synchronous lookup.)
   5807   AddressList addrlist;
   5808   int rv = session_deps.host_resolver->Resolve(
   5809       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
   5810       NULL, NULL, BoundNetLog());
   5811   EXPECT_EQ(OK, rv);
   5812 
   5813   // Verify that it was added to host cache, by doing a subsequent async lookup
   5814   // and confirming it completes synchronously.
   5815   TestCompletionCallback resolve_callback;
   5816   rv = session_deps.host_resolver->Resolve(
   5817       HostResolver::RequestInfo(HostPortPair("www.google.com", 80)), &addrlist,
   5818       &resolve_callback, NULL, BoundNetLog());
   5819   ASSERT_EQ(OK, rv);
   5820 
   5821   // Inject a failure the next time that "www.google.com" is resolved. This way
   5822   // we can tell if the next lookup hit the cache, or the "network".
   5823   // (cache --> success, "network" --> failure).
   5824   session_deps.host_resolver->rules()->AddSimulatedFailure("www.google.com");
   5825 
   5826   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   5827   // first read -- this won't be reached as the host resolution will fail first.
   5828   MockRead data_reads[] = { MockRead(false, ERR_UNEXPECTED) };
   5829   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   5830   session_deps.socket_factory.AddSocketDataProvider(&data);
   5831 
   5832   // Run the request.
   5833   TestCompletionCallback callback;
   5834   rv = trans->Start(&request, &callback, BoundNetLog());
   5835   ASSERT_EQ(ERR_IO_PENDING, rv);
   5836   rv = callback.WaitForResult();
   5837 
   5838   // If we bypassed the cache, we would have gotten a failure while resolving
   5839   // "www.google.com".
   5840   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   5841 }
   5842 
   5843 // There are multiple load flags that should trigger the host cache bypass.
   5844 // Test each in isolation:
   5845 TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh1) {
   5846   BypassHostCacheOnRefreshHelper(LOAD_BYPASS_CACHE);
   5847 }
   5848 
   5849 TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh2) {
   5850   BypassHostCacheOnRefreshHelper(LOAD_VALIDATE_CACHE);
   5851 }
   5852 
   5853 TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh3) {
   5854   BypassHostCacheOnRefreshHelper(LOAD_DISABLE_CACHE);
   5855 }
   5856 
   5857 // Make sure we can handle an error when writing the request.
   5858 TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
   5859   SessionDependencies session_deps;
   5860   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   5861 
   5862   HttpRequestInfo request;
   5863   request.method = "GET";
   5864   request.url = GURL("http://www.foo.com/");
   5865   request.load_flags = 0;
   5866 
   5867   MockWrite write_failure[] = {
   5868     MockWrite(true, ERR_CONNECTION_RESET),
   5869   };
   5870   StaticSocketDataProvider data(NULL, 0,
   5871                                 write_failure, arraysize(write_failure));
   5872   session_deps.socket_factory.AddSocketDataProvider(&data);
   5873 
   5874   TestCompletionCallback callback;
   5875 
   5876   scoped_ptr<HttpTransaction> trans(
   5877       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5878 
   5879   int rv = trans->Start(&request, &callback, BoundNetLog());
   5880   EXPECT_EQ(ERR_IO_PENDING, rv);
   5881 
   5882   rv = callback.WaitForResult();
   5883   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   5884 }
   5885 
   5886 // Check that a connection closed after the start of the headers finishes ok.
   5887 TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
   5888   SessionDependencies session_deps;
   5889   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   5890 
   5891   HttpRequestInfo request;
   5892   request.method = "GET";
   5893   request.url = GURL("http://www.foo.com/");
   5894   request.load_flags = 0;
   5895 
   5896   MockRead data_reads[] = {
   5897     MockRead("HTTP/1."),
   5898     MockRead(false, OK),
   5899   };
   5900 
   5901   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   5902   session_deps.socket_factory.AddSocketDataProvider(&data);
   5903 
   5904   TestCompletionCallback callback;
   5905 
   5906   scoped_ptr<HttpTransaction> trans(
   5907       new HttpNetworkTransaction(CreateSession(&session_deps)));
   5908 
   5909   int rv = trans->Start(&request, &callback, BoundNetLog());
   5910   EXPECT_EQ(ERR_IO_PENDING, rv);
   5911 
   5912   rv = callback.WaitForResult();
   5913   EXPECT_EQ(OK, rv);
   5914 
   5915   const HttpResponseInfo* response = trans->GetResponseInfo();
   5916   EXPECT_TRUE(response != NULL);
   5917 
   5918   EXPECT_TRUE(response->headers != NULL);
   5919   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   5920 
   5921   std::string response_data;
   5922   rv = ReadTransaction(trans.get(), &response_data);
   5923   EXPECT_EQ(OK, rv);
   5924   EXPECT_EQ("", response_data);
   5925 }
   5926 
   5927 // Make sure that a dropped connection while draining the body for auth
   5928 // restart does the right thing.
   5929 TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
   5930   SessionDependencies session_deps;
   5931   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   5932 
   5933   HttpRequestInfo request;
   5934   request.method = "GET";
   5935   request.url = GURL("http://www.google.com/");
   5936   request.load_flags = 0;
   5937 
   5938   MockWrite data_writes1[] = {
   5939     MockWrite("GET / HTTP/1.1\r\n"
   5940               "Host: www.google.com\r\n"
   5941               "Connection: keep-alive\r\n\r\n"),
   5942   };
   5943 
   5944   MockRead data_reads1[] = {
   5945     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   5946     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   5947     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5948     MockRead("Content-Length: 14\r\n\r\n"),
   5949     MockRead("Unauth"),
   5950     MockRead(true, ERR_CONNECTION_RESET),
   5951   };
   5952 
   5953   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   5954                                  data_writes1, arraysize(data_writes1));
   5955   session_deps.socket_factory.AddSocketDataProvider(&data1);
   5956 
   5957   // After calling trans->RestartWithAuth(), this is the request we should
   5958   // be issuing -- the final header line contains the credentials.
   5959   MockWrite data_writes2[] = {
   5960     MockWrite("GET / HTTP/1.1\r\n"
   5961               "Host: www.google.com\r\n"
   5962               "Connection: keep-alive\r\n"
   5963               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   5964   };
   5965 
   5966   // Lastly, the server responds with the actual content.
   5967   MockRead data_reads2[] = {
   5968     MockRead("HTTP/1.1 200 OK\r\n"),
   5969     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   5970     MockRead("Content-Length: 100\r\n\r\n"),
   5971     MockRead(false, OK),
   5972   };
   5973 
   5974   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   5975                                  data_writes2, arraysize(data_writes2));
   5976   session_deps.socket_factory.AddSocketDataProvider(&data2);
   5977 
   5978   TestCompletionCallback callback1;
   5979 
   5980   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   5981 
   5982   int rv = trans->Start(&request, &callback1, BoundNetLog());
   5983   EXPECT_EQ(ERR_IO_PENDING, rv);
   5984 
   5985   rv = callback1.WaitForResult();
   5986   EXPECT_EQ(OK, rv);
   5987 
   5988   const HttpResponseInfo* response = trans->GetResponseInfo();
   5989   EXPECT_FALSE(response == NULL);
   5990 
   5991   // The password prompt info should have been set in response->auth_challenge.
   5992   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   5993 
   5994   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   5995   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   5996   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   5997 
   5998   TestCompletionCallback callback2;
   5999 
   6000   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   6001   EXPECT_EQ(ERR_IO_PENDING, rv);
   6002 
   6003   rv = callback2.WaitForResult();
   6004   EXPECT_EQ(OK, rv);
   6005 
   6006   response = trans->GetResponseInfo();
   6007   EXPECT_FALSE(response == NULL);
   6008   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6009   EXPECT_EQ(100, response->headers->GetContentLength());
   6010 }
   6011 
   6012 // Test HTTPS connections going through a proxy that sends extra data.
   6013 TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
   6014   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   6015 
   6016   HttpRequestInfo request;
   6017   request.method = "GET";
   6018   request.url = GURL("https://www.google.com/");
   6019   request.load_flags = 0;
   6020 
   6021   MockRead proxy_reads[] = {
   6022     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
   6023     MockRead(false, OK)
   6024   };
   6025 
   6026   StaticSocketDataProvider data(proxy_reads, arraysize(proxy_reads), NULL, 0);
   6027   SSLSocketDataProvider ssl(true, OK);
   6028 
   6029   session_deps.socket_factory.AddSocketDataProvider(&data);
   6030   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   6031 
   6032   TestCompletionCallback callback;
   6033 
   6034   session_deps.socket_factory.ResetNextMockIndexes();
   6035 
   6036   scoped_ptr<HttpTransaction> trans(
   6037       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6038 
   6039   int rv = trans->Start(&request, &callback, BoundNetLog());
   6040   EXPECT_EQ(ERR_IO_PENDING, rv);
   6041 
   6042   rv = callback.WaitForResult();
   6043   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   6044 }
   6045 
   6046 TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   6047   HttpRequestInfo request;
   6048   request.method = "GET";
   6049   request.url = GURL("http://www.google.com/");
   6050   request.load_flags = 0;
   6051 
   6052   SessionDependencies session_deps;
   6053   scoped_ptr<HttpTransaction> trans(
   6054       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6055 
   6056   MockRead data_reads[] = {
   6057     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
   6058     MockRead(false, OK),
   6059   };
   6060 
   6061   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   6062   session_deps.socket_factory.AddSocketDataProvider(&data);
   6063 
   6064   TestCompletionCallback callback;
   6065 
   6066   int rv = trans->Start(&request, &callback, BoundNetLog());
   6067   EXPECT_EQ(ERR_IO_PENDING, rv);
   6068 
   6069   EXPECT_EQ(OK, callback.WaitForResult());
   6070 
   6071   const HttpResponseInfo* response = trans->GetResponseInfo();
   6072   EXPECT_TRUE(response != NULL);
   6073 
   6074   EXPECT_TRUE(response->headers != NULL);
   6075   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   6076 
   6077   std::string response_data;
   6078   rv = ReadTransaction(trans.get(), &response_data);
   6079   EXPECT_EQ(ERR_CONNECTION_CLOSED, rv);
   6080 }
   6081 
   6082 TEST_F(HttpNetworkTransactionTest, UploadFileSmallerThanLength) {
   6083   HttpRequestInfo request;
   6084   request.method = "POST";
   6085   request.url = GURL("http://www.google.com/upload");
   6086   request.upload_data = new UploadData;
   6087   request.load_flags = 0;
   6088 
   6089   SessionDependencies session_deps;
   6090   scoped_ptr<HttpTransaction> trans(
   6091       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6092 
   6093   FilePath temp_file_path;
   6094   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path));
   6095   const uint64 kFakeSize = 100000;  // file is actually blank
   6096 
   6097   std::vector<UploadData::Element> elements;
   6098   UploadData::Element element;
   6099   element.SetToFilePath(temp_file_path);
   6100   element.SetContentLength(kFakeSize);
   6101   elements.push_back(element);
   6102   request.upload_data->SetElements(elements);
   6103   EXPECT_EQ(kFakeSize, request.upload_data->GetContentLength());
   6104 
   6105   MockRead data_reads[] = {
   6106     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   6107     MockRead("hello world"),
   6108     MockRead(false, OK),
   6109   };
   6110   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   6111   session_deps.socket_factory.AddSocketDataProvider(&data);
   6112 
   6113   TestCompletionCallback callback;
   6114 
   6115   int rv = trans->Start(&request, &callback, BoundNetLog());
   6116   EXPECT_EQ(ERR_IO_PENDING, rv);
   6117 
   6118   rv = callback.WaitForResult();
   6119   EXPECT_EQ(OK, rv);
   6120 
   6121   const HttpResponseInfo* response = trans->GetResponseInfo();
   6122   EXPECT_TRUE(response != NULL);
   6123 
   6124   EXPECT_TRUE(response->headers != NULL);
   6125   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   6126 
   6127   std::string response_data;
   6128   rv = ReadTransaction(trans.get(), &response_data);
   6129   EXPECT_EQ(OK, rv);
   6130   EXPECT_EQ("hello world", response_data);
   6131 
   6132   file_util::Delete(temp_file_path, false);
   6133 }
   6134 
   6135 TEST_F(HttpNetworkTransactionTest, UploadUnreadableFile) {
   6136   HttpRequestInfo request;
   6137   request.method = "POST";
   6138   request.url = GURL("http://www.google.com/upload");
   6139   request.upload_data = new UploadData;
   6140   request.load_flags = 0;
   6141 
   6142   // If we try to upload an unreadable file, the network stack should report
   6143   // the file size as zero and upload zero bytes for that file.
   6144   SessionDependencies session_deps;
   6145   scoped_ptr<HttpTransaction> trans(
   6146       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6147 
   6148   FilePath temp_file;
   6149   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
   6150   std::string temp_file_content("Unreadable file.");
   6151   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_content.c_str(),
   6152                                    temp_file_content.length()));
   6153   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
   6154 
   6155   std::vector<UploadData::Element> elements;
   6156   UploadData::Element element;
   6157   element.SetToFilePath(temp_file);
   6158   elements.push_back(element);
   6159   request.upload_data->SetElements(elements);
   6160 
   6161   MockRead data_reads[] = {
   6162     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
   6163     MockRead(false, OK),
   6164   };
   6165   MockWrite data_writes[] = {
   6166     MockWrite("POST /upload HTTP/1.1\r\n"
   6167               "Host: www.google.com\r\n"
   6168               "Connection: keep-alive\r\n"
   6169               "Content-Length: 0\r\n\r\n"),
   6170     MockWrite(false, OK),
   6171   };
   6172   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   6173                                 arraysize(data_writes));
   6174   session_deps.socket_factory.AddSocketDataProvider(&data);
   6175 
   6176   TestCompletionCallback callback;
   6177 
   6178   int rv = trans->Start(&request, &callback, BoundNetLog());
   6179   EXPECT_EQ(ERR_IO_PENDING, rv);
   6180 
   6181   rv = callback.WaitForResult();
   6182   EXPECT_EQ(OK, rv);
   6183 
   6184   const HttpResponseInfo* response = trans->GetResponseInfo();
   6185   EXPECT_TRUE(response != NULL);
   6186   EXPECT_TRUE(response->headers != NULL);
   6187   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   6188 
   6189   file_util::Delete(temp_file, false);
   6190 }
   6191 
   6192 TEST_F(HttpNetworkTransactionTest, UnreadableUploadFileAfterAuthRestart) {
   6193   HttpRequestInfo request;
   6194   request.method = "POST";
   6195   request.url = GURL("http://www.google.com/upload");
   6196   request.upload_data = new UploadData;
   6197   request.load_flags = 0;
   6198 
   6199   SessionDependencies session_deps;
   6200   scoped_ptr<HttpTransaction> trans(
   6201       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6202 
   6203   FilePath temp_file;
   6204   ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file));
   6205   std::string temp_file_contents("Unreadable file.");
   6206   std::string unreadable_contents(temp_file_contents.length(), '\0');
   6207   ASSERT_TRUE(file_util::WriteFile(temp_file, temp_file_contents.c_str(),
   6208                                    temp_file_contents.length()));
   6209 
   6210   std::vector<UploadData::Element> elements;
   6211   UploadData::Element element;
   6212   element.SetToFilePath(temp_file);
   6213   elements.push_back(element);
   6214   request.upload_data->SetElements(elements);
   6215 
   6216   MockRead data_reads[] = {
   6217     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   6218     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   6219     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
   6220 
   6221     MockRead("HTTP/1.1 200 OK\r\n"),
   6222     MockRead("Content-Length: 0\r\n\r\n"),
   6223     MockRead(false, OK),
   6224   };
   6225   MockWrite data_writes[] = {
   6226     MockWrite("POST /upload HTTP/1.1\r\n"
   6227               "Host: www.google.com\r\n"
   6228               "Connection: keep-alive\r\n"
   6229               "Content-Length: 16\r\n\r\n"),
   6230     MockWrite(false, temp_file_contents.c_str()),
   6231 
   6232     MockWrite("POST /upload HTTP/1.1\r\n"
   6233               "Host: www.google.com\r\n"
   6234               "Connection: keep-alive\r\n"
   6235               "Content-Length: 16\r\n"
   6236               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   6237     MockWrite(false, unreadable_contents.c_str(), temp_file_contents.length()),
   6238     MockWrite(false, OK),
   6239   };
   6240   StaticSocketDataProvider data(data_reads, arraysize(data_reads), data_writes,
   6241                                 arraysize(data_writes));
   6242   session_deps.socket_factory.AddSocketDataProvider(&data);
   6243 
   6244   TestCompletionCallback callback1;
   6245 
   6246   int rv = trans->Start(&request, &callback1, BoundNetLog());
   6247   EXPECT_EQ(ERR_IO_PENDING, rv);
   6248 
   6249   rv = callback1.WaitForResult();
   6250   EXPECT_EQ(OK, rv);
   6251 
   6252   const HttpResponseInfo* response = trans->GetResponseInfo();
   6253   EXPECT_TRUE(response != NULL);
   6254   EXPECT_TRUE(response->headers != NULL);
   6255   EXPECT_EQ("HTTP/1.1 401 Unauthorized", response->headers->GetStatusLine());
   6256 
   6257   // The password prompt info should have been set in response->auth_challenge.
   6258   EXPECT_TRUE(response->auth_challenge.get() != NULL);
   6259   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   6260   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   6261   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   6262 
   6263   // Now make the file unreadable and try again.
   6264   ASSERT_TRUE(file_util::MakeFileUnreadable(temp_file));
   6265 
   6266   TestCompletionCallback callback2;
   6267 
   6268   rv = trans->RestartWithAuth(kFoo, kBar, &callback2);
   6269   EXPECT_EQ(ERR_IO_PENDING, rv);
   6270 
   6271   rv = callback2.WaitForResult();
   6272   EXPECT_EQ(OK, rv);
   6273 
   6274   response = trans->GetResponseInfo();
   6275   EXPECT_TRUE(response != NULL);
   6276   EXPECT_TRUE(response->headers != NULL);
   6277   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6278   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6279 
   6280   file_util::Delete(temp_file, false);
   6281 }
   6282 
   6283 // Tests that changes to Auth realms are treated like auth rejections.
   6284 TEST_F(HttpNetworkTransactionTest, ChangeAuthRealms) {
   6285   SessionDependencies session_deps;
   6286 
   6287   HttpRequestInfo request;
   6288   request.method = "GET";
   6289   request.url = GURL("http://www.google.com/");
   6290   request.load_flags = 0;
   6291 
   6292   // First transaction will request a resource and receive a Basic challenge
   6293   // with realm="first_realm".
   6294   MockWrite data_writes1[] = {
   6295     MockWrite("GET / HTTP/1.1\r\n"
   6296               "Host: www.google.com\r\n"
   6297               "Connection: keep-alive\r\n"
   6298               "\r\n"),
   6299   };
   6300   MockRead data_reads1[] = {
   6301     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   6302              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   6303              "\r\n"),
   6304   };
   6305 
   6306   // After calling trans->RestartWithAuth(), provide an Authentication header
   6307   // for first_realm. The server will reject and provide a challenge with
   6308   // second_realm.
   6309   MockWrite data_writes2[] = {
   6310     MockWrite("GET / HTTP/1.1\r\n"
   6311               "Host: www.google.com\r\n"
   6312               "Connection: keep-alive\r\n"
   6313               "Authorization: Basic Zmlyc3Q6YmF6\r\n"
   6314               "\r\n"),
   6315   };
   6316   MockRead data_reads2[] = {
   6317     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   6318              "WWW-Authenticate: Basic realm=\"second_realm\"\r\n"
   6319              "\r\n"),
   6320   };
   6321 
   6322   // This again fails, and goes back to first_realm. Make sure that the
   6323   // entry is removed from cache.
   6324   MockWrite data_writes3[] = {
   6325     MockWrite("GET / HTTP/1.1\r\n"
   6326               "Host: www.google.com\r\n"
   6327               "Connection: keep-alive\r\n"
   6328               "Authorization: Basic c2Vjb25kOmZvdQ==\r\n"
   6329               "\r\n"),
   6330   };
   6331   MockRead data_reads3[] = {
   6332     MockRead("HTTP/1.1 401 Unauthorized\r\n"
   6333              "WWW-Authenticate: Basic realm=\"first_realm\"\r\n"
   6334              "\r\n"),
   6335   };
   6336 
   6337   // Try one last time (with the correct password) and get the resource.
   6338   MockWrite data_writes4[] = {
   6339     MockWrite("GET / HTTP/1.1\r\n"
   6340               "Host: www.google.com\r\n"
   6341               "Connection: keep-alive\r\n"
   6342               "Authorization: Basic Zmlyc3Q6YmFy\r\n"
   6343               "\r\n"),
   6344   };
   6345   MockRead data_reads4[] = {
   6346     MockRead("HTTP/1.1 200 OK\r\n"
   6347              "Content-Type: text/html; charset=iso-8859-1\r\n"
   6348              "Content-Length: 5\r\n"
   6349              "\r\n"
   6350              "hello"),
   6351   };
   6352 
   6353   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   6354                                  data_writes1, arraysize(data_writes1));
   6355   StaticSocketDataProvider data2(data_reads2, arraysize(data_reads2),
   6356                                  data_writes2, arraysize(data_writes2));
   6357   StaticSocketDataProvider data3(data_reads3, arraysize(data_reads3),
   6358                                  data_writes3, arraysize(data_writes3));
   6359   StaticSocketDataProvider data4(data_reads4, arraysize(data_reads4),
   6360                                  data_writes4, arraysize(data_writes4));
   6361   session_deps.socket_factory.AddSocketDataProvider(&data1);
   6362   session_deps.socket_factory.AddSocketDataProvider(&data2);
   6363   session_deps.socket_factory.AddSocketDataProvider(&data3);
   6364   session_deps.socket_factory.AddSocketDataProvider(&data4);
   6365 
   6366   TestCompletionCallback callback1;
   6367 
   6368   scoped_ptr<HttpTransaction> trans(
   6369       new HttpNetworkTransaction(CreateSession(&session_deps)));
   6370 
   6371   // Issue the first request with Authorize headers. There should be a
   6372   // password prompt for first_realm waiting to be filled in after the
   6373   // transaction completes.
   6374   int rv = trans->Start(&request, &callback1, BoundNetLog());
   6375   EXPECT_EQ(ERR_IO_PENDING, rv);
   6376   rv = callback1.WaitForResult();
   6377   EXPECT_EQ(OK, rv);
   6378   const HttpResponseInfo* response = trans->GetResponseInfo();
   6379   ASSERT_FALSE(response == NULL);
   6380   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   6381   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   6382   EXPECT_EQ(L"first_realm", response->auth_challenge->realm);
   6383   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   6384 
   6385   // Issue the second request with an incorrect password. There should be a
   6386   // password prompt for second_realm waiting to be filled in after the
   6387   // transaction completes.
   6388   TestCompletionCallback callback2;
   6389   rv = trans->RestartWithAuth(kFirst, kBaz, &callback2);
   6390   EXPECT_EQ(ERR_IO_PENDING, rv);
   6391   rv = callback2.WaitForResult();
   6392   EXPECT_EQ(OK, rv);
   6393   response = trans->GetResponseInfo();
   6394   ASSERT_FALSE(response == NULL);
   6395   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   6396   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   6397   EXPECT_EQ(L"second_realm", response->auth_challenge->realm);
   6398   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   6399 
   6400   // Issue the third request with another incorrect password. There should be
   6401   // a password prompt for first_realm waiting to be filled in. If the password
   6402   // prompt is not present, it indicates that the HttpAuthCacheEntry for
   6403   // first_realm was not correctly removed.
   6404   TestCompletionCallback callback3;
   6405   rv = trans->RestartWithAuth(kSecond, kFou, &callback3);
   6406   EXPECT_EQ(ERR_IO_PENDING, rv);
   6407   rv = callback3.WaitForResult();
   6408   EXPECT_EQ(OK, rv);
   6409   response = trans->GetResponseInfo();
   6410   ASSERT_FALSE(response == NULL);
   6411   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   6412   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   6413   EXPECT_EQ(L"first_realm", response->auth_challenge->realm);
   6414   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   6415 
   6416   // Issue the fourth request with the correct password and username.
   6417   TestCompletionCallback callback4;
   6418   rv = trans->RestartWithAuth(kFirst, kBar, &callback4);
   6419   EXPECT_EQ(ERR_IO_PENDING, rv);
   6420   rv = callback4.WaitForResult();
   6421   EXPECT_EQ(OK, rv);
   6422   response = trans->GetResponseInfo();
   6423   ASSERT_FALSE(response == NULL);
   6424   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   6425 }
   6426 
   6427 TEST_F(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) {
   6428   HttpStreamFactory::set_next_protos("needs_to_be_set_for_this_test");
   6429   HttpStreamFactory::set_use_alternate_protocols(true);
   6430 
   6431   SessionDependencies session_deps;
   6432 
   6433   MockRead data_reads[] = {
   6434     MockRead("HTTP/1.1 200 OK\r\n"),
   6435     MockRead(kAlternateProtocolHttpHeader),
   6436     MockRead("hello world"),
   6437     MockRead(false, OK),
   6438   };
   6439 
   6440   HttpRequestInfo request;
   6441   request.method = "GET";
   6442   request.url = GURL("http://www.google.com/");
   6443   request.load_flags = 0;
   6444 
   6445   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   6446 
   6447   session_deps.socket_factory.AddSocketDataProvider(&data);
   6448 
   6449   TestCompletionCallback callback;
   6450 
   6451   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6452   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   6453 
   6454   int rv = trans->Start(&request, &callback, BoundNetLog());
   6455   EXPECT_EQ(ERR_IO_PENDING, rv);
   6456 
   6457   HostPortPair http_host_port_pair("www.google.com", 80);
   6458   const HttpAlternateProtocols& alternate_protocols =
   6459       session->alternate_protocols();
   6460   EXPECT_FALSE(
   6461       alternate_protocols.HasAlternateProtocolFor(http_host_port_pair));
   6462 
   6463   EXPECT_EQ(OK, callback.WaitForResult());
   6464 
   6465   const HttpResponseInfo* response = trans->GetResponseInfo();
   6466   ASSERT_TRUE(response != NULL);
   6467   ASSERT_TRUE(response->headers != NULL);
   6468   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6469   EXPECT_FALSE(response->was_fetched_via_spdy);
   6470   EXPECT_FALSE(response->was_npn_negotiated);
   6471 
   6472   std::string response_data;
   6473   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6474   EXPECT_EQ("hello world", response_data);
   6475 
   6476   ASSERT_TRUE(alternate_protocols.HasAlternateProtocolFor(http_host_port_pair));
   6477   const HttpAlternateProtocols::PortProtocolPair alternate =
   6478       alternate_protocols.GetAlternateProtocolFor(http_host_port_pair);
   6479   HttpAlternateProtocols::PortProtocolPair expected_alternate;
   6480   expected_alternate.port = 443;
   6481   expected_alternate.protocol = HttpAlternateProtocols::NPN_SPDY_2;
   6482   EXPECT_TRUE(expected_alternate.Equals(alternate));
   6483 
   6484   HttpStreamFactory::set_use_alternate_protocols(false);
   6485   HttpStreamFactory::set_next_protos("");
   6486 }
   6487 
   6488 TEST_F(HttpNetworkTransactionTest, MarkBrokenAlternateProtocolAndFallback) {
   6489   HttpStreamFactory::set_use_alternate_protocols(true);
   6490   SessionDependencies session_deps;
   6491 
   6492   HttpRequestInfo request;
   6493   request.method = "GET";
   6494   request.url = GURL("http://www.google.com/");
   6495   request.load_flags = 0;
   6496 
   6497   MockConnect mock_connect(true, ERR_CONNECTION_REFUSED);
   6498   StaticSocketDataProvider first_data;
   6499   first_data.set_connect_data(mock_connect);
   6500   session_deps.socket_factory.AddSocketDataProvider(&first_data);
   6501 
   6502   MockRead data_reads[] = {
   6503     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
   6504     MockRead("hello world"),
   6505     MockRead(true, OK),
   6506   };
   6507   StaticSocketDataProvider second_data(
   6508       data_reads, arraysize(data_reads), NULL, 0);
   6509   session_deps.socket_factory.AddSocketDataProvider(&second_data);
   6510 
   6511   TestCompletionCallback callback;
   6512 
   6513   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6514 
   6515   HostPortPair http_host_port_pair("www.google.com", 80);
   6516   HttpAlternateProtocols* alternate_protocols =
   6517       session->mutable_alternate_protocols();
   6518   alternate_protocols->SetAlternateProtocolFor(
   6519       http_host_port_pair, 1234 /* port is ignored by MockConnect anyway */,
   6520       HttpAlternateProtocols::NPN_SPDY_2);
   6521 
   6522   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   6523 
   6524   int rv = trans->Start(&request, &callback, BoundNetLog());
   6525   EXPECT_EQ(ERR_IO_PENDING, rv);
   6526   EXPECT_EQ(OK, callback.WaitForResult());
   6527 
   6528   const HttpResponseInfo* response = trans->GetResponseInfo();
   6529   ASSERT_TRUE(response != NULL);
   6530   ASSERT_TRUE(response->headers != NULL);
   6531   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6532 
   6533   std::string response_data;
   6534   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6535   EXPECT_EQ("hello world", response_data);
   6536 
   6537   ASSERT_TRUE(
   6538       alternate_protocols->HasAlternateProtocolFor(http_host_port_pair));
   6539   const HttpAlternateProtocols::PortProtocolPair alternate =
   6540       alternate_protocols->GetAlternateProtocolFor(http_host_port_pair);
   6541   EXPECT_EQ(HttpAlternateProtocols::BROKEN, alternate.protocol);
   6542   HttpStreamFactory::set_use_alternate_protocols(false);
   6543 }
   6544 
   6545 TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForNpnSpdy) {
   6546   HttpStreamFactory::set_use_alternate_protocols(true);
   6547   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   6548   SessionDependencies session_deps;
   6549 
   6550   HttpRequestInfo request;
   6551   request.method = "GET";
   6552   request.url = GURL("http://www.google.com/");
   6553   request.load_flags = 0;
   6554 
   6555   MockRead data_reads[] = {
   6556     MockRead("HTTP/1.1 200 OK\r\n"),
   6557     MockRead(kAlternateProtocolHttpHeader),
   6558     MockRead("hello world"),
   6559     MockRead(true, OK),
   6560   };
   6561 
   6562   StaticSocketDataProvider first_transaction(
   6563       data_reads, arraysize(data_reads), NULL, 0);
   6564   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   6565 
   6566   SSLSocketDataProvider ssl(true, OK);
   6567   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   6568   ssl.next_proto = "spdy/2";
   6569   ssl.was_npn_negotiated = true;
   6570   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   6571 
   6572   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   6573   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   6574 
   6575   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   6576   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   6577   MockRead spdy_reads[] = {
   6578     CreateMockRead(*resp),
   6579     CreateMockRead(*data),
   6580     MockRead(true, 0, 0),
   6581   };
   6582 
   6583   scoped_refptr<DelayedSocketData> spdy_data(
   6584       new DelayedSocketData(
   6585           1,  // wait for one write to finish before reading.
   6586           spdy_reads, arraysize(spdy_reads),
   6587           spdy_writes, arraysize(spdy_writes)));
   6588   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   6589 
   6590   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
   6591   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   6592       NULL, 0, NULL, 0);
   6593   hanging_non_alternate_protocol_socket.set_connect_data(
   6594       never_finishing_connect);
   6595   session_deps.socket_factory.AddSocketDataProvider(
   6596       &hanging_non_alternate_protocol_socket);
   6597 
   6598   TestCompletionCallback callback;
   6599 
   6600   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6601   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   6602 
   6603   int rv = trans->Start(&request, &callback, BoundNetLog());
   6604   EXPECT_EQ(ERR_IO_PENDING, rv);
   6605   EXPECT_EQ(OK, callback.WaitForResult());
   6606 
   6607   const HttpResponseInfo* response = trans->GetResponseInfo();
   6608   ASSERT_TRUE(response != NULL);
   6609   ASSERT_TRUE(response->headers != NULL);
   6610   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6611 
   6612   std::string response_data;
   6613   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6614   EXPECT_EQ("hello world", response_data);
   6615 
   6616   trans.reset(new HttpNetworkTransaction(session));
   6617 
   6618   rv = trans->Start(&request, &callback, BoundNetLog());
   6619   EXPECT_EQ(ERR_IO_PENDING, rv);
   6620   EXPECT_EQ(OK, callback.WaitForResult());
   6621 
   6622   response = trans->GetResponseInfo();
   6623   ASSERT_TRUE(response != NULL);
   6624   ASSERT_TRUE(response->headers != NULL);
   6625   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6626   EXPECT_TRUE(response->was_fetched_via_spdy);
   6627   EXPECT_TRUE(response->was_npn_negotiated);
   6628 
   6629   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6630   EXPECT_EQ("hello!", response_data);
   6631 
   6632   HttpStreamFactory::set_next_protos("");
   6633   HttpStreamFactory::set_use_alternate_protocols(false);
   6634 }
   6635 
   6636 TEST_F(HttpNetworkTransactionTest, AlternateProtocolWithSpdyLateBinding) {
   6637   HttpStreamFactory::set_use_alternate_protocols(true);
   6638   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   6639   SessionDependencies session_deps;
   6640 
   6641   HttpRequestInfo request;
   6642   request.method = "GET";
   6643   request.url = GURL("http://www.google.com/");
   6644   request.load_flags = 0;
   6645 
   6646   MockRead data_reads[] = {
   6647     MockRead("HTTP/1.1 200 OK\r\n"),
   6648     MockRead(kAlternateProtocolHttpHeader),
   6649     MockRead("hello world"),
   6650     MockRead(true, OK),
   6651   };
   6652 
   6653   StaticSocketDataProvider first_transaction(
   6654       data_reads, arraysize(data_reads), NULL, 0);
   6655   // Socket 1 is the HTTP transaction with the Alternate-Protocol header.
   6656   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   6657 
   6658   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
   6659   StaticSocketDataProvider hanging_socket(
   6660       NULL, 0, NULL, 0);
   6661   hanging_socket.set_connect_data(never_finishing_connect);
   6662   // Socket 2 and 3 are the hanging Alternate-Protocol and
   6663   // non-Alternate-Protocol jobs from the 2nd transaction.
   6664   session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
   6665   session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
   6666 
   6667   SSLSocketDataProvider ssl(true, OK);
   6668   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   6669   ssl.next_proto = "spdy/2";
   6670   ssl.was_npn_negotiated = true;
   6671   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   6672 
   6673   scoped_ptr<spdy::SpdyFrame> req1(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   6674   scoped_ptr<spdy::SpdyFrame> req2(ConstructSpdyGet(NULL, 0, false, 3, LOWEST));
   6675   MockWrite spdy_writes[] = {
   6676     CreateMockWrite(*req1),
   6677     CreateMockWrite(*req2),
   6678   };
   6679   scoped_ptr<spdy::SpdyFrame> resp1(ConstructSpdyGetSynReply(NULL, 0, 1));
   6680   scoped_ptr<spdy::SpdyFrame> data1(ConstructSpdyBodyFrame(1, true));
   6681   scoped_ptr<spdy::SpdyFrame> resp2(ConstructSpdyGetSynReply(NULL, 0, 3));
   6682   scoped_ptr<spdy::SpdyFrame> data2(ConstructSpdyBodyFrame(3, true));
   6683   MockRead spdy_reads[] = {
   6684     CreateMockRead(*resp1),
   6685     CreateMockRead(*data1),
   6686     CreateMockRead(*resp2),
   6687     CreateMockRead(*data2),
   6688     MockRead(true, 0, 0),
   6689   };
   6690 
   6691   scoped_refptr<DelayedSocketData> spdy_data(
   6692       new DelayedSocketData(
   6693           2,  // wait for writes to finish before reading.
   6694           spdy_reads, arraysize(spdy_reads),
   6695           spdy_writes, arraysize(spdy_writes)));
   6696   // Socket 4 is the successful Alternate-Protocol for transaction 3.
   6697   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   6698 
   6699   // Socket 5 is the unsuccessful non-Alternate-Protocol for transaction 3.
   6700   session_deps.socket_factory.AddSocketDataProvider(&hanging_socket);
   6701 
   6702   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6703   TestCompletionCallback callback1;
   6704   HttpNetworkTransaction trans1(session);
   6705 
   6706   int rv = trans1.Start(&request, &callback1, BoundNetLog());
   6707   EXPECT_EQ(ERR_IO_PENDING, rv);
   6708   EXPECT_EQ(OK, callback1.WaitForResult());
   6709 
   6710   const HttpResponseInfo* response = trans1.GetResponseInfo();
   6711   ASSERT_TRUE(response != NULL);
   6712   ASSERT_TRUE(response->headers != NULL);
   6713   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6714 
   6715   std::string response_data;
   6716   ASSERT_EQ(OK, ReadTransaction(&trans1, &response_data));
   6717   EXPECT_EQ("hello world", response_data);
   6718 
   6719   TestCompletionCallback callback2;
   6720   HttpNetworkTransaction trans2(session);
   6721   rv = trans2.Start(&request, &callback2, BoundNetLog());
   6722   EXPECT_EQ(ERR_IO_PENDING, rv);
   6723 
   6724   TestCompletionCallback callback3;
   6725   HttpNetworkTransaction trans3(session);
   6726   rv = trans3.Start(&request, &callback3, BoundNetLog());
   6727   EXPECT_EQ(ERR_IO_PENDING, rv);
   6728 
   6729   EXPECT_EQ(OK, callback2.WaitForResult());
   6730   EXPECT_EQ(OK, callback3.WaitForResult());
   6731 
   6732   response = trans2.GetResponseInfo();
   6733   ASSERT_TRUE(response != NULL);
   6734   ASSERT_TRUE(response->headers != NULL);
   6735   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6736   EXPECT_TRUE(response->was_fetched_via_spdy);
   6737   EXPECT_TRUE(response->was_npn_negotiated);
   6738   ASSERT_EQ(OK, ReadTransaction(&trans2, &response_data));
   6739   EXPECT_EQ("hello!", response_data);
   6740 
   6741   response = trans3.GetResponseInfo();
   6742   ASSERT_TRUE(response != NULL);
   6743   ASSERT_TRUE(response->headers != NULL);
   6744   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6745   EXPECT_TRUE(response->was_fetched_via_spdy);
   6746   EXPECT_TRUE(response->was_npn_negotiated);
   6747   ASSERT_EQ(OK, ReadTransaction(&trans3, &response_data));
   6748   EXPECT_EQ("hello!", response_data);
   6749 
   6750   HttpStreamFactory::set_next_protos("");
   6751   HttpStreamFactory::set_use_alternate_protocols(false);
   6752 }
   6753 
   6754 TEST_F(HttpNetworkTransactionTest, StallAlternateProtocolForNpnSpdy) {
   6755   HttpStreamFactory::set_use_alternate_protocols(true);
   6756   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   6757   SessionDependencies session_deps;
   6758 
   6759   HttpRequestInfo request;
   6760   request.method = "GET";
   6761   request.url = GURL("http://www.google.com/");
   6762   request.load_flags = 0;
   6763 
   6764   MockRead data_reads[] = {
   6765     MockRead("HTTP/1.1 200 OK\r\n"),
   6766     MockRead(kAlternateProtocolHttpHeader),
   6767     MockRead("hello world"),
   6768     MockRead(true, OK),
   6769   };
   6770 
   6771   StaticSocketDataProvider first_transaction(
   6772       data_reads, arraysize(data_reads), NULL, 0);
   6773   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   6774 
   6775   SSLSocketDataProvider ssl(true, OK);
   6776   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   6777   ssl.next_proto = "spdy/2";
   6778   ssl.was_npn_negotiated = true;
   6779   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   6780 
   6781   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
   6782   StaticSocketDataProvider hanging_alternate_protocol_socket(
   6783       NULL, 0, NULL, 0);
   6784   hanging_alternate_protocol_socket.set_connect_data(
   6785       never_finishing_connect);
   6786   session_deps.socket_factory.AddSocketDataProvider(
   6787       &hanging_alternate_protocol_socket);
   6788 
   6789   // 2nd request is just a copy of the first one, over HTTP again.
   6790   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   6791 
   6792   TestCompletionCallback callback;
   6793 
   6794   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6795   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   6796 
   6797   int rv = trans->Start(&request, &callback, BoundNetLog());
   6798   EXPECT_EQ(ERR_IO_PENDING, rv);
   6799   EXPECT_EQ(OK, callback.WaitForResult());
   6800 
   6801   const HttpResponseInfo* response = trans->GetResponseInfo();
   6802   ASSERT_TRUE(response != NULL);
   6803   ASSERT_TRUE(response->headers != NULL);
   6804   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6805 
   6806   std::string response_data;
   6807   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6808   EXPECT_EQ("hello world", response_data);
   6809 
   6810   trans.reset(new HttpNetworkTransaction(session));
   6811 
   6812   rv = trans->Start(&request, &callback, BoundNetLog());
   6813   EXPECT_EQ(ERR_IO_PENDING, rv);
   6814   EXPECT_EQ(OK, callback.WaitForResult());
   6815 
   6816   response = trans->GetResponseInfo();
   6817   ASSERT_TRUE(response != NULL);
   6818   ASSERT_TRUE(response->headers != NULL);
   6819   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6820   EXPECT_FALSE(response->was_fetched_via_spdy);
   6821   EXPECT_FALSE(response->was_npn_negotiated);
   6822 
   6823   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6824   EXPECT_EQ("hello world", response_data);
   6825 
   6826   HttpStreamFactory::set_next_protos("");
   6827   HttpStreamFactory::set_use_alternate_protocols(false);
   6828 }
   6829 
   6830 class CapturingProxyResolver : public ProxyResolver {
   6831  public:
   6832   CapturingProxyResolver() : ProxyResolver(false /* expects_pac_bytes */) {}
   6833   virtual ~CapturingProxyResolver() {}
   6834 
   6835   virtual int GetProxyForURL(const GURL& url,
   6836                              ProxyInfo* results,
   6837                              CompletionCallback* callback,
   6838                              RequestHandle* request,
   6839                              const BoundNetLog& net_log) {
   6840     ProxyServer proxy_server(ProxyServer::SCHEME_HTTP,
   6841                              HostPortPair("myproxy", 80));
   6842     results->UseProxyServer(proxy_server);
   6843     resolved_.push_back(url);
   6844     return OK;
   6845   }
   6846 
   6847   virtual void CancelRequest(RequestHandle request) {
   6848     NOTREACHED();
   6849   }
   6850 
   6851   virtual void CancelSetPacScript() {
   6852     NOTREACHED();
   6853   }
   6854 
   6855   virtual int SetPacScript(const scoped_refptr<ProxyResolverScriptData>&,
   6856                            CompletionCallback* /*callback*/) {
   6857     return OK;
   6858   }
   6859 
   6860   const std::vector<GURL>& resolved() const { return resolved_; }
   6861 
   6862  private:
   6863   std::vector<GURL> resolved_;
   6864 
   6865   DISALLOW_COPY_AND_ASSIGN(CapturingProxyResolver);
   6866 };
   6867 
   6868 TEST_F(HttpNetworkTransactionTest, UseAlternateProtocolForTunneledNpnSpdy) {
   6869   HttpStreamFactory::set_use_alternate_protocols(true);
   6870   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   6871 
   6872   ProxyConfig proxy_config;
   6873   proxy_config.set_auto_detect(true);
   6874   proxy_config.set_pac_url(GURL("http://fooproxyurl"));
   6875 
   6876   CapturingProxyResolver* capturing_proxy_resolver =
   6877       new CapturingProxyResolver();
   6878   SessionDependencies session_deps(new ProxyService(
   6879       new ProxyConfigServiceFixed(proxy_config), capturing_proxy_resolver,
   6880       NULL));
   6881 
   6882   HttpRequestInfo request;
   6883   request.method = "GET";
   6884   request.url = GURL("http://www.google.com/");
   6885   request.load_flags = 0;
   6886 
   6887   MockRead data_reads[] = {
   6888     MockRead("HTTP/1.1 200 OK\r\n"),
   6889     MockRead(kAlternateProtocolHttpHeader),
   6890     MockRead("hello world"),
   6891     MockRead(true, OK),
   6892   };
   6893 
   6894   StaticSocketDataProvider first_transaction(
   6895       data_reads, arraysize(data_reads), NULL, 0);
   6896   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   6897 
   6898   SSLSocketDataProvider ssl(true, OK);
   6899   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   6900   ssl.next_proto = "spdy/2";
   6901   ssl.was_npn_negotiated = true;
   6902   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   6903 
   6904   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   6905   MockWrite spdy_writes[] = {
   6906     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   6907               "Host: www.google.com\r\n"
   6908               "Proxy-Connection: keep-alive\r\n\r\n"),  // 0
   6909     CreateMockWrite(*req)  // 3
   6910   };
   6911 
   6912   const char kCONNECTResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   6913 
   6914   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   6915   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   6916   MockRead spdy_reads[] = {
   6917     MockRead(true, kCONNECTResponse, arraysize(kCONNECTResponse) - 1, 1),  // 1
   6918     CreateMockRead(*resp.get(), 4),  // 2, 4
   6919     CreateMockRead(*data.get(), 4),  // 5
   6920     MockRead(true, 0, 0, 4),  // 6
   6921   };
   6922 
   6923   scoped_refptr<OrderedSocketData> spdy_data(
   6924       new OrderedSocketData(
   6925           spdy_reads, arraysize(spdy_reads),
   6926           spdy_writes, arraysize(spdy_writes)));
   6927   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   6928 
   6929   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
   6930   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   6931       NULL, 0, NULL, 0);
   6932   hanging_non_alternate_protocol_socket.set_connect_data(
   6933       never_finishing_connect);
   6934   session_deps.socket_factory.AddSocketDataProvider(
   6935       &hanging_non_alternate_protocol_socket);
   6936 
   6937   TestCompletionCallback callback;
   6938 
   6939   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   6940   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   6941 
   6942   int rv = trans->Start(&request, &callback, BoundNetLog());
   6943   EXPECT_EQ(ERR_IO_PENDING, rv);
   6944   EXPECT_EQ(OK, callback.WaitForResult());
   6945 
   6946   const HttpResponseInfo* response = trans->GetResponseInfo();
   6947   ASSERT_TRUE(response != NULL);
   6948   ASSERT_TRUE(response->headers != NULL);
   6949   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6950   EXPECT_FALSE(response->was_fetched_via_spdy);
   6951   EXPECT_FALSE(response->was_npn_negotiated);
   6952 
   6953   std::string response_data;
   6954   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6955   EXPECT_EQ("hello world", response_data);
   6956 
   6957   trans.reset(new HttpNetworkTransaction(session));
   6958 
   6959   rv = trans->Start(&request, &callback, BoundNetLog());
   6960   EXPECT_EQ(ERR_IO_PENDING, rv);
   6961   EXPECT_EQ(OK, callback.WaitForResult());
   6962 
   6963   response = trans->GetResponseInfo();
   6964   ASSERT_TRUE(response != NULL);
   6965   ASSERT_TRUE(response->headers != NULL);
   6966   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   6967   EXPECT_TRUE(response->was_fetched_via_spdy);
   6968   EXPECT_TRUE(response->was_npn_negotiated);
   6969 
   6970   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   6971   EXPECT_EQ("hello!", response_data);
   6972   ASSERT_EQ(3u, capturing_proxy_resolver->resolved().size());
   6973   EXPECT_EQ("http://www.google.com/",
   6974             capturing_proxy_resolver->resolved()[0].spec());
   6975   EXPECT_EQ("https://www.google.com/",
   6976             capturing_proxy_resolver->resolved()[1].spec());
   6977 
   6978   HttpStreamFactory::set_next_protos("");
   6979   HttpStreamFactory::set_use_alternate_protocols(false);
   6980 }
   6981 
   6982 TEST_F(HttpNetworkTransactionTest,
   6983        UseAlternateProtocolForNpnSpdyWithExistingSpdySession) {
   6984   HttpStreamFactory::set_use_alternate_protocols(true);
   6985   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   6986   SessionDependencies session_deps;
   6987 
   6988   HttpRequestInfo request;
   6989   request.method = "GET";
   6990   request.url = GURL("http://www.google.com/");
   6991   request.load_flags = 0;
   6992 
   6993   MockRead data_reads[] = {
   6994     MockRead("HTTP/1.1 200 OK\r\n"),
   6995     MockRead(kAlternateProtocolHttpHeader),
   6996     MockRead("hello world"),
   6997     MockRead(true, OK),
   6998   };
   6999 
   7000   StaticSocketDataProvider first_transaction(
   7001       data_reads, arraysize(data_reads), NULL, 0);
   7002   session_deps.socket_factory.AddSocketDataProvider(&first_transaction);
   7003 
   7004   SSLSocketDataProvider ssl(true, OK);
   7005   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   7006   ssl.next_proto = "spdy/2";
   7007   ssl.was_npn_negotiated = true;
   7008   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   7009   // Make sure we use ssl for spdy here.
   7010   SpdySession::SetSSLMode(true);
   7011 
   7012   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   7013   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   7014 
   7015   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   7016   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   7017   MockRead spdy_reads[] = {
   7018     CreateMockRead(*resp),
   7019     CreateMockRead(*data),
   7020     MockRead(true, 0, 0),
   7021   };
   7022 
   7023   scoped_refptr<DelayedSocketData> spdy_data(
   7024       new DelayedSocketData(
   7025           1,  // wait for one write to finish before reading.
   7026           spdy_reads, arraysize(spdy_reads),
   7027           spdy_writes, arraysize(spdy_writes)));
   7028   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   7029 
   7030   TestCompletionCallback callback;
   7031 
   7032   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7033 
   7034   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   7035 
   7036   int rv = trans->Start(&request, &callback, BoundNetLog());
   7037   EXPECT_EQ(ERR_IO_PENDING, rv);
   7038   EXPECT_EQ(OK, callback.WaitForResult());
   7039 
   7040   const HttpResponseInfo* response = trans->GetResponseInfo();
   7041   ASSERT_TRUE(response != NULL);
   7042   ASSERT_TRUE(response->headers != NULL);
   7043   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7044 
   7045   std::string response_data;
   7046   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7047   EXPECT_EQ("hello world", response_data);
   7048 
   7049   // Set up an initial SpdySession in the pool to reuse.
   7050   HostPortPair host_port_pair("www.google.com", 443);
   7051   HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
   7052   scoped_refptr<SpdySession> spdy_session =
   7053       session->spdy_session_pool()->Get(pair, BoundNetLog());
   7054   scoped_refptr<TransportSocketParams> transport_params(
   7055       new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false));
   7056 
   7057   scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
   7058   EXPECT_EQ(ERR_IO_PENDING,
   7059             connection->Init(host_port_pair.ToString(),
   7060                              transport_params,
   7061                              LOWEST,
   7062                              &callback,
   7063                              session->transport_socket_pool(),
   7064                              BoundNetLog()));
   7065   EXPECT_EQ(OK, callback.WaitForResult());
   7066 
   7067   SSLConfig ssl_config;
   7068   session->ssl_config_service()->GetSSLConfig(&ssl_config);
   7069   scoped_ptr<ClientSocketHandle> ssl_connection(new ClientSocketHandle);
   7070   ssl_connection->set_socket(session_deps.socket_factory.CreateSSLClientSocket(
   7071       connection.release(), HostPortPair("" , 443), ssl_config,
   7072       NULL /* ssl_host_info */, session_deps.cert_verifier.get(), NULL));
   7073   EXPECT_EQ(ERR_IO_PENDING, ssl_connection->socket()->Connect(&callback));
   7074   EXPECT_EQ(OK, callback.WaitForResult());
   7075 
   7076   EXPECT_EQ(OK, spdy_session->InitializeWithSocket(ssl_connection.release(),
   7077                                                    true, OK));
   7078 
   7079   trans.reset(new HttpNetworkTransaction(session));
   7080 
   7081   rv = trans->Start(&request, &callback, BoundNetLog());
   7082   EXPECT_EQ(ERR_IO_PENDING, rv);
   7083   EXPECT_EQ(OK, callback.WaitForResult());
   7084 
   7085   response = trans->GetResponseInfo();
   7086   ASSERT_TRUE(response != NULL);
   7087   ASSERT_TRUE(response->headers != NULL);
   7088   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7089   EXPECT_TRUE(response->was_fetched_via_spdy);
   7090   EXPECT_TRUE(response->was_npn_negotiated);
   7091 
   7092   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7093   EXPECT_EQ("hello!", response_data);
   7094 
   7095   HttpStreamFactory::set_next_protos("");
   7096   HttpStreamFactory::set_use_alternate_protocols(false);
   7097 }
   7098 
   7099 // GenerateAuthToken is a mighty big test.
   7100 // It tests all permutation of GenerateAuthToken behavior:
   7101 //   - Synchronous and Asynchronous completion.
   7102 //   - OK or error on completion.
   7103 //   - Direct connection, non-authenticating proxy, and authenticating proxy.
   7104 //   - HTTP or HTTPS backend (to include proxy tunneling).
   7105 //   - Non-authenticating and authenticating backend.
   7106 //
   7107 // In all, there are 44 reasonable permuations (for example, if there are
   7108 // problems generating an auth token for an authenticating proxy, we don't
   7109 // need to test all permutations of the backend server).
   7110 //
   7111 // The test proceeds by going over each of the configuration cases, and
   7112 // potentially running up to three rounds in each of the tests. The TestConfig
   7113 // specifies both the configuration for the test as well as the expectations
   7114 // for the results.
   7115 TEST_F(HttpNetworkTransactionTest, GenerateAuthToken) {
   7116   static const char kServer[] = "http://www.example.com";
   7117   static const char kSecureServer[] = "https://www.example.com";
   7118   static const char kProxy[] = "myproxy:70";
   7119   const int kAuthErr = ERR_INVALID_AUTH_CREDENTIALS;
   7120 
   7121   enum AuthTiming {
   7122     AUTH_NONE,
   7123     AUTH_SYNC,
   7124     AUTH_ASYNC,
   7125   };
   7126 
   7127   const MockWrite kGet(
   7128       "GET / HTTP/1.1\r\n"
   7129       "Host: www.example.com\r\n"
   7130       "Connection: keep-alive\r\n\r\n");
   7131   const MockWrite kGetProxy(
   7132       "GET http://www.example.com/ HTTP/1.1\r\n"
   7133       "Host: www.example.com\r\n"
   7134       "Proxy-Connection: keep-alive\r\n\r\n");
   7135   const MockWrite kGetAuth(
   7136       "GET / HTTP/1.1\r\n"
   7137       "Host: www.example.com\r\n"
   7138       "Connection: keep-alive\r\n"
   7139       "Authorization: auth_token\r\n\r\n");
   7140   const MockWrite kGetProxyAuth(
   7141       "GET http://www.example.com/ HTTP/1.1\r\n"
   7142       "Host: www.example.com\r\n"
   7143       "Proxy-Connection: keep-alive\r\n"
   7144       "Proxy-Authorization: auth_token\r\n\r\n");
   7145   const MockWrite kGetAuthThroughProxy(
   7146       "GET http://www.example.com/ HTTP/1.1\r\n"
   7147       "Host: www.example.com\r\n"
   7148       "Proxy-Connection: keep-alive\r\n"
   7149       "Authorization: auth_token\r\n\r\n");
   7150   const MockWrite kGetAuthWithProxyAuth(
   7151       "GET http://www.example.com/ HTTP/1.1\r\n"
   7152       "Host: www.example.com\r\n"
   7153       "Proxy-Connection: keep-alive\r\n"
   7154       "Proxy-Authorization: auth_token\r\n"
   7155       "Authorization: auth_token\r\n\r\n");
   7156   const MockWrite kConnect(
   7157       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   7158       "Host: www.example.com\r\n"
   7159       "Proxy-Connection: keep-alive\r\n\r\n");
   7160   const MockWrite kConnectProxyAuth(
   7161       "CONNECT www.example.com:443 HTTP/1.1\r\n"
   7162       "Host: www.example.com\r\n"
   7163       "Proxy-Connection: keep-alive\r\n"
   7164       "Proxy-Authorization: auth_token\r\n\r\n");
   7165 
   7166   const MockRead kSuccess(
   7167       "HTTP/1.1 200 OK\r\n"
   7168       "Content-Type: text/html; charset=iso-8859-1\r\n"
   7169       "Content-Length: 3\r\n\r\n"
   7170       "Yes");
   7171   const MockRead kFailure(
   7172       "Should not be called.");
   7173   const MockRead kServerChallenge(
   7174       "HTTP/1.1 401 Unauthorized\r\n"
   7175       "WWW-Authenticate: Mock realm=server\r\n"
   7176       "Content-Type: text/html; charset=iso-8859-1\r\n"
   7177       "Content-Length: 14\r\n\r\n"
   7178       "Unauthorized\r\n");
   7179   const MockRead kProxyChallenge(
   7180       "HTTP/1.1 407 Unauthorized\r\n"
   7181       "Proxy-Authenticate: Mock realm=proxy\r\n"
   7182       "Proxy-Connection: close\r\n"
   7183       "Content-Type: text/html; charset=iso-8859-1\r\n"
   7184       "Content-Length: 14\r\n\r\n"
   7185       "Unauthorized\r\n");
   7186   const MockRead kProxyConnected(
   7187       "HTTP/1.1 200 Connection Established\r\n\r\n");
   7188 
   7189   // NOTE(cbentzel): I wanted TestReadWriteRound to be a simple struct with
   7190   // no constructors, but the C++ compiler on Windows warns about
   7191   // unspecified data in compound literals. So, moved to using constructors,
   7192   // and TestRound's created with the default constructor should not be used.
   7193   struct TestRound {
   7194     TestRound()
   7195         : expected_rv(ERR_UNEXPECTED),
   7196           extra_write(NULL),
   7197           extra_read(NULL) {
   7198     }
   7199     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   7200               int expected_rv_arg)
   7201         : write(write_arg),
   7202           read(read_arg),
   7203           expected_rv(expected_rv_arg),
   7204           extra_write(NULL),
   7205           extra_read(NULL) {
   7206     }
   7207     TestRound(const MockWrite& write_arg, const MockRead& read_arg,
   7208               int expected_rv_arg, const MockWrite* extra_write_arg,
   7209               const MockWrite* extra_read_arg)
   7210         : write(write_arg),
   7211           read(read_arg),
   7212           expected_rv(expected_rv_arg),
   7213           extra_write(extra_write_arg),
   7214           extra_read(extra_read_arg) {
   7215     }
   7216     MockWrite write;
   7217     MockRead read;
   7218     int expected_rv;
   7219     const MockWrite* extra_write;
   7220     const MockRead* extra_read;
   7221   };
   7222 
   7223   static const int kNoSSL = 500;
   7224 
   7225   struct TestConfig {
   7226     const char* proxy_url;
   7227     AuthTiming proxy_auth_timing;
   7228     int proxy_auth_rv;
   7229     const char* server_url;
   7230     AuthTiming server_auth_timing;
   7231     int server_auth_rv;
   7232     int num_auth_rounds;
   7233     int first_ssl_round;
   7234     TestRound rounds[3];
   7235   } test_configs[] = {
   7236     // Non-authenticating HTTP server with a direct connection.
   7237     { NULL, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   7238       { TestRound(kGet, kSuccess, OK)}},
   7239     // Authenticating HTTP server with a direct connection.
   7240     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   7241       { TestRound(kGet, kServerChallenge, OK),
   7242         TestRound(kGetAuth, kSuccess, OK)}},
   7243     { NULL, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   7244       { TestRound(kGet, kServerChallenge, OK),
   7245         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7246     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   7247       { TestRound(kGet, kServerChallenge, OK),
   7248         TestRound(kGetAuth, kSuccess, OK)}},
   7249     { NULL, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   7250       { TestRound(kGet, kServerChallenge, OK),
   7251         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7252     // Non-authenticating HTTP server through a non-authenticating proxy.
   7253     { kProxy, AUTH_NONE, OK, kServer, AUTH_NONE, OK, 1, kNoSSL,
   7254       { TestRound(kGetProxy, kSuccess, OK)}},
   7255     // Authenticating HTTP server through a non-authenticating proxy.
   7256     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, OK, 2, kNoSSL,
   7257       { TestRound(kGetProxy, kServerChallenge, OK),
   7258         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   7259     { kProxy, AUTH_NONE, OK, kServer, AUTH_SYNC, kAuthErr, 2, kNoSSL,
   7260       { TestRound(kGetProxy, kServerChallenge, OK),
   7261         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   7262     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, OK, 2, kNoSSL,
   7263       { TestRound(kGetProxy, kServerChallenge, OK),
   7264         TestRound(kGetAuthThroughProxy, kSuccess, OK)}},
   7265     { kProxy, AUTH_NONE, OK, kServer, AUTH_ASYNC, kAuthErr, 2, kNoSSL,
   7266       { TestRound(kGetProxy, kServerChallenge, OK),
   7267         TestRound(kGetAuthThroughProxy, kFailure, kAuthErr)}},
   7268     // Non-authenticating HTTP server through an authenticating proxy.
   7269     { kProxy, AUTH_SYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   7270       { TestRound(kGetProxy, kProxyChallenge, OK),
   7271         TestRound(kGetProxyAuth, kSuccess, OK)}},
   7272     { kProxy, AUTH_SYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   7273       { TestRound(kGetProxy, kProxyChallenge, OK),
   7274         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   7275     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_NONE, OK, 2, kNoSSL,
   7276       { TestRound(kGetProxy, kProxyChallenge, OK),
   7277         TestRound(kGetProxyAuth, kSuccess, OK)}},
   7278     { kProxy, AUTH_ASYNC, kAuthErr, kServer, AUTH_NONE, OK, 2, kNoSSL,
   7279       { TestRound(kGetProxy, kProxyChallenge, OK),
   7280         TestRound(kGetProxyAuth, kFailure, kAuthErr)}},
   7281     // Authenticating HTTP server through an authenticating proxy.
   7282     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   7283       { TestRound(kGetProxy, kProxyChallenge, OK),
   7284         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7285         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   7286     { kProxy, AUTH_SYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   7287       { TestRound(kGetProxy, kProxyChallenge, OK),
   7288         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7289         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   7290     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, OK, 3, kNoSSL,
   7291       { TestRound(kGetProxy, kProxyChallenge, OK),
   7292         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7293         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   7294     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_SYNC, kAuthErr, 3, kNoSSL,
   7295       { TestRound(kGetProxy, kProxyChallenge, OK),
   7296         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7297         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   7298     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   7299       { TestRound(kGetProxy, kProxyChallenge, OK),
   7300         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7301         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   7302     { kProxy, AUTH_SYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   7303       { TestRound(kGetProxy, kProxyChallenge, OK),
   7304         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7305         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   7306     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, OK, 3, kNoSSL,
   7307       { TestRound(kGetProxy, kProxyChallenge, OK),
   7308         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7309         TestRound(kGetAuthWithProxyAuth, kSuccess, OK)}},
   7310     { kProxy, AUTH_ASYNC, OK, kServer, AUTH_ASYNC, kAuthErr, 3, kNoSSL,
   7311       { TestRound(kGetProxy, kProxyChallenge, OK),
   7312         TestRound(kGetProxyAuth, kServerChallenge, OK),
   7313         TestRound(kGetAuthWithProxyAuth, kFailure, kAuthErr)}},
   7314     // Non-authenticating HTTPS server with a direct connection.
   7315     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   7316       { TestRound(kGet, kSuccess, OK)}},
   7317     // Authenticating HTTPS server with a direct connection.
   7318     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   7319       { TestRound(kGet, kServerChallenge, OK),
   7320         TestRound(kGetAuth, kSuccess, OK)}},
   7321     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   7322       { TestRound(kGet, kServerChallenge, OK),
   7323         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7324     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   7325       { TestRound(kGet, kServerChallenge, OK),
   7326         TestRound(kGetAuth, kSuccess, OK)}},
   7327     { NULL, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   7328       { TestRound(kGet, kServerChallenge, OK),
   7329         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7330     // Non-authenticating HTTPS server with a non-authenticating proxy.
   7331     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_NONE, OK, 1, 0,
   7332       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kSuccess)}},
   7333     // Authenticating HTTPS server through a non-authenticating proxy.
   7334     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, OK, 2, 0,
   7335       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   7336         TestRound(kGetAuth, kSuccess, OK)}},
   7337     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_SYNC, kAuthErr, 2, 0,
   7338       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   7339         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7340     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, OK, 2, 0,
   7341       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   7342         TestRound(kGetAuth, kSuccess, OK)}},
   7343     { kProxy, AUTH_NONE, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 2, 0,
   7344       { TestRound(kConnect, kProxyConnected, OK, &kGet, &kServerChallenge),
   7345         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7346     // Non-Authenticating HTTPS server through an authenticating proxy.
   7347     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   7348       { TestRound(kConnect, kProxyChallenge, OK),
   7349         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   7350     { kProxy, AUTH_SYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   7351       { TestRound(kConnect, kProxyChallenge, OK),
   7352         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   7353     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_NONE, OK, 2, 1,
   7354       { TestRound(kConnect, kProxyChallenge, OK),
   7355         TestRound(kConnectProxyAuth, kProxyConnected, OK, &kGet, &kSuccess)}},
   7356     { kProxy, AUTH_ASYNC, kAuthErr, kSecureServer, AUTH_NONE, OK, 2, kNoSSL,
   7357       { TestRound(kConnect, kProxyChallenge, OK),
   7358         TestRound(kConnectProxyAuth, kFailure, kAuthErr)}},
   7359     // Authenticating HTTPS server through an authenticating proxy.
   7360     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   7361       { TestRound(kConnect, kProxyChallenge, OK),
   7362         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7363                   &kGet, &kServerChallenge),
   7364         TestRound(kGetAuth, kSuccess, OK)}},
   7365     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   7366       { TestRound(kConnect, kProxyChallenge, OK),
   7367         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7368                   &kGet, &kServerChallenge),
   7369         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7370     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, OK, 3, 1,
   7371       { TestRound(kConnect, kProxyChallenge, OK),
   7372         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7373                   &kGet, &kServerChallenge),
   7374         TestRound(kGetAuth, kSuccess, OK)}},
   7375     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_SYNC, kAuthErr, 3, 1,
   7376       { TestRound(kConnect, kProxyChallenge, OK),
   7377         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7378                   &kGet, &kServerChallenge),
   7379         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7380     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   7381       { TestRound(kConnect, kProxyChallenge, OK),
   7382         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7383                   &kGet, &kServerChallenge),
   7384         TestRound(kGetAuth, kSuccess, OK)}},
   7385     { kProxy, AUTH_SYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   7386       { TestRound(kConnect, kProxyChallenge, OK),
   7387         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7388                   &kGet, &kServerChallenge),
   7389         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7390     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, OK, 3, 1,
   7391       { TestRound(kConnect, kProxyChallenge, OK),
   7392         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7393                   &kGet, &kServerChallenge),
   7394         TestRound(kGetAuth, kSuccess, OK)}},
   7395     { kProxy, AUTH_ASYNC, OK, kSecureServer, AUTH_ASYNC, kAuthErr, 3, 1,
   7396       { TestRound(kConnect, kProxyChallenge, OK),
   7397         TestRound(kConnectProxyAuth, kProxyConnected, OK,
   7398                   &kGet, &kServerChallenge),
   7399         TestRound(kGetAuth, kFailure, kAuthErr)}},
   7400   };
   7401 
   7402   SessionDependencies session_deps;
   7403   HttpAuthHandlerMock::Factory* auth_factory(
   7404       new HttpAuthHandlerMock::Factory());
   7405   session_deps.http_auth_handler_factory.reset(auth_factory);
   7406 
   7407   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_configs); ++i) {
   7408     const TestConfig& test_config = test_configs[i];
   7409 
   7410     // Set up authentication handlers as necessary.
   7411     if (test_config.proxy_auth_timing != AUTH_NONE) {
   7412       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   7413       std::string auth_challenge = "Mock realm=proxy";
   7414       GURL origin(test_config.proxy_url);
   7415       HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   7416                                              auth_challenge.end());
   7417       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_PROXY,
   7418                                       origin, BoundNetLog());
   7419       auth_handler->SetGenerateExpectation(
   7420           test_config.proxy_auth_timing == AUTH_ASYNC,
   7421           test_config.proxy_auth_rv);
   7422       auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY);
   7423     }
   7424     if (test_config.server_auth_timing != AUTH_NONE) {
   7425       HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   7426       std::string auth_challenge = "Mock realm=server";
   7427       GURL origin(test_config.server_url);
   7428       HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   7429                                              auth_challenge.end());
   7430       auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   7431                                       origin, BoundNetLog());
   7432       auth_handler->SetGenerateExpectation(
   7433           test_config.server_auth_timing == AUTH_ASYNC,
   7434           test_config.server_auth_rv);
   7435       auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_SERVER);
   7436     }
   7437     if (test_config.proxy_url) {
   7438       session_deps.proxy_service =
   7439           ProxyService::CreateFixed(test_config.proxy_url);
   7440     } else {
   7441       session_deps.proxy_service = ProxyService::CreateDirect();
   7442     }
   7443 
   7444     HttpRequestInfo request;
   7445     request.method = "GET";
   7446     request.url = GURL(test_config.server_url);
   7447     request.load_flags = 0;
   7448 
   7449     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7450     HttpNetworkTransaction trans(CreateSession(&session_deps));
   7451 
   7452     for (int round = 0; round < test_config.num_auth_rounds; ++round) {
   7453       const TestRound& read_write_round = test_config.rounds[round];
   7454 
   7455       // Set up expected reads and writes.
   7456       MockRead reads[2];
   7457       reads[0] = read_write_round.read;
   7458       size_t length_reads = 1;
   7459       if (read_write_round.extra_read) {
   7460         reads[1] = *read_write_round.extra_read;
   7461         length_reads = 2;
   7462       }
   7463 
   7464       MockWrite writes[2];
   7465       writes[0] = read_write_round.write;
   7466       size_t length_writes = 1;
   7467       if (read_write_round.extra_write) {
   7468         writes[1] = *read_write_round.extra_write;
   7469         length_writes = 2;
   7470       }
   7471       StaticSocketDataProvider data_provider(
   7472           reads, length_reads, writes, length_writes);
   7473       session_deps.socket_factory.AddSocketDataProvider(&data_provider);
   7474 
   7475       // Add an SSL sequence if necessary.
   7476       SSLSocketDataProvider ssl_socket_data_provider(false, OK);
   7477       if (round >= test_config.first_ssl_round)
   7478         session_deps.socket_factory.AddSSLSocketDataProvider(
   7479             &ssl_socket_data_provider);
   7480 
   7481       // Start or restart the transaction.
   7482       TestCompletionCallback callback;
   7483       int rv;
   7484       if (round == 0) {
   7485         rv = trans.Start(&request, &callback, BoundNetLog());
   7486       } else {
   7487         rv = trans.RestartWithAuth(kFoo, kBar, &callback);
   7488       }
   7489       if (rv == ERR_IO_PENDING)
   7490         rv = callback.WaitForResult();
   7491 
   7492       // Compare results with expected data.
   7493       EXPECT_EQ(read_write_round.expected_rv, rv);
   7494       const HttpResponseInfo* response = trans.GetResponseInfo();
   7495       if (read_write_round.expected_rv == OK) {
   7496         EXPECT_FALSE(response == NULL);
   7497       } else {
   7498         EXPECT_TRUE(response == NULL);
   7499         EXPECT_EQ(round + 1, test_config.num_auth_rounds);
   7500         continue;
   7501       }
   7502       if (round + 1 < test_config.num_auth_rounds) {
   7503         EXPECT_FALSE(response->auth_challenge.get() == NULL);
   7504       } else {
   7505         EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7506       }
   7507     }
   7508   }
   7509 }
   7510 
   7511 TEST_F(HttpNetworkTransactionTest, MultiRoundAuth) {
   7512   // Do multi-round authentication and make sure it works correctly.
   7513   SessionDependencies session_deps;
   7514   HttpAuthHandlerMock::Factory* auth_factory(
   7515       new HttpAuthHandlerMock::Factory());
   7516   session_deps.http_auth_handler_factory.reset(auth_factory);
   7517   session_deps.proxy_service = ProxyService::CreateDirect();
   7518   session_deps.host_resolver->rules()->AddRule("www.example.com", "10.0.0.1");
   7519   session_deps.host_resolver->set_synchronous_mode(true);
   7520 
   7521   HttpAuthHandlerMock* auth_handler(new HttpAuthHandlerMock());
   7522   auth_handler->set_connection_based(true);
   7523   std::string auth_challenge = "Mock realm=server";
   7524   GURL origin("http://www.example.com");
   7525   HttpAuth::ChallengeTokenizer tokenizer(auth_challenge.begin(),
   7526                                          auth_challenge.end());
   7527   auth_handler->InitFromChallenge(&tokenizer, HttpAuth::AUTH_SERVER,
   7528                                   origin, BoundNetLog());
   7529   auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_SERVER);
   7530 
   7531   int rv = OK;
   7532   const HttpResponseInfo* response = NULL;
   7533   HttpRequestInfo request;
   7534   request.method = "GET";
   7535   request.url = origin;
   7536   request.load_flags = 0;
   7537 
   7538   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7539 
   7540   // Use a TCP Socket Pool with only one connection per group. This is used
   7541   // to validate that the TCP socket is not released to the pool between
   7542   // each round of multi-round authentication.
   7543   HttpNetworkSessionPeer session_peer(session);
   7544   ClientSocketPoolHistograms transport_pool_histograms("SmallTCP");
   7545   TransportClientSocketPool* transport_pool = new TransportClientSocketPool(
   7546       50,  // Max sockets for pool
   7547       1,   // Max sockets per group
   7548       &transport_pool_histograms,
   7549       session_deps.host_resolver.get(),
   7550       &session_deps.socket_factory,
   7551       session_deps.net_log);
   7552   session_peer.SetTransportSocketPool(transport_pool);
   7553 
   7554   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   7555   TestCompletionCallback callback;
   7556 
   7557   const MockWrite kGet(
   7558       "GET / HTTP/1.1\r\n"
   7559       "Host: www.example.com\r\n"
   7560       "Connection: keep-alive\r\n\r\n");
   7561   const MockWrite kGetAuth(
   7562       "GET / HTTP/1.1\r\n"
   7563       "Host: www.example.com\r\n"
   7564       "Connection: keep-alive\r\n"
   7565       "Authorization: auth_token\r\n\r\n");
   7566 
   7567   const MockRead kServerChallenge(
   7568       "HTTP/1.1 401 Unauthorized\r\n"
   7569       "WWW-Authenticate: Mock realm=server\r\n"
   7570       "Content-Type: text/html; charset=iso-8859-1\r\n"
   7571       "Content-Length: 14\r\n\r\n"
   7572       "Unauthorized\r\n");
   7573   const MockRead kSuccess(
   7574       "HTTP/1.1 200 OK\r\n"
   7575       "Content-Type: text/html; charset=iso-8859-1\r\n"
   7576       "Content-Length: 3\r\n\r\n"
   7577       "Yes");
   7578 
   7579   MockWrite writes[] = {
   7580     // First round
   7581     kGet,
   7582     // Second round
   7583     kGetAuth,
   7584     // Third round
   7585     kGetAuth,
   7586     // Fourth round
   7587     kGetAuth,
   7588     // Competing request
   7589     kGet,
   7590   };
   7591   MockRead reads[] = {
   7592     // First round
   7593     kServerChallenge,
   7594     // Second round
   7595     kServerChallenge,
   7596     // Third round
   7597     kServerChallenge,
   7598     // Fourth round
   7599     kSuccess,
   7600     // Competing response
   7601     kSuccess,
   7602   };
   7603   StaticSocketDataProvider data_provider(reads, arraysize(reads),
   7604                                          writes, arraysize(writes));
   7605   session_deps.socket_factory.AddSocketDataProvider(&data_provider);
   7606 
   7607   const char* const kSocketGroup = "www.example.com:80";
   7608 
   7609   // First round of authentication.
   7610   auth_handler->SetGenerateExpectation(false, OK);
   7611   rv = trans->Start(&request, &callback, BoundNetLog());
   7612   if (rv == ERR_IO_PENDING)
   7613     rv = callback.WaitForResult();
   7614   EXPECT_EQ(OK, rv);
   7615   response = trans->GetResponseInfo();
   7616   ASSERT_FALSE(response == NULL);
   7617   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   7618   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7619 
   7620   // In between rounds, another request comes in for the same domain.
   7621   // It should not be able to grab the TCP socket that trans has already
   7622   // claimed.
   7623   scoped_ptr<HttpTransaction> trans_compete(
   7624       new HttpNetworkTransaction(session));
   7625   TestCompletionCallback callback_compete;
   7626   rv = trans_compete->Start(&request, &callback_compete, BoundNetLog());
   7627   EXPECT_EQ(ERR_IO_PENDING, rv);
   7628   // callback_compete.WaitForResult at this point would stall forever,
   7629   // since the HttpNetworkTransaction does not release the request back to
   7630   // the pool until after authentication completes.
   7631 
   7632   // Second round of authentication.
   7633   auth_handler->SetGenerateExpectation(false, OK);
   7634   rv = trans->RestartWithAuth(kFoo, kBar, &callback);
   7635   if (rv == ERR_IO_PENDING)
   7636     rv = callback.WaitForResult();
   7637   EXPECT_EQ(OK, rv);
   7638   response = trans->GetResponseInfo();
   7639   ASSERT_FALSE(response == NULL);
   7640   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7641   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7642 
   7643   // Third round of authentication.
   7644   auth_handler->SetGenerateExpectation(false, OK);
   7645   rv = trans->RestartWithAuth(string16(), string16(), &callback);
   7646   if (rv == ERR_IO_PENDING)
   7647     rv = callback.WaitForResult();
   7648   EXPECT_EQ(OK, rv);
   7649   response = trans->GetResponseInfo();
   7650   ASSERT_FALSE(response == NULL);
   7651   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7652   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7653 
   7654   // Fourth round of authentication, which completes successfully.
   7655   auth_handler->SetGenerateExpectation(false, OK);
   7656   rv = trans->RestartWithAuth(string16(), string16(), &callback);
   7657   if (rv == ERR_IO_PENDING)
   7658     rv = callback.WaitForResult();
   7659   EXPECT_EQ(OK, rv);
   7660   response = trans->GetResponseInfo();
   7661   ASSERT_FALSE(response == NULL);
   7662   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   7663   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7664 
   7665   // Read the body since the fourth round was successful. This will also
   7666   // release the socket back to the pool.
   7667   scoped_refptr<IOBufferWithSize> io_buf(new IOBufferWithSize(50));
   7668   rv = trans->Read(io_buf, io_buf->size(), &callback);
   7669   if (rv == ERR_IO_PENDING)
   7670     rv = callback.WaitForResult();
   7671   EXPECT_EQ(3, rv);
   7672   rv = trans->Read(io_buf, io_buf->size(), &callback);
   7673   EXPECT_EQ(0, rv);
   7674   // There are still 0 idle sockets, since the trans_compete transaction
   7675   // will be handed it immediately after trans releases it to the group.
   7676   EXPECT_EQ(0, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7677 
   7678   // The competing request can now finish. Wait for the headers and then
   7679   // read the body.
   7680   rv = callback_compete.WaitForResult();
   7681   EXPECT_EQ(OK, rv);
   7682   rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
   7683   if (rv == ERR_IO_PENDING)
   7684     rv = callback.WaitForResult();
   7685   EXPECT_EQ(3, rv);
   7686   rv = trans_compete->Read(io_buf, io_buf->size(), &callback);
   7687   EXPECT_EQ(0, rv);
   7688 
   7689   // Finally, the socket is released to the group.
   7690   EXPECT_EQ(1, transport_pool->IdleSocketCountInGroup(kSocketGroup));
   7691 }
   7692 
   7693 class TLSDecompressionFailureSocketDataProvider : public SocketDataProvider {
   7694  public:
   7695   explicit TLSDecompressionFailureSocketDataProvider(bool fail_all)
   7696       : fail_all_(fail_all) {
   7697   }
   7698 
   7699   virtual MockRead GetNextRead() {
   7700     if (fail_all_)
   7701       return MockRead(false /* async */, ERR_SSL_DECOMPRESSION_FAILURE_ALERT);
   7702 
   7703     return MockRead(false /* async */,
   7704                     "HTTP/1.1 200 OK\r\nContent-Length: 3\r\n\r\nok.\r\n");
   7705   }
   7706 
   7707   virtual MockWriteResult OnWrite(const std::string& data) {
   7708     return MockWriteResult(false /* async */, data.size());
   7709   }
   7710 
   7711   void Reset() {
   7712   }
   7713 
   7714  private:
   7715   const bool fail_all_;
   7716 };
   7717 
   7718 // Test that we restart a connection when we see a decompression failure from
   7719 // the peer during the handshake. (In the real world we'll restart with SSLv3
   7720 // and we won't offer DEFLATE in that case.)
   7721 TEST_F(HttpNetworkTransactionTest, RestartAfterTLSDecompressionFailure) {
   7722   HttpRequestInfo request;
   7723   request.method = "GET";
   7724   request.url = GURL("https://tlsdecompressionfailure.example.com/");
   7725   request.load_flags = 0;
   7726 
   7727   SessionDependencies session_deps;
   7728   TLSDecompressionFailureSocketDataProvider socket_data_provider1(
   7729       false /* fail all reads */);
   7730   TLSDecompressionFailureSocketDataProvider socket_data_provider2(false);
   7731   SSLSocketDataProvider ssl_socket_data_provider1(
   7732       false, ERR_SSL_DECOMPRESSION_FAILURE_ALERT);
   7733   SSLSocketDataProvider ssl_socket_data_provider2(false, OK);
   7734   session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1);
   7735   session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2);
   7736   session_deps.socket_factory.AddSSLSocketDataProvider(
   7737       &ssl_socket_data_provider1);
   7738   session_deps.socket_factory.AddSSLSocketDataProvider(
   7739       &ssl_socket_data_provider2);
   7740 
   7741   // Work around http://crbug.com/37454
   7742   StaticSocketDataProvider bug37454_connection;
   7743   bug37454_connection.set_connect_data(MockConnect(true, ERR_UNEXPECTED));
   7744   session_deps.socket_factory.AddSocketDataProvider(&bug37454_connection);
   7745 
   7746   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7747   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   7748   TestCompletionCallback callback;
   7749 
   7750   int rv = trans->Start(&request, &callback, BoundNetLog());
   7751   EXPECT_EQ(ERR_IO_PENDING, rv);
   7752   EXPECT_EQ(OK, callback.WaitForResult());
   7753 
   7754   const HttpResponseInfo* response = trans->GetResponseInfo();
   7755   ASSERT_TRUE(response != NULL);
   7756   ASSERT_TRUE(response->headers != NULL);
   7757   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7758 
   7759   std::string response_data;
   7760   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7761   EXPECT_EQ("ok.", response_data);
   7762 }
   7763 
   7764 // Test that we restart a connection if we get a decompression failure from the
   7765 // peer while reading the first bytes from the connection. This occurs when the
   7766 // peer cannot handle DEFLATE but we're using False Start, so we don't notice
   7767 // in the handshake.
   7768 TEST_F(HttpNetworkTransactionTest,
   7769        RestartAfterTLSDecompressionFailureWithFalseStart) {
   7770   HttpRequestInfo request;
   7771   request.method = "GET";
   7772   request.url = GURL("https://tlsdecompressionfailure2.example.com/");
   7773   request.load_flags = 0;
   7774 
   7775   SessionDependencies session_deps;
   7776   TLSDecompressionFailureSocketDataProvider socket_data_provider1(
   7777       true /* fail all reads */);
   7778   TLSDecompressionFailureSocketDataProvider socket_data_provider2(false);
   7779   SSLSocketDataProvider ssl_socket_data_provider1(false, OK);
   7780   SSLSocketDataProvider ssl_socket_data_provider2(false, OK);
   7781   session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider1);
   7782   session_deps.socket_factory.AddSocketDataProvider(&socket_data_provider2);
   7783   session_deps.socket_factory.AddSSLSocketDataProvider(
   7784       &ssl_socket_data_provider1);
   7785   session_deps.socket_factory.AddSSLSocketDataProvider(
   7786       &ssl_socket_data_provider2);
   7787 
   7788   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7789   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   7790   TestCompletionCallback callback;
   7791 
   7792   int rv = trans->Start(&request, &callback, BoundNetLog());
   7793   EXPECT_EQ(ERR_IO_PENDING, rv);
   7794   EXPECT_EQ(OK, callback.WaitForResult());
   7795 
   7796   const HttpResponseInfo* response = trans->GetResponseInfo();
   7797   ASSERT_TRUE(response != NULL);
   7798   ASSERT_TRUE(response->headers != NULL);
   7799   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7800 
   7801   std::string response_data;
   7802   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7803   EXPECT_EQ("ok.", response_data);
   7804 }
   7805 
   7806 // This tests the case that a request is issued via http instead of spdy after
   7807 // npn is negotiated.
   7808 TEST_F(HttpNetworkTransactionTest, NpnWithHttpOverSSL) {
   7809   HttpStreamFactory::set_use_alternate_protocols(true);
   7810   HttpStreamFactory::set_next_protos("\x08http/1.1\x07http1.1");
   7811   SessionDependencies session_deps;
   7812   HttpRequestInfo request;
   7813   request.method = "GET";
   7814   request.url = GURL("https://www.google.com/");
   7815   request.load_flags = 0;
   7816 
   7817   MockWrite data_writes[] = {
   7818     MockWrite("GET / HTTP/1.1\r\n"
   7819               "Host: www.google.com\r\n"
   7820               "Connection: keep-alive\r\n\r\n"),
   7821   };
   7822 
   7823   MockRead data_reads[] = {
   7824     MockRead("HTTP/1.1 200 OK\r\n"),
   7825     MockRead(kAlternateProtocolHttpHeader),
   7826     MockRead("hello world"),
   7827     MockRead(false, OK),
   7828   };
   7829 
   7830   SSLSocketDataProvider ssl(true, OK);
   7831   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   7832   ssl.next_proto = "http/1.1";
   7833 
   7834   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   7835 
   7836   StaticSocketDataProvider data(data_reads, arraysize(data_reads),
   7837                                 data_writes, arraysize(data_writes));
   7838   session_deps.socket_factory.AddSocketDataProvider(&data);
   7839 
   7840   TestCompletionCallback callback;
   7841 
   7842   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7843   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   7844 
   7845   int rv = trans->Start(&request, &callback, BoundNetLog());
   7846 
   7847   EXPECT_EQ(ERR_IO_PENDING, rv);
   7848   EXPECT_EQ(OK, callback.WaitForResult());
   7849 
   7850   const HttpResponseInfo* response = trans->GetResponseInfo();
   7851   ASSERT_TRUE(response != NULL);
   7852   ASSERT_TRUE(response->headers != NULL);
   7853   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   7854 
   7855   std::string response_data;
   7856   ASSERT_EQ(OK, ReadTransaction(trans.get(), &response_data));
   7857   EXPECT_EQ("hello world", response_data);
   7858 
   7859   EXPECT_FALSE(response->was_fetched_via_spdy);
   7860   EXPECT_TRUE(response->was_npn_negotiated);
   7861 
   7862   HttpStreamFactory::set_next_protos("");
   7863   HttpStreamFactory::set_use_alternate_protocols(false);
   7864 }
   7865 
   7866 TEST_F(HttpNetworkTransactionTest, SpdyPostNPNServerHangup) {
   7867   // Simulate the SSL handshake completing with an NPN negotiation
   7868   // followed by an immediate server closing of the socket.
   7869   // Fix crash:  http://crbug.com/46369
   7870   HttpStreamFactory::set_use_alternate_protocols(true);
   7871   HttpStreamFactory::set_next_protos(kExpectedNPNString);
   7872   SessionDependencies session_deps;
   7873 
   7874   HttpRequestInfo request;
   7875   request.method = "GET";
   7876   request.url = GURL("https://www.google.com/");
   7877   request.load_flags = 0;
   7878 
   7879   SSLSocketDataProvider ssl(true, OK);
   7880   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   7881   ssl.next_proto = "spdy/2";
   7882   ssl.was_npn_negotiated = true;
   7883   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   7884 
   7885   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   7886   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   7887 
   7888   MockRead spdy_reads[] = {
   7889     MockRead(false, 0, 0)   // Not async - return 0 immediately.
   7890   };
   7891 
   7892   scoped_refptr<DelayedSocketData> spdy_data(
   7893       new DelayedSocketData(
   7894           0,  // don't wait in this case, immediate hangup.
   7895           spdy_reads, arraysize(spdy_reads),
   7896           spdy_writes, arraysize(spdy_writes)));
   7897   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   7898 
   7899   TestCompletionCallback callback;
   7900 
   7901   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   7902   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   7903 
   7904   int rv = trans->Start(&request, &callback, BoundNetLog());
   7905   EXPECT_EQ(ERR_IO_PENDING, rv);
   7906   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
   7907 
   7908   HttpStreamFactory::set_next_protos("");
   7909   HttpStreamFactory::set_use_alternate_protocols(false);
   7910 }
   7911 
   7912 TEST_F(HttpNetworkTransactionTest, SpdyAlternateProtocolThroughProxy) {
   7913   // This test ensures that the URL passed into the proxy is upgraded
   7914   // to https when doing an Alternate Protocol upgrade.
   7915   HttpStreamFactory::set_use_alternate_protocols(true);
   7916   HttpStreamFactory::set_next_protos(
   7917       "\x08http/1.1\x07http1.1\x06spdy/2\x04spdy");
   7918 
   7919   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   7920   HttpAuthHandlerMock::Factory* auth_factory =
   7921       new HttpAuthHandlerMock::Factory();
   7922   HttpAuthHandlerMock* auth_handler = new HttpAuthHandlerMock();
   7923   auth_factory->set_mock_handler(auth_handler, HttpAuth::AUTH_PROXY);
   7924   auth_factory->set_do_init_from_challenge(true);
   7925   session_deps.http_auth_handler_factory.reset(auth_factory);
   7926 
   7927   HttpRequestInfo request;
   7928   request.method = "GET";
   7929   request.url = GURL("http://www.google.com");
   7930   request.load_flags = 0;
   7931 
   7932   // First round goes unauthenticated through the proxy.
   7933   MockWrite data_writes_1[] = {
   7934     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   7935               "Host: www.google.com\r\n"
   7936               "Proxy-Connection: keep-alive\r\n"
   7937               "\r\n"),
   7938   };
   7939   MockRead data_reads_1[] = {
   7940     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   7941     MockRead("HTTP/1.1 200 OK\r\n"
   7942              "Alternate-Protocol: 443:npn-spdy/2\r\n"
   7943              "Proxy-Connection: close\r\n"
   7944              "\r\n"),
   7945   };
   7946   StaticSocketDataProvider data_1(data_reads_1, arraysize(data_reads_1),
   7947                                   data_writes_1, arraysize(data_writes_1));
   7948 
   7949   // Second round tries to tunnel to www.google.com due to the
   7950   // Alternate-Protocol announcement in the first round. It fails due
   7951   // to a proxy authentication challenge.
   7952   // After the failure, a tunnel is established to www.google.com using
   7953   // Proxy-Authorization headers. There is then a SPDY request round.
   7954   //
   7955   // NOTE: Despite the "Proxy-Connection: Close", these are done on the
   7956   // same MockTCPClientSocket since the underlying HttpNetworkClientSocket
   7957   // does a Disconnect and Connect on the same socket, rather than trying
   7958   // to obtain a new one.
   7959   //
   7960   // NOTE: Originally, the proxy response to the second CONNECT request
   7961   // simply returned another 407 so the unit test could skip the SSL connection
   7962   // establishment and SPDY framing issues. Alas, the
   7963   // retry-http-when-alternate-protocol fails logic kicks in, which was more
   7964   // complicated to set up expectations for than the SPDY session.
   7965 
   7966   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST));
   7967   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   7968   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   7969 
   7970   MockWrite data_writes_2[] = {
   7971     // First connection attempt without Proxy-Authorization.
   7972     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   7973               "Host: www.google.com\r\n"
   7974               "Proxy-Connection: keep-alive\r\n"
   7975               "\r\n"),
   7976 
   7977     // Second connection attempt with Proxy-Authorization.
   7978     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   7979               "Host: www.google.com\r\n"
   7980               "Proxy-Connection: keep-alive\r\n"
   7981               "Proxy-Authorization: auth_token\r\n"
   7982               "\r\n"),
   7983 
   7984     // SPDY request
   7985     CreateMockWrite(*req),
   7986   };
   7987   const char kRejectConnectResponse[] = ("HTTP/1.1 407 Unauthorized\r\n"
   7988                                          "Proxy-Authenticate: Mock\r\n"
   7989                                          "Proxy-Connection: close\r\n"
   7990                                          "\r\n");
   7991   const char kAcceptConnectResponse[] = "HTTP/1.1 200 Connected\r\n\r\n";
   7992   MockRead data_reads_2[] = {
   7993     // First connection attempt fails
   7994     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ, 1),
   7995     MockRead(true, kRejectConnectResponse,
   7996              arraysize(kRejectConnectResponse) - 1, 1),
   7997 
   7998     // Second connection attempt passes
   7999     MockRead(true, kAcceptConnectResponse,
   8000              arraysize(kAcceptConnectResponse) -1, 4),
   8001 
   8002     // SPDY response
   8003     CreateMockRead(*resp.get(), 6),
   8004     CreateMockRead(*data.get(), 6),
   8005     MockRead(true, 0, 0, 6),
   8006   };
   8007   scoped_refptr<OrderedSocketData> data_2(
   8008       new OrderedSocketData(data_reads_2, arraysize(data_reads_2),
   8009                             data_writes_2, arraysize(data_writes_2)));
   8010 
   8011   SSLSocketDataProvider ssl(true, OK);
   8012   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   8013   ssl.next_proto = "spdy/2";
   8014   ssl.was_npn_negotiated = true;
   8015 
   8016   MockConnect never_finishing_connect(false, ERR_IO_PENDING);
   8017   StaticSocketDataProvider hanging_non_alternate_protocol_socket(
   8018       NULL, 0, NULL, 0);
   8019   hanging_non_alternate_protocol_socket.set_connect_data(
   8020       never_finishing_connect);
   8021 
   8022   session_deps.socket_factory.AddSocketDataProvider(&data_1);
   8023   session_deps.socket_factory.AddSocketDataProvider(data_2.get());
   8024   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   8025   session_deps.socket_factory.AddSocketDataProvider(
   8026       &hanging_non_alternate_protocol_socket);
   8027   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8028 
   8029   // First round should work and provide the Alternate-Protocol state.
   8030   TestCompletionCallback callback_1;
   8031   scoped_ptr<HttpTransaction> trans_1(new HttpNetworkTransaction(session));
   8032   int rv = trans_1->Start(&request, &callback_1, BoundNetLog());
   8033   EXPECT_EQ(ERR_IO_PENDING, rv);
   8034   EXPECT_EQ(OK, callback_1.WaitForResult());
   8035 
   8036   // Second round should attempt a tunnel connect and get an auth challenge.
   8037   TestCompletionCallback callback_2;
   8038   scoped_ptr<HttpTransaction> trans_2(new HttpNetworkTransaction(session));
   8039   rv = trans_2->Start(&request, &callback_2, BoundNetLog());
   8040   EXPECT_EQ(ERR_IO_PENDING, rv);
   8041   EXPECT_EQ(OK, callback_2.WaitForResult());
   8042   const HttpResponseInfo* response = trans_2->GetResponseInfo();
   8043   ASSERT_FALSE(response == NULL);
   8044   ASSERT_FALSE(response->auth_challenge.get() == NULL);
   8045 
   8046   // Restart with auth. Tunnel should work and response received.
   8047   TestCompletionCallback callback_3;
   8048   rv = trans_2->RestartWithAuth(kFoo, kBar, &callback_3);
   8049   EXPECT_EQ(ERR_IO_PENDING, rv);
   8050   EXPECT_EQ(OK, callback_3.WaitForResult());
   8051 
   8052   // After all that work, these two lines (or actually, just the scheme) are
   8053   // what this test is all about. Make sure it happens correctly.
   8054   const GURL& request_url = auth_handler->request_url();
   8055   EXPECT_EQ("https", request_url.scheme());
   8056   EXPECT_EQ("www.google.com", request_url.host());
   8057 
   8058   HttpStreamFactory::set_next_protos("");
   8059   HttpStreamFactory::set_use_alternate_protocols(false);
   8060 }
   8061 
   8062 // Test that if we cancel the transaction as the connection is completing, that
   8063 // everything tears down correctly.
   8064 TEST_F(HttpNetworkTransactionTest, SimpleCancel) {
   8065   // Setup everything about the connection to complete synchronously, so that
   8066   // after calling HttpNetworkTransaction::Start, the only thing we're waiting
   8067   // for is the callback from the HttpStreamRequest.
   8068   // Then cancel the transaction.
   8069   // Verify that we don't crash.
   8070   MockConnect mock_connect(false, OK);
   8071   MockRead data_reads[] = {
   8072     MockRead(false, "HTTP/1.0 200 OK\r\n\r\n"),
   8073     MockRead(false, "hello world"),
   8074     MockRead(false, OK),
   8075   };
   8076 
   8077   HttpRequestInfo request;
   8078   request.method = "GET";
   8079   request.url = GURL("http://www.google.com/");
   8080   request.load_flags = 0;
   8081 
   8082   SessionDependencies session_deps;
   8083   session_deps.host_resolver->set_synchronous_mode(true);
   8084   scoped_ptr<HttpTransaction> trans(
   8085       new HttpNetworkTransaction(CreateSession(&session_deps)));
   8086 
   8087   StaticSocketDataProvider data(data_reads, arraysize(data_reads), NULL, 0);
   8088   data.set_connect_data(mock_connect);
   8089   session_deps.socket_factory.AddSocketDataProvider(&data);
   8090 
   8091   TestCompletionCallback callback;
   8092 
   8093   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   8094   int rv = trans->Start(&request, &callback, log.bound());
   8095   EXPECT_EQ(ERR_IO_PENDING, rv);
   8096   trans.reset();  // Cancel the transaction here.
   8097 
   8098   MessageLoop::current()->RunAllPending();
   8099 }
   8100 
   8101 // Test a basic GET request through a proxy.
   8102 TEST_F(HttpNetworkTransactionTest, ProxyGet) {
   8103   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   8104   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   8105   session_deps.net_log = log.bound().net_log();
   8106   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8107 
   8108   HttpRequestInfo request;
   8109   request.method = "GET";
   8110   request.url = GURL("http://www.google.com/");
   8111 
   8112   MockWrite data_writes1[] = {
   8113     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   8114               "Host: www.google.com\r\n"
   8115               "Proxy-Connection: keep-alive\r\n\r\n"),
   8116   };
   8117 
   8118   MockRead data_reads1[] = {
   8119     MockRead("HTTP/1.1 200 OK\r\n"),
   8120     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   8121     MockRead("Content-Length: 100\r\n\r\n"),
   8122     MockRead(false, OK),
   8123   };
   8124 
   8125   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   8126                                  data_writes1, arraysize(data_writes1));
   8127   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8128 
   8129   TestCompletionCallback callback1;
   8130 
   8131   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   8132 
   8133   int rv = trans->Start(&request, &callback1, log.bound());
   8134   EXPECT_EQ(ERR_IO_PENDING, rv);
   8135 
   8136   rv = callback1.WaitForResult();
   8137   EXPECT_EQ(OK, rv);
   8138 
   8139   const HttpResponseInfo* response = trans->GetResponseInfo();
   8140   ASSERT_FALSE(response == NULL);
   8141 
   8142   EXPECT_TRUE(response->headers->IsKeepAlive());
   8143   EXPECT_EQ(200, response->headers->response_code());
   8144   EXPECT_EQ(100, response->headers->GetContentLength());
   8145   EXPECT_TRUE(response->was_fetched_via_proxy);
   8146   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   8147 }
   8148 
   8149 // Test a basic HTTPS GET request through a proxy.
   8150 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGet) {
   8151   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   8152   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   8153   session_deps.net_log = log.bound().net_log();
   8154   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8155 
   8156   HttpRequestInfo request;
   8157   request.method = "GET";
   8158   request.url = GURL("https://www.google.com/");
   8159 
   8160   // Since we have proxy, should try to establish tunnel.
   8161   MockWrite data_writes1[] = {
   8162     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   8163               "Host: www.google.com\r\n"
   8164               "Proxy-Connection: keep-alive\r\n\r\n"),
   8165 
   8166     MockWrite("GET / HTTP/1.1\r\n"
   8167               "Host: www.google.com\r\n"
   8168               "Connection: keep-alive\r\n\r\n"),
   8169   };
   8170 
   8171   MockRead data_reads1[] = {
   8172     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   8173 
   8174     MockRead("HTTP/1.1 200 OK\r\n"),
   8175     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   8176     MockRead("Content-Length: 100\r\n\r\n"),
   8177     MockRead(false, OK),
   8178   };
   8179 
   8180   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   8181                                  data_writes1, arraysize(data_writes1));
   8182   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8183   SSLSocketDataProvider ssl(true, OK);
   8184   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   8185 
   8186   TestCompletionCallback callback1;
   8187 
   8188   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   8189 
   8190   int rv = trans->Start(&request, &callback1, log.bound());
   8191   EXPECT_EQ(ERR_IO_PENDING, rv);
   8192 
   8193   rv = callback1.WaitForResult();
   8194   EXPECT_EQ(OK, rv);
   8195   net::CapturingNetLog::EntryList entries;
   8196   log.GetEntries(&entries);
   8197   size_t pos = ExpectLogContainsSomewhere(
   8198       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   8199       NetLog::PHASE_NONE);
   8200   ExpectLogContainsSomewhere(
   8201       entries, pos,
   8202       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   8203       NetLog::PHASE_NONE);
   8204 
   8205   const HttpResponseInfo* response = trans->GetResponseInfo();
   8206   ASSERT_FALSE(response == NULL);
   8207 
   8208   EXPECT_TRUE(response->headers->IsKeepAlive());
   8209   EXPECT_EQ(200, response->headers->response_code());
   8210   EXPECT_EQ(100, response->headers->GetContentLength());
   8211   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   8212   EXPECT_TRUE(response->was_fetched_via_proxy);
   8213 }
   8214 
   8215 // Test a basic HTTPS GET request through a proxy, but the server hangs up
   8216 // while establishing the tunnel.
   8217 TEST_F(HttpNetworkTransactionTest, ProxyTunnelGetHangup) {
   8218   SessionDependencies session_deps(ProxyService::CreateFixed("myproxy:70"));
   8219   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   8220   session_deps.net_log = log.bound().net_log();
   8221   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8222 
   8223   HttpRequestInfo request;
   8224   request.method = "GET";
   8225   request.url = GURL("https://www.google.com/");
   8226 
   8227   // Since we have proxy, should try to establish tunnel.
   8228   MockWrite data_writes1[] = {
   8229     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   8230               "Host: www.google.com\r\n"
   8231               "Proxy-Connection: keep-alive\r\n\r\n"),
   8232 
   8233     MockWrite("GET / HTTP/1.1\r\n"
   8234               "Host: www.google.com\r\n"
   8235               "Connection: keep-alive\r\n\r\n"),
   8236   };
   8237 
   8238   MockRead data_reads1[] = {
   8239     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   8240     MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
   8241     MockRead(true, 0, 0),  // EOF
   8242   };
   8243 
   8244   StaticSocketDataProvider data1(data_reads1, arraysize(data_reads1),
   8245                                  data_writes1, arraysize(data_writes1));
   8246   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8247   SSLSocketDataProvider ssl(true, OK);
   8248   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   8249 
   8250   TestCompletionCallback callback1;
   8251 
   8252   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   8253 
   8254   int rv = trans->Start(&request, &callback1, log.bound());
   8255   EXPECT_EQ(ERR_IO_PENDING, rv);
   8256 
   8257   rv = callback1.WaitForResult();
   8258   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
   8259   net::CapturingNetLog::EntryList entries;
   8260   log.GetEntries(&entries);
   8261   size_t pos = ExpectLogContainsSomewhere(
   8262       entries, 0, NetLog::TYPE_HTTP_TRANSACTION_SEND_TUNNEL_HEADERS,
   8263       NetLog::PHASE_NONE);
   8264   ExpectLogContainsSomewhere(
   8265       entries, pos,
   8266       NetLog::TYPE_HTTP_TRANSACTION_READ_TUNNEL_RESPONSE_HEADERS,
   8267       NetLog::PHASE_NONE);
   8268 }
   8269 
   8270 // Test for crbug.com/55424.
   8271 TEST_F(HttpNetworkTransactionTest, PreconnectWithExistingSpdySession) {
   8272   SessionDependencies session_deps;
   8273 
   8274   scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(
   8275       "https://www.google.com", false, 1, LOWEST));
   8276   MockWrite spdy_writes[] = { CreateMockWrite(*req) };
   8277 
   8278   scoped_ptr<spdy::SpdyFrame> resp(ConstructSpdyGetSynReply(NULL, 0, 1));
   8279   scoped_ptr<spdy::SpdyFrame> data(ConstructSpdyBodyFrame(1, true));
   8280   MockRead spdy_reads[] = {
   8281     CreateMockRead(*resp),
   8282     CreateMockRead(*data),
   8283     MockRead(true, 0, 0),
   8284   };
   8285 
   8286   scoped_refptr<DelayedSocketData> spdy_data(
   8287       new DelayedSocketData(
   8288           1,  // wait for one write to finish before reading.
   8289           spdy_reads, arraysize(spdy_reads),
   8290           spdy_writes, arraysize(spdy_writes)));
   8291   session_deps.socket_factory.AddSocketDataProvider(spdy_data);
   8292 
   8293   SSLSocketDataProvider ssl(true, OK);
   8294   ssl.next_proto_status = SSLClientSocket::kNextProtoNegotiated;
   8295   ssl.next_proto = "spdy/2";
   8296   ssl.was_npn_negotiated = true;
   8297   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   8298 
   8299   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8300 
   8301   // Set up an initial SpdySession in the pool to reuse.
   8302   HostPortPair host_port_pair("www.google.com", 443);
   8303   HostPortProxyPair pair(host_port_pair, ProxyServer::Direct());
   8304   scoped_refptr<SpdySession> spdy_session =
   8305       session->spdy_session_pool()->Get(pair, BoundNetLog());
   8306   scoped_refptr<TransportSocketParams> transport_params(
   8307       new TransportSocketParams(host_port_pair, MEDIUM, GURL(), false, false));
   8308   TestCompletionCallback callback;
   8309 
   8310   scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle);
   8311   EXPECT_EQ(ERR_IO_PENDING,
   8312             connection->Init(host_port_pair.ToString(), transport_params,
   8313                              LOWEST, &callback,
   8314                              session->transport_socket_pool(), BoundNetLog()));
   8315   EXPECT_EQ(OK, callback.WaitForResult());
   8316   spdy_session->InitializeWithSocket(connection.release(), false, OK);
   8317 
   8318   HttpRequestInfo request;
   8319   request.method = "GET";
   8320   request.url = GURL("https://www.google.com/");
   8321   request.load_flags = 0;
   8322 
   8323   // This is the important line that marks this as a preconnect.
   8324   request.motivation = HttpRequestInfo::PRECONNECT_MOTIVATED;
   8325 
   8326   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   8327 
   8328   int rv = trans->Start(&request, &callback, BoundNetLog());
   8329   EXPECT_EQ(ERR_IO_PENDING, rv);
   8330   EXPECT_EQ(OK, callback.WaitForResult());
   8331 }
   8332 
   8333 // Given a net error, cause that error to be returned from the first Write()
   8334 // call and verify that the HttpTransaction fails with that error.
   8335 static void CheckErrorIsPassedBack(int error, bool async) {
   8336   net::HttpRequestInfo request_info;
   8337   request_info.url = GURL("https://www.example.com/");
   8338   request_info.method = "GET";
   8339   request_info.load_flags = net::LOAD_NORMAL;
   8340 
   8341   SessionDependencies session_deps;
   8342 
   8343   SSLSocketDataProvider ssl_data(async, OK);
   8344   net::MockWrite data_writes[] = {
   8345     net::MockWrite(async, error),
   8346   };
   8347   net::StaticSocketDataProvider data(NULL, 0,
   8348                                      data_writes, arraysize(data_writes));
   8349   session_deps.socket_factory.AddSocketDataProvider(&data);
   8350   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data);
   8351 
   8352   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8353   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   8354 
   8355   TestCompletionCallback callback;
   8356   int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
   8357   if (rv == net::ERR_IO_PENDING)
   8358     rv = callback.WaitForResult();
   8359   ASSERT_EQ(error, rv);
   8360 }
   8361 
   8362 TEST_F(HttpNetworkTransactionTest, SSLWriteCertError) {
   8363   // Just check a grab bag of cert errors.
   8364   static const int kErrors[] = {
   8365     ERR_CERT_COMMON_NAME_INVALID,
   8366     ERR_CERT_AUTHORITY_INVALID,
   8367     ERR_CERT_DATE_INVALID,
   8368   };
   8369   for (size_t i = 0; i < arraysize(kErrors); i++) {
   8370     CheckErrorIsPassedBack(kErrors[i], false /* not async */);
   8371     CheckErrorIsPassedBack(kErrors[i], true /* async */);
   8372   }
   8373 }
   8374 
   8375 // Ensure that a client certificate is removed from the SSL client auth
   8376 // cache when:
   8377 //  1) No proxy is involved.
   8378 //  2) TLS False Start is disabled.
   8379 //  3) The initial TLS handshake requests a client certificate.
   8380 //  4) The client supplies an invalid/unacceptable certificate.
   8381 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_NoFalseStart) {
   8382   net::HttpRequestInfo request_info;
   8383   request_info.url = GURL("https://www.example.com/");
   8384   request_info.method = "GET";
   8385   request_info.load_flags = net::LOAD_NORMAL;
   8386 
   8387   SessionDependencies session_deps;
   8388 
   8389   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   8390   cert_request->host_and_port = "www.example.com:443";
   8391 
   8392   // [ssl_]data1 contains the data for the first SSL handshake. When a
   8393   // CertificateRequest is received for the first time, the handshake will
   8394   // be aborted to allow the caller to provide a certificate.
   8395   SSLSocketDataProvider ssl_data1(true /* async */,
   8396                                   net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   8397   ssl_data1.cert_request_info = cert_request.get();
   8398   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
   8399   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   8400   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8401 
   8402   // [ssl_]data2 contains the data for the second SSL handshake. When TLS
   8403   // False Start is not being used, the result of the SSL handshake will be
   8404   // returned as part of the SSLClientSocket::Connect() call. This test
   8405   // matches the result of a server sending a handshake_failure alert,
   8406   // rather than a Finished message, because it requires a client
   8407   // certificate and none was supplied.
   8408   SSLSocketDataProvider ssl_data2(true /* async */,
   8409                                   net::ERR_SSL_PROTOCOL_ERROR);
   8410   ssl_data2.cert_request_info = cert_request.get();
   8411   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
   8412   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   8413   session_deps.socket_factory.AddSocketDataProvider(&data2);
   8414 
   8415   // [ssl_]data3 contains the data for the third SSL handshake. When a
   8416   // connection to a server fails during an SSL handshake,
   8417   // HttpNetworkTransaction will attempt to fallback to SSLv3 if the initial
   8418   // connection was attempted with TLSv1. This is transparent to the caller
   8419   // of the HttpNetworkTransaction. Because this test failure is due to
   8420   // requiring a client certificate, this fallback handshake should also
   8421   // fail.
   8422   SSLSocketDataProvider ssl_data3(true /* async */,
   8423                                   net::ERR_SSL_PROTOCOL_ERROR);
   8424   ssl_data3.cert_request_info = cert_request.get();
   8425   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
   8426   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   8427   session_deps.socket_factory.AddSocketDataProvider(&data3);
   8428 
   8429   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8430   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   8431 
   8432   // Begin the SSL handshake with the peer. This consumes ssl_data1.
   8433   TestCompletionCallback callback;
   8434   int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
   8435   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8436 
   8437   // Complete the SSL handshake, which should abort due to requiring a
   8438   // client certificate.
   8439   rv = callback.WaitForResult();
   8440   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   8441 
   8442   // Indicate that no certificate should be supplied. From the perspective
   8443   // of SSLClientCertCache, NULL is just as meaningful as a real
   8444   // certificate, so this is the same as supply a
   8445   // legitimate-but-unacceptable certificate.
   8446   rv = trans->RestartWithCertificate(NULL, &callback);
   8447   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8448 
   8449   // Ensure the certificate was added to the client auth cache before
   8450   // allowing the connection to continue restarting.
   8451   scoped_refptr<X509Certificate> client_cert;
   8452   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8453                                                        &client_cert));
   8454   ASSERT_EQ(NULL, client_cert.get());
   8455 
   8456   // Restart the handshake. This will consume ssl_data2, which fails, and
   8457   // then consume ssl_data3, which should also fail. The result code is
   8458   // checked against what ssl_data3 should return.
   8459   rv = callback.WaitForResult();
   8460   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   8461 
   8462   // Ensure that the client certificate is removed from the cache on a
   8463   // handshake failure.
   8464   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8465                                                         &client_cert));
   8466 }
   8467 
   8468 // Ensure that a client certificate is removed from the SSL client auth
   8469 // cache when:
   8470 //  1) No proxy is involved.
   8471 //  2) TLS False Start is enabled.
   8472 //  3) The initial TLS handshake requests a client certificate.
   8473 //  4) The client supplies an invalid/unacceptable certificate.
   8474 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Direct_FalseStart) {
   8475   net::HttpRequestInfo request_info;
   8476   request_info.url = GURL("https://www.example.com/");
   8477   request_info.method = "GET";
   8478   request_info.load_flags = net::LOAD_NORMAL;
   8479 
   8480   SessionDependencies session_deps;
   8481 
   8482   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   8483   cert_request->host_and_port = "www.example.com:443";
   8484 
   8485   // When TLS False Start is used, SSLClientSocket::Connect() calls will
   8486   // return successfully after reading up to the peer's Certificate message.
   8487   // This is to allow the caller to call SSLClientSocket::Write(), which can
   8488   // enqueue application data to be sent in the same packet as the
   8489   // ChangeCipherSpec and Finished messages.
   8490   // The actual handshake will be finished when SSLClientSocket::Read() is
   8491   // called, which expects to process the peer's ChangeCipherSpec and
   8492   // Finished messages. If there was an error negotiating with the peer,
   8493   // such as due to the peer requiring a client certificate when none was
   8494   // supplied, the alert sent by the peer won't be processed until Read() is
   8495   // called.
   8496 
   8497   // Like the non-False Start case, when a client certificate is requested by
   8498   // the peer, the handshake is aborted during the Connect() call.
   8499   // [ssl_]data1 represents the initial SSL handshake with the peer.
   8500   SSLSocketDataProvider ssl_data1(true /* async */,
   8501                                   net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   8502   ssl_data1.cert_request_info = cert_request.get();
   8503   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
   8504   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   8505   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8506 
   8507   // When a client certificate is supplied, Connect() will not be aborted
   8508   // when the peer requests the certificate. Instead, the handshake will
   8509   // artificially succeed, allowing the caller to write the HTTP request to
   8510   // the socket. The handshake messages are not processed until Read() is
   8511   // called, which then detects that the handshake was aborted, due to the
   8512   // peer sending a handshake_failure because it requires a client
   8513   // certificate.
   8514   SSLSocketDataProvider ssl_data2(true /* async */, net::OK);
   8515   ssl_data2.cert_request_info = cert_request.get();
   8516   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
   8517   net::MockRead data2_reads[] = {
   8518     net::MockRead(true /* async */, net::ERR_SSL_PROTOCOL_ERROR),
   8519   };
   8520   net::StaticSocketDataProvider data2(
   8521       data2_reads, arraysize(data2_reads), NULL, 0);
   8522   session_deps.socket_factory.AddSocketDataProvider(&data2);
   8523 
   8524   // As described in ClientAuthCertCache_Direct_NoFalseStart, [ssl_]data3 is
   8525   // the data for the SSL handshake once the TLSv1 connection falls back to
   8526   // SSLv3. It has the same behaviour as [ssl_]data2.
   8527   SSLSocketDataProvider ssl_data3(true /* async */, net::OK);
   8528   ssl_data3.cert_request_info = cert_request.get();
   8529   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
   8530   net::StaticSocketDataProvider data3(
   8531       data2_reads, arraysize(data2_reads), NULL, 0);
   8532   session_deps.socket_factory.AddSocketDataProvider(&data3);
   8533 
   8534   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8535   scoped_ptr<HttpNetworkTransaction> trans(new HttpNetworkTransaction(session));
   8536 
   8537   // Begin the initial SSL handshake.
   8538   TestCompletionCallback callback;
   8539   int rv = trans->Start(&request_info, &callback, net::BoundNetLog());
   8540   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8541 
   8542   // Complete the SSL handshake, which should abort due to requiring a
   8543   // client certificate.
   8544   rv = callback.WaitForResult();
   8545   ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   8546 
   8547   // Indicate that no certificate should be supplied. From the perspective
   8548   // of SSLClientCertCache, NULL is just as meaningful as a real
   8549   // certificate, so this is the same as supply a
   8550   // legitimate-but-unacceptable certificate.
   8551   rv = trans->RestartWithCertificate(NULL, &callback);
   8552   ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8553 
   8554   // Ensure the certificate was added to the client auth cache before
   8555   // allowing the connection to continue restarting.
   8556   scoped_refptr<X509Certificate> client_cert;
   8557   ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8558                                                        &client_cert));
   8559   ASSERT_EQ(NULL, client_cert.get());
   8560 
   8561 
   8562   // Restart the handshake. This will consume ssl_data2, which fails, and
   8563   // then consume ssl_data3, which should also fail. The result code is
   8564   // checked against what ssl_data3 should return.
   8565   rv = callback.WaitForResult();
   8566   ASSERT_EQ(net::ERR_SSL_PROTOCOL_ERROR, rv);
   8567 
   8568   // Ensure that the client certificate is removed from the cache on a
   8569   // handshake failure.
   8570   ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8571                                                         &client_cert));
   8572 }
   8573 
   8574 // Ensure that a client certificate is removed from the SSL client auth
   8575 // cache when:
   8576 //  1) An HTTPS proxy is involved.
   8577 //  3) The HTTPS proxy requests a client certificate.
   8578 //  4) The client supplies an invalid/unacceptable certificate for the
   8579 //     proxy.
   8580 // The test is repeated twice, first for connecting to an HTTPS endpoint,
   8581 // then for connecting to an HTTP endpoint.
   8582 TEST_F(HttpNetworkTransactionTest, ClientAuthCertCache_Proxy_Fail) {
   8583   SessionDependencies session_deps(
   8584       ProxyService::CreateFixed("https://proxy:70"));
   8585   CapturingBoundNetLog log(CapturingNetLog::kUnbounded);
   8586   session_deps.net_log = log.bound().net_log();
   8587 
   8588   scoped_refptr<SSLCertRequestInfo> cert_request(new SSLCertRequestInfo());
   8589   cert_request->host_and_port = "proxy:70";
   8590 
   8591   // See ClientAuthCertCache_Direct_NoFalseStart for the explanation of
   8592   // [ssl_]data[1-3]. Rather than represending the endpoint
   8593   // (www.example.com:443), they represent failures with the HTTPS proxy
   8594   // (proxy:70).
   8595   SSLSocketDataProvider ssl_data1(true /* async */,
   8596                                   net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED);
   8597   ssl_data1.cert_request_info = cert_request.get();
   8598   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data1);
   8599   net::StaticSocketDataProvider data1(NULL, 0, NULL, 0);
   8600   session_deps.socket_factory.AddSocketDataProvider(&data1);
   8601 
   8602   SSLSocketDataProvider ssl_data2(true /* async */,
   8603                                   net::ERR_SSL_PROTOCOL_ERROR);
   8604   ssl_data2.cert_request_info = cert_request.get();
   8605   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data2);
   8606   net::StaticSocketDataProvider data2(NULL, 0, NULL, 0);
   8607   session_deps.socket_factory.AddSocketDataProvider(&data2);
   8608 
   8609   SSLSocketDataProvider ssl_data3(true /* async */,
   8610                                   net::ERR_SSL_PROTOCOL_ERROR);
   8611   ssl_data3.cert_request_info = cert_request.get();
   8612   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_data3);
   8613   net::StaticSocketDataProvider data3(NULL, 0, NULL, 0);
   8614   session_deps.socket_factory.AddSocketDataProvider(&data3);
   8615 
   8616   net::HttpRequestInfo requests[2];
   8617   requests[0].url = GURL("https://www.example.com/");
   8618   requests[0].method = "GET";
   8619   requests[0].load_flags = net::LOAD_NORMAL;
   8620 
   8621   requests[1].url = GURL("http://www.example.com/");
   8622   requests[1].method = "GET";
   8623   requests[1].load_flags = net::LOAD_NORMAL;
   8624 
   8625   for (size_t i = 0; i < arraysize(requests); ++i) {
   8626     session_deps.socket_factory.ResetNextMockIndexes();
   8627     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   8628     scoped_ptr<HttpNetworkTransaction> trans(
   8629         new HttpNetworkTransaction(session));
   8630 
   8631     // Begin the SSL handshake with the proxy.
   8632     TestCompletionCallback callback;
   8633     int rv = trans->Start(&requests[i], &callback, net::BoundNetLog());
   8634     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8635 
   8636     // Complete the SSL handshake, which should abort due to requiring a
   8637     // client certificate.
   8638     rv = callback.WaitForResult();
   8639     ASSERT_EQ(net::ERR_SSL_CLIENT_AUTH_CERT_NEEDED, rv);
   8640 
   8641     // Indicate that no certificate should be supplied. From the perspective
   8642     // of SSLClientCertCache, NULL is just as meaningful as a real
   8643     // certificate, so this is the same as supply a
   8644     // legitimate-but-unacceptable certificate.
   8645     rv = trans->RestartWithCertificate(NULL, &callback);
   8646     ASSERT_EQ(net::ERR_IO_PENDING, rv);
   8647 
   8648     // Ensure the certificate was added to the client auth cache before
   8649     // allowing the connection to continue restarting.
   8650     scoped_refptr<X509Certificate> client_cert;
   8651     ASSERT_TRUE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   8652                                                          &client_cert));
   8653     ASSERT_EQ(NULL, client_cert.get());
   8654     // Ensure the certificate was NOT cached for the endpoint. This only
   8655     // applies to HTTPS requests, but is fine to check for HTTP requests.
   8656     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8657                                                           &client_cert));
   8658 
   8659     // Restart the handshake. This will consume ssl_data2, which fails, and
   8660     // then consume ssl_data3, which should also fail. The result code is
   8661     // checked against what ssl_data3 should return.
   8662     rv = callback.WaitForResult();
   8663     ASSERT_EQ(net::ERR_PROXY_CONNECTION_FAILED, rv);
   8664 
   8665     // Now that the new handshake has failed, ensure that the client
   8666     // certificate was removed from the client auth cache.
   8667     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("proxy:70",
   8668                                                           &client_cert));
   8669     ASSERT_FALSE(session->ssl_client_auth_cache()->Lookup("www.example.com:443",
   8670                                                           &client_cert));
   8671   }
   8672 }
   8673 
   8674 }  // namespace net
   8675