// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/http/http_proxy_client_socket_pool.h"

#include "base/callback.h"
#include "base/compiler_specific.h"
#include "base/run_loop.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/time/time.h"
#include "net/base/auth.h"
#include "net/base/load_timing_info.h"
#include "net/base/load_timing_info_test_util.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/proxy_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/client_socket_pool_histograms.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_test_util.h"
#include "net/spdy/spdy_session.h"
#include "net/spdy/spdy_session_pool.h"
#include "net/spdy/spdy_test_util_common.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/test/test_certificate_data.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

const int kMaxSockets = 32;
const int kMaxSocketsPerGroup = 6;

// Make sure |handle|'s load times are set correctly.  DNS and connect start
// times comes from mock client sockets in these tests, so primarily serves to
// check those times were copied, and ssl times / connect end are set correctly.
void TestLoadTimingInfo(const ClientSocketHandle& handle) {
  LoadTimingInfo load_timing_info;
  EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));

  EXPECT_FALSE(load_timing_info.socket_reused);
  // None of these tests use a NetLog.
  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  ExpectConnectTimingHasTimes(
      load_timing_info.connect_timing,
      CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
  ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
}

// Just like TestLoadTimingInfo, except DNS times are expected to be null, for
// tests over proxies that do DNS lookups themselves.
void TestLoadTimingInfoNoDns(const ClientSocketHandle& handle) {
  LoadTimingInfo load_timing_info;
  EXPECT_TRUE(handle.GetLoadTimingInfo(false, &load_timing_info));

  // None of these tests use a NetLog.
  EXPECT_EQ(NetLog::Source::kInvalidId, load_timing_info.socket_log_id);

  EXPECT_FALSE(load_timing_info.socket_reused);

  ExpectConnectTimingHasTimes(load_timing_info.connect_timing,
                              CONNECT_TIMING_HAS_SSL_TIMES);
  ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
}

class SSLClientSocketPoolTest
    : public testing::Test,
      public ::testing::WithParamInterface<NextProto> {
 protected:
  SSLClientSocketPoolTest()
      : transport_security_state_(new TransportSecurityState),
        proxy_service_(ProxyService::CreateDirect()),
        ssl_config_service_(new SSLConfigServiceDefaults),
        http_auth_handler_factory_(
            HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
        session_(CreateNetworkSession()),
        direct_transport_socket_params_(
            new TransportSocketParams(
                HostPortPair("host", 443),
                false,
                false,
                OnHostResolutionCallback(),
                TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
        transport_histograms_("MockTCP"),
        transport_socket_pool_(kMaxSockets,
                               kMaxSocketsPerGroup,
                               &transport_histograms_,
                               &socket_factory_),
        proxy_transport_socket_params_(
            new TransportSocketParams(
                HostPortPair("proxy", 443),
                false,
                false,
                OnHostResolutionCallback(),
                TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)),
        socks_socket_params_(
            new SOCKSSocketParams(proxy_transport_socket_params_,
                                  true,
                                  HostPortPair("sockshost", 443))),
        socks_histograms_("MockSOCKS"),
        socks_socket_pool_(kMaxSockets,
                           kMaxSocketsPerGroup,
                           &socks_histograms_,
                           &transport_socket_pool_),
        http_proxy_socket_params_(
            new HttpProxySocketParams(proxy_transport_socket_params_,
                                      NULL,
                                      GURL("http://host"),
                                      std::string(),
                                      HostPortPair("host", 80),
                                      session_->http_auth_cache(),
                                      session_->http_auth_handler_factory(),
                                      session_->spdy_session_pool(),
                                      true,
                                      NULL)),
        http_proxy_histograms_("MockHttpProxy"),
        http_proxy_socket_pool_(kMaxSockets,
                                kMaxSocketsPerGroup,
                                &http_proxy_histograms_,
                                &host_resolver_,
                                &transport_socket_pool_,
                                NULL,
                                NULL,
                                NULL),
        enable_ssl_connect_job_waiting_(false) {
    scoped_refptr<SSLConfigService> ssl_config_service(
        new SSLConfigServiceDefaults);
    ssl_config_service->GetSSLConfig(&ssl_config_);
  }

  void CreatePool(bool transport_pool, bool http_proxy_pool, bool socks_pool) {
    ssl_histograms_.reset(new ClientSocketPoolHistograms("SSLUnitTest"));
    pool_.reset(new SSLClientSocketPool(
        kMaxSockets,
        kMaxSocketsPerGroup,
        ssl_histograms_.get(),
        NULL /* host_resolver */,
        NULL /* cert_verifier */,
        NULL /* channel_id_service */,
        NULL /* transport_security_state */,
        NULL /* cert_transparency_verifier */,
        std::string() /* ssl_session_cache_shard */,
        &socket_factory_,
        transport_pool ? &transport_socket_pool_ : NULL,
        socks_pool ? &socks_socket_pool_ : NULL,
        http_proxy_pool ? &http_proxy_socket_pool_ : NULL,
        NULL,
        enable_ssl_connect_job_waiting_,
        NULL));
  }

  scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy,
                                           bool want_spdy_over_npn) {
    return make_scoped_refptr(new SSLSocketParams(
        proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
                                            : NULL,
        proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : NULL,
        proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : NULL,
        HostPortPair("host", 443),
        ssl_config_,
        PRIVACY_MODE_DISABLED,
        0,
        false,
        want_spdy_over_npn));
  }

  void AddAuthToCache() {
    const base::string16 kFoo(base::ASCIIToUTF16("foo"));
    const base::string16 kBar(base::ASCIIToUTF16("bar"));
    session_->http_auth_cache()->Add(GURL("http://proxy:443/"),
                                     "MyRealm1",
                                     HttpAuth::AUTH_SCHEME_BASIC,
                                     "Basic realm=MyRealm1",
                                     AuthCredentials(kFoo, kBar),
                                     "/");
  }

  HttpNetworkSession* CreateNetworkSession() {
    HttpNetworkSession::Params params;
    params.host_resolver = &host_resolver_;
    params.cert_verifier = cert_verifier_.get();
    params.transport_security_state = transport_security_state_.get();
    params.proxy_service = proxy_service_.get();
    params.client_socket_factory = &socket_factory_;
    params.ssl_config_service = ssl_config_service_.get();
    params.http_auth_handler_factory = http_auth_handler_factory_.get();
    params.http_server_properties =
        http_server_properties_.GetWeakPtr();
    params.enable_spdy_compression = false;
    params.spdy_default_protocol = GetParam();
    return new HttpNetworkSession(params);
  }

  void TestIPPoolingDisabled(SSLSocketDataProvider* ssl);

  MockClientSocketFactory socket_factory_;
  MockCachingHostResolver host_resolver_;
  scoped_ptr<CertVerifier> cert_verifier_;
  scoped_ptr<TransportSecurityState> transport_security_state_;
  const scoped_ptr<ProxyService> proxy_service_;
  const scoped_refptr<SSLConfigService> ssl_config_service_;
  const scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
  HttpServerPropertiesImpl http_server_properties_;
  const scoped_refptr<HttpNetworkSession> session_;

  scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
  ClientSocketPoolHistograms transport_histograms_;
  MockTransportClientSocketPool transport_socket_pool_;

  scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;

  scoped_refptr<SOCKSSocketParams> socks_socket_params_;
  ClientSocketPoolHistograms socks_histograms_;
  MockSOCKSClientSocketPool socks_socket_pool_;

  scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
  ClientSocketPoolHistograms http_proxy_histograms_;
  HttpProxyClientSocketPool http_proxy_socket_pool_;

  SSLConfig ssl_config_;
  scoped_ptr<ClientSocketPoolHistograms> ssl_histograms_;
  scoped_ptr<SSLClientSocketPool> pool_;

  bool enable_ssl_connect_job_waiting_;
};

INSTANTIATE_TEST_CASE_P(
    NextProto,
    SSLClientSocketPoolTest,
    testing::Values(kProtoDeprecatedSPDY2,
                    kProtoSPDY3, kProtoSPDY31, kProtoSPDY4));

// Tests that the final socket will connect even if all sockets
// prior to it fail.
//
// All sockets should wait for the first socket to attempt to
// connect. Once it fails to connect, all other sockets should
// attempt to connect. All should fail, except the final socket.
TEST_P(SSLClientSocketPoolTest, AllSocketsFailButLast) {
  // Although we request four sockets, the first three socket connect
  // failures cause the socket pool to create three more sockets because
  // there are pending requests.
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  StaticSocketDataProvider data4;
  StaticSocketDataProvider data5;
  StaticSocketDataProvider data6;
  StaticSocketDataProvider data7;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);
  socket_factory_.AddSocketDataProvider(&data4);
  socket_factory_.AddSocketDataProvider(&data5);
  socket_factory_.AddSocketDataProvider(&data6);
  socket_factory_.AddSocketDataProvider(&data7);
  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  ssl.is_in_session_cache = false;
  SSLSocketDataProvider ssl2(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  ssl2.is_in_session_cache = false;
  SSLSocketDataProvider ssl3(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  ssl3.is_in_session_cache = false;
  SSLSocketDataProvider ssl4(ASYNC, OK);
  ssl4.is_in_session_cache = false;
  SSLSocketDataProvider ssl5(ASYNC, OK);
  ssl5.is_in_session_cache = false;
  SSLSocketDataProvider ssl6(ASYNC, OK);
  ssl6.is_in_session_cache = false;
  SSLSocketDataProvider ssl7(ASYNC, OK);
  ssl7.is_in_session_cache = false;

  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);
  socket_factory_.AddSSLSocketDataProvider(&ssl4);
  socket_factory_.AddSSLSocketDataProvider(&ssl5);
  socket_factory_.AddSSLSocketDataProvider(&ssl6);
  socket_factory_.AddSSLSocketDataProvider(&ssl7);

  enable_ssl_connect_job_waiting_ = true;
  CreatePool(true, false, false);

  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params4 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  ClientSocketHandle handle4;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;
  TestCompletionCallback callback4;

  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());
  handle4.Init(
      "b", params4, MEDIUM, callback4.callback(), pool_.get(), BoundNetLog());

  base::RunLoop().RunUntilIdle();

  // Only the last socket should have connected.
  EXPECT_FALSE(handle1.socket());
  EXPECT_FALSE(handle2.socket());
  EXPECT_FALSE(handle3.socket());
  EXPECT_TRUE(handle4.socket()->IsConnected());
}

// Tests that sockets will still connect in parallel if the
// EnableSSLConnectJobWaiting flag is not enabled.
TEST_P(SSLClientSocketPoolTest, SocketsConnectWithoutFlag) {
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);

  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.is_in_session_cache = false;
  ssl.should_pause_on_connect = true;
  SSLSocketDataProvider ssl2(ASYNC, OK);
  ssl2.is_in_session_cache = false;
  ssl2.should_pause_on_connect = true;
  SSLSocketDataProvider ssl3(ASYNC, OK);
  ssl3.is_in_session_cache = false;
  ssl3.should_pause_on_connect = true;
  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);

  CreatePool(true, false, false);

  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;

  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());

  base::RunLoop().RunUntilIdle();

  std::vector<MockSSLClientSocket*> sockets =
      socket_factory_.ssl_client_sockets();

  // All sockets should have started their connections.
  for (std::vector<MockSSLClientSocket*>::iterator it = sockets.begin();
       it != sockets.end();
       ++it) {
    EXPECT_TRUE((*it)->reached_connect());
  }

  // Resume connecting all of the sockets.
  for (std::vector<MockSSLClientSocket*>::iterator it = sockets.begin();
       it != sockets.end();
       ++it) {
    (*it)->RestartPausedConnect();
  }

  callback1.WaitForResult();
  callback2.WaitForResult();
  callback3.WaitForResult();

  EXPECT_TRUE(handle1.socket()->IsConnected());
  EXPECT_TRUE(handle2.socket()->IsConnected());
  EXPECT_TRUE(handle3.socket()->IsConnected());
}

// Tests that the pool deleting an SSLConnectJob will not cause a crash,
// or prevent pending sockets from connecting.
TEST_P(SSLClientSocketPoolTest, DeletedSSLConnectJob) {
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);

  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.is_in_session_cache = false;
  ssl.should_pause_on_connect = true;
  SSLSocketDataProvider ssl2(ASYNC, OK);
  ssl2.is_in_session_cache = false;
  SSLSocketDataProvider ssl3(ASYNC, OK);
  ssl3.is_in_session_cache = false;
  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);

  enable_ssl_connect_job_waiting_ = true;
  CreatePool(true, false, false);

  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;

  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());

  // Allow the connections to proceed until the first socket has started
  // connecting.
  base::RunLoop().RunUntilIdle();

  std::vector<MockSSLClientSocket*> sockets =
      socket_factory_.ssl_client_sockets();

  pool_->CancelRequest("b", &handle2);

  sockets[0]->RestartPausedConnect();

  callback1.WaitForResult();
  callback3.WaitForResult();

  EXPECT_TRUE(handle1.socket()->IsConnected());
  EXPECT_FALSE(handle2.socket());
  EXPECT_TRUE(handle3.socket()->IsConnected());
}

// Tests that all pending sockets still connect when the pool deletes a pending
// SSLConnectJob which immediately followed a failed leading connection.
TEST_P(SSLClientSocketPoolTest, DeletedSocketAfterFail) {
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  StaticSocketDataProvider data4;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);
  socket_factory_.AddSocketDataProvider(&data4);

  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  ssl.is_in_session_cache = false;
  ssl.should_pause_on_connect = true;
  SSLSocketDataProvider ssl2(ASYNC, OK);
  ssl2.is_in_session_cache = false;
  SSLSocketDataProvider ssl3(ASYNC, OK);
  ssl3.is_in_session_cache = false;
  SSLSocketDataProvider ssl4(ASYNC, OK);
  ssl4.is_in_session_cache = false;
  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);
  socket_factory_.AddSSLSocketDataProvider(&ssl4);

  enable_ssl_connect_job_waiting_ = true;
  CreatePool(true, false, false);

  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;

  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());

  // Allow the connections to proceed until the first socket has started
  // connecting.
  base::RunLoop().RunUntilIdle();

  std::vector<MockSSLClientSocket*> sockets =
      socket_factory_.ssl_client_sockets();

  EXPECT_EQ(3u, sockets.size());
  EXPECT_TRUE(sockets[0]->reached_connect());
  EXPECT_FALSE(handle1.socket());

  pool_->CancelRequest("b", &handle2);

  sockets[0]->RestartPausedConnect();

  callback1.WaitForResult();
  callback3.WaitForResult();

  EXPECT_FALSE(handle1.socket());
  EXPECT_FALSE(handle2.socket());
  EXPECT_TRUE(handle3.socket()->IsConnected());
}

// Make sure that sockets still connect after the leader socket's
// connection fails.
TEST_P(SSLClientSocketPoolTest, SimultaneousConnectJobsFail) {
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  StaticSocketDataProvider data4;
  StaticSocketDataProvider data5;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);
  socket_factory_.AddSocketDataProvider(&data4);
  socket_factory_.AddSocketDataProvider(&data5);
  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  ssl.is_in_session_cache = false;
  ssl.should_pause_on_connect = true;
  SSLSocketDataProvider ssl2(ASYNC, OK);
  ssl2.is_in_session_cache = false;
  ssl2.should_pause_on_connect = true;
  SSLSocketDataProvider ssl3(ASYNC, OK);
  ssl3.is_in_session_cache = false;
  SSLSocketDataProvider ssl4(ASYNC, OK);
  ssl4.is_in_session_cache = false;
  SSLSocketDataProvider ssl5(ASYNC, OK);
  ssl5.is_in_session_cache = false;

  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);
  socket_factory_.AddSSLSocketDataProvider(&ssl4);
  socket_factory_.AddSSLSocketDataProvider(&ssl5);

  enable_ssl_connect_job_waiting_ = true;
  CreatePool(true, false, false);
  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params4 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  ClientSocketHandle handle4;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;
  TestCompletionCallback callback4;
  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());
  handle4.Init(
      "b", params4, MEDIUM, callback4.callback(), pool_.get(), BoundNetLog());

  base::RunLoop().RunUntilIdle();

  std::vector<MockSSLClientSocket*> sockets =
      socket_factory_.ssl_client_sockets();

  std::vector<MockSSLClientSocket*>::const_iterator it = sockets.begin();

  // The first socket should have had Connect called on it.
  EXPECT_TRUE((*it)->reached_connect());
  ++it;

  // No other socket should have reached connect yet.
  for (; it != sockets.end(); ++it)
    EXPECT_FALSE((*it)->reached_connect());

  // Allow the first socket to resume it's connection process.
  sockets[0]->RestartPausedConnect();

  base::RunLoop().RunUntilIdle();

  // The second socket should have reached connect.
  EXPECT_TRUE(sockets[1]->reached_connect());

  // Allow the second socket to continue its connection.
  sockets[1]->RestartPausedConnect();

  base::RunLoop().RunUntilIdle();

  EXPECT_FALSE(handle1.socket());
  EXPECT_TRUE(handle2.socket()->IsConnected());
  EXPECT_TRUE(handle3.socket()->IsConnected());
  EXPECT_TRUE(handle4.socket()->IsConnected());
}

// Make sure that no sockets connect before the "leader" socket,
// given that the leader has a successful connection.
TEST_P(SSLClientSocketPoolTest, SimultaneousConnectJobsSuccess) {
  StaticSocketDataProvider data1;
  StaticSocketDataProvider data2;
  StaticSocketDataProvider data3;
  socket_factory_.AddSocketDataProvider(&data1);
  socket_factory_.AddSocketDataProvider(&data2);
  socket_factory_.AddSocketDataProvider(&data3);

  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.is_in_session_cache = false;
  ssl.should_pause_on_connect = true;
  SSLSocketDataProvider ssl2(ASYNC, OK);
  ssl2.is_in_session_cache = false;
  SSLSocketDataProvider ssl3(ASYNC, OK);
  ssl3.is_in_session_cache = false;
  socket_factory_.AddSSLSocketDataProvider(&ssl);
  socket_factory_.AddSSLSocketDataProvider(&ssl2);
  socket_factory_.AddSSLSocketDataProvider(&ssl3);

  enable_ssl_connect_job_waiting_ = true;
  CreatePool(true, false, false);

  scoped_refptr<SSLSocketParams> params1 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params2 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  scoped_refptr<SSLSocketParams> params3 =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);
  ClientSocketHandle handle1;
  ClientSocketHandle handle2;
  ClientSocketHandle handle3;
  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  TestCompletionCallback callback3;

  handle1.Init(
      "b", params1, MEDIUM, callback1.callback(), pool_.get(), BoundNetLog());
  handle2.Init(
      "b", params2, MEDIUM, callback2.callback(), pool_.get(), BoundNetLog());
  handle3.Init(
      "b", params3, MEDIUM, callback3.callback(), pool_.get(), BoundNetLog());

  // Allow the connections to proceed until the first socket has finished
  // connecting.
  base::RunLoop().RunUntilIdle();

  std::vector<MockSSLClientSocket*> sockets =
      socket_factory_.ssl_client_sockets();

  std::vector<MockSSLClientSocket*>::const_iterator it = sockets.begin();
  // The first socket should have reached connect.
  EXPECT_TRUE((*it)->reached_connect());
  ++it;
  // No other socket should have reached connect yet.
  for (; it != sockets.end(); ++it)
    EXPECT_FALSE((*it)->reached_connect());

  sockets[0]->RestartPausedConnect();

  callback1.WaitForResult();
  callback2.WaitForResult();
  callback3.WaitForResult();

  EXPECT_TRUE(handle1.socket()->IsConnected());
  EXPECT_TRUE(handle2.socket()->IsConnected());
  EXPECT_TRUE(handle3.socket()->IsConnected());
}

TEST_P(SSLClientSocketPoolTest, TCPFail) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  int rv = handle.Init("a", params, MEDIUM, CompletionCallback(), pool_.get(),
                       BoundNetLog());
  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, TCPFailAsync) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, BasicDirect) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
}

// Make sure that SSLConnectJob passes on its priority to its
// socket request on Init (for the DIRECT case).
TEST_P(SSLClientSocketPoolTest, SetSocketRequestPriorityOnInitDirect) {
  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params =
      SSLParams(ProxyServer::SCHEME_DIRECT, false);

  for (int i = MINIMUM_PRIORITY; i <= MAXIMUM_PRIORITY; ++i) {
    RequestPriority priority = static_cast<RequestPriority>(i);
    StaticSocketDataProvider data;
    data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
    socket_factory_.AddSocketDataProvider(&data);
    SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
    socket_factory_.AddSSLSocketDataProvider(&ssl);

    ClientSocketHandle handle;
    TestCompletionCallback callback;
    EXPECT_EQ(OK, handle.Init("a", params, priority, callback.callback(),
                              pool_.get(), BoundNetLog()));
    EXPECT_EQ(priority, transport_socket_pool_.last_request_priority());
    handle.socket()->Disconnect();
  }
}

TEST_P(SSLClientSocketPoolTest, BasicDirectAsync) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
}

TEST_P(SSLClientSocketPoolTest, DirectCertError) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
}

TEST_P(SSLClientSocketPoolTest, DirectSSLError) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_SSL_PROTOCOL_ERROR, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_TRUE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, DirectWithNPN) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.SetNextProto(kProtoHTTP11);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);
  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
}

TEST_P(SSLClientSocketPoolTest, DirectNoSPDY) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.SetNextProto(kProtoHTTP11);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    true);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_TRUE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, DirectGotSPDY) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.SetNextProto(GetParam());
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    true);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);

  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
  std::string proto;
  ssl_socket->GetNextProto(&proto);
  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
}

TEST_P(SSLClientSocketPoolTest, DirectGotBonusSPDY) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.SetNextProto(GetParam());
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_DIRECT,
                                                    true);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfo(handle);

  SSLClientSocket* ssl_socket = static_cast<SSLClientSocket*>(handle.socket());
  EXPECT_TRUE(ssl_socket->WasNpnNegotiated());
  std::string proto;
  ssl_socket->GetNextProto(&proto);
  EXPECT_EQ(GetParam(), SSLClientSocket::NextProtoFromString(proto));
}

TEST_P(SSLClientSocketPoolTest, SOCKSFail) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_CONNECTION_FAILED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, SOCKSFailAsync) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_CONNECTION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, SOCKSBasic) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
  // don't go through the real logic, unlike in the HTTP proxy tests.
  TestLoadTimingInfo(handle);
}

// Make sure that SSLConnectJob passes on its priority to its
// transport socket on Init (for the SOCKS_PROXY case).
TEST_P(SSLClientSocketPoolTest, SetTransportPriorityOnInitSOCKS) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params =
      SSLParams(ProxyServer::SCHEME_SOCKS5, false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  EXPECT_EQ(OK, handle.Init("a", params, HIGHEST, callback.callback(),
                            pool_.get(), BoundNetLog()));
  EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
}

TEST_P(SSLClientSocketPoolTest, SOCKSBasicAsync) {
  StaticSocketDataProvider data;
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_SOCKS5,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  // SOCKS5 generally has no DNS times, but the mock SOCKS5 sockets used here
  // don't go through the real logic, unlike in the HTTP proxy tests.
  TestLoadTimingInfo(handle);
}

TEST_P(SSLClientSocketPoolTest, HttpProxyFail) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(SYNCHRONOUS, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, HttpProxyFailAsync) {
  StaticSocketDataProvider data;
  data.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_FAILED));
  socket_factory_.AddSocketDataProvider(&data);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_PROXY_CONNECTION_FAILED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
}

TEST_P(SSLClientSocketPoolTest, HttpProxyBasic) {
  MockWrite writes[] = {
      MockWrite(SYNCHRONOUS,
                "CONNECT host:80 HTTP/1.1\r\n"
                "Host: host\r\n"
                "Proxy-Connection: keep-alive\r\n"
                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead reads[] = {
      MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), writes,
                                arraysize(writes));
  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory_.AddSocketDataProvider(&data);
  AddAuthToCache();
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(OK, rv);
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfoNoDns(handle);
}

// Make sure that SSLConnectJob passes on its priority to its
// transport socket on Init (for the HTTP_PROXY case).
TEST_P(SSLClientSocketPoolTest, SetTransportPriorityOnInitHTTP) {
  MockWrite writes[] = {
      MockWrite(SYNCHRONOUS,
                "CONNECT host:80 HTTP/1.1\r\n"
                "Host: host\r\n"
                "Proxy-Connection: keep-alive\r\n"
                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead reads[] = {
      MockRead(SYNCHRONOUS, "HTTP/1.1 200 Connection Established\r\n\r\n"),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), writes,
                                arraysize(writes));
  data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
  socket_factory_.AddSocketDataProvider(&data);
  AddAuthToCache();
  SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params =
      SSLParams(ProxyServer::SCHEME_HTTP, false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  EXPECT_EQ(OK, handle.Init("a", params, HIGHEST, callback.callback(),
                            pool_.get(), BoundNetLog()));
  EXPECT_EQ(HIGHEST, transport_socket_pool_.last_request_priority());
}

TEST_P(SSLClientSocketPoolTest, HttpProxyBasicAsync) {
  MockWrite writes[] = {
      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
                "Host: host\r\n"
                "Proxy-Connection: keep-alive\r\n"
                "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
  };
  MockRead reads[] = {
      MockRead("HTTP/1.1 200 Connection Established\r\n\r\n"),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), writes,
                                arraysize(writes));
  socket_factory_.AddSocketDataProvider(&data);
  AddAuthToCache();
  SSLSocketDataProvider ssl(ASYNC, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(handle.is_initialized());
  EXPECT_TRUE(handle.socket());
  TestLoadTimingInfoNoDns(handle);
}

TEST_P(SSLClientSocketPoolTest, NeedProxyAuth) {
  MockWrite writes[] = {
      MockWrite("CONNECT host:80 HTTP/1.1\r\n"
                "Host: host\r\n"
                "Proxy-Connection: keep-alive\r\n\r\n"),
  };
  MockRead reads[] = {
      MockRead("HTTP/1.1 407 Proxy Authentication Required\r\n"),
      MockRead("Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
      MockRead("Content-Length: 10\r\n\r\n"),
      MockRead("0123456789"),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), writes,
                                arraysize(writes));
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(false, true /* http proxy pool */, true /* socks pool */);
  scoped_refptr<SSLSocketParams> params = SSLParams(ProxyServer::SCHEME_HTTP,
                                                    false);

  ClientSocketHandle handle;
  TestCompletionCallback callback;
  int rv = handle.Init(
      "a", params, MEDIUM, callback.callback(), pool_.get(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());

  EXPECT_EQ(ERR_PROXY_AUTH_REQUESTED, callback.WaitForResult());
  EXPECT_FALSE(handle.is_initialized());
  EXPECT_FALSE(handle.socket());
  EXPECT_FALSE(handle.is_ssl_error());
  const HttpResponseInfo& tunnel_info = handle.ssl_error_response_info();
  EXPECT_EQ(tunnel_info.headers->response_code(), 407);
  scoped_ptr<ClientSocketHandle> tunnel_handle(
      handle.release_pending_http_proxy_connection());
  EXPECT_TRUE(tunnel_handle->socket());
  EXPECT_FALSE(tunnel_handle->socket()->IsConnected());
}

TEST_P(SSLClientSocketPoolTest, IPPooling) {
  const int kTestPort = 80;
  struct TestHosts {
    std::string name;
    std::string iplist;
    SpdySessionKey key;
    AddressList addresses;
  } test_hosts[] = {
    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
    { "code.google.com",   "192.168.0.2,192.168.0.3,192.168.0.5" },
    { "js.webkit.org",     "192.168.0.4,192.168.0.1,192.0.2.33" },
  };

  host_resolver_.set_synchronous_mode(true);
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
    host_resolver_.rules()->AddIPLiteralRule(
        test_hosts[i].name, test_hosts[i].iplist, std::string());

    // This test requires that the HostResolver cache be populated.  Normal
    // code would have done this already, but we do it manually.
    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
    host_resolver_.Resolve(info,
                           DEFAULT_PRIORITY,
                           &test_hosts[i].addresses,
                           CompletionCallback(),
                           NULL,
                           BoundNetLog());

    // Setup a SpdySessionKey
    test_hosts[i].key = SpdySessionKey(
        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
        PRIVACY_MODE_DISABLED);
  }

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.cert = X509Certificate::CreateFromBytes(
      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
  ssl.SetNextProto(GetParam());
  socket_factory_.AddSSLSocketDataProvider(&ssl);

  CreatePool(true /* tcp pool */, false, false);
  base::WeakPtr<SpdySession> spdy_session =
      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());

  EXPECT_TRUE(
      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
  EXPECT_FALSE(
      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));
  EXPECT_TRUE(
      HasSpdySession(session_->spdy_session_pool(), test_hosts[2].key));

  session_->spdy_session_pool()->CloseAllSessions();
}

void SSLClientSocketPoolTest::TestIPPoolingDisabled(
    SSLSocketDataProvider* ssl) {
  const int kTestPort = 80;
  struct TestHosts {
    std::string name;
    std::string iplist;
    SpdySessionKey key;
    AddressList addresses;
  } test_hosts[] = {
    { "www.webkit.org",    "192.0.2.33,192.168.0.1,192.168.0.5" },
    { "js.webkit.com",     "192.168.0.4,192.168.0.1,192.0.2.33" },
  };

  TestCompletionCallback callback;
  int rv;
  for (size_t i = 0; i < ARRAYSIZE_UNSAFE(test_hosts); i++) {
    host_resolver_.rules()->AddIPLiteralRule(
        test_hosts[i].name, test_hosts[i].iplist, std::string());

    // This test requires that the HostResolver cache be populated.  Normal
    // code would have done this already, but we do it manually.
    HostResolver::RequestInfo info(HostPortPair(test_hosts[i].name, kTestPort));
    rv = host_resolver_.Resolve(info,
                                DEFAULT_PRIORITY,
                                &test_hosts[i].addresses,
                                callback.callback(),
                                NULL,
                                BoundNetLog());
    EXPECT_EQ(OK, callback.GetResult(rv));

    // Setup a SpdySessionKey
    test_hosts[i].key = SpdySessionKey(
        HostPortPair(test_hosts[i].name, kTestPort), ProxyServer::Direct(),
        PRIVACY_MODE_DISABLED);
  }

  MockRead reads[] = {
      MockRead(ASYNC, ERR_IO_PENDING),
  };
  StaticSocketDataProvider data(reads, arraysize(reads), NULL, 0);
  socket_factory_.AddSocketDataProvider(&data);
  socket_factory_.AddSSLSocketDataProvider(ssl);

  CreatePool(true /* tcp pool */, false, false);
  base::WeakPtr<SpdySession> spdy_session =
      CreateSecureSpdySession(session_, test_hosts[0].key, BoundNetLog());

  EXPECT_TRUE(
      HasSpdySession(session_->spdy_session_pool(), test_hosts[0].key));
  EXPECT_FALSE(
      HasSpdySession(session_->spdy_session_pool(), test_hosts[1].key));

  session_->spdy_session_pool()->CloseAllSessions();
}

// Verifies that an SSL connection with client authentication disables SPDY IP
// pooling.
TEST_P(SSLClientSocketPoolTest, IPPoolingClientCert) {
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.cert = X509Certificate::CreateFromBytes(
      reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der));
  ssl.client_cert_sent = true;
  ssl.SetNextProto(GetParam());
  TestIPPoolingDisabled(&ssl);
}

// Verifies that an SSL connection with channel ID disables SPDY IP pooling.
TEST_P(SSLClientSocketPoolTest, IPPoolingChannelID) {
  SSLSocketDataProvider ssl(ASYNC, OK);
  ssl.channel_id_sent = true;
  ssl.SetNextProto(GetParam());
  TestIPPoolingDisabled(&ssl);
}

// It would be nice to also test the timeouts in SSLClientSocketPool.

}  // namespace

}  // namespace net
