Home | History | Annotate | Download | only in http
      1 // Copyright (c) 2009 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 <math.h>  // ceil
      6 
      7 #include "base/compiler_specific.h"
      8 #include "net/base/completion_callback.h"
      9 #include "net/base/mock_host_resolver.h"
     10 #include "net/base/request_priority.h"
     11 #include "net/base/ssl_config_service_defaults.h"
     12 #include "net/base/ssl_info.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "net/base/upload_data.h"
     15 #include "net/flip/flip_session_pool.h"
     16 #include "net/http/http_auth_handler_ntlm.h"
     17 #include "net/http/http_basic_stream.h"
     18 #include "net/http/http_network_session.h"
     19 #include "net/http/http_network_transaction.h"
     20 #include "net/http/http_stream.h"
     21 #include "net/http/http_transaction_unittest.h"
     22 #include "net/proxy/proxy_config_service_fixed.h"
     23 #include "net/socket/client_socket_factory.h"
     24 #include "net/socket/socket_test_util.h"
     25 #include "net/socket/ssl_client_socket.h"
     26 #include "testing/gtest/include/gtest/gtest.h"
     27 #include "testing/platform_test.h"
     28 
     29 //-----------------------------------------------------------------------------
     30 
     31 // TODO(eroman): Add a regression test for http://crbug.com/32316 -- when the
     32 // proxy service returns an error, we should fallback to DIRECT instead of
     33 // failing with ERR_NO_SUPPORTED_PROXIES.
     34 
     35 namespace net {
     36 
     37 // Create a proxy service which fails on all requests (falls back to direct).
     38 ProxyService* CreateNullProxyService() {
     39   return ProxyService::CreateNull();
     40 }
     41 
     42 // Helper to manage the lifetimes of the dependencies for a
     43 // HttpNetworkTransaction.
     44 class SessionDependencies {
     45  public:
     46   // Default set of dependencies -- "null" proxy service.
     47   SessionDependencies()
     48       : host_resolver(new MockHostResolver),
     49         proxy_service(CreateNullProxyService()),
     50         ssl_config_service(new SSLConfigServiceDefaults),
     51         flip_session_pool(new FlipSessionPool) {}
     52 
     53   // Custom proxy service dependency.
     54   explicit SessionDependencies(ProxyService* proxy_service)
     55       : host_resolver(new MockHostResolver),
     56         proxy_service(proxy_service),
     57         ssl_config_service(new SSLConfigServiceDefaults),
     58         flip_session_pool(new FlipSessionPool) {}
     59 
     60   scoped_refptr<MockHostResolverBase> host_resolver;
     61   scoped_refptr<ProxyService> proxy_service;
     62   scoped_refptr<SSLConfigService> ssl_config_service;
     63   MockClientSocketFactory socket_factory;
     64   scoped_refptr<FlipSessionPool> flip_session_pool;
     65 };
     66 
     67 ProxyService* CreateFixedProxyService(const std::string& proxy) {
     68   net::ProxyConfig proxy_config;
     69   proxy_config.proxy_rules.ParseFromString(proxy);
     70   return ProxyService::CreateFixed(proxy_config);
     71 }
     72 
     73 
     74 HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
     75   return new HttpNetworkSession(NULL,
     76                                 session_deps->host_resolver,
     77                                 session_deps->proxy_service,
     78                                 &session_deps->socket_factory,
     79                                 session_deps->ssl_config_service,
     80                                 session_deps->flip_session_pool);
     81 }
     82 
     83 class HttpNetworkTransactionTest : public PlatformTest {
     84  public:
     85   virtual void TearDown() {
     86     // Empty the current queue.
     87     MessageLoop::current()->RunAllPending();
     88     PlatformTest::TearDown();
     89   }
     90 
     91  protected:
     92   void KeepAliveConnectionResendRequestTest(const MockRead& read_failure);
     93 
     94   struct SimpleGetHelperResult {
     95     int rv;
     96     std::string status_line;
     97     std::string response_data;
     98   };
     99 
    100   SimpleGetHelperResult SimpleGetHelper(MockRead data_reads[]) {
    101     SimpleGetHelperResult out;
    102 
    103     SessionDependencies session_deps;
    104     scoped_ptr<HttpTransaction> trans(
    105         new HttpNetworkTransaction(CreateSession(&session_deps)));
    106 
    107     HttpRequestInfo request;
    108     request.method = "GET";
    109     request.url = GURL("http://www.google.com/");
    110     request.load_flags = 0;
    111 
    112     StaticSocketDataProvider data(data_reads, NULL);
    113     session_deps.socket_factory.AddSocketDataProvider(&data);
    114 
    115     TestCompletionCallback callback;
    116 
    117     int rv = trans->Start(&request, &callback, NULL);
    118     EXPECT_EQ(ERR_IO_PENDING, rv);
    119 
    120     out.rv = callback.WaitForResult();
    121     if (out.rv != OK)
    122       return out;
    123 
    124     const HttpResponseInfo* response = trans->GetResponseInfo();
    125     EXPECT_TRUE(response != NULL);
    126 
    127     EXPECT_TRUE(response->headers != NULL);
    128     out.status_line = response->headers->GetStatusLine();
    129 
    130     rv = ReadTransaction(trans.get(), &out.response_data);
    131     EXPECT_EQ(OK, rv);
    132 
    133     return out;
    134   }
    135 
    136   void ConnectStatusHelperWithExpectedStatus(const MockRead& status,
    137                                              int expected_status);
    138 
    139   void ConnectStatusHelper(const MockRead& status);
    140 };
    141 
    142 // Fill |str| with a long header list that consumes >= |size| bytes.
    143 void FillLargeHeadersString(std::string* str, int size) {
    144   const char* row =
    145       "SomeHeaderName: xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx\r\n";
    146   const int sizeof_row = strlen(row);
    147   const int num_rows = static_cast<int>(
    148       ceil(static_cast<float>(size) / sizeof_row));
    149   const int sizeof_data = num_rows * sizeof_row;
    150   DCHECK(sizeof_data >= size);
    151   str->reserve(sizeof_data);
    152 
    153   for (int i = 0; i < num_rows; ++i)
    154     str->append(row, sizeof_row);
    155 }
    156 
    157 // Alternative functions that eliminate randomness and dependency on the local
    158 // host name so that the generated NTLM messages are reproducible.
    159 void MockGenerateRandom1(uint8* output, size_t n) {
    160   static const uint8 bytes[] = {
    161     0x55, 0x29, 0x66, 0x26, 0x6b, 0x9c, 0x73, 0x54
    162   };
    163   static size_t current_byte = 0;
    164   for (size_t i = 0; i < n; ++i) {
    165     output[i] = bytes[current_byte++];
    166     current_byte %= arraysize(bytes);
    167   }
    168 }
    169 
    170 void MockGenerateRandom2(uint8* output, size_t n) {
    171   static const uint8 bytes[] = {
    172     0x96, 0x79, 0x85, 0xe7, 0x49, 0x93, 0x70, 0xa1,
    173     0x4e, 0xe7, 0x87, 0x45, 0x31, 0x5b, 0xd3, 0x1f
    174   };
    175   static size_t current_byte = 0;
    176   for (size_t i = 0; i < n; ++i) {
    177     output[i] = bytes[current_byte++];
    178     current_byte %= arraysize(bytes);
    179   }
    180 }
    181 
    182 std::string MockGetHostName() {
    183   return "WTC-WIN7";
    184 }
    185 
    186 class CaptureGroupNameSocketPool : public TCPClientSocketPool {
    187  public:
    188   CaptureGroupNameSocketPool() : TCPClientSocketPool(0, 0, NULL, NULL, NULL) {}
    189   const std::string last_group_name_received() const {
    190     return last_group_name_;
    191   }
    192 
    193   virtual int RequestSocket(const std::string& group_name,
    194                             const void* socket_params,
    195                             RequestPriority priority,
    196                             ClientSocketHandle* handle,
    197                             CompletionCallback* callback,
    198                             LoadLog* load_log) {
    199     last_group_name_ = group_name;
    200     return ERR_IO_PENDING;
    201   }
    202   virtual void CancelRequest(const std::string& group_name,
    203                              const ClientSocketHandle* handle) { }
    204   virtual void ReleaseSocket(const std::string& group_name,
    205                              ClientSocket* socket) {}
    206   virtual void CloseIdleSockets() {}
    207   virtual HostResolver* GetHostResolver() const {
    208     return NULL;
    209   }
    210   virtual int IdleSocketCount() const {
    211     return 0;
    212   }
    213   virtual int IdleSocketCountInGroup(const std::string& group_name) const {
    214     return 0;
    215   }
    216   virtual LoadState GetLoadState(const std::string& group_name,
    217                                  const ClientSocketHandle* handle) const {
    218     return LOAD_STATE_IDLE;
    219   }
    220 
    221  private:
    222   std::string last_group_name_;
    223 };
    224 
    225 //-----------------------------------------------------------------------------
    226 
    227 TEST_F(HttpNetworkTransactionTest, Basic) {
    228   SessionDependencies session_deps;
    229   scoped_ptr<HttpTransaction> trans(
    230       new HttpNetworkTransaction(CreateSession(&session_deps)));
    231 }
    232 
    233 TEST_F(HttpNetworkTransactionTest, SimpleGET) {
    234   MockRead data_reads[] = {
    235     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    236     MockRead("hello world"),
    237     MockRead(false, OK),
    238   };
    239   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    240   EXPECT_EQ(OK, out.rv);
    241   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
    242   EXPECT_EQ("hello world", out.response_data);
    243 }
    244 
    245 // Response with no status line.
    246 TEST_F(HttpNetworkTransactionTest, SimpleGETNoHeaders) {
    247   MockRead data_reads[] = {
    248     MockRead("hello world"),
    249     MockRead(false, OK),
    250   };
    251   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    252   EXPECT_EQ(OK, out.rv);
    253   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    254   EXPECT_EQ("hello world", out.response_data);
    255 }
    256 
    257 // Allow up to 4 bytes of junk to precede status line.
    258 TEST_F(HttpNetworkTransactionTest, StatusLineJunk2Bytes) {
    259   MockRead data_reads[] = {
    260     MockRead("xxxHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    261     MockRead(false, OK),
    262   };
    263   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    264   EXPECT_EQ(OK, out.rv);
    265   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    266   EXPECT_EQ("DATA", out.response_data);
    267 }
    268 
    269 // Allow up to 4 bytes of junk to precede status line.
    270 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes) {
    271   MockRead data_reads[] = {
    272     MockRead("\n\nQJHTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    273     MockRead(false, OK),
    274   };
    275   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    276   EXPECT_EQ(OK, out.rv);
    277   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    278   EXPECT_EQ("DATA", out.response_data);
    279 }
    280 
    281 // Beyond 4 bytes of slop and it should fail to find a status line.
    282 TEST_F(HttpNetworkTransactionTest, StatusLineJunk5Bytes) {
    283   MockRead data_reads[] = {
    284     MockRead("xxxxxHTTP/1.1 404 Not Found\nServer: blah"),
    285     MockRead(false, OK),
    286   };
    287   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    288   EXPECT_EQ(OK, out.rv);
    289   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    290   EXPECT_EQ("xxxxxHTTP/1.1 404 Not Found\nServer: blah", out.response_data);
    291 }
    292 
    293 // Same as StatusLineJunk4Bytes, except the read chunks are smaller.
    294 TEST_F(HttpNetworkTransactionTest, StatusLineJunk4Bytes_Slow) {
    295   MockRead data_reads[] = {
    296     MockRead("\n"),
    297     MockRead("\n"),
    298     MockRead("Q"),
    299     MockRead("J"),
    300     MockRead("HTTP/1.0 404 Not Found\nServer: blah\n\nDATA"),
    301     MockRead(false, OK),
    302   };
    303   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    304   EXPECT_EQ(OK, out.rv);
    305   EXPECT_EQ("HTTP/1.0 404 Not Found", out.status_line);
    306   EXPECT_EQ("DATA", out.response_data);
    307 }
    308 
    309 // Close the connection before enough bytes to have a status line.
    310 TEST_F(HttpNetworkTransactionTest, StatusLinePartial) {
    311   MockRead data_reads[] = {
    312     MockRead("HTT"),
    313     MockRead(false, OK),
    314   };
    315   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    316   EXPECT_EQ(OK, out.rv);
    317   EXPECT_EQ("HTTP/0.9 200 OK", out.status_line);
    318   EXPECT_EQ("HTT", out.response_data);
    319 }
    320 
    321 // Simulate a 204 response, lacking a Content-Length header, sent over a
    322 // persistent connection.  The response should still terminate since a 204
    323 // cannot have a response body.
    324 TEST_F(HttpNetworkTransactionTest, StopsReading204) {
    325   MockRead data_reads[] = {
    326     MockRead("HTTP/1.1 204 No Content\r\n\r\n"),
    327     MockRead("junk"),  // Should not be read!!
    328     MockRead(false, OK),
    329   };
    330   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    331   EXPECT_EQ(OK, out.rv);
    332   EXPECT_EQ("HTTP/1.1 204 No Content", out.status_line);
    333   EXPECT_EQ("", out.response_data);
    334 }
    335 
    336 // A simple request using chunked encoding with some extra data after.
    337 // (Like might be seen in a pipelined response.)
    338 TEST_F(HttpNetworkTransactionTest, ChunkedEncoding) {
    339   MockRead data_reads[] = {
    340     MockRead("HTTP/1.1 200 OK\r\nTransfer-Encoding: chunked\r\n\r\n"),
    341     MockRead("5\r\nHello\r\n"),
    342     MockRead("1\r\n"),
    343     MockRead(" \r\n"),
    344     MockRead("5\r\nworld\r\n"),
    345     MockRead("0\r\n\r\nHTTP/1.1 200 OK\r\n"),
    346     MockRead(false, OK),
    347   };
    348   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    349   EXPECT_EQ(OK, out.rv);
    350   EXPECT_EQ("HTTP/1.1 200 OK", out.status_line);
    351   EXPECT_EQ("Hello world", out.response_data);
    352 }
    353 
    354 // Do a request using the HEAD method. Verify that we don't try to read the
    355 // message body (since HEAD has none).
    356 TEST_F(HttpNetworkTransactionTest, Head) {
    357   SessionDependencies session_deps;
    358   scoped_ptr<HttpTransaction> trans(
    359       new HttpNetworkTransaction(CreateSession(&session_deps)));
    360 
    361   HttpRequestInfo request;
    362   request.method = "HEAD";
    363   request.url = GURL("http://www.google.com/");
    364   request.load_flags = 0;
    365 
    366   MockWrite data_writes1[] = {
    367     MockWrite("HEAD / HTTP/1.1\r\n"
    368               "Host: www.google.com\r\n"
    369               "Connection: keep-alive\r\n"
    370               "Content-Length: 0\r\n\r\n"),
    371   };
    372   MockRead data_reads1[] = {
    373     MockRead("HTTP/1.1 404 Not Found\r\n"),
    374     MockRead("Server: Blah\r\n"),
    375     MockRead("Content-Length: 1234\r\n\r\n"),
    376 
    377     // No response body because the test stops reading here.
    378     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
    379   };
    380 
    381   StaticSocketDataProvider data1(data_reads1, data_writes1);
    382   session_deps.socket_factory.AddSocketDataProvider(&data1);
    383 
    384   TestCompletionCallback callback1;
    385 
    386   int rv = trans->Start(&request, &callback1, NULL);
    387   EXPECT_EQ(ERR_IO_PENDING, rv);
    388 
    389   rv = callback1.WaitForResult();
    390   EXPECT_EQ(OK, rv);
    391 
    392   const HttpResponseInfo* response = trans->GetResponseInfo();
    393   EXPECT_FALSE(response == NULL);
    394 
    395   // Check that the headers got parsed.
    396   EXPECT_TRUE(response->headers != NULL);
    397   EXPECT_EQ(1234, response->headers->GetContentLength());
    398   EXPECT_EQ("HTTP/1.1 404 Not Found", response->headers->GetStatusLine());
    399 
    400   std::string server_header;
    401   void* iter = NULL;
    402   bool has_server_header = response->headers->EnumerateHeader(
    403       &iter, "Server", &server_header);
    404   EXPECT_TRUE(has_server_header);
    405   EXPECT_EQ("Blah", server_header);
    406 
    407   // Reading should give EOF right away, since there is no message body
    408   // (despite non-zero content-length).
    409   std::string response_data;
    410   rv = ReadTransaction(trans.get(), &response_data);
    411   EXPECT_EQ(OK, rv);
    412   EXPECT_EQ("", response_data);
    413 }
    414 
    415 TEST_F(HttpNetworkTransactionTest, ReuseConnection) {
    416   SessionDependencies session_deps;
    417   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
    418 
    419   MockRead data_reads[] = {
    420     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    421     MockRead("hello"),
    422     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    423     MockRead("world"),
    424     MockRead(false, OK),
    425   };
    426   StaticSocketDataProvider data(data_reads, NULL);
    427   session_deps.socket_factory.AddSocketDataProvider(&data);
    428 
    429   const char* kExpectedResponseData[] = {
    430     "hello", "world"
    431   };
    432 
    433   for (int i = 0; i < 2; ++i) {
    434     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    435 
    436     HttpRequestInfo request;
    437     request.method = "GET";
    438     request.url = GURL("http://www.google.com/");
    439     request.load_flags = 0;
    440 
    441     TestCompletionCallback callback;
    442 
    443     int rv = trans->Start(&request, &callback, NULL);
    444     EXPECT_EQ(ERR_IO_PENDING, rv);
    445 
    446     rv = callback.WaitForResult();
    447     EXPECT_EQ(OK, rv);
    448 
    449     const HttpResponseInfo* response = trans->GetResponseInfo();
    450     EXPECT_TRUE(response != NULL);
    451 
    452     EXPECT_TRUE(response->headers != NULL);
    453     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    454 
    455     std::string response_data;
    456     rv = ReadTransaction(trans.get(), &response_data);
    457     EXPECT_EQ(OK, rv);
    458     EXPECT_EQ(kExpectedResponseData[i], response_data);
    459   }
    460 }
    461 
    462 TEST_F(HttpNetworkTransactionTest, Ignores100) {
    463   SessionDependencies session_deps;
    464   scoped_ptr<HttpTransaction> trans(
    465       new HttpNetworkTransaction(CreateSession(&session_deps)));
    466 
    467   HttpRequestInfo request;
    468   request.method = "POST";
    469   request.url = GURL("http://www.foo.com/");
    470   request.upload_data = new UploadData;
    471   request.upload_data->AppendBytes("foo", 3);
    472   request.load_flags = 0;
    473 
    474   MockRead data_reads[] = {
    475     MockRead("HTTP/1.0 100 Continue\r\n\r\n"),
    476     MockRead("HTTP/1.0 200 OK\r\n\r\n"),
    477     MockRead("hello world"),
    478     MockRead(false, OK),
    479   };
    480   StaticSocketDataProvider data(data_reads, NULL);
    481   session_deps.socket_factory.AddSocketDataProvider(&data);
    482 
    483   TestCompletionCallback callback;
    484 
    485   int rv = trans->Start(&request, &callback, NULL);
    486   EXPECT_EQ(ERR_IO_PENDING, rv);
    487 
    488   rv = callback.WaitForResult();
    489   EXPECT_EQ(OK, rv);
    490 
    491   const HttpResponseInfo* response = trans->GetResponseInfo();
    492   EXPECT_TRUE(response != NULL);
    493 
    494   EXPECT_TRUE(response->headers != NULL);
    495   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
    496 
    497   std::string response_data;
    498   rv = ReadTransaction(trans.get(), &response_data);
    499   EXPECT_EQ(OK, rv);
    500   EXPECT_EQ("hello world", response_data);
    501 }
    502 
    503 // This test is almost the same as Ignores100 above, but the response contains
    504 // a 102 instead of a 100. Also, instead of HTTP/1.0 the response is
    505 // HTTP/1.1 and the two status headers are read in one read.
    506 TEST_F(HttpNetworkTransactionTest, Ignores1xx) {
    507   SessionDependencies session_deps;
    508   scoped_ptr<HttpTransaction> trans(
    509       new HttpNetworkTransaction(CreateSession(&session_deps)));
    510 
    511   HttpRequestInfo request;
    512   request.method = "GET";
    513   request.url = GURL("http://www.foo.com/");
    514   request.load_flags = 0;
    515 
    516   MockRead data_reads[] = {
    517     MockRead("HTTP/1.1 102 Unspecified status code\r\n\r\n"
    518              "HTTP/1.1 200 OK\r\n\r\n"),
    519     MockRead("hello world"),
    520     MockRead(false, OK),
    521   };
    522   StaticSocketDataProvider data(data_reads, NULL);
    523   session_deps.socket_factory.AddSocketDataProvider(&data);
    524 
    525   TestCompletionCallback callback;
    526 
    527   int rv = trans->Start(&request, &callback, NULL);
    528   EXPECT_EQ(ERR_IO_PENDING, rv);
    529 
    530   rv = callback.WaitForResult();
    531   EXPECT_EQ(OK, rv);
    532 
    533   const HttpResponseInfo* response = trans->GetResponseInfo();
    534   EXPECT_TRUE(response != NULL);
    535 
    536   EXPECT_TRUE(response->headers != NULL);
    537   EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    538 
    539   std::string response_data;
    540   rv = ReadTransaction(trans.get(), &response_data);
    541   EXPECT_EQ(OK, rv);
    542   EXPECT_EQ("hello world", response_data);
    543 }
    544 
    545 TEST_F(HttpNetworkTransactionTest, Incomplete100ThenEOF) {
    546   SessionDependencies session_deps;
    547   scoped_ptr<HttpTransaction> trans(
    548       new HttpNetworkTransaction(CreateSession(&session_deps)));
    549 
    550   HttpRequestInfo request;
    551   request.method = "POST";
    552   request.url = GURL("http://www.foo.com/");
    553   request.load_flags = 0;
    554 
    555   MockRead data_reads[] = {
    556     MockRead(false, "HTTP/1.0 100 Continue\r\n"),
    557     MockRead(true, 0),
    558   };
    559   StaticSocketDataProvider data(data_reads, NULL);
    560   session_deps.socket_factory.AddSocketDataProvider(&data);
    561 
    562   TestCompletionCallback callback;
    563 
    564   int rv = trans->Start(&request, &callback, NULL);
    565   EXPECT_EQ(ERR_IO_PENDING, rv);
    566 
    567   rv = callback.WaitForResult();
    568   EXPECT_EQ(OK, rv);
    569 
    570   std::string response_data;
    571   rv = ReadTransaction(trans.get(), &response_data);
    572   EXPECT_EQ(OK, rv);
    573   EXPECT_EQ("", response_data);
    574 }
    575 
    576 TEST_F(HttpNetworkTransactionTest, EmptyResponse) {
    577   SessionDependencies session_deps;
    578   scoped_ptr<HttpTransaction> trans(
    579       new HttpNetworkTransaction(CreateSession(&session_deps)));
    580 
    581   HttpRequestInfo request;
    582   request.method = "POST";
    583   request.url = GURL("http://www.foo.com/");
    584   request.load_flags = 0;
    585 
    586   MockRead data_reads[] = {
    587     MockRead(true, 0),
    588   };
    589   StaticSocketDataProvider data(data_reads, NULL);
    590   session_deps.socket_factory.AddSocketDataProvider(&data);
    591 
    592   TestCompletionCallback callback;
    593 
    594   int rv = trans->Start(&request, &callback, NULL);
    595   EXPECT_EQ(ERR_IO_PENDING, rv);
    596 
    597   rv = callback.WaitForResult();
    598   EXPECT_EQ(ERR_EMPTY_RESPONSE, rv);
    599 }
    600 
    601 // read_failure specifies a read failure that should cause the network
    602 // transaction to resend the request.
    603 void HttpNetworkTransactionTest::KeepAliveConnectionResendRequestTest(
    604     const MockRead& read_failure) {
    605   SessionDependencies session_deps;
    606   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
    607 
    608   HttpRequestInfo request;
    609   request.method = "GET";
    610   request.url = GURL("http://www.foo.com/");
    611   request.load_flags = 0;
    612 
    613   MockRead data1_reads[] = {
    614     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    615     MockRead("hello"),
    616     read_failure,  // Now, we reuse the connection and fail the first read.
    617   };
    618   StaticSocketDataProvider data1(data1_reads, NULL);
    619   session_deps.socket_factory.AddSocketDataProvider(&data1);
    620 
    621   MockRead data2_reads[] = {
    622     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 5\r\n\r\n"),
    623     MockRead("world"),
    624     MockRead(true, OK),
    625   };
    626   StaticSocketDataProvider data2(data2_reads, NULL);
    627   session_deps.socket_factory.AddSocketDataProvider(&data2);
    628 
    629   const char* kExpectedResponseData[] = {
    630     "hello", "world"
    631   };
    632 
    633   for (int i = 0; i < 2; ++i) {
    634     TestCompletionCallback callback;
    635 
    636     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
    637 
    638     int rv = trans->Start(&request, &callback, NULL);
    639     EXPECT_EQ(ERR_IO_PENDING, rv);
    640 
    641     rv = callback.WaitForResult();
    642     EXPECT_EQ(OK, rv);
    643 
    644     const HttpResponseInfo* response = trans->GetResponseInfo();
    645     EXPECT_TRUE(response != NULL);
    646 
    647     EXPECT_TRUE(response->headers != NULL);
    648     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    649 
    650     std::string response_data;
    651     rv = ReadTransaction(trans.get(), &response_data);
    652     EXPECT_EQ(OK, rv);
    653     EXPECT_EQ(kExpectedResponseData[i], response_data);
    654   }
    655 }
    656 
    657 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionReset) {
    658   MockRead read_failure(true, ERR_CONNECTION_RESET);
    659   KeepAliveConnectionResendRequestTest(read_failure);
    660 }
    661 
    662 TEST_F(HttpNetworkTransactionTest, KeepAliveConnectionEOF) {
    663   MockRead read_failure(false, OK);  // EOF
    664   KeepAliveConnectionResendRequestTest(read_failure);
    665 }
    666 
    667 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionReset) {
    668   SessionDependencies session_deps;
    669   scoped_ptr<HttpTransaction> trans(
    670       new HttpNetworkTransaction(CreateSession(&session_deps)));
    671 
    672   HttpRequestInfo request;
    673   request.method = "GET";
    674   request.url = GURL("http://www.google.com/");
    675   request.load_flags = 0;
    676 
    677   MockRead data_reads[] = {
    678     MockRead(true, ERR_CONNECTION_RESET),
    679     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
    680     MockRead("hello world"),
    681     MockRead(false, OK),
    682   };
    683   StaticSocketDataProvider data(data_reads, NULL);
    684   session_deps.socket_factory.AddSocketDataProvider(&data);
    685 
    686   TestCompletionCallback callback;
    687 
    688   int rv = trans->Start(&request, &callback, NULL);
    689   EXPECT_EQ(ERR_IO_PENDING, rv);
    690 
    691   rv = callback.WaitForResult();
    692   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
    693 
    694   const HttpResponseInfo* response = trans->GetResponseInfo();
    695   EXPECT_TRUE(response == NULL);
    696 }
    697 
    698 // What do various browsers do when the server closes a non-keepalive
    699 // connection without sending any response header or body?
    700 //
    701 // IE7: error page
    702 // Safari 3.1.2 (Windows): error page
    703 // Firefox 3.0.1: blank page
    704 // Opera 9.52: after five attempts, blank page
    705 // Us with WinHTTP: error page (ERR_INVALID_RESPONSE)
    706 // Us: error page (EMPTY_RESPONSE)
    707 TEST_F(HttpNetworkTransactionTest, NonKeepAliveConnectionEOF) {
    708   MockRead data_reads[] = {
    709     MockRead(false, OK),  // EOF
    710     MockRead("HTTP/1.0 200 OK\r\n\r\n"),  // Should not be used
    711     MockRead("hello world"),
    712     MockRead(false, OK),
    713   };
    714   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
    715   EXPECT_EQ(ERR_EMPTY_RESPONSE, out.rv);
    716 }
    717 
    718 // Test the request-challenge-retry sequence for basic auth.
    719 // (basic auth is the easiest to mock, because it has no randomness).
    720 TEST_F(HttpNetworkTransactionTest, BasicAuth) {
    721   SessionDependencies session_deps;
    722   scoped_ptr<HttpTransaction> trans(
    723       new HttpNetworkTransaction(CreateSession(&session_deps)));
    724 
    725   HttpRequestInfo request;
    726   request.method = "GET";
    727   request.url = GURL("http://www.google.com/");
    728   request.load_flags = 0;
    729 
    730   MockWrite data_writes1[] = {
    731     MockWrite("GET / HTTP/1.1\r\n"
    732               "Host: www.google.com\r\n"
    733               "Connection: keep-alive\r\n\r\n"),
    734   };
    735 
    736   MockRead data_reads1[] = {
    737     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
    738     // Give a couple authenticate options (only the middle one is actually
    739     // supported).
    740     MockRead("WWW-Authenticate: Basic invalid\r\n"),  // Malformed.
    741     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
    742     MockRead("WWW-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
    743     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    744     // Large content-length -- won't matter, as connection will be reset.
    745     MockRead("Content-Length: 10000\r\n\r\n"),
    746     MockRead(false, ERR_FAILED),
    747   };
    748 
    749   // After calling trans->RestartWithAuth(), this is the request we should
    750   // be issuing -- the final header line contains the credentials.
    751   MockWrite data_writes2[] = {
    752     MockWrite("GET / HTTP/1.1\r\n"
    753               "Host: www.google.com\r\n"
    754               "Connection: keep-alive\r\n"
    755               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
    756   };
    757 
    758   // Lastly, the server responds with the actual content.
    759   MockRead data_reads2[] = {
    760     MockRead("HTTP/1.0 200 OK\r\n"),
    761     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    762     MockRead("Content-Length: 100\r\n\r\n"),
    763     MockRead(false, OK),
    764   };
    765 
    766   StaticSocketDataProvider data1(data_reads1, data_writes1);
    767   StaticSocketDataProvider data2(data_reads2, data_writes2);
    768   session_deps.socket_factory.AddSocketDataProvider(&data1);
    769   session_deps.socket_factory.AddSocketDataProvider(&data2);
    770 
    771   TestCompletionCallback callback1;
    772 
    773   int rv = trans->Start(&request, &callback1, NULL);
    774   EXPECT_EQ(ERR_IO_PENDING, rv);
    775 
    776   rv = callback1.WaitForResult();
    777   EXPECT_EQ(OK, rv);
    778 
    779   const HttpResponseInfo* response = trans->GetResponseInfo();
    780   EXPECT_FALSE(response == NULL);
    781 
    782   // The password prompt info should have been set in response->auth_challenge.
    783   EXPECT_FALSE(response->auth_challenge.get() == NULL);
    784 
    785   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
    786   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
    787   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
    788 
    789   TestCompletionCallback callback2;
    790 
    791   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
    792   EXPECT_EQ(ERR_IO_PENDING, rv);
    793 
    794   rv = callback2.WaitForResult();
    795   EXPECT_EQ(OK, rv);
    796 
    797   response = trans->GetResponseInfo();
    798   EXPECT_FALSE(response == NULL);
    799   EXPECT_TRUE(response->auth_challenge.get() == NULL);
    800   EXPECT_EQ(100, response->headers->GetContentLength());
    801 }
    802 
    803 TEST_F(HttpNetworkTransactionTest, DoNotSendAuth) {
    804   SessionDependencies session_deps;
    805   scoped_ptr<HttpTransaction> trans(
    806       new HttpNetworkTransaction(CreateSession(&session_deps)));
    807 
    808   HttpRequestInfo request;
    809   request.method = "GET";
    810   request.url = GURL("http://www.google.com/");
    811   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
    812 
    813   MockWrite data_writes[] = {
    814     MockWrite("GET / HTTP/1.1\r\n"
    815               "Host: www.google.com\r\n"
    816               "Connection: keep-alive\r\n\r\n"),
    817   };
    818 
    819   MockRead data_reads[] = {
    820     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
    821     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
    822     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    823     // Large content-length -- won't matter, as connection will be reset.
    824     MockRead("Content-Length: 10000\r\n\r\n"),
    825     MockRead(false, ERR_FAILED),
    826   };
    827 
    828   StaticSocketDataProvider data(data_reads, data_writes);
    829   session_deps.socket_factory.AddSocketDataProvider(&data);
    830   TestCompletionCallback callback;
    831 
    832   int rv = trans->Start(&request, &callback, NULL);
    833   EXPECT_EQ(ERR_IO_PENDING, rv);
    834 
    835   rv = callback.WaitForResult();
    836   EXPECT_EQ(0, rv);
    837 
    838   const HttpResponseInfo* response = trans->GetResponseInfo();
    839   ASSERT_FALSE(response == NULL);
    840   EXPECT_TRUE(response->auth_challenge.get() == NULL);
    841 }
    842 
    843 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
    844 // connection.
    845 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAlive) {
    846   SessionDependencies session_deps;
    847   scoped_ptr<HttpTransaction> trans(
    848       new HttpNetworkTransaction(CreateSession(&session_deps)));
    849 
    850   HttpRequestInfo request;
    851   request.method = "GET";
    852   request.url = GURL("http://www.google.com/");
    853   request.load_flags = 0;
    854 
    855   MockWrite data_writes1[] = {
    856     MockWrite("GET / HTTP/1.1\r\n"
    857               "Host: www.google.com\r\n"
    858               "Connection: keep-alive\r\n\r\n"),
    859 
    860     // After calling trans->RestartWithAuth(), this is the request we should
    861     // be issuing -- the final header line contains the credentials.
    862     MockWrite("GET / HTTP/1.1\r\n"
    863               "Host: www.google.com\r\n"
    864               "Connection: keep-alive\r\n"
    865               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
    866   };
    867 
    868   MockRead data_reads1[] = {
    869     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
    870     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
    871     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    872     MockRead("Content-Length: 14\r\n\r\n"),
    873     MockRead("Unauthorized\r\n"),
    874 
    875     // Lastly, the server responds with the actual content.
    876     MockRead("HTTP/1.1 200 OK\r\n"),
    877     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    878     MockRead("Content-Length: 100\r\n\r\n"),
    879     MockRead(false, OK),
    880   };
    881 
    882   StaticSocketDataProvider data1(data_reads1, data_writes1);
    883   session_deps.socket_factory.AddSocketDataProvider(&data1);
    884 
    885   TestCompletionCallback callback1;
    886 
    887   int rv = trans->Start(&request, &callback1, NULL);
    888   EXPECT_EQ(ERR_IO_PENDING, rv);
    889 
    890   rv = callback1.WaitForResult();
    891   EXPECT_EQ(OK, rv);
    892 
    893   const HttpResponseInfo* response = trans->GetResponseInfo();
    894   EXPECT_FALSE(response == NULL);
    895 
    896   // The password prompt info should have been set in response->auth_challenge.
    897   EXPECT_FALSE(response->auth_challenge.get() == NULL);
    898 
    899   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
    900   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
    901   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
    902 
    903   TestCompletionCallback callback2;
    904 
    905   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
    906   EXPECT_EQ(ERR_IO_PENDING, rv);
    907 
    908   rv = callback2.WaitForResult();
    909   EXPECT_EQ(OK, rv);
    910 
    911   response = trans->GetResponseInfo();
    912   EXPECT_FALSE(response == NULL);
    913   EXPECT_TRUE(response->auth_challenge.get() == NULL);
    914   EXPECT_EQ(100, response->headers->GetContentLength());
    915 }
    916 
    917 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
    918 // connection and with no response body to drain.
    919 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveNoBody) {
    920   SessionDependencies session_deps;
    921   scoped_ptr<HttpTransaction> trans(
    922       new HttpNetworkTransaction(CreateSession(&session_deps)));
    923 
    924   HttpRequestInfo request;
    925   request.method = "GET";
    926   request.url = GURL("http://www.google.com/");
    927   request.load_flags = 0;
    928 
    929   MockWrite data_writes1[] = {
    930     MockWrite("GET / HTTP/1.1\r\n"
    931               "Host: www.google.com\r\n"
    932               "Connection: keep-alive\r\n\r\n"),
    933 
    934     // After calling trans->RestartWithAuth(), this is the request we should
    935     // be issuing -- the final header line contains the credentials.
    936     MockWrite("GET / HTTP/1.1\r\n"
    937               "Host: www.google.com\r\n"
    938               "Connection: keep-alive\r\n"
    939               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
    940   };
    941 
    942   MockRead data_reads1[] = {
    943     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
    944     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
    945     MockRead("Content-Length: 0\r\n\r\n"),  // No response body.
    946 
    947     // Lastly, the server responds with the actual content.
    948     MockRead("HTTP/1.1 200 OK\r\n"),
    949     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
    950     MockRead("Content-Length: 100\r\n\r\n"),
    951     MockRead(false, OK),
    952   };
    953 
    954   StaticSocketDataProvider data1(data_reads1, data_writes1);
    955   session_deps.socket_factory.AddSocketDataProvider(&data1);
    956 
    957   TestCompletionCallback callback1;
    958 
    959   int rv = trans->Start(&request, &callback1, NULL);
    960   EXPECT_EQ(ERR_IO_PENDING, rv);
    961 
    962   rv = callback1.WaitForResult();
    963   EXPECT_EQ(OK, rv);
    964 
    965   const HttpResponseInfo* response = trans->GetResponseInfo();
    966   EXPECT_FALSE(response == NULL);
    967 
    968   // The password prompt info should have been set in response->auth_challenge.
    969   EXPECT_FALSE(response->auth_challenge.get() == NULL);
    970 
    971   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
    972   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
    973   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
    974 
    975   TestCompletionCallback callback2;
    976 
    977   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
    978   EXPECT_EQ(ERR_IO_PENDING, rv);
    979 
    980   rv = callback2.WaitForResult();
    981   EXPECT_EQ(OK, rv);
    982 
    983   response = trans->GetResponseInfo();
    984   EXPECT_FALSE(response == NULL);
    985   EXPECT_TRUE(response->auth_challenge.get() == NULL);
    986   EXPECT_EQ(100, response->headers->GetContentLength());
    987 }
    988 
    989 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
    990 // connection and with a large response body to drain.
    991 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveLargeBody) {
    992   SessionDependencies session_deps;
    993   scoped_ptr<HttpTransaction> trans(
    994       new HttpNetworkTransaction(CreateSession(&session_deps)));
    995 
    996   HttpRequestInfo request;
    997   request.method = "GET";
    998   request.url = GURL("http://www.google.com/");
    999   request.load_flags = 0;
   1000 
   1001   MockWrite data_writes1[] = {
   1002     MockWrite("GET / HTTP/1.1\r\n"
   1003               "Host: www.google.com\r\n"
   1004               "Connection: keep-alive\r\n\r\n"),
   1005 
   1006     // After calling trans->RestartWithAuth(), this is the request we should
   1007     // be issuing -- the final header line contains the credentials.
   1008     MockWrite("GET / HTTP/1.1\r\n"
   1009               "Host: www.google.com\r\n"
   1010               "Connection: keep-alive\r\n"
   1011               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1012   };
   1013 
   1014   // Respond with 5 kb of response body.
   1015   std::string large_body_string("Unauthorized");
   1016   large_body_string.append(5 * 1024, ' ');
   1017   large_body_string.append("\r\n");
   1018 
   1019   MockRead data_reads1[] = {
   1020     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1021     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1022     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1023     // 5134 = 12 + 5 * 1024 + 2
   1024     MockRead("Content-Length: 5134\r\n\r\n"),
   1025     MockRead(true, large_body_string.data(), large_body_string.size()),
   1026 
   1027     // Lastly, the server responds with the actual content.
   1028     MockRead("HTTP/1.1 200 OK\r\n"),
   1029     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1030     MockRead("Content-Length: 100\r\n\r\n"),
   1031     MockRead(false, OK),
   1032   };
   1033 
   1034   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1035   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1036 
   1037   TestCompletionCallback callback1;
   1038 
   1039   int rv = trans->Start(&request, &callback1, NULL);
   1040   EXPECT_EQ(ERR_IO_PENDING, rv);
   1041 
   1042   rv = callback1.WaitForResult();
   1043   EXPECT_EQ(OK, rv);
   1044 
   1045   const HttpResponseInfo* response = trans->GetResponseInfo();
   1046   EXPECT_FALSE(response == NULL);
   1047 
   1048   // The password prompt info should have been set in response->auth_challenge.
   1049   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1050 
   1051   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1052   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1053   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1054 
   1055   TestCompletionCallback callback2;
   1056 
   1057   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
   1058   EXPECT_EQ(ERR_IO_PENDING, rv);
   1059 
   1060   rv = callback2.WaitForResult();
   1061   EXPECT_EQ(OK, rv);
   1062 
   1063   response = trans->GetResponseInfo();
   1064   EXPECT_FALSE(response == NULL);
   1065   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1066   EXPECT_EQ(100, response->headers->GetContentLength());
   1067 }
   1068 
   1069 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1070 // connection, but the server gets impatient and closes the connection.
   1071 TEST_F(HttpNetworkTransactionTest, BasicAuthKeepAliveImpatientServer) {
   1072   SessionDependencies session_deps;
   1073   scoped_ptr<HttpTransaction> trans(
   1074       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1075 
   1076   HttpRequestInfo request;
   1077   request.method = "GET";
   1078   request.url = GURL("http://www.google.com/");
   1079   request.load_flags = 0;
   1080 
   1081   MockWrite data_writes1[] = {
   1082     MockWrite("GET / HTTP/1.1\r\n"
   1083               "Host: www.google.com\r\n"
   1084               "Connection: keep-alive\r\n\r\n"),
   1085     // This simulates the seemingly successful write to a closed connection
   1086     // if the bug is not fixed.
   1087     MockWrite("GET / HTTP/1.1\r\n"
   1088               "Host: www.google.com\r\n"
   1089               "Connection: keep-alive\r\n"
   1090               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1091   };
   1092 
   1093   MockRead data_reads1[] = {
   1094     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   1095     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1096     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1097     MockRead("Content-Length: 14\r\n\r\n"),
   1098     // Tell MockTCPClientSocket to simulate the server closing the connection.
   1099     MockRead(false, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
   1100     MockRead("Unauthorized\r\n"),
   1101     MockRead(false, OK),  // The server closes the connection.
   1102   };
   1103 
   1104   // After calling trans->RestartWithAuth(), this is the request we should
   1105   // be issuing -- the final header line contains the credentials.
   1106   MockWrite data_writes2[] = {
   1107     MockWrite("GET / HTTP/1.1\r\n"
   1108               "Host: www.google.com\r\n"
   1109               "Connection: keep-alive\r\n"
   1110               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1111   };
   1112 
   1113   // Lastly, the server responds with the actual content.
   1114   MockRead data_reads2[] = {
   1115     MockRead("HTTP/1.1 200 OK\r\n"),
   1116     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1117     MockRead("Content-Length: 100\r\n\r\n"),
   1118     MockRead(false, OK),
   1119   };
   1120 
   1121   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1122   StaticSocketDataProvider data2(data_reads2, data_writes2);
   1123   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1124   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1125 
   1126   TestCompletionCallback callback1;
   1127 
   1128   int rv = trans->Start(&request, &callback1, NULL);
   1129   EXPECT_EQ(ERR_IO_PENDING, rv);
   1130 
   1131   rv = callback1.WaitForResult();
   1132   EXPECT_EQ(OK, rv);
   1133 
   1134   const HttpResponseInfo* response = trans->GetResponseInfo();
   1135   EXPECT_FALSE(response == NULL);
   1136 
   1137   // The password prompt info should have been set in response->auth_challenge.
   1138   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1139 
   1140   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1141   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1142   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1143 
   1144   TestCompletionCallback callback2;
   1145 
   1146   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
   1147   EXPECT_EQ(ERR_IO_PENDING, rv);
   1148 
   1149   rv = callback2.WaitForResult();
   1150   EXPECT_EQ(OK, rv);
   1151 
   1152   response = trans->GetResponseInfo();
   1153   ASSERT_FALSE(response == NULL);
   1154   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1155   EXPECT_EQ(100, response->headers->GetContentLength());
   1156 }
   1157 
   1158 // Test the request-challenge-retry sequence for basic auth, over a keep-alive
   1159 // proxy connection, when setting up an SSL tunnel.
   1160 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyKeepAlive) {
   1161   // Configure against proxy server "myproxy:70".
   1162   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   1163   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1164 
   1165   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1166 
   1167   HttpRequestInfo request;
   1168   request.method = "GET";
   1169   request.url = GURL("https://www.google.com/");
   1170   // Ensure that proxy authentication is attempted even
   1171   // when the no authentication data flag is set.
   1172   request.load_flags = net::LOAD_DO_NOT_SEND_AUTH_DATA;
   1173 
   1174   // Since we have proxy, should try to establish tunnel.
   1175   MockWrite data_writes1[] = {
   1176     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1177               "Host: www.google.com\r\n"
   1178               "Proxy-Connection: keep-alive\r\n\r\n"),
   1179 
   1180     // After calling trans->RestartWithAuth(), this is the request we should
   1181     // be issuing -- the final header line contains the credentials.
   1182     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1183               "Host: www.google.com\r\n"
   1184               "Proxy-Connection: keep-alive\r\n"
   1185               "Proxy-Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   1186   };
   1187 
   1188   // The proxy responds to the connect with a 407, using a persistent
   1189   // connection.
   1190   MockRead data_reads1[] = {
   1191     // No credentials.
   1192     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1193     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1194     MockRead("Content-Length: 10\r\n\r\n"),
   1195     MockRead("0123456789"),
   1196 
   1197     // Wrong credentials (wrong password).
   1198     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1199     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1200     MockRead("Content-Length: 10\r\n\r\n"),
   1201     // No response body because the test stops reading here.
   1202     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   1203   };
   1204 
   1205   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1206   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1207 
   1208   TestCompletionCallback callback1;
   1209 
   1210   int rv = trans->Start(&request, &callback1, NULL);
   1211   EXPECT_EQ(ERR_IO_PENDING, rv);
   1212 
   1213   rv = callback1.WaitForResult();
   1214   EXPECT_EQ(OK, rv);
   1215 
   1216   const HttpResponseInfo* response = trans->GetResponseInfo();
   1217   EXPECT_FALSE(response == NULL);
   1218 
   1219   EXPECT_TRUE(response->headers->IsKeepAlive());
   1220   EXPECT_EQ(407, response->headers->response_code());
   1221   EXPECT_EQ(10, response->headers->GetContentLength());
   1222   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1223 
   1224   // The password prompt info should have been set in response->auth_challenge.
   1225   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1226 
   1227   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1228   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1229   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1230 
   1231   TestCompletionCallback callback2;
   1232 
   1233   // Wrong password (should be "bar").
   1234   rv = trans->RestartWithAuth(L"foo", L"baz", &callback2);
   1235   EXPECT_EQ(ERR_IO_PENDING, rv);
   1236 
   1237   rv = callback2.WaitForResult();
   1238   EXPECT_EQ(OK, rv);
   1239 
   1240   response = trans->GetResponseInfo();
   1241   EXPECT_FALSE(response == NULL);
   1242 
   1243   EXPECT_TRUE(response->headers->IsKeepAlive());
   1244   EXPECT_EQ(407, response->headers->response_code());
   1245   EXPECT_EQ(10, response->headers->GetContentLength());
   1246   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1247 
   1248   // The password prompt info should have been set in response->auth_challenge.
   1249   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1250 
   1251   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1252   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1253   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1254 }
   1255 
   1256 // Test that we don't read the response body when we fail to establish a tunnel,
   1257 // even if the user cancels the proxy's auth attempt.
   1258 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyCancelTunnel) {
   1259   // Configure against proxy server "myproxy:70".
   1260   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   1261 
   1262   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1263 
   1264   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1265 
   1266   HttpRequestInfo request;
   1267   request.method = "GET";
   1268   request.url = GURL("https://www.google.com/");
   1269   request.load_flags = 0;
   1270 
   1271   // Since we have proxy, should try to establish tunnel.
   1272   MockWrite data_writes[] = {
   1273     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1274               "Host: www.google.com\r\n"
   1275               "Proxy-Connection: keep-alive\r\n\r\n"),
   1276   };
   1277 
   1278   // The proxy responds to the connect with a 407.
   1279   MockRead data_reads[] = {
   1280     MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1281     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1282     MockRead("Content-Length: 10\r\n\r\n"),
   1283     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   1284   };
   1285 
   1286   StaticSocketDataProvider data(data_reads, data_writes);
   1287   session_deps.socket_factory.AddSocketDataProvider(&data);
   1288 
   1289   TestCompletionCallback callback;
   1290 
   1291   int rv = trans->Start(&request, &callback, NULL);
   1292   EXPECT_EQ(ERR_IO_PENDING, rv);
   1293 
   1294   rv = callback.WaitForResult();
   1295   EXPECT_EQ(OK, rv);
   1296 
   1297   const HttpResponseInfo* response = trans->GetResponseInfo();
   1298   EXPECT_FALSE(response == NULL);
   1299 
   1300   EXPECT_TRUE(response->headers->IsKeepAlive());
   1301   EXPECT_EQ(407, response->headers->response_code());
   1302   EXPECT_EQ(10, response->headers->GetContentLength());
   1303   EXPECT_TRUE(HttpVersion(1, 1) == response->headers->GetHttpVersion());
   1304 
   1305   std::string response_data;
   1306   rv = ReadTransaction(trans.get(), &response_data);
   1307   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   1308 }
   1309 
   1310 void HttpNetworkTransactionTest::ConnectStatusHelperWithExpectedStatus(
   1311     const MockRead& status, int expected_status) {
   1312   // Configure against proxy server "myproxy:70".
   1313   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   1314 
   1315   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   1316 
   1317   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   1318 
   1319   HttpRequestInfo request;
   1320   request.method = "GET";
   1321   request.url = GURL("https://www.google.com/");
   1322   request.load_flags = 0;
   1323 
   1324   // Since we have proxy, should try to establish tunnel.
   1325   MockWrite data_writes[] = {
   1326     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   1327               "Host: www.google.com\r\n"
   1328               "Proxy-Connection: keep-alive\r\n\r\n"),
   1329   };
   1330 
   1331   MockRead data_reads[] = {
   1332     status,
   1333     MockRead("Content-Length: 10\r\n\r\n"),
   1334     // No response body because the test stops reading here.
   1335     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   1336   };
   1337 
   1338   StaticSocketDataProvider data(data_reads, data_writes);
   1339   session_deps.socket_factory.AddSocketDataProvider(&data);
   1340 
   1341   TestCompletionCallback callback;
   1342 
   1343   int rv = trans->Start(&request, &callback, NULL);
   1344   EXPECT_EQ(ERR_IO_PENDING, rv);
   1345 
   1346   rv = callback.WaitForResult();
   1347   EXPECT_EQ(expected_status, rv);
   1348 }
   1349 
   1350 void HttpNetworkTransactionTest::ConnectStatusHelper(const MockRead& status) {
   1351   ConnectStatusHelperWithExpectedStatus(
   1352       status, ERR_TUNNEL_CONNECTION_FAILED);
   1353 }
   1354 
   1355 TEST_F(HttpNetworkTransactionTest, ConnectStatus100) {
   1356   ConnectStatusHelper(MockRead("HTTP/1.1 100 Continue\r\n"));
   1357 }
   1358 
   1359 TEST_F(HttpNetworkTransactionTest, ConnectStatus101) {
   1360   ConnectStatusHelper(MockRead("HTTP/1.1 101 Switching Protocols\r\n"));
   1361 }
   1362 
   1363 TEST_F(HttpNetworkTransactionTest, ConnectStatus201) {
   1364   ConnectStatusHelper(MockRead("HTTP/1.1 201 Created\r\n"));
   1365 }
   1366 
   1367 TEST_F(HttpNetworkTransactionTest, ConnectStatus202) {
   1368   ConnectStatusHelper(MockRead("HTTP/1.1 202 Accepted\r\n"));
   1369 }
   1370 
   1371 TEST_F(HttpNetworkTransactionTest, ConnectStatus203) {
   1372   ConnectStatusHelper(
   1373       MockRead("HTTP/1.1 203 Non-Authoritative Information\r\n"));
   1374 }
   1375 
   1376 TEST_F(HttpNetworkTransactionTest, ConnectStatus204) {
   1377   ConnectStatusHelper(MockRead("HTTP/1.1 204 No Content\r\n"));
   1378 }
   1379 
   1380 TEST_F(HttpNetworkTransactionTest, ConnectStatus205) {
   1381   ConnectStatusHelper(MockRead("HTTP/1.1 205 Reset Content\r\n"));
   1382 }
   1383 
   1384 TEST_F(HttpNetworkTransactionTest, ConnectStatus206) {
   1385   ConnectStatusHelper(MockRead("HTTP/1.1 206 Partial Content\r\n"));
   1386 }
   1387 
   1388 TEST_F(HttpNetworkTransactionTest, ConnectStatus300) {
   1389   ConnectStatusHelper(MockRead("HTTP/1.1 300 Multiple Choices\r\n"));
   1390 }
   1391 
   1392 TEST_F(HttpNetworkTransactionTest, ConnectStatus301) {
   1393   ConnectStatusHelper(MockRead("HTTP/1.1 301 Moved Permanently\r\n"));
   1394 }
   1395 
   1396 TEST_F(HttpNetworkTransactionTest, ConnectStatus302) {
   1397   ConnectStatusHelper(MockRead("HTTP/1.1 302 Found\r\n"));
   1398 }
   1399 
   1400 TEST_F(HttpNetworkTransactionTest, ConnectStatus303) {
   1401   ConnectStatusHelper(MockRead("HTTP/1.1 303 See Other\r\n"));
   1402 }
   1403 
   1404 TEST_F(HttpNetworkTransactionTest, ConnectStatus304) {
   1405   ConnectStatusHelper(MockRead("HTTP/1.1 304 Not Modified\r\n"));
   1406 }
   1407 
   1408 TEST_F(HttpNetworkTransactionTest, ConnectStatus305) {
   1409   ConnectStatusHelper(MockRead("HTTP/1.1 305 Use Proxy\r\n"));
   1410 }
   1411 
   1412 TEST_F(HttpNetworkTransactionTest, ConnectStatus306) {
   1413   ConnectStatusHelper(MockRead("HTTP/1.1 306\r\n"));
   1414 }
   1415 
   1416 TEST_F(HttpNetworkTransactionTest, ConnectStatus307) {
   1417   ConnectStatusHelper(MockRead("HTTP/1.1 307 Temporary Redirect\r\n"));
   1418 }
   1419 
   1420 TEST_F(HttpNetworkTransactionTest, ConnectStatus400) {
   1421   ConnectStatusHelper(MockRead("HTTP/1.1 400 Bad Request\r\n"));
   1422 }
   1423 
   1424 TEST_F(HttpNetworkTransactionTest, ConnectStatus401) {
   1425   ConnectStatusHelper(MockRead("HTTP/1.1 401 Unauthorized\r\n"));
   1426 }
   1427 
   1428 TEST_F(HttpNetworkTransactionTest, ConnectStatus402) {
   1429   ConnectStatusHelper(MockRead("HTTP/1.1 402 Payment Required\r\n"));
   1430 }
   1431 
   1432 TEST_F(HttpNetworkTransactionTest, ConnectStatus403) {
   1433   ConnectStatusHelper(MockRead("HTTP/1.1 403 Forbidden\r\n"));
   1434 }
   1435 
   1436 TEST_F(HttpNetworkTransactionTest, ConnectStatus404) {
   1437   ConnectStatusHelper(MockRead("HTTP/1.1 404 Not Found\r\n"));
   1438 }
   1439 
   1440 TEST_F(HttpNetworkTransactionTest, ConnectStatus405) {
   1441   ConnectStatusHelper(MockRead("HTTP/1.1 405 Method Not Allowed\r\n"));
   1442 }
   1443 
   1444 TEST_F(HttpNetworkTransactionTest, ConnectStatus406) {
   1445   ConnectStatusHelper(MockRead("HTTP/1.1 406 Not Acceptable\r\n"));
   1446 }
   1447 
   1448 TEST_F(HttpNetworkTransactionTest, ConnectStatus407) {
   1449   ConnectStatusHelperWithExpectedStatus(
   1450       MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
   1451       ERR_PROXY_AUTH_REQUESTED);
   1452 }
   1453 
   1454 TEST_F(HttpNetworkTransactionTest, ConnectStatus408) {
   1455   ConnectStatusHelper(MockRead("HTTP/1.1 408 Request Timeout\r\n"));
   1456 }
   1457 
   1458 TEST_F(HttpNetworkTransactionTest, ConnectStatus409) {
   1459   ConnectStatusHelper(MockRead("HTTP/1.1 409 Conflict\r\n"));
   1460 }
   1461 
   1462 TEST_F(HttpNetworkTransactionTest, ConnectStatus410) {
   1463   ConnectStatusHelper(MockRead("HTTP/1.1 410 Gone\r\n"));
   1464 }
   1465 
   1466 TEST_F(HttpNetworkTransactionTest, ConnectStatus411) {
   1467   ConnectStatusHelper(MockRead("HTTP/1.1 411 Length Required\r\n"));
   1468 }
   1469 
   1470 TEST_F(HttpNetworkTransactionTest, ConnectStatus412) {
   1471   ConnectStatusHelper(MockRead("HTTP/1.1 412 Precondition Failed\r\n"));
   1472 }
   1473 
   1474 TEST_F(HttpNetworkTransactionTest, ConnectStatus413) {
   1475   ConnectStatusHelper(MockRead("HTTP/1.1 413 Request Entity Too Large\r\n"));
   1476 }
   1477 
   1478 TEST_F(HttpNetworkTransactionTest, ConnectStatus414) {
   1479   ConnectStatusHelper(MockRead("HTTP/1.1 414 Request-URI Too Long\r\n"));
   1480 }
   1481 
   1482 TEST_F(HttpNetworkTransactionTest, ConnectStatus415) {
   1483   ConnectStatusHelper(MockRead("HTTP/1.1 415 Unsupported Media Type\r\n"));
   1484 }
   1485 
   1486 TEST_F(HttpNetworkTransactionTest, ConnectStatus416) {
   1487   ConnectStatusHelper(
   1488       MockRead("HTTP/1.1 416 Requested Range Not Satisfiable\r\n"));
   1489 }
   1490 
   1491 TEST_F(HttpNetworkTransactionTest, ConnectStatus417) {
   1492   ConnectStatusHelper(MockRead("HTTP/1.1 417 Expectation Failed\r\n"));
   1493 }
   1494 
   1495 TEST_F(HttpNetworkTransactionTest, ConnectStatus500) {
   1496   ConnectStatusHelper(MockRead("HTTP/1.1 500 Internal Server Error\r\n"));
   1497 }
   1498 
   1499 TEST_F(HttpNetworkTransactionTest, ConnectStatus501) {
   1500   ConnectStatusHelper(MockRead("HTTP/1.1 501 Not Implemented\r\n"));
   1501 }
   1502 
   1503 TEST_F(HttpNetworkTransactionTest, ConnectStatus502) {
   1504   ConnectStatusHelper(MockRead("HTTP/1.1 502 Bad Gateway\r\n"));
   1505 }
   1506 
   1507 TEST_F(HttpNetworkTransactionTest, ConnectStatus503) {
   1508   ConnectStatusHelper(MockRead("HTTP/1.1 503 Service Unavailable\r\n"));
   1509 }
   1510 
   1511 TEST_F(HttpNetworkTransactionTest, ConnectStatus504) {
   1512   ConnectStatusHelper(MockRead("HTTP/1.1 504 Gateway Timeout\r\n"));
   1513 }
   1514 
   1515 TEST_F(HttpNetworkTransactionTest, ConnectStatus505) {
   1516   ConnectStatusHelper(MockRead("HTTP/1.1 505 HTTP Version Not Supported\r\n"));
   1517 }
   1518 
   1519 // Test the flow when both the proxy server AND origin server require
   1520 // authentication. Again, this uses basic auth for both since that is
   1521 // the simplest to mock.
   1522 TEST_F(HttpNetworkTransactionTest, BasicAuthProxyThenServer) {
   1523   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   1524 
   1525   // Configure against proxy server "myproxy:70".
   1526   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   1527       CreateSession(&session_deps)));
   1528 
   1529   HttpRequestInfo request;
   1530   request.method = "GET";
   1531   request.url = GURL("http://www.google.com/");
   1532   request.load_flags = 0;
   1533 
   1534   MockWrite data_writes1[] = {
   1535     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   1536               "Host: www.google.com\r\n"
   1537               "Proxy-Connection: keep-alive\r\n\r\n"),
   1538   };
   1539 
   1540   MockRead data_reads1[] = {
   1541     MockRead("HTTP/1.0 407 Unauthorized\r\n"),
   1542     // Give a couple authenticate options (only the middle one is actually
   1543     // supported).
   1544     MockRead("Proxy-Authenticate: Basic invalid\r\n"),  // Malformed.
   1545     MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1546     MockRead("Proxy-Authenticate: UNSUPPORTED realm=\"FOO\"\r\n"),
   1547     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1548     // Large content-length -- won't matter, as connection will be reset.
   1549     MockRead("Content-Length: 10000\r\n\r\n"),
   1550     MockRead(false, ERR_FAILED),
   1551   };
   1552 
   1553   // After calling trans->RestartWithAuth() the first time, this is the
   1554   // request we should be issuing -- the final header line contains the
   1555   // proxy's credentials.
   1556   MockWrite data_writes2[] = {
   1557     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   1558               "Host: www.google.com\r\n"
   1559               "Proxy-Connection: keep-alive\r\n"
   1560               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   1561   };
   1562 
   1563   // Now the proxy server lets the request pass through to origin server.
   1564   // The origin server responds with a 401.
   1565   MockRead data_reads2[] = {
   1566     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   1567     // Note: We are using the same realm-name as the proxy server. This is
   1568     // completely valid, as realms are unique across hosts.
   1569     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   1570     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1571     MockRead("Content-Length: 2000\r\n\r\n"),
   1572     MockRead(false, ERR_FAILED),  // Won't be reached.
   1573   };
   1574 
   1575   // After calling trans->RestartWithAuth() the second time, we should send
   1576   // the credentials for both the proxy and origin server.
   1577   MockWrite data_writes3[] = {
   1578     MockWrite("GET http://www.google.com/ HTTP/1.1\r\n"
   1579               "Host: www.google.com\r\n"
   1580               "Proxy-Connection: keep-alive\r\n"
   1581               "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n"
   1582               "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   1583   };
   1584 
   1585   // Lastly we get the desired content.
   1586   MockRead data_reads3[] = {
   1587     MockRead("HTTP/1.0 200 OK\r\n"),
   1588     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   1589     MockRead("Content-Length: 100\r\n\r\n"),
   1590     MockRead(false, OK),
   1591   };
   1592 
   1593   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1594   StaticSocketDataProvider data2(data_reads2, data_writes2);
   1595   StaticSocketDataProvider data3(data_reads3, data_writes3);
   1596   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1597   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1598   session_deps.socket_factory.AddSocketDataProvider(&data3);
   1599 
   1600   TestCompletionCallback callback1;
   1601 
   1602   int rv = trans->Start(&request, &callback1, NULL);
   1603   EXPECT_EQ(ERR_IO_PENDING, rv);
   1604 
   1605   rv = callback1.WaitForResult();
   1606   EXPECT_EQ(OK, rv);
   1607 
   1608   const HttpResponseInfo* response = trans->GetResponseInfo();
   1609   EXPECT_FALSE(response == NULL);
   1610 
   1611   // The password prompt info should have been set in response->auth_challenge.
   1612   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1613 
   1614   EXPECT_EQ(L"myproxy:70", response->auth_challenge->host_and_port);
   1615   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1616   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1617 
   1618   TestCompletionCallback callback2;
   1619 
   1620   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
   1621   EXPECT_EQ(ERR_IO_PENDING, rv);
   1622 
   1623   rv = callback2.WaitForResult();
   1624   EXPECT_EQ(OK, rv);
   1625 
   1626   response = trans->GetResponseInfo();
   1627   EXPECT_FALSE(response == NULL);
   1628   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1629 
   1630   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   1631   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   1632   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   1633 
   1634   TestCompletionCallback callback3;
   1635 
   1636   rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback3);
   1637   EXPECT_EQ(ERR_IO_PENDING, rv);
   1638 
   1639   rv = callback3.WaitForResult();
   1640   EXPECT_EQ(OK, rv);
   1641 
   1642   response = trans->GetResponseInfo();
   1643   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1644   EXPECT_EQ(100, response->headers->GetContentLength());
   1645 }
   1646 
   1647 // For the NTLM implementation using SSPI, we skip the NTLM tests since we
   1648 // can't hook into its internals to cause it to generate predictable NTLM
   1649 // authorization headers.
   1650 #if defined(NTLM_PORTABLE)
   1651 // The NTLM authentication unit tests were generated by capturing the HTTP
   1652 // requests and responses using Fiddler 2 and inspecting the generated random
   1653 // bytes in the debugger.
   1654 
   1655 // Enter the correct password and authenticate successfully.
   1656 TEST_F(HttpNetworkTransactionTest, NTLMAuth1) {
   1657   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom1,
   1658                                                          MockGetHostName);
   1659   SessionDependencies session_deps;
   1660   scoped_ptr<HttpTransaction> trans(
   1661       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1662 
   1663   HttpRequestInfo request;
   1664   request.method = "GET";
   1665   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   1666   request.load_flags = 0;
   1667 
   1668   MockWrite data_writes1[] = {
   1669     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1670               "Host: 172.22.68.17\r\n"
   1671               "Connection: keep-alive\r\n\r\n"),
   1672   };
   1673 
   1674   MockRead data_reads1[] = {
   1675     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1676     // Negotiate and NTLM are often requested together.  We only support NTLM.
   1677     MockRead("WWW-Authenticate: Negotiate\r\n"),
   1678     MockRead("WWW-Authenticate: NTLM\r\n"),
   1679     MockRead("Connection: close\r\n"),
   1680     MockRead("Content-Length: 42\r\n"),
   1681     MockRead("Content-Type: text/html\r\n\r\n"),
   1682     // Missing content -- won't matter, as connection will be reset.
   1683     MockRead(false, ERR_UNEXPECTED),
   1684   };
   1685 
   1686   MockWrite data_writes2[] = {
   1687     // After restarting with a null identity, this is the
   1688     // request we should be issuing -- the final header line contains a Type
   1689     // 1 message.
   1690     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1691               "Host: 172.22.68.17\r\n"
   1692               "Connection: keep-alive\r\n"
   1693               "Authorization: NTLM "
   1694               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   1695 
   1696     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   1697     // (the credentials for the origin server).  The second request continues
   1698     // on the same connection.
   1699     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1700               "Host: 172.22.68.17\r\n"
   1701               "Connection: keep-alive\r\n"
   1702               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   1703               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   1704               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBVKW"
   1705               "Yma5xzVAAAAAAAAAAAAAAAAAAAAACH+gWcm+YsP9Tqb9zCR3WAeZZX"
   1706               "ahlhx5I=\r\n\r\n"),
   1707   };
   1708 
   1709   MockRead data_reads2[] = {
   1710     // The origin server responds with a Type 2 message.
   1711     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1712     MockRead("WWW-Authenticate: NTLM "
   1713              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCjGpMpPGlYKkAAAAAAAAAALo"
   1714              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   1715              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   1716              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   1717              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   1718              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   1719              "BtAAAAAAA=\r\n"),
   1720     MockRead("Content-Length: 42\r\n"),
   1721     MockRead("Content-Type: text/html\r\n\r\n"),
   1722     MockRead("You are not authorized to view this page\r\n"),
   1723 
   1724     // Lastly we get the desired content.
   1725     MockRead("HTTP/1.1 200 OK\r\n"),
   1726     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   1727     MockRead("Content-Length: 13\r\n\r\n"),
   1728     MockRead("Please Login\r\n"),
   1729     MockRead(false, OK),
   1730   };
   1731 
   1732   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1733   StaticSocketDataProvider data2(data_reads2, data_writes2);
   1734   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1735   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1736 
   1737   TestCompletionCallback callback1;
   1738 
   1739   int rv = trans->Start(&request, &callback1, NULL);
   1740   EXPECT_EQ(ERR_IO_PENDING, rv);
   1741 
   1742   rv = callback1.WaitForResult();
   1743   EXPECT_EQ(OK, rv);
   1744 
   1745   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   1746   TestCompletionCallback callback2;
   1747   rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   1748   EXPECT_EQ(ERR_IO_PENDING, rv);
   1749   rv = callback2.WaitForResult();
   1750   EXPECT_EQ(OK, rv);
   1751   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   1752 
   1753   const HttpResponseInfo* response = trans->GetResponseInfo();
   1754   EXPECT_FALSE(response == NULL);
   1755 
   1756   // The password prompt info should have been set in response->auth_challenge.
   1757   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1758 
   1759   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   1760   EXPECT_EQ(L"", response->auth_challenge->realm);
   1761   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   1762 
   1763   TestCompletionCallback callback3;
   1764 
   1765   rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback3);
   1766   EXPECT_EQ(ERR_IO_PENDING, rv);
   1767 
   1768   rv = callback3.WaitForResult();
   1769   EXPECT_EQ(OK, rv);
   1770 
   1771   response = trans->GetResponseInfo();
   1772   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1773   EXPECT_EQ(13, response->headers->GetContentLength());
   1774 }
   1775 
   1776 // Enter a wrong password, and then the correct one.
   1777 TEST_F(HttpNetworkTransactionTest, NTLMAuth2) {
   1778   HttpAuthHandlerNTLM::ScopedProcSetter proc_setter(MockGenerateRandom2,
   1779                                                          MockGetHostName);
   1780   SessionDependencies session_deps;
   1781   scoped_ptr<HttpTransaction> trans(
   1782       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1783 
   1784   HttpRequestInfo request;
   1785   request.method = "GET";
   1786   request.url = GURL("http://172.22.68.17/kids/login.aspx");
   1787   request.load_flags = 0;
   1788 
   1789   MockWrite data_writes1[] = {
   1790     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1791               "Host: 172.22.68.17\r\n"
   1792               "Connection: keep-alive\r\n\r\n"),
   1793   };
   1794 
   1795   MockRead data_reads1[] = {
   1796     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1797     // Negotiate and NTLM are often requested together.  We only support NTLM.
   1798     MockRead("WWW-Authenticate: Negotiate\r\n"),
   1799     MockRead("WWW-Authenticate: NTLM\r\n"),
   1800     MockRead("Connection: close\r\n"),
   1801     MockRead("Content-Length: 42\r\n"),
   1802     MockRead("Content-Type: text/html\r\n\r\n"),
   1803     // Missing content -- won't matter, as connection will be reset.
   1804     MockRead(false, ERR_UNEXPECTED),
   1805   };
   1806 
   1807   MockWrite data_writes2[] = {
   1808     // After restarting with a null identity, this is the
   1809     // request we should be issuing -- the final header line contains a Type
   1810     // 1 message.
   1811     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1812               "Host: 172.22.68.17\r\n"
   1813               "Connection: keep-alive\r\n"
   1814               "Authorization: NTLM "
   1815               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   1816 
   1817     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   1818     // (the credentials for the origin server).  The second request continues
   1819     // on the same connection.
   1820     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1821               "Host: 172.22.68.17\r\n"
   1822               "Connection: keep-alive\r\n"
   1823               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   1824               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   1825               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwCWeY"
   1826               "XnSZNwoQAAAAAAAAAAAAAAAAAAAADLa34/phTTKzNTWdub+uyFleOj"
   1827               "4Ww7b7E=\r\n\r\n"),
   1828   };
   1829 
   1830   MockRead data_reads2[] = {
   1831     // The origin server responds with a Type 2 message.
   1832     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1833     MockRead("WWW-Authenticate: NTLM "
   1834              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCbVWUZezVGpAAAAAAAAAAALo"
   1835              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   1836              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   1837              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   1838              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   1839              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   1840              "BtAAAAAAA=\r\n"),
   1841     MockRead("Content-Length: 42\r\n"),
   1842     MockRead("Content-Type: text/html\r\n\r\n"),
   1843     MockRead("You are not authorized to view this page\r\n"),
   1844 
   1845     // Wrong password.
   1846     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1847     MockRead("WWW-Authenticate: Negotiate\r\n"),
   1848     MockRead("WWW-Authenticate: NTLM\r\n"),
   1849     MockRead("Connection: close\r\n"),
   1850     MockRead("Content-Length: 42\r\n"),
   1851     MockRead("Content-Type: text/html\r\n\r\n"),
   1852     // Missing content -- won't matter, as connection will be reset.
   1853     MockRead(false, ERR_UNEXPECTED),
   1854   };
   1855 
   1856   MockWrite data_writes3[] = {
   1857     // After restarting with a null identity, this is the
   1858     // request we should be issuing -- the final header line contains a Type
   1859     // 1 message.
   1860     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1861               "Host: 172.22.68.17\r\n"
   1862               "Connection: keep-alive\r\n"
   1863               "Authorization: NTLM "
   1864               "TlRMTVNTUAABAAAAB4IIAAAAAAAAAAAAAAAAAAAAAAA=\r\n\r\n"),
   1865 
   1866     // After calling trans->RestartWithAuth(), we should send a Type 3 message
   1867     // (the credentials for the origin server).  The second request continues
   1868     // on the same connection.
   1869     MockWrite("GET /kids/login.aspx HTTP/1.1\r\n"
   1870               "Host: 172.22.68.17\r\n"
   1871               "Connection: keep-alive\r\n"
   1872               "Authorization: NTLM TlRMTVNTUAADAAAAGAAYAGgAAAAYABgAgA"
   1873               "AAAAAAAABAAAAAGAAYAEAAAAAQABAAWAAAAAAAAAAAAAAABYIIAHQA"
   1874               "ZQBzAHQAaQBuAGcALQBuAHQAbABtAFcAVABDAC0AVwBJAE4ANwBO54"
   1875               "dFMVvTHwAAAAAAAAAAAAAAAAAAAACS7sT6Uzw7L0L//WUqlIaVWpbI"
   1876               "+4MUm7c=\r\n\r\n"),
   1877   };
   1878 
   1879   MockRead data_reads3[] = {
   1880     // The origin server responds with a Type 2 message.
   1881     MockRead("HTTP/1.1 401 Access Denied\r\n"),
   1882     MockRead("WWW-Authenticate: NTLM "
   1883              "TlRMTVNTUAACAAAADAAMADgAAAAFgokCL24VN8dgOR8AAAAAAAAAALo"
   1884              "AugBEAAAABQEoCgAAAA9HAE8ATwBHAEwARQACAAwARwBPAE8ARwBMAE"
   1885              "UAAQAaAEEASwBFAEUAUwBBAFIAQQAtAEMATwBSAFAABAAeAGMAbwByA"
   1886              "HAALgBnAG8AbwBnAGwAZQAuAGMAbwBtAAMAQABhAGsAZQBlAHMAYQBy"
   1887              "AGEALQBjAG8AcgBwAC4AYQBkAC4AYwBvAHIAcAAuAGcAbwBvAGcAbAB"
   1888              "lAC4AYwBvAG0ABQAeAGMAbwByAHAALgBnAG8AbwBnAGwAZQAuAGMAbw"
   1889              "BtAAAAAAA=\r\n"),
   1890     MockRead("Content-Length: 42\r\n"),
   1891     MockRead("Content-Type: text/html\r\n\r\n"),
   1892     MockRead("You are not authorized to view this page\r\n"),
   1893 
   1894     // Lastly we get the desired content.
   1895     MockRead("HTTP/1.1 200 OK\r\n"),
   1896     MockRead("Content-Type: text/html; charset=utf-8\r\n"),
   1897     MockRead("Content-Length: 13\r\n\r\n"),
   1898     MockRead("Please Login\r\n"),
   1899     MockRead(false, OK),
   1900   };
   1901 
   1902   StaticSocketDataProvider data1(data_reads1, data_writes1);
   1903   StaticSocketDataProvider data2(data_reads2, data_writes2);
   1904   StaticSocketDataProvider data3(data_reads3, data_writes3);
   1905   session_deps.socket_factory.AddSocketDataProvider(&data1);
   1906   session_deps.socket_factory.AddSocketDataProvider(&data2);
   1907   session_deps.socket_factory.AddSocketDataProvider(&data3);
   1908 
   1909   TestCompletionCallback callback1;
   1910 
   1911   int rv = trans->Start(&request, &callback1, NULL);
   1912   EXPECT_EQ(ERR_IO_PENDING, rv);
   1913 
   1914   rv = callback1.WaitForResult();
   1915   EXPECT_EQ(OK, rv);
   1916 
   1917   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   1918   TestCompletionCallback callback2;
   1919   rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   1920   EXPECT_EQ(ERR_IO_PENDING, rv);
   1921   rv = callback2.WaitForResult();
   1922   EXPECT_EQ(OK, rv);
   1923   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   1924 
   1925   const HttpResponseInfo* response = trans->GetResponseInfo();
   1926   EXPECT_FALSE(response == NULL);
   1927 
   1928   // The password prompt info should have been set in response->auth_challenge.
   1929   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1930 
   1931   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   1932   EXPECT_EQ(L"", response->auth_challenge->realm);
   1933   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   1934 
   1935   TestCompletionCallback callback3;
   1936 
   1937   // Enter the wrong password.
   1938   rv = trans->RestartWithAuth(L"testing-ntlm", L"wrongpassword", &callback3);
   1939   EXPECT_EQ(ERR_IO_PENDING, rv);
   1940 
   1941   rv = callback3.WaitForResult();
   1942   EXPECT_EQ(OK, rv);
   1943 
   1944   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   1945   TestCompletionCallback callback4;
   1946   rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback4);
   1947   EXPECT_EQ(ERR_IO_PENDING, rv);
   1948   rv = callback4.WaitForResult();
   1949   EXPECT_EQ(OK, rv);
   1950   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   1951 
   1952   response = trans->GetResponseInfo();
   1953   EXPECT_FALSE(response == NULL);
   1954 
   1955   // The password prompt info should have been set in response->auth_challenge.
   1956   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   1957 
   1958   EXPECT_EQ(L"172.22.68.17:80", response->auth_challenge->host_and_port);
   1959   EXPECT_EQ(L"", response->auth_challenge->realm);
   1960   EXPECT_EQ(L"ntlm", response->auth_challenge->scheme);
   1961 
   1962   TestCompletionCallback callback5;
   1963 
   1964   // Now enter the right password.
   1965   rv = trans->RestartWithAuth(L"testing-ntlm", L"testing-ntlm", &callback5);
   1966   EXPECT_EQ(ERR_IO_PENDING, rv);
   1967 
   1968   rv = callback5.WaitForResult();
   1969   EXPECT_EQ(OK, rv);
   1970 
   1971   response = trans->GetResponseInfo();
   1972   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   1973   EXPECT_EQ(13, response->headers->GetContentLength());
   1974 }
   1975 #endif  // NTLM_PORTABLE
   1976 
   1977 // Test reading a server response which has only headers, and no body.
   1978 // After some maximum number of bytes is consumed, the transaction should
   1979 // fail with ERR_RESPONSE_HEADERS_TOO_BIG.
   1980 TEST_F(HttpNetworkTransactionTest, LargeHeadersNoBody) {
   1981   SessionDependencies session_deps;
   1982   scoped_ptr<HttpTransaction> trans(
   1983       new HttpNetworkTransaction(CreateSession(&session_deps)));
   1984 
   1985   HttpRequestInfo request;
   1986   request.method = "GET";
   1987   request.url = GURL("http://www.google.com/");
   1988   request.load_flags = 0;
   1989 
   1990   // Respond with 300 kb of headers (we should fail after 256 kb).
   1991   std::string large_headers_string;
   1992   FillLargeHeadersString(&large_headers_string, 300 * 1024);
   1993 
   1994   MockRead data_reads[] = {
   1995     MockRead("HTTP/1.0 200 OK\r\n"),
   1996     MockRead(true, large_headers_string.data(), large_headers_string.size()),
   1997     MockRead("\r\nBODY"),
   1998     MockRead(false, OK),
   1999   };
   2000   StaticSocketDataProvider data(data_reads, NULL);
   2001   session_deps.socket_factory.AddSocketDataProvider(&data);
   2002 
   2003   TestCompletionCallback callback;
   2004 
   2005   int rv = trans->Start(&request, &callback, NULL);
   2006   EXPECT_EQ(ERR_IO_PENDING, rv);
   2007 
   2008   rv = callback.WaitForResult();
   2009   EXPECT_EQ(ERR_RESPONSE_HEADERS_TOO_BIG, rv);
   2010 
   2011   const HttpResponseInfo* response = trans->GetResponseInfo();
   2012   EXPECT_TRUE(response == NULL);
   2013 }
   2014 
   2015 // Make sure that we don't try to reuse a TCPClientSocket when failing to
   2016 // establish tunnel.
   2017 // http://code.google.com/p/chromium/issues/detail?id=3772
   2018 TEST_F(HttpNetworkTransactionTest, DontRecycleTCPSocketForSSLTunnel) {
   2019   // Configure against proxy server "myproxy:70".
   2020   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   2021 
   2022   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2023 
   2024   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2025 
   2026   HttpRequestInfo request;
   2027   request.method = "GET";
   2028   request.url = GURL("https://www.google.com/");
   2029   request.load_flags = 0;
   2030 
   2031   // Since we have proxy, should try to establish tunnel.
   2032   MockWrite data_writes1[] = {
   2033     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2034               "Host: www.google.com\r\n"
   2035               "Proxy-Connection: keep-alive\r\n\r\n"),
   2036   };
   2037 
   2038   // The proxy responds to the connect with a 404, using a persistent
   2039   // connection. Usually a proxy would return 501 (not implemented),
   2040   // or 200 (tunnel established).
   2041   MockRead data_reads1[] = {
   2042     MockRead("HTTP/1.1 404 Not Found\r\n"),
   2043     MockRead("Content-Length: 10\r\n\r\n"),
   2044     MockRead(false, ERR_UNEXPECTED),  // Should not be reached.
   2045   };
   2046 
   2047   StaticSocketDataProvider data1(data_reads1, data_writes1);
   2048   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2049 
   2050   TestCompletionCallback callback1;
   2051 
   2052   int rv = trans->Start(&request, &callback1, NULL);
   2053   EXPECT_EQ(ERR_IO_PENDING, rv);
   2054 
   2055   rv = callback1.WaitForResult();
   2056   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   2057 
   2058   const HttpResponseInfo* response = trans->GetResponseInfo();
   2059   EXPECT_TRUE(response == NULL);
   2060 
   2061   // Empty the current queue.  This is necessary because idle sockets are
   2062   // added to the connection pool asynchronously with a PostTask.
   2063   MessageLoop::current()->RunAllPending();
   2064 
   2065   // We now check to make sure the TCPClientSocket was not added back to
   2066   // the pool.
   2067   EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
   2068   trans.reset();
   2069   MessageLoop::current()->RunAllPending();
   2070   // Make sure that the socket didn't get recycled after calling the destructor.
   2071   EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
   2072 }
   2073 
   2074 // Make sure that we recycle a socket after reading all of the response body.
   2075 TEST_F(HttpNetworkTransactionTest, RecycleSocket) {
   2076   SessionDependencies session_deps;
   2077   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2078 
   2079   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2080 
   2081   HttpRequestInfo request;
   2082   request.method = "GET";
   2083   request.url = GURL("http://www.google.com/");
   2084   request.load_flags = 0;
   2085 
   2086   MockRead data_reads[] = {
   2087     // A part of the response body is received with the response headers.
   2088     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\nhel"),
   2089     // The rest of the response body is received in two parts.
   2090     MockRead("lo"),
   2091     MockRead(" world"),
   2092     MockRead("junk"),  // Should not be read!!
   2093     MockRead(false, OK),
   2094   };
   2095 
   2096   StaticSocketDataProvider data(data_reads, NULL);
   2097   session_deps.socket_factory.AddSocketDataProvider(&data);
   2098 
   2099   TestCompletionCallback callback;
   2100 
   2101   int rv = trans->Start(&request, &callback, NULL);
   2102   EXPECT_EQ(ERR_IO_PENDING, rv);
   2103 
   2104   rv = callback.WaitForResult();
   2105   EXPECT_EQ(OK, rv);
   2106 
   2107   const HttpResponseInfo* response = trans->GetResponseInfo();
   2108   EXPECT_TRUE(response != NULL);
   2109 
   2110   EXPECT_TRUE(response->headers != NULL);
   2111   std::string status_line = response->headers->GetStatusLine();
   2112   EXPECT_EQ("HTTP/1.1 200 OK", status_line);
   2113 
   2114   EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
   2115 
   2116   std::string response_data;
   2117   rv = ReadTransaction(trans.get(), &response_data);
   2118   EXPECT_EQ(OK, rv);
   2119   EXPECT_EQ("hello world", response_data);
   2120 
   2121   // Empty the current queue.  This is necessary because idle sockets are
   2122   // added to the connection pool asynchronously with a PostTask.
   2123   MessageLoop::current()->RunAllPending();
   2124 
   2125   // We now check to make sure the socket was added back to the pool.
   2126   EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount());
   2127 }
   2128 
   2129 // Make sure that we recycle a socket after a zero-length response.
   2130 // http://crbug.com/9880
   2131 TEST_F(HttpNetworkTransactionTest, RecycleSocketAfterZeroContentLength) {
   2132   SessionDependencies session_deps;
   2133   scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   2134 
   2135   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2136 
   2137   HttpRequestInfo request;
   2138   request.method = "GET";
   2139   request.url = GURL("http://www.google.com/csi?v=3&s=web&action=&"
   2140                      "tran=undefined&ei=mAXcSeegAo-SMurloeUN&"
   2141                      "e=17259,18167,19592,19773,19981,20133,20173,20233&"
   2142                      "rt=prt.2642,ol.2649,xjs.2951");
   2143   request.load_flags = 0;
   2144 
   2145   MockRead data_reads[] = {
   2146     MockRead("HTTP/1.1 204 No Content\r\n"
   2147              "Content-Length: 0\r\n"
   2148              "Content-Type: text/html\r\n\r\n"),
   2149     MockRead("junk"),  // Should not be read!!
   2150     MockRead(false, OK),
   2151   };
   2152 
   2153   StaticSocketDataProvider data(data_reads, NULL);
   2154   session_deps.socket_factory.AddSocketDataProvider(&data);
   2155 
   2156   TestCompletionCallback callback;
   2157 
   2158   int rv = trans->Start(&request, &callback, NULL);
   2159   EXPECT_EQ(ERR_IO_PENDING, rv);
   2160 
   2161   rv = callback.WaitForResult();
   2162   EXPECT_EQ(OK, rv);
   2163 
   2164   const HttpResponseInfo* response = trans->GetResponseInfo();
   2165   EXPECT_TRUE(response != NULL);
   2166 
   2167   EXPECT_TRUE(response->headers != NULL);
   2168   std::string status_line = response->headers->GetStatusLine();
   2169   EXPECT_EQ("HTTP/1.1 204 No Content", status_line);
   2170 
   2171   EXPECT_EQ(0, session->tcp_socket_pool()->IdleSocketCount());
   2172 
   2173   std::string response_data;
   2174   rv = ReadTransaction(trans.get(), &response_data);
   2175   EXPECT_EQ(OK, rv);
   2176   EXPECT_EQ("", response_data);
   2177 
   2178   // Empty the current queue.  This is necessary because idle sockets are
   2179   // added to the connection pool asynchronously with a PostTask.
   2180   MessageLoop::current()->RunAllPending();
   2181 
   2182   // We now check to make sure the socket was added back to the pool.
   2183   EXPECT_EQ(1, session->tcp_socket_pool()->IdleSocketCount());
   2184 }
   2185 
   2186 TEST_F(HttpNetworkTransactionTest, ResendRequestOnWriteBodyError) {
   2187   HttpRequestInfo request[2];
   2188   // Transaction 1: a GET request that succeeds.  The socket is recycled
   2189   // after use.
   2190   request[0].method = "GET";
   2191   request[0].url = GURL("http://www.google.com/");
   2192   request[0].load_flags = 0;
   2193   // Transaction 2: a POST request.  Reuses the socket kept alive from
   2194   // transaction 1.  The first attempts fails when writing the POST data.
   2195   // This causes the transaction to retry with a new socket.  The second
   2196   // attempt succeeds.
   2197   request[1].method = "POST";
   2198   request[1].url = GURL("http://www.google.com/login.cgi");
   2199   request[1].upload_data = new UploadData;
   2200   request[1].upload_data->AppendBytes("foo", 3);
   2201   request[1].load_flags = 0;
   2202 
   2203   SessionDependencies session_deps;
   2204   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
   2205 
   2206   // The first socket is used for transaction 1 and the first attempt of
   2207   // transaction 2.
   2208 
   2209   // The response of transaction 1.
   2210   MockRead data_reads1[] = {
   2211     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 11\r\n\r\n"),
   2212     MockRead("hello world"),
   2213     MockRead(false, OK),
   2214   };
   2215   // The mock write results of transaction 1 and the first attempt of
   2216   // transaction 2.
   2217   MockWrite data_writes1[] = {
   2218     MockWrite(false, 64),  // GET
   2219     MockWrite(false, 93),  // POST
   2220     MockWrite(false, ERR_CONNECTION_ABORTED),  // POST data
   2221   };
   2222   StaticSocketDataProvider data1(data_reads1, data_writes1);
   2223 
   2224   // The second socket is used for the second attempt of transaction 2.
   2225 
   2226   // The response of transaction 2.
   2227   MockRead data_reads2[] = {
   2228     MockRead("HTTP/1.1 200 OK\r\nContent-Length: 7\r\n\r\n"),
   2229     MockRead("welcome"),
   2230     MockRead(false, OK),
   2231   };
   2232   // The mock write results of the second attempt of transaction 2.
   2233   MockWrite data_writes2[] = {
   2234     MockWrite(false, 93),  // POST
   2235     MockWrite(false, 3),  // POST data
   2236   };
   2237   StaticSocketDataProvider data2(data_reads2, data_writes2);
   2238 
   2239   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2240   session_deps.socket_factory.AddSocketDataProvider(&data2);
   2241 
   2242   const char* kExpectedResponseData[] = {
   2243     "hello world", "welcome"
   2244   };
   2245 
   2246   for (int i = 0; i < 2; ++i) {
   2247     scoped_ptr<HttpTransaction> trans(
   2248         new HttpNetworkTransaction(session));
   2249 
   2250     TestCompletionCallback callback;
   2251 
   2252     int rv = trans->Start(&request[i], &callback, NULL);
   2253     EXPECT_EQ(ERR_IO_PENDING, rv);
   2254 
   2255     rv = callback.WaitForResult();
   2256     EXPECT_EQ(OK, rv);
   2257 
   2258     const HttpResponseInfo* response = trans->GetResponseInfo();
   2259     EXPECT_TRUE(response != NULL);
   2260 
   2261     EXPECT_TRUE(response->headers != NULL);
   2262     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
   2263 
   2264     std::string response_data;
   2265     rv = ReadTransaction(trans.get(), &response_data);
   2266     EXPECT_EQ(OK, rv);
   2267     EXPECT_EQ(kExpectedResponseData[i], response_data);
   2268   }
   2269 }
   2270 
   2271 // Test the request-challenge-retry sequence for basic auth when there is
   2272 // an identity in the URL. The request should be sent as normal, but when
   2273 // it fails the identity from the URL is used to answer the challenge.
   2274 TEST_F(HttpNetworkTransactionTest, AuthIdentityInURL) {
   2275   SessionDependencies session_deps;
   2276   scoped_ptr<HttpTransaction> trans(
   2277       new HttpNetworkTransaction(CreateSession(&session_deps)));
   2278 
   2279   HttpRequestInfo request;
   2280   request.method = "GET";
   2281   // Note: the URL has a username:password in it.
   2282   request.url = GURL("http://foo:b@r@www.google.com/");
   2283 
   2284   // The password contains an escaped character -- for this test to pass it
   2285   // will need to be unescaped by HttpNetworkTransaction.
   2286   EXPECT_EQ("b%40r", request.url.password());
   2287 
   2288   request.load_flags = LOAD_NORMAL;
   2289 
   2290   MockWrite data_writes1[] = {
   2291     MockWrite("GET / HTTP/1.1\r\n"
   2292               "Host: www.google.com\r\n"
   2293               "Connection: keep-alive\r\n\r\n"),
   2294   };
   2295 
   2296   MockRead data_reads1[] = {
   2297     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2298     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2299     MockRead("Content-Length: 10\r\n\r\n"),
   2300     MockRead(false, ERR_FAILED),
   2301   };
   2302 
   2303   // After the challenge above, the transaction will be restarted using the
   2304   // identity from the url (foo, b@r) to answer the challenge.
   2305   MockWrite data_writes2[] = {
   2306     MockWrite("GET / HTTP/1.1\r\n"
   2307               "Host: www.google.com\r\n"
   2308               "Connection: keep-alive\r\n"
   2309               "Authorization: Basic Zm9vOmJAcg==\r\n\r\n"),
   2310   };
   2311 
   2312   MockRead data_reads2[] = {
   2313     MockRead("HTTP/1.0 200 OK\r\n"),
   2314     MockRead("Content-Length: 100\r\n\r\n"),
   2315     MockRead(false, OK),
   2316   };
   2317 
   2318   StaticSocketDataProvider data1(data_reads1, data_writes1);
   2319   StaticSocketDataProvider data2(data_reads2, data_writes2);
   2320   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2321   session_deps.socket_factory.AddSocketDataProvider(&data2);
   2322 
   2323   TestCompletionCallback callback1;
   2324 
   2325   int rv = trans->Start(&request, &callback1, NULL);
   2326   EXPECT_EQ(ERR_IO_PENDING, rv);
   2327 
   2328   rv = callback1.WaitForResult();
   2329   EXPECT_EQ(OK, rv);
   2330 
   2331   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   2332   TestCompletionCallback callback2;
   2333   rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   2334   EXPECT_EQ(ERR_IO_PENDING, rv);
   2335   rv = callback2.WaitForResult();
   2336   EXPECT_EQ(OK, rv);
   2337   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2338 
   2339   const HttpResponseInfo* response = trans->GetResponseInfo();
   2340   EXPECT_FALSE(response == NULL);
   2341 
   2342   // There is no challenge info, since the identity in URL worked.
   2343   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2344 
   2345   EXPECT_EQ(100, response->headers->GetContentLength());
   2346 
   2347   // Empty the current queue.
   2348   MessageLoop::current()->RunAllPending();
   2349 }
   2350 
   2351 // Test the request-challenge-retry sequence for basic auth when there is
   2352 // an incorrect identity in the URL. The identity from the URL should be used
   2353 // only once.
   2354 TEST_F(HttpNetworkTransactionTest, WrongAuthIdentityInURL) {
   2355   SessionDependencies session_deps;
   2356   scoped_ptr<HttpTransaction> trans(
   2357       new HttpNetworkTransaction(CreateSession(&session_deps)));
   2358 
   2359   HttpRequestInfo request;
   2360   request.method = "GET";
   2361   // Note: the URL has a username:password in it.  The password "baz" is
   2362   // wrong (should be "bar").
   2363   request.url = GURL("http://foo:baz@www.google.com/");
   2364 
   2365   request.load_flags = LOAD_NORMAL;
   2366 
   2367   MockWrite data_writes1[] = {
   2368     MockWrite("GET / HTTP/1.1\r\n"
   2369               "Host: www.google.com\r\n"
   2370               "Connection: keep-alive\r\n\r\n"),
   2371   };
   2372 
   2373   MockRead data_reads1[] = {
   2374     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2375     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2376     MockRead("Content-Length: 10\r\n\r\n"),
   2377     MockRead(false, ERR_FAILED),
   2378   };
   2379 
   2380   // After the challenge above, the transaction will be restarted using the
   2381   // identity from the url (foo, baz) to answer the challenge.
   2382   MockWrite data_writes2[] = {
   2383     MockWrite("GET / HTTP/1.1\r\n"
   2384               "Host: www.google.com\r\n"
   2385               "Connection: keep-alive\r\n"
   2386               "Authorization: Basic Zm9vOmJheg==\r\n\r\n"),
   2387   };
   2388 
   2389   MockRead data_reads2[] = {
   2390     MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2391     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2392     MockRead("Content-Length: 10\r\n\r\n"),
   2393     MockRead(false, ERR_FAILED),
   2394   };
   2395 
   2396   // After the challenge above, the transaction will be restarted using the
   2397   // identity supplied by the user (foo, bar) to answer the challenge.
   2398   MockWrite data_writes3[] = {
   2399     MockWrite("GET / HTTP/1.1\r\n"
   2400               "Host: www.google.com\r\n"
   2401               "Connection: keep-alive\r\n"
   2402               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2403   };
   2404 
   2405   MockRead data_reads3[] = {
   2406     MockRead("HTTP/1.0 200 OK\r\n"),
   2407     MockRead("Content-Length: 100\r\n\r\n"),
   2408     MockRead(false, OK),
   2409   };
   2410 
   2411   StaticSocketDataProvider data1(data_reads1, data_writes1);
   2412   StaticSocketDataProvider data2(data_reads2, data_writes2);
   2413   StaticSocketDataProvider data3(data_reads3, data_writes3);
   2414   session_deps.socket_factory.AddSocketDataProvider(&data1);
   2415   session_deps.socket_factory.AddSocketDataProvider(&data2);
   2416   session_deps.socket_factory.AddSocketDataProvider(&data3);
   2417 
   2418   TestCompletionCallback callback1;
   2419 
   2420   int rv = trans->Start(&request, &callback1, NULL);
   2421   EXPECT_EQ(ERR_IO_PENDING, rv);
   2422 
   2423   rv = callback1.WaitForResult();
   2424   EXPECT_EQ(OK, rv);
   2425 
   2426   EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   2427   TestCompletionCallback callback2;
   2428   rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   2429   EXPECT_EQ(ERR_IO_PENDING, rv);
   2430   rv = callback2.WaitForResult();
   2431   EXPECT_EQ(OK, rv);
   2432   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2433 
   2434   const HttpResponseInfo* response = trans->GetResponseInfo();
   2435   EXPECT_FALSE(response == NULL);
   2436   // The password prompt info should have been set in response->auth_challenge.
   2437   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2438 
   2439   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   2440   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2441   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2442 
   2443   TestCompletionCallback callback3;
   2444   rv = trans->RestartWithAuth(L"foo", L"bar", &callback3);
   2445   EXPECT_EQ(ERR_IO_PENDING, rv);
   2446   rv = callback3.WaitForResult();
   2447   EXPECT_EQ(OK, rv);
   2448   EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2449 
   2450   response = trans->GetResponseInfo();
   2451   EXPECT_FALSE(response == NULL);
   2452 
   2453   // There is no challenge info, since the identity worked.
   2454   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2455 
   2456   EXPECT_EQ(100, response->headers->GetContentLength());
   2457 
   2458   // Empty the current queue.
   2459   MessageLoop::current()->RunAllPending();
   2460 }
   2461 
   2462 // Test that previously tried username/passwords for a realm get re-used.
   2463 TEST_F(HttpNetworkTransactionTest, BasicAuthCacheAndPreauth) {
   2464   SessionDependencies session_deps;
   2465   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
   2466 
   2467   // Transaction 1: authenticate (foo, bar) on MyRealm1
   2468   {
   2469     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2470 
   2471     HttpRequestInfo request;
   2472     request.method = "GET";
   2473     request.url = GURL("http://www.google.com/x/y/z");
   2474     request.load_flags = 0;
   2475 
   2476     MockWrite data_writes1[] = {
   2477       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   2478                 "Host: www.google.com\r\n"
   2479                 "Connection: keep-alive\r\n\r\n"),
   2480     };
   2481 
   2482     MockRead data_reads1[] = {
   2483       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2484       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2485       MockRead("Content-Length: 10000\r\n\r\n"),
   2486       MockRead(false, ERR_FAILED),
   2487     };
   2488 
   2489     // Resend with authorization (username=foo, password=bar)
   2490     MockWrite data_writes2[] = {
   2491       MockWrite("GET /x/y/z HTTP/1.1\r\n"
   2492                 "Host: www.google.com\r\n"
   2493                 "Connection: keep-alive\r\n"
   2494                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2495     };
   2496 
   2497     // Sever accepts the authorization.
   2498     MockRead data_reads2[] = {
   2499       MockRead("HTTP/1.0 200 OK\r\n"),
   2500       MockRead("Content-Length: 100\r\n\r\n"),
   2501       MockRead(false, OK),
   2502     };
   2503 
   2504     StaticSocketDataProvider data1(data_reads1, data_writes1);
   2505     StaticSocketDataProvider data2(data_reads2, data_writes2);
   2506     session_deps.socket_factory.AddSocketDataProvider(&data1);
   2507     session_deps.socket_factory.AddSocketDataProvider(&data2);
   2508 
   2509     TestCompletionCallback callback1;
   2510 
   2511     int rv = trans->Start(&request, &callback1, NULL);
   2512     EXPECT_EQ(ERR_IO_PENDING, rv);
   2513 
   2514     rv = callback1.WaitForResult();
   2515     EXPECT_EQ(OK, rv);
   2516 
   2517     const HttpResponseInfo* response = trans->GetResponseInfo();
   2518     EXPECT_FALSE(response == NULL);
   2519 
   2520     // The password prompt info should have been set in
   2521     // response->auth_challenge.
   2522     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2523 
   2524     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   2525     EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2526     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2527 
   2528     TestCompletionCallback callback2;
   2529 
   2530     rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
   2531     EXPECT_EQ(ERR_IO_PENDING, rv);
   2532 
   2533     rv = callback2.WaitForResult();
   2534     EXPECT_EQ(OK, rv);
   2535 
   2536     response = trans->GetResponseInfo();
   2537     EXPECT_FALSE(response == NULL);
   2538     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2539     EXPECT_EQ(100, response->headers->GetContentLength());
   2540   }
   2541 
   2542   // ------------------------------------------------------------------------
   2543 
   2544   // Transaction 2: authenticate (foo2, bar2) on MyRealm2
   2545   {
   2546     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2547 
   2548     HttpRequestInfo request;
   2549     request.method = "GET";
   2550     // Note that Transaction 1 was at /x/y/z, so this is in the same
   2551     // protection space as MyRealm1.
   2552     request.url = GURL("http://www.google.com/x/y/a/b");
   2553     request.load_flags = 0;
   2554 
   2555     MockWrite data_writes1[] = {
   2556       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   2557                 "Host: www.google.com\r\n"
   2558                 "Connection: keep-alive\r\n"
   2559                 // Send preemptive authorization for MyRealm1
   2560                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2561     };
   2562 
   2563     // The server didn't like the preemptive authorization, and
   2564     // challenges us for a different realm (MyRealm2).
   2565     MockRead data_reads1[] = {
   2566       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2567       MockRead("WWW-Authenticate: Basic realm=\"MyRealm2\"\r\n"),
   2568       MockRead("Content-Length: 10000\r\n\r\n"),
   2569       MockRead(false, ERR_FAILED),
   2570     };
   2571 
   2572     // Resend with authorization for MyRealm2 (username=foo2, password=bar2)
   2573     MockWrite data_writes2[] = {
   2574       MockWrite("GET /x/y/a/b HTTP/1.1\r\n"
   2575                 "Host: www.google.com\r\n"
   2576                 "Connection: keep-alive\r\n"
   2577                 "Authorization: Basic Zm9vMjpiYXIy\r\n\r\n"),
   2578     };
   2579 
   2580     // Sever accepts the authorization.
   2581     MockRead data_reads2[] = {
   2582       MockRead("HTTP/1.0 200 OK\r\n"),
   2583       MockRead("Content-Length: 100\r\n\r\n"),
   2584       MockRead(false, OK),
   2585     };
   2586 
   2587     StaticSocketDataProvider data1(data_reads1, data_writes1);
   2588     StaticSocketDataProvider data2(data_reads2, data_writes2);
   2589     session_deps.socket_factory.AddSocketDataProvider(&data1);
   2590     session_deps.socket_factory.AddSocketDataProvider(&data2);
   2591 
   2592     TestCompletionCallback callback1;
   2593 
   2594     int rv = trans->Start(&request, &callback1, NULL);
   2595     EXPECT_EQ(ERR_IO_PENDING, rv);
   2596 
   2597     rv = callback1.WaitForResult();
   2598     EXPECT_EQ(OK, rv);
   2599 
   2600     const HttpResponseInfo* response = trans->GetResponseInfo();
   2601     EXPECT_FALSE(response == NULL);
   2602 
   2603     // The password prompt info should have been set in
   2604     // response->auth_challenge.
   2605     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2606 
   2607     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   2608     EXPECT_EQ(L"MyRealm2", response->auth_challenge->realm);
   2609     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2610 
   2611     TestCompletionCallback callback2;
   2612 
   2613     rv = trans->RestartWithAuth(L"foo2", L"bar2", &callback2);
   2614     EXPECT_EQ(ERR_IO_PENDING, rv);
   2615 
   2616     rv = callback2.WaitForResult();
   2617     EXPECT_EQ(OK, rv);
   2618 
   2619     response = trans->GetResponseInfo();
   2620     EXPECT_FALSE(response == NULL);
   2621     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2622     EXPECT_EQ(100, response->headers->GetContentLength());
   2623   }
   2624 
   2625   // ------------------------------------------------------------------------
   2626 
   2627   // Transaction 3: Resend a request in MyRealm's protection space --
   2628   // succeed with preemptive authorization.
   2629   {
   2630     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2631 
   2632     HttpRequestInfo request;
   2633     request.method = "GET";
   2634     request.url = GURL("http://www.google.com/x/y/z2");
   2635     request.load_flags = 0;
   2636 
   2637     MockWrite data_writes1[] = {
   2638       MockWrite("GET /x/y/z2 HTTP/1.1\r\n"
   2639                 "Host: www.google.com\r\n"
   2640                 "Connection: keep-alive\r\n"
   2641                 // The authorization for MyRealm1 gets sent preemptively
   2642                 // (since the url is in the same protection space)
   2643                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2644     };
   2645 
   2646     // Sever accepts the preemptive authorization
   2647     MockRead data_reads1[] = {
   2648       MockRead("HTTP/1.0 200 OK\r\n"),
   2649       MockRead("Content-Length: 100\r\n\r\n"),
   2650       MockRead(false, OK),
   2651     };
   2652 
   2653     StaticSocketDataProvider data1(data_reads1, data_writes1);
   2654     session_deps.socket_factory.AddSocketDataProvider(&data1);
   2655 
   2656     TestCompletionCallback callback1;
   2657 
   2658     int rv = trans->Start(&request, &callback1, NULL);
   2659     EXPECT_EQ(ERR_IO_PENDING, rv);
   2660 
   2661     rv = callback1.WaitForResult();
   2662     EXPECT_EQ(OK, rv);
   2663 
   2664     const HttpResponseInfo* response = trans->GetResponseInfo();
   2665     EXPECT_FALSE(response == NULL);
   2666 
   2667     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2668     EXPECT_EQ(100, response->headers->GetContentLength());
   2669   }
   2670 
   2671   // ------------------------------------------------------------------------
   2672 
   2673   // Transaction 4: request another URL in MyRealm (however the
   2674   // url is not known to belong to the protection space, so no pre-auth).
   2675   {
   2676     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2677 
   2678     HttpRequestInfo request;
   2679     request.method = "GET";
   2680     request.url = GURL("http://www.google.com/x/1");
   2681     request.load_flags = 0;
   2682 
   2683     MockWrite data_writes1[] = {
   2684       MockWrite("GET /x/1 HTTP/1.1\r\n"
   2685                 "Host: www.google.com\r\n"
   2686                 "Connection: keep-alive\r\n\r\n"),
   2687     };
   2688 
   2689     MockRead data_reads1[] = {
   2690       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2691       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2692       MockRead("Content-Length: 10000\r\n\r\n"),
   2693       MockRead(false, ERR_FAILED),
   2694     };
   2695 
   2696     // Resend with authorization from MyRealm's cache.
   2697     MockWrite data_writes2[] = {
   2698       MockWrite("GET /x/1 HTTP/1.1\r\n"
   2699                 "Host: www.google.com\r\n"
   2700                 "Connection: keep-alive\r\n"
   2701                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2702     };
   2703 
   2704     // Sever accepts the authorization.
   2705     MockRead data_reads2[] = {
   2706       MockRead("HTTP/1.0 200 OK\r\n"),
   2707       MockRead("Content-Length: 100\r\n\r\n"),
   2708       MockRead(false, OK),
   2709     };
   2710 
   2711     StaticSocketDataProvider data1(data_reads1, data_writes1);
   2712     StaticSocketDataProvider data2(data_reads2, data_writes2);
   2713     session_deps.socket_factory.AddSocketDataProvider(&data1);
   2714     session_deps.socket_factory.AddSocketDataProvider(&data2);
   2715 
   2716     TestCompletionCallback callback1;
   2717 
   2718     int rv = trans->Start(&request, &callback1, NULL);
   2719     EXPECT_EQ(ERR_IO_PENDING, rv);
   2720 
   2721     rv = callback1.WaitForResult();
   2722     EXPECT_EQ(OK, rv);
   2723 
   2724     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   2725     TestCompletionCallback callback2;
   2726     rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   2727     EXPECT_EQ(ERR_IO_PENDING, rv);
   2728     rv = callback2.WaitForResult();
   2729     EXPECT_EQ(OK, rv);
   2730     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2731 
   2732     const HttpResponseInfo* response = trans->GetResponseInfo();
   2733     EXPECT_FALSE(response == NULL);
   2734     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2735     EXPECT_EQ(100, response->headers->GetContentLength());
   2736   }
   2737 
   2738   // ------------------------------------------------------------------------
   2739 
   2740   // Transaction 5: request a URL in MyRealm, but the server rejects the
   2741   // cached identity. Should invalidate and re-prompt.
   2742   {
   2743     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   2744 
   2745     HttpRequestInfo request;
   2746     request.method = "GET";
   2747     request.url = GURL("http://www.google.com/p/q/t");
   2748     request.load_flags = 0;
   2749 
   2750     MockWrite data_writes1[] = {
   2751       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   2752                 "Host: www.google.com\r\n"
   2753                 "Connection: keep-alive\r\n\r\n"),
   2754     };
   2755 
   2756     MockRead data_reads1[] = {
   2757       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2758       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2759       MockRead("Content-Length: 10000\r\n\r\n"),
   2760       MockRead(false, ERR_FAILED),
   2761     };
   2762 
   2763     // Resend with authorization from cache for MyRealm.
   2764     MockWrite data_writes2[] = {
   2765       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   2766                 "Host: www.google.com\r\n"
   2767                 "Connection: keep-alive\r\n"
   2768                 "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   2769     };
   2770 
   2771     // Sever rejects the authorization.
   2772     MockRead data_reads2[] = {
   2773       MockRead("HTTP/1.0 401 Unauthorized\r\n"),
   2774       MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   2775       MockRead("Content-Length: 10000\r\n\r\n"),
   2776       MockRead(false, ERR_FAILED),
   2777     };
   2778 
   2779     // At this point we should prompt for new credentials for MyRealm.
   2780     // Restart with username=foo3, password=foo4.
   2781     MockWrite data_writes3[] = {
   2782       MockWrite("GET /p/q/t HTTP/1.1\r\n"
   2783                 "Host: www.google.com\r\n"
   2784                 "Connection: keep-alive\r\n"
   2785                 "Authorization: Basic Zm9vMzpiYXIz\r\n\r\n"),
   2786     };
   2787 
   2788     // Sever accepts the authorization.
   2789     MockRead data_reads3[] = {
   2790       MockRead("HTTP/1.0 200 OK\r\n"),
   2791       MockRead("Content-Length: 100\r\n\r\n"),
   2792       MockRead(false, OK),
   2793     };
   2794 
   2795     StaticSocketDataProvider data1(data_reads1, data_writes1);
   2796     StaticSocketDataProvider data2(data_reads2, data_writes2);
   2797     StaticSocketDataProvider data3(data_reads3, data_writes3);
   2798     session_deps.socket_factory.AddSocketDataProvider(&data1);
   2799     session_deps.socket_factory.AddSocketDataProvider(&data2);
   2800     session_deps.socket_factory.AddSocketDataProvider(&data3);
   2801 
   2802     TestCompletionCallback callback1;
   2803 
   2804     int rv = trans->Start(&request, &callback1, NULL);
   2805     EXPECT_EQ(ERR_IO_PENDING, rv);
   2806 
   2807     rv = callback1.WaitForResult();
   2808     EXPECT_EQ(OK, rv);
   2809 
   2810     EXPECT_TRUE(trans->IsReadyToRestartForAuth());
   2811     TestCompletionCallback callback2;
   2812     rv = trans->RestartWithAuth(std::wstring(), std::wstring(), &callback2);
   2813     EXPECT_EQ(ERR_IO_PENDING, rv);
   2814     rv = callback2.WaitForResult();
   2815     EXPECT_EQ(OK, rv);
   2816     EXPECT_FALSE(trans->IsReadyToRestartForAuth());
   2817 
   2818     const HttpResponseInfo* response = trans->GetResponseInfo();
   2819     EXPECT_FALSE(response == NULL);
   2820 
   2821     // The password prompt info should have been set in
   2822     // response->auth_challenge.
   2823     EXPECT_FALSE(response->auth_challenge.get() == NULL);
   2824 
   2825     EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   2826     EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   2827     EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   2828 
   2829     TestCompletionCallback callback3;
   2830 
   2831     rv = trans->RestartWithAuth(L"foo3", L"bar3", &callback3);
   2832     EXPECT_EQ(ERR_IO_PENDING, rv);
   2833 
   2834     rv = callback3.WaitForResult();
   2835     EXPECT_EQ(OK, rv);
   2836 
   2837     response = trans->GetResponseInfo();
   2838     EXPECT_FALSE(response == NULL);
   2839     EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2840     EXPECT_EQ(100, response->headers->GetContentLength());
   2841   }
   2842 }
   2843 
   2844 // Test the ResetStateForRestart() private method.
   2845 TEST_F(HttpNetworkTransactionTest, ResetStateForRestart) {
   2846   // Create a transaction (the dependencies aren't important).
   2847   SessionDependencies session_deps;
   2848   scoped_ptr<HttpNetworkTransaction> trans(
   2849       new HttpNetworkTransaction(CreateSession(&session_deps)));
   2850 
   2851   // Setup some state (which we expect ResetStateForRestart() will clear).
   2852   trans->read_buf_ = new IOBuffer(15);
   2853   trans->read_buf_len_ = 15;
   2854   trans->request_headers_ = "Authorization: NTLM";
   2855 
   2856   // Setup state in response_
   2857   HttpResponseInfo* response = &trans->response_;
   2858   response->auth_challenge = new AuthChallengeInfo();
   2859   response->ssl_info.cert_status = -15;
   2860   response->response_time = base::Time::Now();
   2861   response->was_cached = true;  // (Wouldn't ever actually be true...)
   2862 
   2863   { // Setup state for response_.vary_data
   2864     HttpRequestInfo request;
   2865     std::string temp("HTTP/1.1 200 OK\nVary: foo, bar\n\n");
   2866     std::replace(temp.begin(), temp.end(), '\n', '\0');
   2867     scoped_refptr<HttpResponseHeaders> headers = new HttpResponseHeaders(temp);
   2868     request.extra_headers = "Foo: 1\nbar: 23";
   2869     EXPECT_TRUE(response->vary_data.Init(request, *headers));
   2870   }
   2871 
   2872   // Cause the above state to be reset.
   2873   trans->ResetStateForRestart();
   2874 
   2875   // Verify that the state that needed to be reset, has been reset.
   2876   EXPECT_TRUE(trans->read_buf_.get() == NULL);
   2877   EXPECT_EQ(0, trans->read_buf_len_);
   2878   EXPECT_EQ(0U, trans->request_headers_.size());
   2879   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   2880   EXPECT_TRUE(response->headers.get() == NULL);
   2881   EXPECT_EQ(false, response->was_cached);
   2882   EXPECT_EQ(0, response->ssl_info.cert_status);
   2883   EXPECT_FALSE(response->vary_data.is_valid());
   2884 }
   2885 
   2886 // Test HTTPS connections to a site with a bad certificate
   2887 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificate) {
   2888   SessionDependencies session_deps;
   2889   scoped_ptr<HttpTransaction> trans(
   2890       new HttpNetworkTransaction(CreateSession(&session_deps)));
   2891 
   2892   HttpRequestInfo request;
   2893   request.method = "GET";
   2894   request.url = GURL("https://www.google.com/");
   2895   request.load_flags = 0;
   2896 
   2897   MockWrite data_writes[] = {
   2898     MockWrite("GET / HTTP/1.1\r\n"
   2899               "Host: www.google.com\r\n"
   2900               "Connection: keep-alive\r\n\r\n"),
   2901   };
   2902 
   2903   MockRead data_reads[] = {
   2904     MockRead("HTTP/1.0 200 OK\r\n"),
   2905     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2906     MockRead("Content-Length: 100\r\n\r\n"),
   2907     MockRead(false, OK),
   2908   };
   2909 
   2910   StaticSocketDataProvider ssl_bad_certificate;
   2911   StaticSocketDataProvider data(data_reads, data_writes);
   2912   SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
   2913   SSLSocketDataProvider ssl(true, OK);
   2914 
   2915   session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
   2916   session_deps.socket_factory.AddSocketDataProvider(&data);
   2917   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
   2918   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2919 
   2920   TestCompletionCallback callback;
   2921 
   2922   int rv = trans->Start(&request, &callback, NULL);
   2923   EXPECT_EQ(ERR_IO_PENDING, rv);
   2924 
   2925   rv = callback.WaitForResult();
   2926   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   2927 
   2928   rv = trans->RestartIgnoringLastError(&callback);
   2929   EXPECT_EQ(ERR_IO_PENDING, rv);
   2930 
   2931   rv = callback.WaitForResult();
   2932   EXPECT_EQ(OK, rv);
   2933 
   2934   const HttpResponseInfo* response = trans->GetResponseInfo();
   2935 
   2936   EXPECT_FALSE(response == NULL);
   2937   EXPECT_EQ(100, response->headers->GetContentLength());
   2938 }
   2939 
   2940 // Test HTTPS connections to a site with a bad certificate, going through a
   2941 // proxy
   2942 TEST_F(HttpNetworkTransactionTest, HTTPSBadCertificateViaProxy) {
   2943   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   2944 
   2945   HttpRequestInfo request;
   2946   request.method = "GET";
   2947   request.url = GURL("https://www.google.com/");
   2948   request.load_flags = 0;
   2949 
   2950   MockWrite proxy_writes[] = {
   2951     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2952               "Host: www.google.com\r\n"
   2953               "Proxy-Connection: keep-alive\r\n\r\n"),
   2954   };
   2955 
   2956   MockRead proxy_reads[] = {
   2957     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   2958     MockRead(false, OK)
   2959   };
   2960 
   2961   MockWrite data_writes[] = {
   2962     MockWrite("CONNECT www.google.com:443 HTTP/1.1\r\n"
   2963               "Host: www.google.com\r\n"
   2964               "Proxy-Connection: keep-alive\r\n\r\n"),
   2965     MockWrite("GET / HTTP/1.1\r\n"
   2966               "Host: www.google.com\r\n"
   2967               "Connection: keep-alive\r\n\r\n"),
   2968   };
   2969 
   2970   MockRead data_reads[] = {
   2971     MockRead("HTTP/1.0 200 Connected\r\n\r\n"),
   2972     MockRead("HTTP/1.0 200 OK\r\n"),
   2973     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   2974     MockRead("Content-Length: 100\r\n\r\n"),
   2975     MockRead(false, OK),
   2976   };
   2977 
   2978   StaticSocketDataProvider ssl_bad_certificate(proxy_reads, proxy_writes);
   2979   StaticSocketDataProvider data(data_reads, data_writes);
   2980   SSLSocketDataProvider ssl_bad(true, ERR_CERT_AUTHORITY_INVALID);
   2981   SSLSocketDataProvider ssl(true, OK);
   2982 
   2983   session_deps.socket_factory.AddSocketDataProvider(&ssl_bad_certificate);
   2984   session_deps.socket_factory.AddSocketDataProvider(&data);
   2985   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl_bad);
   2986   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   2987 
   2988   TestCompletionCallback callback;
   2989 
   2990   for (int i = 0; i < 2; i++) {
   2991     session_deps.socket_factory.ResetNextMockIndexes();
   2992 
   2993     scoped_ptr<HttpTransaction> trans(
   2994         new HttpNetworkTransaction(CreateSession(&session_deps)));
   2995 
   2996     int rv = trans->Start(&request, &callback, NULL);
   2997     EXPECT_EQ(ERR_IO_PENDING, rv);
   2998 
   2999     rv = callback.WaitForResult();
   3000     EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, rv);
   3001 
   3002     rv = trans->RestartIgnoringLastError(&callback);
   3003     EXPECT_EQ(ERR_IO_PENDING, rv);
   3004 
   3005     rv = callback.WaitForResult();
   3006     EXPECT_EQ(OK, rv);
   3007 
   3008     const HttpResponseInfo* response = trans->GetResponseInfo();
   3009 
   3010     EXPECT_FALSE(response == NULL);
   3011     EXPECT_EQ(100, response->headers->GetContentLength());
   3012   }
   3013 }
   3014 
   3015 TEST_F(HttpNetworkTransactionTest, BuildRequest_UserAgent) {
   3016   SessionDependencies session_deps;
   3017   scoped_ptr<HttpTransaction> trans(
   3018       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3019 
   3020   HttpRequestInfo request;
   3021   request.method = "GET";
   3022   request.url = GURL("http://www.google.com/");
   3023   request.user_agent = "Chromium Ultra Awesome X Edition";
   3024 
   3025   MockWrite data_writes[] = {
   3026     MockWrite("GET / HTTP/1.1\r\n"
   3027               "Host: www.google.com\r\n"
   3028               "Connection: keep-alive\r\n"
   3029               "User-Agent: Chromium Ultra Awesome X Edition\r\n\r\n"),
   3030   };
   3031 
   3032   // Lastly, the server responds with the actual content.
   3033   MockRead data_reads[] = {
   3034     MockRead("HTTP/1.0 200 OK\r\n"),
   3035     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3036     MockRead("Content-Length: 100\r\n\r\n"),
   3037     MockRead(false, OK),
   3038   };
   3039 
   3040   StaticSocketDataProvider data(data_reads, data_writes);
   3041   session_deps.socket_factory.AddSocketDataProvider(&data);
   3042 
   3043   TestCompletionCallback callback;
   3044 
   3045   int rv = trans->Start(&request, &callback, NULL);
   3046   EXPECT_EQ(ERR_IO_PENDING, rv);
   3047 
   3048   rv = callback.WaitForResult();
   3049   EXPECT_EQ(OK, rv);
   3050 }
   3051 
   3052 TEST_F(HttpNetworkTransactionTest, BuildRequest_Referer) {
   3053   SessionDependencies session_deps;
   3054   scoped_ptr<HttpTransaction> trans(
   3055       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3056 
   3057   HttpRequestInfo request;
   3058   request.method = "GET";
   3059   request.url = GURL("http://www.google.com/");
   3060   request.load_flags = 0;
   3061   request.referrer = GURL("http://the.previous.site.com/");
   3062 
   3063   MockWrite data_writes[] = {
   3064     MockWrite("GET / HTTP/1.1\r\n"
   3065               "Host: www.google.com\r\n"
   3066               "Connection: keep-alive\r\n"
   3067               "Referer: http://the.previous.site.com/\r\n\r\n"),
   3068   };
   3069 
   3070   // Lastly, the server responds with the actual content.
   3071   MockRead data_reads[] = {
   3072     MockRead("HTTP/1.0 200 OK\r\n"),
   3073     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3074     MockRead("Content-Length: 100\r\n\r\n"),
   3075     MockRead(false, OK),
   3076   };
   3077 
   3078   StaticSocketDataProvider data(data_reads, data_writes);
   3079   session_deps.socket_factory.AddSocketDataProvider(&data);
   3080 
   3081   TestCompletionCallback callback;
   3082 
   3083   int rv = trans->Start(&request, &callback, NULL);
   3084   EXPECT_EQ(ERR_IO_PENDING, rv);
   3085 
   3086   rv = callback.WaitForResult();
   3087   EXPECT_EQ(OK, rv);
   3088 }
   3089 
   3090 TEST_F(HttpNetworkTransactionTest, BuildRequest_PostContentLengthZero) {
   3091   SessionDependencies session_deps;
   3092   scoped_ptr<HttpTransaction> trans(
   3093       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3094 
   3095   HttpRequestInfo request;
   3096   request.method = "POST";
   3097   request.url = GURL("http://www.google.com/");
   3098 
   3099   MockWrite data_writes[] = {
   3100     MockWrite("POST / HTTP/1.1\r\n"
   3101               "Host: www.google.com\r\n"
   3102               "Connection: keep-alive\r\n"
   3103               "Content-Length: 0\r\n\r\n"),
   3104   };
   3105 
   3106   // Lastly, the server responds with the actual content.
   3107   MockRead data_reads[] = {
   3108     MockRead("HTTP/1.0 200 OK\r\n"),
   3109     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3110     MockRead("Content-Length: 100\r\n\r\n"),
   3111     MockRead(false, OK),
   3112   };
   3113 
   3114   StaticSocketDataProvider data(data_reads, data_writes);
   3115   session_deps.socket_factory.AddSocketDataProvider(&data);
   3116 
   3117   TestCompletionCallback callback;
   3118 
   3119   int rv = trans->Start(&request, &callback, NULL);
   3120   EXPECT_EQ(ERR_IO_PENDING, rv);
   3121 
   3122   rv = callback.WaitForResult();
   3123   EXPECT_EQ(OK, rv);
   3124 }
   3125 
   3126 TEST_F(HttpNetworkTransactionTest, BuildRequest_PutContentLengthZero) {
   3127   SessionDependencies session_deps;
   3128   scoped_ptr<HttpTransaction> trans(
   3129       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3130 
   3131   HttpRequestInfo request;
   3132   request.method = "PUT";
   3133   request.url = GURL("http://www.google.com/");
   3134 
   3135   MockWrite data_writes[] = {
   3136     MockWrite("PUT / HTTP/1.1\r\n"
   3137               "Host: www.google.com\r\n"
   3138               "Connection: keep-alive\r\n"
   3139               "Content-Length: 0\r\n\r\n"),
   3140   };
   3141 
   3142   // Lastly, the server responds with the actual content.
   3143   MockRead data_reads[] = {
   3144     MockRead("HTTP/1.0 200 OK\r\n"),
   3145     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3146     MockRead("Content-Length: 100\r\n\r\n"),
   3147     MockRead(false, OK),
   3148   };
   3149 
   3150   StaticSocketDataProvider data(data_reads, data_writes);
   3151   session_deps.socket_factory.AddSocketDataProvider(&data);
   3152 
   3153   TestCompletionCallback callback;
   3154 
   3155   int rv = trans->Start(&request, &callback, NULL);
   3156   EXPECT_EQ(ERR_IO_PENDING, rv);
   3157 
   3158   rv = callback.WaitForResult();
   3159   EXPECT_EQ(OK, rv);
   3160 }
   3161 
   3162 TEST_F(HttpNetworkTransactionTest, BuildRequest_HeadContentLengthZero) {
   3163   SessionDependencies session_deps;
   3164   scoped_ptr<HttpTransaction> trans(
   3165       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3166 
   3167   HttpRequestInfo request;
   3168   request.method = "HEAD";
   3169   request.url = GURL("http://www.google.com/");
   3170 
   3171   MockWrite data_writes[] = {
   3172     MockWrite("HEAD / HTTP/1.1\r\n"
   3173               "Host: www.google.com\r\n"
   3174               "Connection: keep-alive\r\n"
   3175               "Content-Length: 0\r\n\r\n"),
   3176   };
   3177 
   3178   // Lastly, the server responds with the actual content.
   3179   MockRead data_reads[] = {
   3180     MockRead("HTTP/1.0 200 OK\r\n"),
   3181     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3182     MockRead("Content-Length: 100\r\n\r\n"),
   3183     MockRead(false, OK),
   3184   };
   3185 
   3186   StaticSocketDataProvider data(data_reads, data_writes);
   3187   session_deps.socket_factory.AddSocketDataProvider(&data);
   3188 
   3189   TestCompletionCallback callback;
   3190 
   3191   int rv = trans->Start(&request, &callback, NULL);
   3192   EXPECT_EQ(ERR_IO_PENDING, rv);
   3193 
   3194   rv = callback.WaitForResult();
   3195   EXPECT_EQ(OK, rv);
   3196 }
   3197 
   3198 TEST_F(HttpNetworkTransactionTest, BuildRequest_CacheControlNoCache) {
   3199   SessionDependencies session_deps;
   3200   scoped_ptr<HttpTransaction> trans(
   3201       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3202 
   3203   HttpRequestInfo request;
   3204   request.method = "GET";
   3205   request.url = GURL("http://www.google.com/");
   3206   request.load_flags = LOAD_BYPASS_CACHE;
   3207 
   3208   MockWrite data_writes[] = {
   3209     MockWrite("GET / HTTP/1.1\r\n"
   3210               "Host: www.google.com\r\n"
   3211               "Connection: keep-alive\r\n"
   3212               "Pragma: no-cache\r\n"
   3213               "Cache-Control: no-cache\r\n\r\n"),
   3214   };
   3215 
   3216   // Lastly, the server responds with the actual content.
   3217   MockRead data_reads[] = {
   3218     MockRead("HTTP/1.0 200 OK\r\n"),
   3219     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3220     MockRead("Content-Length: 100\r\n\r\n"),
   3221     MockRead(false, OK),
   3222   };
   3223 
   3224   StaticSocketDataProvider data(data_reads, data_writes);
   3225   session_deps.socket_factory.AddSocketDataProvider(&data);
   3226 
   3227   TestCompletionCallback callback;
   3228 
   3229   int rv = trans->Start(&request, &callback, NULL);
   3230   EXPECT_EQ(ERR_IO_PENDING, rv);
   3231 
   3232   rv = callback.WaitForResult();
   3233   EXPECT_EQ(OK, rv);
   3234 }
   3235 
   3236 TEST_F(HttpNetworkTransactionTest,
   3237        BuildRequest_CacheControlValidateCache) {
   3238   SessionDependencies session_deps;
   3239   scoped_ptr<HttpTransaction> trans(
   3240       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3241 
   3242   HttpRequestInfo request;
   3243   request.method = "GET";
   3244   request.url = GURL("http://www.google.com/");
   3245   request.load_flags = LOAD_VALIDATE_CACHE;
   3246 
   3247   MockWrite data_writes[] = {
   3248     MockWrite("GET / HTTP/1.1\r\n"
   3249               "Host: www.google.com\r\n"
   3250               "Connection: keep-alive\r\n"
   3251               "Cache-Control: max-age=0\r\n\r\n"),
   3252   };
   3253 
   3254   // Lastly, the server responds with the actual content.
   3255   MockRead data_reads[] = {
   3256     MockRead("HTTP/1.0 200 OK\r\n"),
   3257     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3258     MockRead("Content-Length: 100\r\n\r\n"),
   3259     MockRead(false, OK),
   3260   };
   3261 
   3262   StaticSocketDataProvider data(data_reads, data_writes);
   3263   session_deps.socket_factory.AddSocketDataProvider(&data);
   3264 
   3265   TestCompletionCallback callback;
   3266 
   3267   int rv = trans->Start(&request, &callback, NULL);
   3268   EXPECT_EQ(ERR_IO_PENDING, rv);
   3269 
   3270   rv = callback.WaitForResult();
   3271   EXPECT_EQ(OK, rv);
   3272 }
   3273 
   3274 TEST_F(HttpNetworkTransactionTest, BuildRequest_ExtraHeaders) {
   3275   SessionDependencies session_deps;
   3276   scoped_ptr<HttpTransaction> trans(
   3277       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3278 
   3279   HttpRequestInfo request;
   3280   request.method = "GET";
   3281   request.url = GURL("http://www.google.com/");
   3282   request.extra_headers = "FooHeader: Bar\r\n";
   3283 
   3284   MockWrite data_writes[] = {
   3285     MockWrite("GET / HTTP/1.1\r\n"
   3286               "Host: www.google.com\r\n"
   3287               "Connection: keep-alive\r\n"
   3288               "FooHeader: Bar\r\n\r\n"),
   3289   };
   3290 
   3291   // Lastly, the server responds with the actual content.
   3292   MockRead data_reads[] = {
   3293     MockRead("HTTP/1.0 200 OK\r\n"),
   3294     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3295     MockRead("Content-Length: 100\r\n\r\n"),
   3296     MockRead(false, OK),
   3297   };
   3298 
   3299   StaticSocketDataProvider data(data_reads, data_writes);
   3300   session_deps.socket_factory.AddSocketDataProvider(&data);
   3301 
   3302   TestCompletionCallback callback;
   3303 
   3304   int rv = trans->Start(&request, &callback, NULL);
   3305   EXPECT_EQ(ERR_IO_PENDING, rv);
   3306 
   3307   rv = callback.WaitForResult();
   3308   EXPECT_EQ(OK, rv);
   3309 }
   3310 
   3311 TEST_F(HttpNetworkTransactionTest, SOCKS4_HTTP_GET) {
   3312   SessionDependencies session_deps(
   3313       CreateFixedProxyService("socks4://myproxy:1080"));
   3314 
   3315   scoped_ptr<HttpTransaction> trans(
   3316       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3317 
   3318   HttpRequestInfo request;
   3319   request.method = "GET";
   3320   request.url = GURL("http://www.google.com/");
   3321   request.load_flags = 0;
   3322 
   3323   char write_buffer[] = { 0x04, 0x01, 0x00, 0x50, 127, 0, 0, 1, 0 };
   3324   char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   3325 
   3326   MockWrite data_writes[] = {
   3327     MockWrite(true, write_buffer, arraysize(write_buffer)),
   3328     MockWrite("GET / HTTP/1.1\r\n"
   3329               "Host: www.google.com\r\n"
   3330               "Connection: keep-alive\r\n\r\n")
   3331   };
   3332 
   3333   MockRead data_reads[] = {
   3334     MockRead(true, read_buffer, arraysize(read_buffer)),
   3335     MockRead("HTTP/1.0 200 OK\r\n"),
   3336     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   3337     MockRead("Payload"),
   3338     MockRead(false, OK)
   3339   };
   3340 
   3341   StaticSocketDataProvider data(data_reads, data_writes);
   3342   session_deps.socket_factory.AddSocketDataProvider(&data);
   3343 
   3344   TestCompletionCallback callback;
   3345 
   3346   int rv = trans->Start(&request, &callback, NULL);
   3347   EXPECT_EQ(ERR_IO_PENDING, rv);
   3348 
   3349   rv = callback.WaitForResult();
   3350   EXPECT_EQ(OK, rv);
   3351 
   3352   const HttpResponseInfo* response = trans->GetResponseInfo();
   3353   EXPECT_FALSE(response == NULL);
   3354 
   3355   std::string response_text;
   3356   rv = ReadTransaction(trans.get(), &response_text);
   3357   EXPECT_EQ(OK, rv);
   3358   EXPECT_EQ("Payload", response_text);
   3359 }
   3360 
   3361 TEST_F(HttpNetworkTransactionTest, SOCKS4_SSL_GET) {
   3362   SessionDependencies session_deps(
   3363       CreateFixedProxyService("socks4://myproxy:1080"));
   3364 
   3365   scoped_ptr<HttpTransaction> trans(
   3366       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3367 
   3368   HttpRequestInfo request;
   3369   request.method = "GET";
   3370   request.url = GURL("https://www.google.com/");
   3371   request.load_flags = 0;
   3372 
   3373   unsigned char write_buffer[] = { 0x04, 0x01, 0x01, 0xBB, 127, 0, 0, 1, 0 };
   3374   unsigned char read_buffer[] = { 0x00, 0x5A, 0x00, 0x00, 0, 0, 0, 0 };
   3375 
   3376   MockWrite data_writes[] = {
   3377     MockWrite(true, reinterpret_cast<char*>(write_buffer),
   3378               arraysize(write_buffer)),
   3379     MockWrite("GET / HTTP/1.1\r\n"
   3380               "Host: www.google.com\r\n"
   3381               "Connection: keep-alive\r\n\r\n")
   3382   };
   3383 
   3384   MockRead data_reads[] = {
   3385     MockWrite(true, reinterpret_cast<char*>(read_buffer),
   3386               arraysize(read_buffer)),
   3387     MockRead("HTTP/1.0 200 OK\r\n"),
   3388     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   3389     MockRead("Payload"),
   3390     MockRead(false, OK)
   3391   };
   3392 
   3393   StaticSocketDataProvider data(data_reads, data_writes);
   3394   session_deps.socket_factory.AddSocketDataProvider(&data);
   3395 
   3396   SSLSocketDataProvider ssl(true, OK);
   3397   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   3398 
   3399   TestCompletionCallback callback;
   3400 
   3401   int rv = trans->Start(&request, &callback, NULL);
   3402   EXPECT_EQ(ERR_IO_PENDING, rv);
   3403 
   3404   rv = callback.WaitForResult();
   3405   EXPECT_EQ(OK, rv);
   3406 
   3407   const HttpResponseInfo* response = trans->GetResponseInfo();
   3408   EXPECT_FALSE(response == NULL);
   3409 
   3410   std::string response_text;
   3411   rv = ReadTransaction(trans.get(), &response_text);
   3412   EXPECT_EQ(OK, rv);
   3413   EXPECT_EQ("Payload", response_text);
   3414 }
   3415 
   3416 TEST_F(HttpNetworkTransactionTest, SOCKS5_HTTP_GET) {
   3417   SessionDependencies session_deps(
   3418       CreateFixedProxyService("socks5://myproxy:1080"));
   3419 
   3420   scoped_ptr<HttpTransaction> trans(
   3421       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3422 
   3423   HttpRequestInfo request;
   3424   request.method = "GET";
   3425   request.url = GURL("http://www.google.com/");
   3426   request.load_flags = 0;
   3427 
   3428   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   3429   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   3430   const char kSOCKS5OkRequest[] = {
   3431     0x05,  // Version
   3432     0x01,  // Command (CONNECT)
   3433     0x00,  // Reserved.
   3434     0x03,  // Address type (DOMAINNAME).
   3435     0x0E,  // Length of domain (14)
   3436     // Domain string:
   3437     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   3438     0x00, 0x50,  // 16-bit port (80)
   3439   };
   3440   const char kSOCKS5OkResponse[] =
   3441       { 0x05, 0x00, 0x00, 0x01, 127, 0, 0, 1, 0x00, 0x50 };
   3442 
   3443   MockWrite data_writes[] = {
   3444     MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   3445     MockWrite(true, kSOCKS5OkRequest, arraysize(kSOCKS5OkRequest)),
   3446     MockWrite("GET / HTTP/1.1\r\n"
   3447               "Host: www.google.com\r\n"
   3448               "Connection: keep-alive\r\n\r\n")
   3449   };
   3450 
   3451   MockRead data_reads[] = {
   3452     MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   3453     MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   3454     MockRead("HTTP/1.0 200 OK\r\n"),
   3455     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   3456     MockRead("Payload"),
   3457     MockRead(false, OK)
   3458   };
   3459 
   3460   StaticSocketDataProvider data(data_reads, data_writes);
   3461   session_deps.socket_factory.AddSocketDataProvider(&data);
   3462 
   3463   TestCompletionCallback callback;
   3464 
   3465   int rv = trans->Start(&request, &callback, NULL);
   3466   EXPECT_EQ(ERR_IO_PENDING, rv);
   3467 
   3468   rv = callback.WaitForResult();
   3469   EXPECT_EQ(OK, rv);
   3470 
   3471   const HttpResponseInfo* response = trans->GetResponseInfo();
   3472   EXPECT_FALSE(response == NULL);
   3473 
   3474   std::string response_text;
   3475   rv = ReadTransaction(trans.get(), &response_text);
   3476   EXPECT_EQ(OK, rv);
   3477   EXPECT_EQ("Payload", response_text);
   3478 }
   3479 
   3480 TEST_F(HttpNetworkTransactionTest, SOCKS5_SSL_GET) {
   3481   SessionDependencies session_deps(
   3482       CreateFixedProxyService("socks5://myproxy:1080"));
   3483 
   3484   scoped_ptr<HttpTransaction> trans(
   3485       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3486 
   3487   HttpRequestInfo request;
   3488   request.method = "GET";
   3489   request.url = GURL("https://www.google.com/");
   3490   request.load_flags = 0;
   3491 
   3492   const char kSOCKS5GreetRequest[] = { 0x05, 0x01, 0x00 };
   3493   const char kSOCKS5GreetResponse[] = { 0x05, 0x00 };
   3494   const unsigned char kSOCKS5OkRequest[] = {
   3495     0x05,  // Version
   3496     0x01,  // Command (CONNECT)
   3497     0x00,  // Reserved.
   3498     0x03,  // Address type (DOMAINNAME).
   3499     0x0E,  // Length of domain (14)
   3500     // Domain string:
   3501     'w', 'w', 'w', '.', 'g', 'o', 'o', 'g', 'l', 'e', '.', 'c', 'o', 'm',
   3502     0x01, 0xBB,  // 16-bit port (443)
   3503   };
   3504 
   3505   const char kSOCKS5OkResponse[] =
   3506       { 0x05, 0x00, 0x00, 0x01, 0, 0, 0, 0, 0x00, 0x00 };
   3507 
   3508   MockWrite data_writes[] = {
   3509     MockWrite(true, kSOCKS5GreetRequest, arraysize(kSOCKS5GreetRequest)),
   3510     MockWrite(true, reinterpret_cast<const char*>(kSOCKS5OkRequest),
   3511               arraysize(kSOCKS5OkRequest)),
   3512     MockWrite("GET / HTTP/1.1\r\n"
   3513               "Host: www.google.com\r\n"
   3514               "Connection: keep-alive\r\n\r\n")
   3515   };
   3516 
   3517   MockRead data_reads[] = {
   3518     MockWrite(true, kSOCKS5GreetResponse, arraysize(kSOCKS5GreetResponse)),
   3519     MockWrite(true, kSOCKS5OkResponse, arraysize(kSOCKS5OkResponse)),
   3520     MockRead("HTTP/1.0 200 OK\r\n"),
   3521     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n\r\n"),
   3522     MockRead("Payload"),
   3523     MockRead(false, OK)
   3524   };
   3525 
   3526   StaticSocketDataProvider data(data_reads, data_writes);
   3527   session_deps.socket_factory.AddSocketDataProvider(&data);
   3528 
   3529   SSLSocketDataProvider ssl(true, OK);
   3530   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   3531 
   3532   TestCompletionCallback callback;
   3533 
   3534   int rv = trans->Start(&request, &callback, NULL);
   3535   EXPECT_EQ(ERR_IO_PENDING, rv);
   3536 
   3537   rv = callback.WaitForResult();
   3538   EXPECT_EQ(OK, rv);
   3539 
   3540   const HttpResponseInfo* response = trans->GetResponseInfo();
   3541   EXPECT_FALSE(response == NULL);
   3542 
   3543   std::string response_text;
   3544   rv = ReadTransaction(trans.get(), &response_text);
   3545   EXPECT_EQ(OK, rv);
   3546   EXPECT_EQ("Payload", response_text);
   3547 }
   3548 
   3549 // Tests that for connection endpoints the group names are correctly set.
   3550 TEST_F(HttpNetworkTransactionTest, GroupNameForProxyConnections) {
   3551   const struct {
   3552     const std::string proxy_server;
   3553     const std::string url;
   3554     const std::string expected_group_name;
   3555   } tests[] = {
   3556     {
   3557       "",  // no proxy (direct)
   3558       "http://www.google.com/direct",
   3559       "http://www.google.com/",
   3560     },
   3561     {
   3562       "http_proxy",
   3563       "http://www.google.com/http_proxy_normal",
   3564       "proxy/http_proxy:80/",
   3565     },
   3566     {
   3567       "socks4://socks_proxy:1080",
   3568       "http://www.google.com/socks4_direct",
   3569       "proxy/socks4://socks_proxy:1080/http://www.google.com/",
   3570     },
   3571 
   3572     // SSL Tests
   3573     {
   3574       "",
   3575       "https://www.google.com/direct_ssl",
   3576       "https://www.google.com/",
   3577     },
   3578     {
   3579       "http_proxy",
   3580       "https://www.google.com/http_connect_ssl",
   3581       "proxy/http_proxy:80/https://www.google.com/",
   3582     },
   3583     {
   3584       "socks4://socks_proxy:1080",
   3585       "https://www.google.com/socks4_ssl",
   3586       "proxy/socks4://socks_proxy:1080/https://www.google.com/",
   3587     },
   3588   };
   3589 
   3590   for (size_t i = 0; i < ARRAYSIZE_UNSAFE(tests); ++i) {
   3591     SessionDependencies session_deps(
   3592         CreateFixedProxyService(tests[i].proxy_server));
   3593 
   3594     scoped_refptr<CaptureGroupNameSocketPool> conn_pool(
   3595         new CaptureGroupNameSocketPool());
   3596 
   3597     scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps));
   3598     session->tcp_socket_pool_ = conn_pool.get();
   3599 
   3600     scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(session));
   3601 
   3602     HttpRequestInfo request;
   3603     request.method = "GET";
   3604     request.url = GURL(tests[i].url);
   3605     request.load_flags = 0;
   3606 
   3607     TestCompletionCallback callback;
   3608 
   3609     // We do not complete this request, the dtor will clean the transaction up.
   3610     EXPECT_EQ(ERR_IO_PENDING, trans->Start(&request, &callback, NULL));
   3611     EXPECT_EQ(tests[i].expected_group_name,
   3612               conn_pool->last_group_name_received());
   3613   }
   3614 }
   3615 
   3616 TEST_F(HttpNetworkTransactionTest, ReconsiderProxyAfterFailedConnection) {
   3617   SessionDependencies session_deps(
   3618       CreateFixedProxyService("myproxy:70;foobar:80"));
   3619 
   3620   // This simulates failure resolving all hostnames; that means we will fail
   3621   // connecting to both proxies (myproxy:70 and foobar:80).
   3622   session_deps.host_resolver->rules()->AddSimulatedFailure("*");
   3623 
   3624   scoped_ptr<HttpTransaction> trans(
   3625       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3626 
   3627   HttpRequestInfo request;
   3628   request.method = "GET";
   3629   request.url = GURL("http://www.google.com/");
   3630 
   3631   TestCompletionCallback callback;
   3632 
   3633   int rv = trans->Start(&request, &callback, NULL);
   3634   EXPECT_EQ(ERR_IO_PENDING, rv);
   3635 
   3636   rv = callback.WaitForResult();
   3637   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   3638 }
   3639 
   3640 // Host resolution observer used by
   3641 // HttpNetworkTransactionTest.ResolveMadeWithReferrer to check that host
   3642 // resovle requests are issued with a referrer of |expected_referrer|.
   3643 class ResolutionReferrerObserver : public HostResolver::Observer {
   3644  public:
   3645   explicit ResolutionReferrerObserver(const GURL& expected_referrer)
   3646       : expected_referrer_(expected_referrer),
   3647         called_start_with_referrer_(false),
   3648         called_finish_with_referrer_(false) {
   3649   }
   3650 
   3651   virtual void OnStartResolution(int id,
   3652                                  const HostResolver::RequestInfo& info) {
   3653     if (info.referrer() == expected_referrer_)
   3654       called_start_with_referrer_ = true;
   3655   }
   3656 
   3657   virtual void OnFinishResolutionWithStatus(
   3658       int id, bool was_resolved, const HostResolver::RequestInfo& info ) {
   3659     if (info.referrer() == expected_referrer_)
   3660       called_finish_with_referrer_ = true;
   3661   }
   3662 
   3663   virtual void OnCancelResolution(int id,
   3664                                   const HostResolver::RequestInfo& info ) {
   3665     FAIL() << "Should not be cancelling any requests!";
   3666   }
   3667 
   3668   bool did_complete_with_expected_referrer() const {
   3669     return called_start_with_referrer_ && called_finish_with_referrer_;
   3670   }
   3671 
   3672  private:
   3673   GURL expected_referrer_;
   3674   bool called_start_with_referrer_;
   3675   bool called_finish_with_referrer_;
   3676 
   3677   DISALLOW_COPY_AND_ASSIGN(ResolutionReferrerObserver);
   3678 };
   3679 
   3680 // Make sure that when HostResolver::Resolve() is invoked, it passes through
   3681 // the "referrer". This is depended on by the DNS prefetch observer.
   3682 TEST_F(HttpNetworkTransactionTest, ResolveMadeWithReferrer) {
   3683   GURL referrer = GURL("http://expected-referrer/");
   3684   EXPECT_TRUE(referrer.is_valid());
   3685   ResolutionReferrerObserver resolution_observer(referrer);
   3686 
   3687   SessionDependencies session_deps;
   3688   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   3689       CreateSession(&session_deps)));
   3690 
   3691   // Attach an observer to watch the host resolutions being made.
   3692   session_deps.host_resolver->AddObserver(&resolution_observer);
   3693 
   3694   // Connect up a mock socket which will fail when reading.
   3695   MockRead data_reads[] = {
   3696     MockRead(false, ERR_FAILED),
   3697   };
   3698   StaticSocketDataProvider data(data_reads, NULL);
   3699   session_deps.socket_factory.AddSocketDataProvider(&data);
   3700 
   3701   // Issue a request, containing an HTTP referrer.
   3702   HttpRequestInfo request;
   3703   request.method = "GET";
   3704   request.referrer = referrer;
   3705   request.url = GURL("http://www.google.com/");
   3706 
   3707   // Run the request until it fails reading from the socket.
   3708   TestCompletionCallback callback;
   3709   int rv = trans->Start(&request, &callback, NULL);
   3710   EXPECT_EQ(ERR_IO_PENDING, rv);
   3711   rv = callback.WaitForResult();
   3712   EXPECT_EQ(ERR_FAILED, rv);
   3713 
   3714   // Check that the host resolution observer saw |referrer|.
   3715   EXPECT_TRUE(resolution_observer.did_complete_with_expected_referrer());
   3716 }
   3717 
   3718 // Make sure that when the load flags contain LOAD_BYPASS_CACHE, the resolver's
   3719 // host cache is bypassed.
   3720 TEST_F(HttpNetworkTransactionTest, BypassHostCacheOnRefresh) {
   3721   SessionDependencies session_deps;
   3722 
   3723   // Select a host resolver that does caching.
   3724   session_deps.host_resolver = new MockCachingHostResolver;
   3725 
   3726   scoped_ptr<HttpTransaction> trans(new HttpNetworkTransaction(
   3727       CreateSession(&session_deps)));
   3728 
   3729   // Warm up the host cache so it has an entry for "www.google.com" (by doing
   3730   // a synchronous lookup.)
   3731   AddressList addrlist;
   3732   int rv = session_deps.host_resolver->Resolve(
   3733       HostResolver::RequestInfo("www.google.com", 80), &addrlist,
   3734       NULL, NULL, NULL);
   3735   EXPECT_EQ(OK, rv);
   3736 
   3737   // Verify that it was added to host cache, by doing a subsequent async lookup
   3738   // and confirming it completes synchronously.
   3739   TestCompletionCallback resolve_callback;
   3740   rv = session_deps.host_resolver->Resolve(
   3741       HostResolver::RequestInfo("www.google.com", 80), &addrlist,
   3742       &resolve_callback, NULL, NULL);
   3743   ASSERT_EQ(OK, rv);
   3744 
   3745   // Inject a failure the next time that "www.google.com" is resolved. This way
   3746   // we can tell if the next lookup hit the cache, or the "network".
   3747   // (cache --> success, "network" --> failure).
   3748   session_deps.host_resolver->rules()->AddSimulatedFailure("www.google.com");
   3749 
   3750   // Connect up a mock socket which will fail with ERR_UNEXPECTED during the
   3751   // first read -- this won't be reached as the host resolution will fail first.
   3752   MockRead data_reads[] = { MockRead(false, ERR_UNEXPECTED) };
   3753   StaticSocketDataProvider data(data_reads, NULL);
   3754   session_deps.socket_factory.AddSocketDataProvider(&data);
   3755 
   3756   // Issue a request, asking to bypass the cache(s).
   3757   HttpRequestInfo request;
   3758   request.method = "GET";
   3759   request.load_flags = LOAD_BYPASS_CACHE;
   3760   request.url = GURL("http://www.google.com/");
   3761 
   3762   // Run the request.
   3763   TestCompletionCallback callback;
   3764   rv = trans->Start(&request, &callback, NULL);
   3765   ASSERT_EQ(ERR_IO_PENDING, rv);
   3766   rv = callback.WaitForResult();
   3767 
   3768   // If we bypassed the cache, we would have gotten a failure while resolving
   3769   // "www.google.com".
   3770   EXPECT_EQ(ERR_NAME_NOT_RESOLVED, rv);
   3771 }
   3772 
   3773 // Make sure we can handle an error when writing the request.
   3774 TEST_F(HttpNetworkTransactionTest, RequestWriteError) {
   3775   SessionDependencies session_deps;
   3776   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
   3777 
   3778   HttpRequestInfo request;
   3779   request.method = "GET";
   3780   request.url = GURL("http://www.foo.com/");
   3781   request.load_flags = 0;
   3782 
   3783   MockWrite write_failure[] = {
   3784     MockWrite(true, ERR_CONNECTION_RESET),
   3785   };
   3786   StaticSocketDataProvider data(NULL, write_failure);
   3787   session_deps.socket_factory.AddSocketDataProvider(&data);
   3788 
   3789   TestCompletionCallback callback;
   3790 
   3791   scoped_ptr<HttpTransaction> trans(
   3792       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3793 
   3794   int rv = trans->Start(&request, &callback, NULL);
   3795   EXPECT_EQ(ERR_IO_PENDING, rv);
   3796 
   3797   rv = callback.WaitForResult();
   3798   EXPECT_EQ(ERR_CONNECTION_RESET, rv);
   3799 }
   3800 
   3801 // Check that a connection closed after the start of the headers finishes ok.
   3802 TEST_F(HttpNetworkTransactionTest, ConnectionClosedAfterStartOfHeaders) {
   3803   SessionDependencies session_deps;
   3804   scoped_refptr<HttpNetworkSession> session = CreateSession(&session_deps);
   3805 
   3806   HttpRequestInfo request;
   3807   request.method = "GET";
   3808   request.url = GURL("http://www.foo.com/");
   3809   request.load_flags = 0;
   3810 
   3811   MockRead data_reads[] = {
   3812     MockRead("HTTP/1."),
   3813     MockRead(false, OK),
   3814   };
   3815 
   3816   StaticSocketDataProvider data(data_reads, NULL);
   3817   session_deps.socket_factory.AddSocketDataProvider(&data);
   3818 
   3819   TestCompletionCallback callback;
   3820 
   3821   scoped_ptr<HttpTransaction> trans(
   3822       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3823 
   3824   int rv = trans->Start(&request, &callback, NULL);
   3825   EXPECT_EQ(ERR_IO_PENDING, rv);
   3826 
   3827   rv = callback.WaitForResult();
   3828   EXPECT_EQ(OK, rv);
   3829 
   3830   const HttpResponseInfo* response = trans->GetResponseInfo();
   3831   EXPECT_TRUE(response != NULL);
   3832 
   3833   EXPECT_TRUE(response->headers != NULL);
   3834   EXPECT_EQ("HTTP/1.0 200 OK", response->headers->GetStatusLine());
   3835 
   3836   std::string response_data;
   3837   rv = ReadTransaction(trans.get(), &response_data);
   3838   EXPECT_EQ(OK, rv);
   3839   EXPECT_EQ("", response_data);
   3840 }
   3841 
   3842 // Make sure that a dropped connection while draining the body for auth
   3843 // restart does the right thing.
   3844 TEST_F(HttpNetworkTransactionTest, DrainResetOK) {
   3845   SessionDependencies session_deps;
   3846   scoped_ptr<HttpTransaction> trans(
   3847       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3848 
   3849   HttpRequestInfo request;
   3850   request.method = "GET";
   3851   request.url = GURL("http://www.google.com/");
   3852   request.load_flags = 0;
   3853 
   3854   MockWrite data_writes1[] = {
   3855     MockWrite("GET / HTTP/1.1\r\n"
   3856               "Host: www.google.com\r\n"
   3857               "Connection: keep-alive\r\n\r\n"),
   3858   };
   3859 
   3860   MockRead data_reads1[] = {
   3861     MockRead("HTTP/1.1 401 Unauthorized\r\n"),
   3862     MockRead("WWW-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
   3863     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3864     MockRead("Content-Length: 14\r\n\r\n"),
   3865     MockRead("Unauth"),
   3866     MockRead(true, ERR_CONNECTION_RESET),
   3867   };
   3868 
   3869   StaticSocketDataProvider data1(data_reads1, data_writes1);
   3870   session_deps.socket_factory.AddSocketDataProvider(&data1);
   3871 
   3872   // After calling trans->RestartWithAuth(), this is the request we should
   3873   // be issuing -- the final header line contains the credentials.
   3874   MockWrite data_writes2[] = {
   3875     MockWrite("GET / HTTP/1.1\r\n"
   3876               "Host: www.google.com\r\n"
   3877               "Connection: keep-alive\r\n"
   3878               "Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
   3879   };
   3880 
   3881   // Lastly, the server responds with the actual content.
   3882   MockRead data_reads2[] = {
   3883     MockRead("HTTP/1.1 200 OK\r\n"),
   3884     MockRead("Content-Type: text/html; charset=iso-8859-1\r\n"),
   3885     MockRead("Content-Length: 100\r\n\r\n"),
   3886     MockRead(false, OK),
   3887   };
   3888 
   3889   StaticSocketDataProvider data2(data_reads2, data_writes2);
   3890   session_deps.socket_factory.AddSocketDataProvider(&data2);
   3891 
   3892   TestCompletionCallback callback1;
   3893 
   3894   int rv = trans->Start(&request, &callback1, NULL);
   3895   EXPECT_EQ(ERR_IO_PENDING, rv);
   3896 
   3897   rv = callback1.WaitForResult();
   3898   EXPECT_EQ(OK, rv);
   3899 
   3900   const HttpResponseInfo* response = trans->GetResponseInfo();
   3901   EXPECT_FALSE(response == NULL);
   3902 
   3903   // The password prompt info should have been set in response->auth_challenge.
   3904   EXPECT_FALSE(response->auth_challenge.get() == NULL);
   3905 
   3906   EXPECT_EQ(L"www.google.com:80", response->auth_challenge->host_and_port);
   3907   EXPECT_EQ(L"MyRealm1", response->auth_challenge->realm);
   3908   EXPECT_EQ(L"basic", response->auth_challenge->scheme);
   3909 
   3910   TestCompletionCallback callback2;
   3911 
   3912   rv = trans->RestartWithAuth(L"foo", L"bar", &callback2);
   3913   EXPECT_EQ(ERR_IO_PENDING, rv);
   3914 
   3915   rv = callback2.WaitForResult();
   3916   EXPECT_EQ(OK, rv);
   3917 
   3918   response = trans->GetResponseInfo();
   3919   EXPECT_FALSE(response == NULL);
   3920   EXPECT_TRUE(response->auth_challenge.get() == NULL);
   3921   EXPECT_EQ(100, response->headers->GetContentLength());
   3922 }
   3923 
   3924 // Test HTTPS connections going through a proxy that sends extra data.
   3925 TEST_F(HttpNetworkTransactionTest, HTTPSViaProxyWithExtraData) {
   3926   SessionDependencies session_deps(CreateFixedProxyService("myproxy:70"));
   3927 
   3928   HttpRequestInfo request;
   3929   request.method = "GET";
   3930   request.url = GURL("https://www.google.com/");
   3931   request.load_flags = 0;
   3932 
   3933   MockRead proxy_reads[] = {
   3934     MockRead("HTTP/1.0 200 Connected\r\n\r\nExtra data"),
   3935     MockRead(false, OK)
   3936   };
   3937 
   3938   StaticSocketDataProvider data(proxy_reads, NULL);
   3939   SSLSocketDataProvider ssl(true, OK);
   3940 
   3941   session_deps.socket_factory.AddSocketDataProvider(&data);
   3942   session_deps.socket_factory.AddSSLSocketDataProvider(&ssl);
   3943 
   3944   TestCompletionCallback callback;
   3945 
   3946   session_deps.socket_factory.ResetNextMockIndexes();
   3947 
   3948   scoped_ptr<HttpTransaction> trans(
   3949       new HttpNetworkTransaction(CreateSession(&session_deps)));
   3950 
   3951   int rv = trans->Start(&request, &callback, NULL);
   3952   EXPECT_EQ(ERR_IO_PENDING, rv);
   3953 
   3954   rv = callback.WaitForResult();
   3955   EXPECT_EQ(ERR_TUNNEL_CONNECTION_FAILED, rv);
   3956 }
   3957 
   3958 TEST_F(HttpNetworkTransactionTest, LargeContentLengthThenClose) {
   3959   MockRead data_reads[] = {
   3960     MockRead("HTTP/1.0 200 OK\r\nContent-Length:6719476739\r\n\r\n"),
   3961     MockRead(false, OK),
   3962   };
   3963   SimpleGetHelperResult out = SimpleGetHelper(data_reads);
   3964   EXPECT_EQ(OK, out.rv);
   3965   EXPECT_EQ("HTTP/1.0 200 OK", out.status_line);
   3966   EXPECT_EQ("", out.response_data);
   3967 }
   3968 
   3969 }  // namespace net
   3970