// 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 <string>
#include <utility>
#include <vector>

#include "base/containers/span.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/run_loop.h"
#include "base/test/bind_test_util.h"
#include "base/test/task_environment.h"
#include "jingle/glue/fake_ssl_client_socket.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/socket/socket_test_util.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/proxy_resolving_socket_mojo.h"
#include "services/network/socket_factory.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace network {

namespace {

// A net::TestURLRequestContext implementation that configures the proxy to be
// a PAC string.
class TestURLRequestContextWithProxy : public net::TestURLRequestContext {
 public:
  explicit TestURLRequestContextWithProxy(const std::string& pac_result)
      : TestURLRequestContext(true) {
    context_storage_.set_proxy_resolution_service(
        net::ProxyResolutionService::CreateFixedFromPacResult(
            pac_result, TRAFFIC_ANNOTATION_FOR_TESTS));
    // net::MockHostResolver maps all hosts to localhost.
    auto host_resolver = std::make_unique<net::MockHostResolver>();
    context_storage_.set_host_resolver(std::move(host_resolver));
  }

  ~TestURLRequestContextWithProxy() override {}
};

}  // namespace

class ProxyResolvingSocketTestBase {
 public:
  ProxyResolvingSocketTestBase(bool use_tls)
      : use_tls_(use_tls),
        fake_tls_handshake_(false),
        task_environment_(base::test::TaskEnvironment::MainThreadType::IO) {}

  ~ProxyResolvingSocketTestBase() {}

  void Init(const std::string& pac_result) {
    // Init() can be called multiple times in a test. Reset the members for each
    // invocation. |context_with_proxy_| must outlive |factory_impl_|, which
    // uses the URLRequestContet.
    factory_receiver_ = nullptr;
    factory_impl_ = nullptr;
    factory_remote_.reset();
    context_with_proxy_ = nullptr;

    mock_client_socket_factory_ =
        std::make_unique<net::MockClientSocketFactory>();
    mock_client_socket_factory_->set_enable_read_if_ready(true);
    context_with_proxy_ =
        std::make_unique<TestURLRequestContextWithProxy>(pac_result);
    context_with_proxy_->set_client_socket_factory(
        mock_client_socket_factory_.get());
    context_with_proxy_->Init();

    factory_impl_ = std::make_unique<ProxyResolvingSocketFactoryMojo>(
        context_with_proxy_.get());
    factory_receiver_ =
        std::make_unique<mojo::Receiver<mojom::ProxyResolvingSocketFactory>>(
            factory_impl_.get(), factory_remote_.BindNewPipeAndPassReceiver());
  }

  // 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 - received_contents.size());
      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;
  }

  int CreateSocketSync(
      mojo::PendingReceiver<mojom::ProxyResolvingSocket> receiver,
      mojo::PendingRemote<mojom::SocketObserver> socket_observer,
      net::IPEndPoint* peer_addr_out,
      const GURL& url,
      mojo::ScopedDataPipeConsumerHandle* receive_pipe_handle_out,
      mojo::ScopedDataPipeProducerHandle* send_pipe_handle_out) {
    base::RunLoop run_loop;
    int net_error = net::ERR_FAILED;
    network::mojom::ProxyResolvingSocketOptionsPtr options =
        network::mojom::ProxyResolvingSocketOptions::New();
    options->use_tls = use_tls_;
    options->fake_tls_handshake = fake_tls_handshake_;
    factory_remote_->CreateProxyResolvingSocket(
        url, std::move(options),
        net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
        std::move(receiver), std::move(socket_observer),
        base::BindLambdaForTesting(
            [&](int result, const base::Optional<net::IPEndPoint>& local_addr,
                const base::Optional<net::IPEndPoint>& peer_addr,
                mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
                mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
              net_error = result;
              if (net_error == net::OK)
                EXPECT_NE(0, local_addr.value().port());
              if (peer_addr_out && peer_addr)
                *peer_addr_out = peer_addr.value();
              *receive_pipe_handle_out = std::move(receive_pipe_handle);
              *send_pipe_handle_out = std::move(send_pipe_handle);
              run_loop.Quit();
            }));
    run_loop.Run();
    return net_error;
  }

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

  bool use_tls() const { return use_tls_; }
  void set_fake_tls_handshake(bool val) { fake_tls_handshake_ = val; }

  mojom::ProxyResolvingSocketFactory* factory() {
    return factory_remote_.get();
  }

 private:
  const bool use_tls_;
  bool fake_tls_handshake_;
  base::test::TaskEnvironment task_environment_;
  std::unique_ptr<net::MockClientSocketFactory> mock_client_socket_factory_;
  std::unique_ptr<TestURLRequestContextWithProxy> context_with_proxy_;
  mojo::Remote<mojom::ProxyResolvingSocketFactory> factory_remote_;
  std::unique_ptr<mojo::Receiver<mojom::ProxyResolvingSocketFactory>>
      factory_receiver_;
  std::unique_ptr<ProxyResolvingSocketFactoryMojo> factory_impl_;

  DISALLOW_COPY_AND_ASSIGN(ProxyResolvingSocketTestBase);
};

class ProxyResolvingSocketTest : public ProxyResolvingSocketTestBase,
                                 public testing::TestWithParam<bool> {
 public:
  ProxyResolvingSocketTest() : ProxyResolvingSocketTestBase(GetParam()) {}

  ~ProxyResolvingSocketTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ProxyResolvingSocketTest);
};

INSTANTIATE_TEST_SUITE_P(/* no prefix */,
                         ProxyResolvingSocketTest,
                         ::testing::Bool());

// Tests that the connection is established to the proxy.
TEST_P(ProxyResolvingSocketTest, ConnectToProxy) {
  const GURL kDestination("https://example.com:443");
  const int kProxyPort = 8009;
  const int kDirectPort = 443;
  for (bool is_direct : {true, false}) {
    net::MockClientSocketFactory socket_factory;
    std::unique_ptr<net::URLRequestContext> context;
    if (is_direct) {
      Init("DIRECT");
    } else {
      Init(base::StringPrintf("PROXY myproxy.com:%d", kProxyPort));
    }
    // Note that this read is not consumed when |!is_direct|.
    net::MockRead reads[] = {net::MockRead("HTTP/1.1 200 Success\r\n\r\n"),
                             net::MockRead(net::ASYNC, net::OK)};
    // Note that this write is not consumed when |is_direct|.
    net::MockWrite writes[] = {
        net::MockWrite("CONNECT example.com:443 HTTP/1.1\r\n"
                       "Host: example.com:443\r\n"
                       "Proxy-Connection: keep-alive\r\n\r\n")};
    net::SSLSocketDataProvider ssl_socket(net::ASYNC, net::OK);
    mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_socket);

    net::StaticSocketDataProvider socket_data(reads, writes);
    net::IPEndPoint remote_addr(net::IPAddress(127, 0, 0, 1),
                                is_direct ? kDirectPort : kProxyPort);
    socket_data.set_connect_data(
        net::MockConnect(net::ASYNC, net::OK, remote_addr));
    mock_client_socket_factory()->AddSocketDataProvider(&socket_data);
    mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
    mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle;
    mojo::ScopedDataPipeProducerHandle client_socket_send_handle;
    net::IPEndPoint actual_remote_addr;
    EXPECT_EQ(net::OK, CreateSocketSync(socket.InitWithNewPipeAndPassReceiver(),
                                        mojo::NullRemote() /* socket_observer*/,
                                        &actual_remote_addr, kDestination,
                                        &client_socket_receive_handle,
                                        &client_socket_send_handle));
    // Consume all read data.
    base::RunLoop().RunUntilIdle();
    if (!is_direct) {
      EXPECT_EQ(net::IPEndPoint(), actual_remote_addr);
      EXPECT_TRUE(socket_data.AllReadDataConsumed());
      EXPECT_TRUE(socket_data.AllWriteDataConsumed());
    } else {
      EXPECT_EQ(remote_addr.ToString(), actual_remote_addr.ToString());
      EXPECT_TRUE(socket_data.AllReadDataConsumed());
      EXPECT_FALSE(socket_data.AllWriteDataConsumed());
    }
    EXPECT_EQ(use_tls(), ssl_socket.ConnectDataConsumed());
  }
}

TEST_P(ProxyResolvingSocketTest, ConnectError) {
  const struct TestData {
    // Whether the error is encountered synchronously as opposed to
    // asynchronously.
    bool is_error_sync;
    // Whether it is using a direct connection as opposed to a proxy connection.
    bool is_direct;
  } kTestCases[] = {
      {true, true}, {true, false}, {false, true}, {false, false},
  };
  const GURL kDestination("https://example.com:443");
  for (auto test : kTestCases) {
    std::unique_ptr<net::URLRequestContext> context;
    if (test.is_direct) {
      Init("DIRECT");
    } else {
      Init("PROXY myproxy.com:89");
    }
    net::StaticSocketDataProvider socket_data;
    socket_data.set_connect_data(net::MockConnect(
        test.is_error_sync ? net::SYNCHRONOUS : net::ASYNC, net::ERR_FAILED));
    mock_client_socket_factory()->AddSocketDataProvider(&socket_data);

    mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
    mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle;
    mojo::ScopedDataPipeProducerHandle client_socket_send_handle;
    int status = CreateSocketSync(socket.InitWithNewPipeAndPassReceiver(),
                                  mojo::NullRemote() /* socket_observer*/,
                                  nullptr /* peer_addr_out */, kDestination,
                                  &client_socket_receive_handle,
                                  &client_socket_send_handle);
    if (test.is_direct) {
      EXPECT_EQ(net::ERR_FAILED, status);
    } else {
      EXPECT_EQ(net::ERR_PROXY_CONNECTION_FAILED, status);
    }
    EXPECT_TRUE(socket_data.AllReadDataConsumed());
    EXPECT_TRUE(socket_data.AllWriteDataConsumed());
  }
}

// Tests writing to and reading from a mojom::ProxyResolvingSocket.
TEST_P(ProxyResolvingSocketTest, BasicReadWrite) {
  Init("DIRECT");
  mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
  const char kTestMsg[] = "abcdefghij";
  const size_t kMsgSize = strlen(kTestMsg);
  const int kNumIterations = 3;
  std::vector<net::MockRead> reads;
  std::vector<net::MockWrite> writes;
  int sequence_number = 0;
  for (int j = 0; j < kNumIterations; ++j) {
    for (size_t i = 0; i < kMsgSize; ++i) {
      reads.push_back(
          net::MockRead(net::ASYNC, &kTestMsg[i], 1, sequence_number++));
    }
    if (j == kNumIterations - 1) {
      reads.push_back(net::MockRead(net::ASYNC, net::OK, sequence_number++));
    }
    for (size_t i = 0; i < kMsgSize; ++i) {
      writes.push_back(
          net::MockWrite(net::ASYNC, &kTestMsg[i], 1, sequence_number++));
    }
  }
  net::StaticSocketDataProvider 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_data(net::ASYNC, net::OK);
  mock_client_socket_factory()->AddSSLSocketDataProvider(&ssl_data);
  mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle;
  mojo::ScopedDataPipeProducerHandle client_socket_send_handle;
  const GURL kDestination("http://example.com");
  EXPECT_EQ(net::OK, CreateSocketSync(socket.InitWithNewPipeAndPassReceiver(),
                                      mojo::NullRemote() /* socket_observer */,
                                      nullptr /* peer_addr_out */, kDestination,
                                      &client_socket_receive_handle,
                                      &client_socket_send_handle));
  // Loop kNumIterations times to test that writes can follow reads, and reads
  // can follow writes.
  for (int j = 0; j < kNumIterations; ++j) {
    // Reading kMsgSize should coalesce the 1-byte mock reads.
    EXPECT_EQ(kTestMsg, Read(&client_socket_receive_handle, kMsgSize));
    // Write multiple times.
    for (size_t i = 0; i < kMsgSize; ++i) {
      uint32_t num_bytes = 1;
      EXPECT_EQ(MOJO_RESULT_OK,
                client_socket_send_handle->WriteData(
                    &kTestMsg[i], &num_bytes, MOJO_WRITE_DATA_FLAG_NONE));
      // Flush the 1 byte write.
      base::RunLoop().RunUntilIdle();
    }
  }
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
  EXPECT_EQ(use_tls(), ssl_data.ConnectDataConsumed());
}

// Tests that exercise logic related to mojo.
class ProxyResolvingSocketMojoTest : public ProxyResolvingSocketTestBase,
                                     public testing::Test {
 public:
  ProxyResolvingSocketMojoTest() : ProxyResolvingSocketTestBase(false) {}

  ~ProxyResolvingSocketMojoTest() override {}

 private:
  DISALLOW_COPY_AND_ASSIGN(ProxyResolvingSocketMojoTest);
};

TEST_F(ProxyResolvingSocketMojoTest, ConnectWithFakeTLSHandshake) {
  const GURL kDestination("https://example.com:443");
  const char kTestMsg[] = "abcdefghij";
  const size_t kMsgSize = strlen(kTestMsg);

  Init("DIRECT");
  set_fake_tls_handshake(true);

  base::StringPiece client_hello =
      jingle_glue::FakeSSLClientSocket::GetSslClientHello();
  base::StringPiece server_hello =
      jingle_glue::FakeSSLClientSocket::GetSslServerHello();
  std::vector<net::MockRead> reads = {
      net::MockRead(net::ASYNC, server_hello.data(), server_hello.length(), 1),
      net::MockRead(net::ASYNC, 2, kTestMsg),
      net::MockRead(net::ASYNC, net::OK, 3)};

  std::vector<net::MockWrite> writes = {net::MockWrite(
      net::ASYNC, client_hello.data(), client_hello.length(), 0)};

  net::StaticSocketDataProvider data_provider(reads, writes);
  data_provider.set_connect_data(net::MockConnect(net::ASYNC, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);

  mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
  mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle;
  mojo::ScopedDataPipeProducerHandle client_socket_send_handle;
  net::IPEndPoint actual_remote_addr;
  EXPECT_EQ(net::OK, CreateSocketSync(socket.InitWithNewPipeAndPassReceiver(),
                                      mojo::NullRemote() /* socket_observer*/,
                                      &actual_remote_addr, kDestination,
                                      &client_socket_receive_handle,
                                      &client_socket_send_handle));

  EXPECT_EQ(kTestMsg, Read(&client_socket_receive_handle, kMsgSize));
  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

// Tests that when ProxyResolvingSocketPtr is destroyed but not the
// ProxyResolvingSocketFactory, the connect callback is not dropped.
// Regression test for https://crbug.com/862608.
TEST_F(ProxyResolvingSocketMojoTest, SocketDestroyedBeforeConnectCompletes) {
  Init("DIRECT");
  std::vector<net::MockRead> reads;
  std::vector<net::MockWrite> writes;

  net::StaticSocketDataProvider data_provider(reads, writes);
  data_provider.set_connect_data(net::MockConnect(net::ASYNC, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);
  const GURL kDestination("http://example.com");
  mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
  base::RunLoop run_loop;
  int net_error = net::OK;
  factory()->CreateProxyResolvingSocket(
      kDestination, nullptr,
      net::MutableNetworkTrafficAnnotationTag(TRAFFIC_ANNOTATION_FOR_TESTS),
      socket.InitWithNewPipeAndPassReceiver(),
      mojo::NullRemote() /* observer */,
      base::BindLambdaForTesting(
          [&](int result, const base::Optional<net::IPEndPoint>& local_addr,
              const base::Optional<net::IPEndPoint>& peer_addr,
              mojo::ScopedDataPipeConsumerHandle receive_pipe_handle,
              mojo::ScopedDataPipeProducerHandle send_pipe_handle) {
            net_error = result;
          }));
  socket.reset();
  base::RunLoop().RunUntilIdle();
  EXPECT_EQ(net::ERR_ABORTED, net_error);
}

TEST_F(ProxyResolvingSocketMojoTest, SocketObserver) {
  Init("DIRECT");

  const char kMsg[] = "message!";
  const char kMsgLen = strlen(kMsg);

  std::vector<net::MockRead> reads = {
      net::MockRead(kMsg),
      net::MockRead(net::ASYNC, net::ERR_CONNECTION_ABORTED)};
  std::vector<net::MockWrite> writes = {
      net::MockWrite(net::ASYNC, net::ERR_TIMED_OUT)};

  net::StaticSocketDataProvider data_provider(reads, writes);
  data_provider.set_connect_data(net::MockConnect(net::ASYNC, net::OK));
  mock_client_socket_factory()->AddSocketDataProvider(&data_provider);

  const GURL kDestination("http://example.com");

  mojo::PendingRemote<mojom::ProxyResolvingSocket> socket;
  mojo::ScopedDataPipeConsumerHandle client_socket_receive_handle;
  mojo::ScopedDataPipeProducerHandle client_socket_send_handle;
  TestSocketObserver test_observer;

  int status = CreateSocketSync(
      socket.InitWithNewPipeAndPassReceiver(),
      test_observer.GetObserverRemote(), nullptr /* peer_addr_out */,
      kDestination, &client_socket_receive_handle, &client_socket_send_handle);
  EXPECT_EQ(net::OK, status);

  EXPECT_EQ(kMsg, Read(&client_socket_receive_handle, kMsgLen));
  EXPECT_EQ(net::ERR_CONNECTION_ABORTED, test_observer.WaitForReadError());

  EXPECT_TRUE(mojo::BlockingCopyFromString(kMsg, client_socket_send_handle));
  EXPECT_EQ(net::ERR_TIMED_OUT, test_observer.WaitForWriteError());

  EXPECT_TRUE(data_provider.AllReadDataConsumed());
  EXPECT_TRUE(data_provider.AllWriteDataConsumed());
}

}  // namespace network
