// Copyright 2018 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 <stdint.h>

#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/scoped_task_environment.h"
#include "base/threading/thread.h"
#include "net/base/completion_once_callback.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/socket/server_socket.h"
#include "net/socket/socket_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "net/url_request/url_request_test_util.h"
#include "services/network/mojo_socket_test_util.h"
#include "services/network/proxy_resolving_socket_factory_mojo.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/socket_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace network {

namespace {

// Message sent over the tcp connection.
const char kMsg[] = "please start tls!";
const size_t kMsgSize = strlen(kMsg);

// Message sent over the tls connection.
const char kSecretMsg[] = "here is secret.";
const size_t kSecretMsgSize = strlen(kSecretMsg);

class TLSClientSocketTestBase {
 public:
  enum Mode { kDirect, kProxyResolving };

  explicit TLSClientSocketTestBase(Mode mode)
      : mode_(mode),
        scoped_task_environment_(
            base::test::ScopedTaskEnvironment::MainThreadType::IO),
        url_request_context_(true) {}
  virtual ~TLSClientSocketTestBase() {}

  Mode mode() { return mode_; }

 protected:
  // One of the two fields will be set, depending on the mode.
  struct SocketHandle {
    mojom::TCPConnectedSocketPtr tcp_socket;
    mojom::ProxyResolvingSocketPtr proxy_socket;
  };

  struct SocketRequest {
    mojom::TCPConnectedSocketRequest tcp_socket_request;
    mojom::ProxyResolvingSocketRequest proxy_socket_request;
  };

  // Initializes the test fixture. If |use_mock_sockets|, mock client socket
  // factory will be used.
  void Init(bool use_mock_sockets, bool configure_proxy) {
    if (use_mock_sockets) {
      mock_client_socket_factory_.set_enable_read_if_ready(true);
      url_request_context_.set_client_socket_factory(
          &mock_client_socket_factory_);
    }
    if (configure_proxy) {
      proxy_resolution_service_ = net::ProxyResolutionService::CreateFixed(
          "http://proxy:8080", TRAFFIC_ANNOTATION_FOR_TESTS);
      url_request_context_.set_proxy_resolution_service(
          proxy_resolution_service_.get());
    }
    url_request_context_.Init();
    factory_ = std::make_unique<SocketFactory>(nullptr /*net_log*/,
                                               &url_request_context_);
    proxy_resolving_factory_ =
        std::make_unique<ProxyResolvingSocketFactoryMojo>(
            &url_request_context_);
  }

  // Reads |num_bytes| from |handle| or reads until an error occurs. Returns the
  // bytes read as a string.
  std::string Read(mojo::ScopedDataPipeConsumerHandle* handle,
                   size_t num_bytes) {
    std::string received_contents;
    while (received_contents.size() < num_bytes) {
      base::RunLoop().RunUntilIdle();
      std::vector<char> buffer(num_bytes);
      uint32_t read_size = static_cast<uint32_t>(num_bytes);
      MojoResult result = handle->get().ReadData(buffer.data(), &read_size,
                                                 MOJO_READ_DATA_FLAG_NONE);
      if (result == MOJO_RESULT_SHOULD_WAIT)
        continue;
      if (result != MOJO_RESULT_OK)
        return received_contents;
      received_contents.append(buffer.data(), read_size);
    }
    return received_contents;
  }

  SocketRequest MakeRequest(SocketHandle* handle) {
    SocketRequest result;
    if (mode_ == kDirect)
      result.tcp_socket_request = mojo::MakeRequest(&handle->tcp_socket);
    else
      result.proxy_socket_request = mojo::MakeRequest(&handle->proxy_socket);
    return result;
  }

  void ResetSocket(SocketHandle* handle) {
    if (mode_ == kDirect)
      handle->tcp_socket.reset();
    else
      handle->proxy_socket.reset();
  }

  int CreateSocketSync(SocketRequest request,
                       const net::IPEndPoint& remote_addr) {
    if (mode_ == kDirect) {
      return CreateTCPConnectedSocketSync(std::move(request.tcp_socket_request),
                                          remote_addr);
    } else {
      return CreateProxyResolvingSocketSync(
          std::move(request.proxy_socket_request), remote_addr);
    }
  }

  int CreateTCPConnectedSocketSync(mojom::TCPConnectedSocketRequest request,
                                   const net::IPEndPoint& remote_addr) {
    net::AddressList remote_addr_list(remote_addr);
    base::RunLoop run_loop;
    int net_error = net::ERR_FAILED;
    factory_->CreateTCPConnectedSocket(
        base::nullopt /* local_addr */, remote_addr_list,
        nullptr /* tcp_connected_socket_options */,
        TRAFFIC_ANNOTATION_FOR_TESTS, std::move(request),
        pre_tls_observer()->GetObserverPtr(),
        base::BindLambdaForTesting(
            [&](int result,
                const base::Optional<net::IPEndPoint>& actual_local_addr,
                const base::Optional<net::IPEndPoint>& peer_addr,
                mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
                mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
              net_error = result;
              pre_tls_recv_handle_ = std::move(receive_pipe_handle);
              pre_tls_send_handle_ = std::move(send_pipe_handle);
              run_loop.Quit();
            }));
    run_loop.Run();
    return net_error;
  }

  int CreateProxyResolvingSocketSync(mojom::ProxyResolvingSocketRequest request,
                                     const net::IPEndPoint& remote_addr) {
    GURL url("https://" + remote_addr.ToString());
    base::RunLoop run_loop;
    int net_error = net::ERR_FAILED;
    proxy_resolving_factory_->CreateProxyResolvingSocket(
        url, nullptr /* options */,
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        std::move(request), nullptr /* observer */,
        base::BindLambdaForTesting(
            [&](int result,
                const base::Optional<net::IPEndPoint>& actual_local_addr,
                const base::Optional<net::IPEndPoint>& peer_addr,
                mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
                mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
              net_error = result;
              pre_tls_recv_handle_ = std::move(receive_pipe_handle);
              pre_tls_send_handle_ = std::move(send_pipe_handle);
              run_loop.Quit();
            }));
    run_loop.Run();
    return net_error;
  }

  void UpgradeToTLS(SocketHandle* handle,
                    const net::HostPortPair& host_port_pair,
                    mojom::TLSClientSocketRequest request,
                    net::CompletionOnceCallback callback) {
    if (mode_ == kDirect) {
      UpgradeTCPConnectedSocketToTLS(handle->tcp_socket.get(), host_port_pair,
                                     nullptr /* options */, std::move(request),
                                     std::move(callback));
    } else {
      UpgradeProxyResolvingSocketToTLS(handle->proxy_socket.get(),
                                       host_port_pair, std::move(request),
                                       std::move(callback));
    }
  }

  void UpgradeTCPConnectedSocketToTLS(mojom::TCPConnectedSocket* client_socket,
                                      const net::HostPortPair& host_port_pair,
                                      mojom::TLSClientSocketOptionsPtr options,
                                      mojom::TLSClientSocketRequest request,
                                      net::CompletionOnceCallback callback) {
    client_socket->UpgradeToTLS(
        host_port_pair, std::move(options),
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        std::move(request), post_tls_observer()->GetObserverPtr(),
        base::BindOnce(
            [](net::CompletionOnceCallback cb,
               mojo::ScopedDataPipeConsumerHandle* consumer_handle_out,
               mojo::ScopedDataPipeProducerHandle* producer_handle_out,
               base::Optional<net::SSLInfo>* ssl_info_out, int result,
               mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
               mojo::ScopedDataPipeProducerHandle send_pipe_handle,
               const base::Optional<net::SSLInfo>& ssl_info) {
              *consumer_handle_out = std::move(receive_pipe_handle);
              *producer_handle_out = std::move(send_pipe_handle);
              *ssl_info_out = ssl_info;
              std::move(cb).Run(result);
            },
            std::move(callback), &post_tls_recv_handle_, &post_tls_send_handle_,
            &ssl_info_));
  }

  void UpgradeProxyResolvingSocketToTLS(
      mojom::ProxyResolvingSocket* client_socket,
      const net::HostPortPair& host_port_pair,
      mojom::TLSClientSocketRequest request,
      net::CompletionOnceCallback callback) {
    client_socket->UpgradeToTLS(
        host_port_pair,
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        std::move(request), post_tls_observer()->GetObserverPtr(),
        base::BindOnce(
            [](net::CompletionOnceCallback cb,
               mojo::ScopedDataPipeConsumerHandle* consumer_handle,
               mojo::ScopedDataPipeProducerHandle* producer_handle, int result,
               mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
               mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
              *consumer_handle = std::move(receive_pipe_handle);
              *producer_handle = std::move(send_pipe_handle);
              std::move(cb).Run(result);
            },
            std::move(callback), &post_tls_recv_handle_,
            &post_tls_send_handle_));
  }

  TestSocketObserver* pre_tls_observer() { return &pre_tls_observer_; }
  TestSocketObserver* post_tls_observer() { return &post_tls_observer_; }

  mojo::ScopedDataPipeConsumerHandle* pre_tls_recv_handle() {
    return &pre_tls_recv_handle_;
  }

  mojo::ScopedDataPipeProducerHandle* pre_tls_send_handle() {
    return &pre_tls_send_handle_;
  }

  mojo::ScopedDataPipeConsumerHandle* post_tls_recv_handle() {
    return &post_tls_recv_handle_;
  }

  mojo::ScopedDataPipeProducerHandle* post_tls_send_handle() {
    return &post_tls_send_handle_;
  }

  const base::Optional<net::SSLInfo>& ssl_info() { return ssl_info_; }

  net::MockClientSocketFactory* mock_client_socket_factory() {
    return &mock_client_socket_factory_;
  }

  Mode mode() const { return mode_; }

 private:
  Mode mode_;
  base::test::ScopedTaskEnvironment scoped_task_environment_;

  // Mojo data handles obtained from CreateTCPConnectedSocket.
  mojo::ScopedDataPipeConsumerHandle pre_tls_recv_handle_;
  mojo::ScopedDataPipeProducerHandle pre_tls_send_handle_;

  // Mojo data handles obtained from UpgradeToTLS.
  mojo::ScopedDataPipeConsumerHandle post_tls_recv_handle_;
  mojo::ScopedDataPipeProducerHandle post_tls_send_handle_;

  // SSLInfo obtained from UpgradeToTLS.
  base::Optional<net::SSLInfo> ssl_info_;

  std::unique_ptr<net::ProxyResolutionService> proxy_resolution_service_;
  net::TestURLRequestContext url_request_context_;
  net::MockClientSocketFactory mock_client_socket_factory_;
  std::unique_ptr<SocketFactory> factory_;
  std::unique_ptr<ProxyResolvingSocketFactoryMojo> proxy_resolving_factory_;
  TestSocketObserver pre_tls_observer_;
  TestSocketObserver post_tls_observer_;
  mojo::StrongBindingSet<mojom::TCPServerSocket> tcp_server_socket_bindings_;
  mojo::StrongBindingSet<mojom::TCPConnectedSocket>
      tcp_connected_socket_bindings_;

  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketTestBase);
};

class TLSClientSocketTest
    : public ::testing::TestWithParam<TLSClientSocketTestBase::Mode>,
      public TLSClientSocketTestBase {
 public:
  TLSClientSocketTest() : TLSClientSocketTestBase(GetParam()) {
    Init(true /* use_mock_sockets */, false /* configure_proxy */);
  }

  ~TLSClientSocketTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketTest);
};

// Basic test to call UpgradeToTLS, and then read/write after UpgradeToTLS is
// successful.
TEST_P(TLSClientSocketTest, UpgradeToTLS) {
  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, kMsg, kMsgSize, 1),
                                  net::MockRead(net::SYNCHRONOUS, net::OK, 2)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Same as the UpgradeToTLS test above, except this test calls
// base::RunLoop().RunUntilIdle() after destroying the pre-tls data pipes.
TEST_P(TLSClientSocketTest, ClosePipesRunUntilIdleAndUpgradeToTLS) {
  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, kMsg, kMsgSize, 1),
                                  net::MockRead(net::SYNCHRONOUS, net::OK, 2)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);

  // Call RunUntilIdle() to test the case that pipes are closed before
  // UpgradeToTLS.
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  base::RunLoop().RunUntilIdle();

  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Calling UpgradeToTLS on the same TCPConnectedSocketPtr is illegal and should
// receive an error.
TEST_P(TLSClientSocketTest, UpgradeToTLSTwice) {
  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
  net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();

  // First UpgradeToTLS should complete successfully.
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());

  // Second time UpgradeToTLS is called, it should fail.
  mojom::TLSClientSocketPtr tls_socket2;
  base::RunLoop run_loop;
  int net_error = net::ERR_FAILED;
  if (mode() == kDirect) {
    auto upgrade2_callback = base::BindLambdaForTesting(
        [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
            mojo::ScopedDataPipeProducerHandle send_pipe_handle,
            const base::Optional<net::SSLInfo>& ssl_info) {
          net_error = result;
          run_loop.Quit();
        });
    client_socket.tcp_socket->UpgradeToTLS(
        host_port_pair, nullptr /* ssl_config_ptr */,
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        mojo::MakeRequest(&tls_socket2), nullptr /*observer */,
        std::move(upgrade2_callback));
  } else {
    auto upgrade2_callback = base::BindLambdaForTesting(
        [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
            mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
          net_error = result;
          run_loop.Quit();
        });
    client_socket.proxy_socket->UpgradeToTLS(
        host_port_pair,
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        mojo::MakeRequest(&tls_socket2), nullptr /*observer */,
        std::move(upgrade2_callback));
  }
  run_loop.Run();
  ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, net_error);

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

TEST_P(TLSClientSocketTest, UpgradeToTLSWithCustomSSLConfig) {
  // No custom options in the proxy-resolving case.
  if (mode() != kDirect)
    return;
  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
  net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  ssl_socket.expected_ssl_version_min = net::SSL_PROTOCOL_VERSION_TLS1_1;
  ssl_socket.expected_ssl_version_max = net::SSL_PROTOCOL_VERSION_TLS1_2;
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();

  mojom::TLSClientSocketPtr tls_socket;
  base::RunLoop run_loop;
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->version_min = mojom::SSLVersion::kTLS11;
  options->version_max = mojom::SSLVersion::kTLS12;
  int net_error = net::ERR_FAILED;
  auto upgrade_callback = base::BindLambdaForTesting(
      [&](int result, mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
          mojo::ScopedDataPipeProducerHandle send_pipe_handle,
          const base::Optional<net::SSLInfo>& ssl_info) {
        net_error = result;
        run_loop.Quit();
      });
  client_socket.tcp_socket->UpgradeToTLS(
      host_port_pair, std::move(options),
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
      mojo::MakeRequest(&tls_socket), nullptr /*observer */,
      std::move(upgrade_callback));
  run_loop.Run();
  ASSERT_EQ(net::OK, net_error);

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Same as the UpgradeToTLS test, except this also reads and writes to the tcp
// connection before UpgradeToTLS is called.
TEST_P(TLSClientSocketTest, ReadWriteBeforeUpgradeToTLS) {
  const net::MockRead kReads[] = {
      net::MockRead(net::SYNCHRONOUS, kMsg, kMsgSize, 0),
      net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 3),
      net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 1),
      net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 2),
  };
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));

  uint32_t num_bytes = kMsgSize;
  EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that a read error is encountered after UpgradeToTLS completes
// successfully.
TEST_P(TLSClientSocketTest, ReadErrorAfterUpgradeToTLS) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 1),
      net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 2)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 0)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
            post_tls_observer()->WaitForReadError());

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that a read error is encountered after UpgradeToTLS completes
// successfully.
TEST_P(TLSClientSocketTest, WriteErrorAfterUpgradeToTLS) {
  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 0)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 1)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
            post_tls_observer()->WaitForWriteError());

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that reading from the pre-tls data pipe is okay even after UpgradeToTLS
// is called.
TEST_P(TLSClientSocketTest, ReadFromPreTlsDataPipeAfterUpgradeToTLS) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
      net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 2),
      net::MockRead(net::SYNCHRONOUS, net::OK, 3)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 1)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  base::RunLoop().RunUntilIdle();

  EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));

  // Reset pre-tls receive pipe now and UpgradeToTLS should complete.
  pre_tls_recv_handle()->reset();
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that writing to the pre-tls data pipe is okay even after UpgradeToTLS
// is called.
TEST_P(TLSClientSocketTest, WriteToPreTlsDataPipeAfterUpgradeToTLS) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 2),
      net::MockRead(net::SYNCHRONOUS, net::OK, 3)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 0),
      net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 1)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  base::RunLoop().RunUntilIdle();

  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));

  // Reset pre-tls send pipe now and UpgradeToTLS should complete.
  pre_tls_send_handle()->reset();
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that reading from and writing to pre-tls data pipe is okay even after
// UpgradeToTLS is called.
TEST_P(TLSClientSocketTest, ReadAndWritePreTlsDataPipeAfterUpgradeToTLS) {
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
      net::MockRead(net::ASYNC, kSecretMsg, kSecretMsgSize, 3),
      net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 1),
      net::MockWrite(net::SYNCHRONOUS, kSecretMsg, kSecretMsgSize, 2)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  base::RunLoop run_loop;
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));

  // Reset pre-tls pipes now and UpgradeToTLS should complete.
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  num_bytes = strlen(kSecretMsg);
  EXPECT_EQ(MOJO_RESULT_OK,
            post_tls_send_handle()->get().WriteData(&kSecretMsg, &num_bytes,
                                                    MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that a read error is encountered before UpgradeToTLS completes.
TEST_P(TLSClientSocketTest, ReadErrorBeforeUpgradeToTLS) {
  // This requires pre_tls_observer(), which is not provided by proxy resolving
  // sockets.
  if (mode() != kDirect)
    return;
  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kMsg, kMsgSize, 0),
      net::MockRead(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 1)};
  net::SequencedSocketData data_provider(kReads, base::span<net::MockWrite>());
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());

  EXPECT_EQ(kMsg, Read(pre_tls_recv_handle(), kMsgSize));
  EXPECT_EQ(net::ERR_CONNECTION_CLOSED, pre_tls_observer()->WaitForReadError());

  // Reset pre-tls receive pipe now and UpgradeToTLS should complete.
  pre_tls_recv_handle()->reset();
  ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
  ResetSocket(&client_socket);

  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that a write error is encountered before UpgradeToTLS completes.
TEST_P(TLSClientSocketTest, WriteErrorBeforeUpgradeToTLS) {
  // This requires pre_tls_observer(), which is not provided by proxy resolving
  // sockets.
  if (mode() != kDirect)
    return;

  const net::MockRead kReads[] = {net::MockRead(net::ASYNC, net::OK, 1)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::SYNCHRONOUS, net::ERR_CONNECTION_CLOSED, 0)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, pre_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));

  EXPECT_EQ(net::ERR_CONNECTION_CLOSED,
            pre_tls_observer()->WaitForWriteError());
  // Reset pre-tls send pipe now and UpgradeToTLS should complete.
  pre_tls_send_handle()->reset();
  ASSERT_EQ(net::ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
  ResetSocket(&client_socket);

  base::RunLoop().RunUntilIdle();
  // Write failed before the mock read can be consumed.
  EXPECT_FALSE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    TLSClientSocketTest,
    ::testing::Values(TLSClientSocketTestBase::kDirect,
                      TLSClientSocketTestBase::kProxyResolving));

// Tests with proxy resolving socket and a proxy actually configured.
class TLSCLientSocketProxyTest : public ::testing::Test,
                                 public TLSClientSocketTestBase {
 public:
  TLSCLientSocketProxyTest()
      : TLSClientSocketTestBase(TLSClientSocketTestBase::kProxyResolving) {
    Init(true /* use_mock_sockets*/, true /* configure_proxy */);
  }

  ~TLSCLientSocketProxyTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TLSCLientSocketProxyTest);
};

TEST_F(TLSCLientSocketProxyTest, UpgradeToTLS) {
  const char kConnectRequest[] =
      "CONNECT 192.168.1.1:1234 HTTP/1.1\r\n"
      "Host: 192.168.1.1:1234\r\n"
      "Proxy-Connection: keep-alive\r\n\r\n";
  const char kConnectResponse[] = "HTTP/1.1 200 OK\r\n\r\n";

  const net::MockRead kReads[] = {
      net::MockRead(net::ASYNC, kConnectResponse, strlen(kConnectResponse), 1),
      net::MockRead(net::ASYNC, kMsg, kMsgSize, 3),
      net::MockRead(net::SYNCHRONOUS, net::OK, 4)};
  const net::MockWrite kWrites[] = {
      net::MockWrite(net::ASYNC, kConnectRequest, strlen(kConnectRequest), 0),
      net::MockWrite(net::SYNCHRONOUS, kMsg, kMsgSize, 2)};
  net::SequencedSocketData data_provider(kReads, kWrites);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  SocketHandle client_socket;
  net::IPEndPoint server_addr(net::IPAddress(192, 168, 1, 1), 1234);
  EXPECT_EQ(net::OK,
            CreateSocketSync(MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeToTLS(&client_socket, host_port_pair, mojo::MakeRequest(&tls_socket),
               callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ResetSocket(&client_socket);

  uint32_t num_bytes = strlen(kMsg);
  EXPECT_EQ(MOJO_RESULT_OK, post_tls_send_handle()->get().WriteData(
                                &kMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
  EXPECT_EQ(kMsg, Read(post_tls_recv_handle(), kMsgSize));
  base::RunLoop().RunUntilIdle();
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

class TLSClientSocketIoModeTest : public TLSClientSocketTestBase,
                                  public testing::TestWithParam<net::IoMode> {
 public:
  TLSClientSocketIoModeTest()
      : TLSClientSocketTestBase(TLSClientSocketTestBase::kDirect) {
    Init(true /* use_mock_sockets*/, false /* configure_proxy */);
  }

  ~TLSClientSocketIoModeTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketIoModeTest);
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         TLSClientSocketIoModeTest,
                         testing::Values(net::SYNCHRONOUS, net::ASYNC));

TEST_P(TLSClientSocketIoModeTest, MultipleWriteToTLSSocket) {
  const int kNumIterations = 3;
  std::vector<net::MockRead> reads;
  std::vector<net::MockWrite> writes;
  int sequence_number = 0;
  net::IoMode mode = GetParam();
  for (int j = 0; j < kNumIterations; ++j) {
    for (size_t i = 0; i < kSecretMsgSize; ++i) {
      writes.push_back(
          net::MockWrite(mode, &kSecretMsg[i], 1, sequence_number++));
    }
    for (size_t i = 0; i < kSecretMsgSize; ++i) {
      reads.push_back(
          net::MockRead(net::ASYNC, &kSecretMsg[i], 1, sequence_number++));
    }
    if (j == kNumIterations - 1) {
      reads.push_back(net::MockRead(mode, net::OK, sequence_number++));
    }
  }
  net::SequencedSocketData data_provider(reads, writes);
  data_provider.set_connect_data(net::MockConnect(GetParam(), net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  mojom::TCPConnectedSocketPtr client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK, CreateTCPConnectedSocketSync(
                         mojo::MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  UpgradeTCPConnectedSocketToTLS(
      client_socket.get(), host_port_pair, nullptr /* options */,
      mojo::MakeRequest(&tls_socket), callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  client_socket.reset();
  EXPECT_FALSE(ssl_info());

  // Loop kNumIterations times to test that writes can follow reads, and reads
  // can follow writes.
  for (int j = 0; j < kNumIterations; ++j) {
    // Write multiple times.
    for (size_t i = 0; i < kSecretMsgSize; ++i) {
      uint32_t num_bytes = 1;
      EXPECT_EQ(MOJO_RESULT_OK,
                post_tls_send_handle()->get().WriteData(
                    &kSecretMsg[i], &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
      // Flush the 1 byte write.
      base::RunLoop().RunUntilIdle();
    }
    // Reading kSecretMsgSize should coalesce the 1-byte mock reads.
    EXPECT_EQ(kSecretMsg, Read(post_tls_recv_handle(), kSecretMsgSize));
  }
  EXPECT_TRUE(ssl_socket.ConnectDataConsumed());
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Check SSLInfo is provided in both sync and async cases.
TEST_P(TLSClientSocketIoModeTest, SSLInfo) {
  // End of file. Reads don't matter, only the handshake does.
  std::vector<net::MockRead> reads = {net::MockRead(net::SYNCHRONOUS, net::OK)};
  std::vector<net::MockWrite> writes;
  net::SequencedSocketData data_provider(reads, writes);
  data_provider.set_connect_data(net::MockConnect(net::SYNCHRONOUS, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  net::SSLSocketDataProvider ssl_socket(GetParam(), net::OK);
  // Set a value on SSLInfo to make sure it's correctly received.
  ssl_socket.ssl_info.is_issued_by_known_root = true;
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

  mojom::TCPConnectedSocketPtr client_socket;
  net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(), 1234);
  EXPECT_EQ(net::OK, CreateTCPConnectedSocketSync(
                         mojo::MakeRequest(&client_socket), server_addr));

  net::HostPortPair host_port_pair("example.org", 443);
  pre_tls_recv_handle()->reset();
  pre_tls_send_handle()->reset();
  net::TestCompletionCallback callback;
  mojom::TLSClientSocketPtr tls_socket;
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->send_ssl_info = true;
  UpgradeTCPConnectedSocketToTLS(
      client_socket.get(), host_port_pair, std::move(options),
      mojo::MakeRequest(&tls_socket), callback.callback());
  ASSERT_EQ(net::OK, callback.WaitForResult());
  ASSERT_TRUE(ssl_info());
  EXPECT_TRUE(ssl_socket.ssl_info.is_issued_by_known_root);
  EXPECT_FALSE(ssl_socket.ssl_info.is_fatal_cert_error);
}

class TLSClientSocketTestWithEmbeddedTestServerBase
    : public TLSClientSocketTestBase {
 public:
  explicit TLSClientSocketTestWithEmbeddedTestServerBase(Mode mode)
      : TLSClientSocketTestBase(mode),
        server_(net::EmbeddedTestServer::TYPE_HTTPS) {
    Init(false /* use_mock_sockets */, false /* configure_proxy */);
  }

  ~TLSClientSocketTestWithEmbeddedTestServerBase() override {}

  // Starts the test server using the specified certificate.
  bool StartTestServer(net::EmbeddedTestServer::ServerCertificate certificate)
      WARN_UNUSED_RESULT {
    server_.RegisterRequestHandler(
        base::BindRepeating([](const net::test_server::HttpRequest& request) {
          if (base::StartsWith(request.relative_url, "/secret",
                               base::CompareCase::INSENSITIVE_ASCII)) {
            return std::unique_ptr<net::test_server::HttpResponse>(
                new net::test_server::RawHttpResponse("HTTP/1.1 200 OK",
                                                      "Hello There!"));
          }
          return std::unique_ptr<net::test_server::HttpResponse>();
        }));
    server_.SetSSLConfig(certificate);
    return server_.Start();
  }

  // Attempts to eastablish a TLS connection to the test server by first
  // establishing a TCP connection, and then upgrading it.  Returns the
  // resulting network error code.
  int CreateTLSSocket() WARN_UNUSED_RESULT {
    SocketHandle client_socket;
    net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(),
                                server_.port());
    EXPECT_EQ(net::OK,
              CreateSocketSync(MakeRequest(&client_socket), server_addr));

    pre_tls_recv_handle()->reset();
    pre_tls_send_handle()->reset();
    net::TestCompletionCallback callback;
    UpgradeToTLS(&client_socket, server_.host_port_pair(),
                 mojo::MakeRequest(&tls_socket_), callback.callback());
    int result = callback.WaitForResult();
    ResetSocket(&client_socket);
    return result;
  }

  int CreateTLSSocketWithOptions(mojom::TLSClientSocketOptionsPtr options)
      WARN_UNUSED_RESULT {
    // Proxy connections don't support TLSClientSocketOptions.
    DCHECK_EQ(kDirect, mode());

    mojom::TCPConnectedSocketPtr tcp_socket;
    net::IPEndPoint server_addr(net::IPAddress::IPv4Localhost(),
                                server_.port());
    EXPECT_EQ(net::OK, CreateTCPConnectedSocketSync(
                           mojo::MakeRequest(&tcp_socket), server_addr));

    pre_tls_recv_handle()->reset();
    pre_tls_send_handle()->reset();
    net::TestCompletionCallback callback;
    UpgradeTCPConnectedSocketToTLS(
        tcp_socket.get(), server_.host_port_pair(), std::move(options),
        mojo::MakeRequest(&tls_socket_), callback.callback());
    int result = callback.WaitForResult();
    tcp_socket.reset();
    return result;
  }

  void TestTlsSocket() {
    ASSERT_TRUE(tls_socket_.is_bound());
    const char kTestMsg[] = "GET /secret HTTP/1.1\r\n\r\n";
    uint32_t num_bytes = strlen(kTestMsg);
    const char kResponse[] = "HTTP/1.1 200 OK\n\n";
    EXPECT_EQ(MOJO_RESULT_OK,
              post_tls_send_handle()->get().WriteData(
                  &kTestMsg, &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
    EXPECT_EQ(kResponse, Read(post_tls_recv_handle(), strlen(kResponse)));
  }

  net::EmbeddedTestServer* server() { return &server_; }

 private:
  net::EmbeddedTestServer server_;

  mojom::TLSClientSocketPtr tls_socket_;

  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketTestWithEmbeddedTestServerBase);
};

class TLSClientSocketTestWithEmbeddedTestServer
    : public TLSClientSocketTestWithEmbeddedTestServerBase,
      public ::testing::TestWithParam<TLSClientSocketTestBase::Mode> {
 public:
  TLSClientSocketTestWithEmbeddedTestServer()
      : TLSClientSocketTestWithEmbeddedTestServerBase(GetParam()) {}
  ~TLSClientSocketTestWithEmbeddedTestServer() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketTestWithEmbeddedTestServer);
};

TEST_P(TLSClientSocketTestWithEmbeddedTestServer, Basic) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
  ASSERT_EQ(net::OK, CreateTLSSocket());
  // No SSLInfo should be received by default. SSLInfo is only supported in the
  // kDirect case, but it doesn't hurt to check it's null it in the
  // kProxyResolving case.
  EXPECT_FALSE(ssl_info());
  TestTlsSocket();
}

TEST_P(TLSClientSocketTestWithEmbeddedTestServer, ServerCertError) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
  ASSERT_EQ(net::ERR_CERT_COMMON_NAME_INVALID, CreateTLSSocket());
  // No SSLInfo should be received by default. SSLInfo is only supported in the
  // kDirect case, but it doesn't hurt to check it's null in the kProxyResolving
  // case.
  EXPECT_FALSE(ssl_info());

  // Handles should be invalid.
  EXPECT_FALSE(post_tls_recv_handle()->is_valid());
  EXPECT_FALSE(post_tls_send_handle()->is_valid());
}

INSTANTIATE_TEST_SUITE_P(
    /* no prefix */,
    TLSClientSocketTestWithEmbeddedTestServer,
    ::testing::Values(TLSClientSocketTestBase::kDirect,
                      TLSClientSocketTestBase::kProxyResolving));

class TLSClientSocketDirectTestWithEmbeddedTestServer
    : public TLSClientSocketTestWithEmbeddedTestServerBase,
      public testing::Test {
 public:
  TLSClientSocketDirectTestWithEmbeddedTestServer()
      : TLSClientSocketTestWithEmbeddedTestServerBase(kDirect) {}
  ~TLSClientSocketDirectTestWithEmbeddedTestServer() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(TLSClientSocketDirectTestWithEmbeddedTestServer);
};

TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer, SSLInfo) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->send_ssl_info = true;
  ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));

  ASSERT_TRUE(ssl_info());
  EXPECT_TRUE(ssl_info()->is_valid());
  EXPECT_FALSE(ssl_info()->is_fatal_cert_error);

  TestTlsSocket();
}

TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
       SSLInfoServerCertError) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->send_ssl_info = true;
  // Requesting SSLInfo should not bypass cert verification.
  ASSERT_EQ(net::ERR_CERT_COMMON_NAME_INVALID,
            CreateTLSSocketWithOptions(std::move(options)));

  // No SSLInfo should be provided on error.
  EXPECT_FALSE(ssl_info());

  // Handles should be invalid.
  EXPECT_FALSE(post_tls_recv_handle()->is_valid());
  EXPECT_FALSE(post_tls_send_handle()->is_valid());
}

// Check skipping cert verification always received SSLInfo, even with valid
// certs.
TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
       UnsafelySkipCertVerification) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_OK));
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->unsafely_skip_cert_verification = true;
  ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));

  ASSERT_TRUE(ssl_info());
  EXPECT_TRUE(ssl_info()->is_valid());
  EXPECT_FALSE(ssl_info()->is_fatal_cert_error);

  TestTlsSocket();
}

TEST_F(TLSClientSocketDirectTestWithEmbeddedTestServer,
       UnsafelySkipCertVerificationServerCertError) {
  ASSERT_TRUE(StartTestServer(net::EmbeddedTestServer::CERT_MISMATCHED_NAME));
  mojom::TLSClientSocketOptionsPtr options =
      mojom::TLSClientSocketOptions::New();
  options->unsafely_skip_cert_verification = true;
  ASSERT_EQ(net::OK, CreateTLSSocketWithOptions(std::move(options)));

  ASSERT_TRUE(ssl_info());
  EXPECT_TRUE(ssl_info()->is_valid());
  EXPECT_FALSE(ssl_info()->is_fatal_cert_error);

  TestTlsSocket();
}

}  // namespace

}  // namespace network
