// Copyright (c) 2012 The Chromium OS 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 "shill/http_proxy.h"

#include <netinet/in.h>

#include <string>
#include <vector>

#include <base/strings/stringprintf.h>
#include <gtest/gtest.h>

#include "shill/ip_address.h"
#include "shill/mock_async_connection.h"
#include "shill/mock_connection.h"
#include "shill/mock_control.h"
#include "shill/mock_device_info.h"
#include "shill/mock_dns_client.h"
#include "shill/mock_event_dispatcher.h"
#include "shill/mock_sockets.h"

using base::StringPrintf;
using std::string;
using std::vector;
using ::testing::_;
using ::testing::AtLeast;
using ::testing::DoAll;
using ::testing::Invoke;
using ::testing::NiceMock;
using ::testing::Return;
using ::testing::ReturnArg;
using ::testing::ReturnNew;
using ::testing::ReturnRef;
using ::testing::SetArgumentPointee;
using ::testing::StrEq;
using ::testing::StrictMock;
using ::testing::Test;

namespace shill {

namespace {
const char kBadHeaderMissingURL[] = "BLAH\r\n";
const char kBadHeaderMissingVersion[] = "BLAH http://hostname\r\n";
const char kBadHostnameLine[] = "GET HTTP/1.1 http://hostname\r\n";
const char kBasicGetHeader[] = "GET / HTTP/1.1\r\n";
const char kBasicGetHeaderWithURL[] =
    "GET http://www.chromium.org/ HTTP/1.1\r\n";
const char kBasicGetHeaderWithURLNoTrailingSlash[] =
    "GET http://www.chromium.org HTTP/1.1\r\n";
const char kConnectQuery[] =
    "CONNECT 10.10.10.10:443 HTTP/1.1\r\n"
    "Host: 10.10.10.10:443\r\n\r\n";
const char kQueryTemplate[] = "GET %s HTTP/%s\r\n%s"
    "User-Agent: Mozilla/5.0 (X11; CrOS i686 1299.0.2011) "
    "AppleWebKit/535.8 (KHTML, like Gecko) Chrome/17.0.936.0 Safari/535.8\r\n"
    "Accept: text/html,application/xhtml+xml,application/xml;"
    "q=0.9,*/*;q=0.8\r\n"
    "Accept-Encoding: gzip,deflate,sdch\r\n"
    "Accept-Language: en-US,en;q=0.8,ja;q=0.6\r\n"
    "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3\r\n"
    "Cookie: PREF=ID=xxxxxxxxxxxxxxxx:U=xxxxxxxxxxxxxxxx:FF=0:"
    "TM=1317340083:LM=1317390705:GM=1:S=_xxxxxxxxxxxxxxx; "
    "NID=52=xxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxx; "
    "HSID=xxxxxxxxxxxx-xxxx; APISID=xxxxxxxxxxxxxxxx/xxxxxxxxxxxxxxxxx; "
    "SID=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx_xxxxxxxxxxx"
    "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxx"
    "xxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx-xxxxxxxxxxxxxxxxxx"
    "_xxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxx-xx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
    "xxxxxxxxxxxxxxxx\r\n\r\n";
const char kInterfaceName[] = "int0";
const char kDNSServer0[] = "8.8.8.8";
const char kDNSServer1[] = "8.8.4.4";
const char kServerAddress[] = "10.10.10.10";
const char *kDNSServers[] = { kDNSServer0, kDNSServer1 };
const int kProxyFD = 10203;
const int kServerFD = 10204;
const int kClientFD = 10205;
const int kServerPort = 40506;
const int kConnectPort = 443;
}  // namespace

MATCHER_P(IsIPAddress, address, "") {
  IPAddress ip_address(IPAddress::kFamilyIPv4);
  EXPECT_TRUE(ip_address.SetAddressFromString(address));
  return ip_address.Equals(arg);
}

MATCHER_P(CallbackEq, callback, "") {
  return arg.Equals(callback);
}

class HTTPProxyTest : public Test {
 public:
  HTTPProxyTest()
      : interface_name_(kInterfaceName),
        server_async_connection_(NULL),
        dns_servers_(kDNSServers, kDNSServers + 2),
        dns_client_(NULL),
        device_info_(new NiceMock<MockDeviceInfo>(
            &control_,
            reinterpret_cast<EventDispatcher*>(NULL),
            reinterpret_cast<Metrics*>(NULL),
            reinterpret_cast<Manager*>(NULL))),
        connection_(new StrictMock<MockConnection>(device_info_.get())),
        proxy_(connection_) { }

 protected:
  virtual void SetUp() {
    EXPECT_CALL(*connection_.get(), interface_name())
        .WillRepeatedly(ReturnRef(interface_name_));
    EXPECT_CALL(*connection_.get(), dns_servers())
        .WillRepeatedly(ReturnRef(dns_servers_));
  }
  virtual void TearDown() {
    if (proxy_.sockets_) {
      ExpectStop();
    }
    const int proxy_fds[] = {
      proxy_.client_socket_,
      proxy_.server_socket_,
      proxy_.proxy_socket_
    };
    for (const int fd : proxy_fds) {
      if (fd != -1) {
        EXPECT_CALL(sockets_, Close(fd));
      }
    }
  }
  string CreateRequest(const string &url, const string &http_version,
                       const string &extra_lines) {
    string append_lines(extra_lines);
    if (append_lines.size()) {
      append_lines.append("\r\n");
    }
    return StringPrintf(kQueryTemplate, url.c_str(), http_version.c_str(),
                        append_lines.c_str());
  }
  int InvokeGetSockName(int fd, struct sockaddr *addr_out,
                        socklen_t *sockaddr_size) {
    struct sockaddr_in addr;
    EXPECT_EQ(kProxyFD, fd);
    EXPECT_GE(sizeof(sockaddr_in), *sockaddr_size);
    addr.sin_addr.s_addr = 0;
    addr.sin_port = kServerPort;
    memcpy(addr_out, &addr, sizeof(addr));
    *sockaddr_size = sizeof(sockaddr_in);
    return 0;
  }
  void  InvokeSyncConnect(const IPAddress &/*address*/, int /*port*/) {
    proxy_.OnConnectCompletion(true, kServerFD);
  }
  size_t FindInRequest(const string &find_string) {
    const ByteString &request_data = GetClientData();
    string request_string(
        reinterpret_cast<const char *>(request_data.GetConstData()),
        request_data.GetLength());
    return request_string.find(find_string);
  }
  // Accessors
  const ByteString &GetClientData() {
    return proxy_.client_data_;
  }
  HTTPProxy *proxy() { return &proxy_; }
  HTTPProxy::State GetProxyState() {
    return proxy_.state_;
  }
  const ByteString &GetServerData() {
    return proxy_.server_data_;
  }
  MockSockets &sockets() { return sockets_; }
  MockEventDispatcher &dispatcher() { return dispatcher_; }


  // Expectations
  void ExpectClientReset() {
    EXPECT_EQ(-1, proxy_.client_socket_);
    EXPECT_TRUE(proxy_.client_version_.empty());
    EXPECT_EQ(HTTPProxy::kDefaultServerPort, proxy_.server_port_);
    EXPECT_EQ(-1, proxy_.server_socket_);
    EXPECT_TRUE(proxy_.idle_timeout_.IsCancelled());
    EXPECT_TRUE(proxy_.client_headers_.empty());
    EXPECT_TRUE(proxy_.server_hostname_.empty());
    EXPECT_TRUE(proxy_.client_data_.IsEmpty());
    EXPECT_TRUE(proxy_.server_data_.IsEmpty());
    EXPECT_FALSE(proxy_.read_client_handler_.get());
    EXPECT_FALSE(proxy_.write_client_handler_.get());
    EXPECT_FALSE(proxy_.read_server_handler_.get());
    EXPECT_FALSE(proxy_.write_server_handler_.get());
    EXPECT_FALSE(proxy_.is_route_requested_);
  }
  void ExpectReset() {
    EXPECT_FALSE(proxy_.accept_handler_.get());
    EXPECT_EQ(proxy_.connection_.get(), connection_.get());
    EXPECT_FALSE(proxy_.dispatcher_);
    EXPECT_FALSE(proxy_.dns_client_.get());
    EXPECT_EQ(-1, proxy_.proxy_port_);
    EXPECT_EQ(-1, proxy_.proxy_socket_);
    EXPECT_FALSE(proxy_.server_async_connection_.get());
    EXPECT_FALSE(proxy_.sockets_);
    EXPECT_EQ(HTTPProxy::kStateIdle, proxy_.state_);
    ExpectClientReset();
  }
  void ExpectStart() {
    EXPECT_CALL(sockets(), Socket(_, _, _))
        .WillOnce(Return(kProxyFD));
    EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
        .WillOnce(Return(0));
    EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
        .WillOnce(Invoke(this, &HTTPProxyTest::InvokeGetSockName));
    EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
        .WillOnce(Return(0));
    EXPECT_CALL(sockets(), Listen(kProxyFD, _))
        .WillOnce(Return(0));
    EXPECT_CALL(dispatcher_,
                CreateReadyHandler(kProxyFD,
                                   IOHandler::kModeInput,
                                   CallbackEq(proxy_.accept_callback_)))
        .WillOnce(ReturnNew<IOHandler>());
  }
  void ExpectStop() {
     if (dns_client_) {
       EXPECT_CALL(*dns_client_, Stop())
           .Times(AtLeast(1));
     }
     if (server_async_connection_) {
       EXPECT_CALL(*server_async_connection_, Stop())
           .Times(AtLeast(1));
     }
     if (proxy_.is_route_requested_) {
       EXPECT_CALL(*connection_.get(), ReleaseRouting());
     }
  }
  void ExpectClientInput(int fd) {
    EXPECT_CALL(sockets(), Accept(kProxyFD, _, _))
        .WillOnce(Return(fd));
    EXPECT_CALL(sockets(), SetNonBlocking(fd))
        .WillOnce(Return(0));
    EXPECT_CALL(dispatcher(),
                CreateInputHandler(fd,
                                   CallbackEq(proxy_.read_client_callback_), _))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectTransactionTimeout();
    ExpectClientHeaderTimeout();
  }
  void ExpectTimeout(int timeout) {
    EXPECT_CALL(dispatcher_, PostDelayedTask(_, timeout * 1000))
        .WillOnce(Return(true));
  }
  void ExpectClientHeaderTimeout() {
    ExpectTimeout(HTTPProxy::kClientHeaderTimeoutSeconds);
  }
  void ExpectConnectTimeout() {
    ExpectTimeout(HTTPProxy::kConnectTimeoutSeconds);
  }
  void ExpectInputTimeout() {
    ExpectTimeout(HTTPProxy::kInputTimeoutSeconds);
  }
  void ExpectRepeatedInputTimeout() {
    EXPECT_CALL(dispatcher_,
                PostDelayedTask(_, HTTPProxy::kInputTimeoutSeconds * 1000))
        .WillRepeatedly(Return(true));
  }
  void ExpectTransactionTimeout() {
    ExpectTimeout(HTTPProxy::kTransactionTimeoutSeconds);
  }
  void ExpectInClientResponse(const string &response_data) {
    string server_data(reinterpret_cast<char *>(proxy_.server_data_.GetData()),
                       proxy_.server_data_.GetLength());
    EXPECT_NE(string::npos, server_data.find(response_data));
  }
  void ExpectClientError(int code, const string &error) {
    EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());
    string status_line = StringPrintf("HTTP/1.1 %d ERROR", code);
    ExpectInClientResponse(status_line);
    ExpectInClientResponse(error);
  }
  void ExpectClientInternalError() {
    ExpectClientError(500, HTTPProxy::kInternalErrorMsg);
  }
  void ExpectClientVersion(const string &version) {
    EXPECT_EQ(version, proxy_.client_version_);
  }
  void ExpectServerHostname(const string &hostname) {
    EXPECT_EQ(hostname, proxy_.server_hostname_);
  }
  void ExpectFirstLine(const string &line) {
    EXPECT_EQ(line, proxy_.client_headers_[0] + "\r\n");
  }
  void ExpectDNSRequest(const string &host, bool return_value) {
    EXPECT_CALL(*dns_client_, Start(StrEq(host), _))
        .WillOnce(Return(return_value));
  }
  void ExpectAsyncConnect(const string &address, int port,
                          bool return_value) {
    EXPECT_CALL(*server_async_connection_, Start(IsIPAddress(address), port))
        .WillOnce(Return(return_value));
  }
  void ExpectSyncConnect(const string &address, int port) {
    EXPECT_CALL(*server_async_connection_, Start(IsIPAddress(address), port))
        .WillOnce(DoAll(Invoke(this, &HTTPProxyTest::InvokeSyncConnect),
                        Return(true)));
  }
  void ExpectClientData() {
    EXPECT_CALL(dispatcher(),
                CreateReadyHandler(kClientFD,
                                   IOHandler::kModeOutput,
                                   CallbackEq(proxy_.write_client_callback_)))
        .WillOnce(ReturnNew<IOHandler>());
  }
  void ExpectClientResult() {
    ExpectClientData();
    ExpectInputTimeout();
  }
  void ExpectServerInput() {
    EXPECT_CALL(dispatcher(),
                CreateInputHandler(kServerFD,
                                   CallbackEq(proxy_.read_server_callback_), _))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectInputTimeout();
  }
  void ExpectServerOutput() {
    EXPECT_CALL(dispatcher(),
                CreateReadyHandler(kServerFD,
                                   IOHandler::kModeOutput,
                                   CallbackEq(proxy_.write_server_callback_)))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectInputTimeout();
  }
  void ExpectRepeatedServerOutput() {
    EXPECT_CALL(dispatcher(),
                CreateReadyHandler(kServerFD, IOHandler::kModeOutput,
                                   CallbackEq(proxy_.write_server_callback_)))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectRepeatedInputTimeout();
  }
  void ExpectTunnelClose() {
    EXPECT_CALL(sockets(), Close(kClientFD))
        .WillOnce(Return(0));
    EXPECT_CALL(sockets(), Close(kServerFD))
        .WillOnce(Return(0));
    ExpectStop();
  }
  void ExpectRouteRequest() {
    EXPECT_CALL(*connection_.get(), RequestRouting());
  }
  void ExpectRouteRelease() {
    EXPECT_CALL(*connection_.get(), ReleaseRouting());
  }

  // Callers for various private routines in the proxy
  bool StartProxy() {
    bool ret = proxy_.Start(&dispatcher_, &sockets_);
    if (ret) {
      dns_client_ = new StrictMock<MockDNSClient>();
      // Passes ownership.
      proxy_.dns_client_.reset(dns_client_);
      server_async_connection_ = new StrictMock<MockAsyncConnection>();
      // Passes ownership.
      proxy_.server_async_connection_.reset(server_async_connection_);
    }
    return ret;
  }
  void AcceptClient(int fd) {
    proxy_.AcceptClient(fd);
  }
  void GetDNSResultFailure(const string &error_msg) {
    Error error(Error::kOperationFailed, error_msg);
    IPAddress address(IPAddress::kFamilyUnknown);
    proxy_.GetDNSResult(error, address);
  }
  void GetDNSResultSuccess(const IPAddress &address) {
    Error error;
    proxy_.GetDNSResult(error, address);
  }
  void OnConnectCompletion(bool result, int sockfd) {
    proxy_.OnConnectCompletion(result, sockfd);
  }
  void ReadFromClient(const string &data) {
    const unsigned char *ptr =
        reinterpret_cast<const unsigned char *>(data.c_str());
    vector<unsigned char> data_bytes(ptr, ptr + data.length());
    InputData proxy_data(data_bytes.data(), data_bytes.size());
    proxy_.ReadFromClient(&proxy_data);
  }
  void ReadFromServer(const string &data) {
    const unsigned char *ptr =
        reinterpret_cast<const unsigned char *>(data.c_str());
    vector<unsigned char> data_bytes(ptr, ptr + data.length());
    InputData proxy_data(data_bytes.data(), data_bytes.size());
    proxy_.ReadFromServer(&proxy_data);
  }
  void SendClientError(int code, const string &error) {
    proxy_.SendClientError(code, error);
    EXPECT_FALSE(proxy_.server_data_.IsEmpty());
  }
  void StopClient() {
    EXPECT_CALL(*dns_client_, Stop());
    EXPECT_CALL(*server_async_connection_, Stop());
    proxy_.StopClient();
  }
  void StopProxy() {
    ExpectStop();
    proxy_.Stop();
    server_async_connection_ = NULL;
    dns_client_ = NULL;
    ExpectReset();
  }
  void WriteToClient(int fd) {
    proxy_.WriteToClient(fd);
  }
  void WriteToServer(int fd) {
    proxy_.WriteToServer(fd);
  }

  void SetupClient() {
    ExpectStart();
    ASSERT_TRUE(StartProxy());
    ExpectClientInput(kClientFD);
    AcceptClient(kProxyFD);
    EXPECT_EQ(HTTPProxy::kStateReadClientHeader, GetProxyState());
  }
  void SetupConnectWithRequest(const string &url, const string &http_version,
                               const string &extra_lines) {
    ExpectDNSRequest("www.chromium.org", true);
    ExpectRouteRequest();
    ReadFromClient(CreateRequest(url, http_version, extra_lines));
    IPAddress addr(IPAddress::kFamilyIPv4);
    EXPECT_TRUE(addr.SetAddressFromString(kServerAddress));
    GetDNSResultSuccess(addr);
  }
  void SetupConnect() {
    SetupConnectWithRequest("/", "1.1", "Host: www.chromium.org:40506");
  }
  void SetupConnectAsync() {
    SetupClient();
    ExpectAsyncConnect(kServerAddress, kServerPort, true);
    ExpectConnectTimeout();
    SetupConnect();
  }
  void SetupConnectComplete() {
    SetupConnectAsync();
    ExpectServerOutput();
    OnConnectCompletion(true, kServerFD);
    EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
  }
  void CauseReadError() {
    proxy_.OnReadError(Error());
  }

 private:
  const string interface_name_;
  // Owned by the HTTPProxy, but tracked here for EXPECT().
  StrictMock<MockAsyncConnection> *server_async_connection_;
  vector<string> dns_servers_;
  // Owned by the HTTPProxy, but tracked here for EXPECT().
  StrictMock<MockDNSClient> *dns_client_;
  MockEventDispatcher dispatcher_;
  MockControl control_;
  scoped_ptr<MockDeviceInfo> device_info_;
  scoped_refptr<MockConnection> connection_;
  StrictMock<MockSockets> sockets_;
  HTTPProxy proxy_;  // Destroy first, before anything it references.
};

TEST_F(HTTPProxyTest, StartFailSocket) {
  EXPECT_CALL(sockets(), Socket(_, _, _))
      .WillOnce(Return(-1));
  EXPECT_FALSE(StartProxy());
  ExpectReset();
}

TEST_F(HTTPProxyTest, StartFailBind) {
  EXPECT_CALL(sockets(), Socket(_, _, _))
      .WillOnce(Return(kProxyFD));
  EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
      .WillOnce(Return(-1));
  EXPECT_CALL(sockets(), Close(kProxyFD))
      .WillOnce(Return(0));
  EXPECT_FALSE(StartProxy());
  ExpectReset();
}

TEST_F(HTTPProxyTest, StartFailGetSockName) {
  EXPECT_CALL(sockets(), Socket(_, _, _))
      .WillOnce(Return(kProxyFD));
  EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
      .WillOnce(Return(-1));
  EXPECT_CALL(sockets(), Close(kProxyFD))
      .WillOnce(Return(0));
  EXPECT_FALSE(StartProxy());
  ExpectReset();
}

TEST_F(HTTPProxyTest, StartFailSetNonBlocking) {
  EXPECT_CALL(sockets(), Socket(_, _, _))
      .WillOnce(Return(kProxyFD));
  EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
      .WillOnce(Return(-1));
  EXPECT_CALL(sockets(), Close(kProxyFD))
      .WillOnce(Return(0));
  EXPECT_FALSE(StartProxy());
  ExpectReset();
}

TEST_F(HTTPProxyTest, StartFailListen) {
  EXPECT_CALL(sockets(), Socket(_, _, _))
      .WillOnce(Return(kProxyFD));
  EXPECT_CALL(sockets(), Bind(kProxyFD, _, _))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), GetSockName(kProxyFD, _, _))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), SetNonBlocking(kProxyFD))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), Listen(kProxyFD, _))
      .WillOnce(Return(-1));
  EXPECT_CALL(sockets(), Close(kProxyFD))
      .WillOnce(Return(0));
  EXPECT_FALSE(StartProxy());
  ExpectReset();
}

TEST_F(HTTPProxyTest, StartSuccess) {
  ExpectStart();
  EXPECT_TRUE(StartProxy());
}

TEST_F(HTTPProxyTest, SendClientError) {
  SetupClient();
  ExpectClientResult();
  SendClientError(500, "This is an error");
  ExpectClientError(500, "This is an error");

  // We succeed in sending all but one byte of the client response.
  int buf_len = GetServerData().GetLength();
  EXPECT_CALL(sockets(), Send(kClientFD, _, buf_len, 0))
      .WillOnce(Return(buf_len - 1));
  ExpectInputTimeout();
  WriteToClient(kClientFD);
  EXPECT_EQ(1, GetServerData().GetLength());
  EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());

  // When we are able to send the last byte, we close the connection.
  EXPECT_CALL(sockets(), Send(kClientFD, _, 1, 0))
      .WillOnce(Return(1));
  EXPECT_CALL(sockets(), Close(kClientFD))
      .WillOnce(Return(0));
  ExpectStop();
  WriteToClient(kClientFD);
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, ReadMissingURL) {
  SetupClient();
  ExpectClientResult();
  ReadFromClient(kBadHeaderMissingURL);
  ExpectClientError(501, "Server could not parse HTTP method");
}

TEST_F(HTTPProxyTest, ReadMissingVersion) {
  SetupClient();
  ExpectClientResult();
  ReadFromClient(kBadHeaderMissingVersion);
  ExpectClientError(501, "Server only accepts HTTP/1.x requests");
}

TEST_F(HTTPProxyTest, ReadBadHostname) {
  SetupClient();
  ExpectClientResult();
  ReadFromClient(kBadHostnameLine);
  ExpectClientInternalError();
}

TEST_F(HTTPProxyTest, GoodFirstLineWithoutURL) {
  SetupClient();
  ExpectClientHeaderTimeout();
  ReadFromClient(kBasicGetHeader);
  ExpectClientVersion("1.1");
  ExpectServerHostname("");
  ExpectFirstLine(kBasicGetHeader);
}

TEST_F(HTTPProxyTest, GoodFirstLineWithURL) {
  SetupClient();
  ExpectClientHeaderTimeout();
  ReadFromClient(kBasicGetHeaderWithURL);
  ExpectClientVersion("1.1");
  ExpectServerHostname("www.chromium.org");
  ExpectFirstLine(kBasicGetHeader);
}

TEST_F(HTTPProxyTest, GoodFirstLineWithURLNoSlash) {
  SetupClient();
  ExpectClientHeaderTimeout();
  ReadFromClient(kBasicGetHeaderWithURLNoTrailingSlash);
  ExpectClientVersion("1.1");
  ExpectServerHostname("www.chromium.org");
  ExpectFirstLine(kBasicGetHeader);
}

TEST_F(HTTPProxyTest, NoHostInRequest) {
  SetupClient();
  ExpectClientResult();
  ReadFromClient(CreateRequest("/", "1.1", ""));
  ExpectClientError(400, "I don't know what host you want me to connect to");
}

TEST_F(HTTPProxyTest, TooManyColonsInHost) {
  SetupClient();
  ExpectClientResult();
  ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:80:40506"));
  ExpectClientError(400, "Too many colons in hostname");
}

TEST_F(HTTPProxyTest, ClientReadError) {
  SetupClient();
  EXPECT_CALL(sockets(), Close(kClientFD))
      .WillOnce(Return(0));
  ExpectStop();
  CauseReadError();
  ExpectClientReset();
}

TEST_F(HTTPProxyTest, DNSRequestFailure) {
  SetupClient();
  ExpectRouteRequest();
  ExpectDNSRequest("www.chromium.org", false);
  ExpectClientResult();
  ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506"));
  ExpectClientError(502, "Could not resolve hostname");
}

TEST_F(HTTPProxyTest, DNSRequestDelayedFailure) {
  SetupClient();
  ExpectRouteRequest();
  ExpectDNSRequest("www.chromium.org", true);
  ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506"));
  ExpectClientResult();
  const std::string not_found_error(DNSClient::kErrorNotFound);
  GetDNSResultFailure(not_found_error);
  ExpectClientError(502, string("Could not resolve hostname: ") +
                    not_found_error);
}

TEST_F(HTTPProxyTest, TrailingClientData) {
  SetupClient();
  ExpectRouteRequest();
  ExpectDNSRequest("www.chromium.org", true);
  const string trailing_data("Trailing client data");
  ReadFromClient(CreateRequest("/", "1.1", "Host: www.chromium.org:40506") +
                 trailing_data);
  EXPECT_EQ(GetClientData().GetLength() - trailing_data.length(),
            FindInRequest(trailing_data));
  EXPECT_EQ(HTTPProxy::kStateLookupServer, GetProxyState());
}

TEST_F(HTTPProxyTest, LineContinuation) {
  SetupClient();
  ExpectRouteRequest();
  ExpectDNSRequest("www.chromium.org", true);
  string text_to_keep("X-Long-Header: this is one line\r\n"
                      "\tand this is another");
  ReadFromClient(CreateRequest("http://www.chromium.org/", "1.1",
                               text_to_keep));
  EXPECT_NE(string::npos, FindInRequest(text_to_keep));
}

// NB: This tests two different things:
//   1) That the system replaces the value for "Proxy-Connection" headers.
//   2) That when it replaces a header, it also removes the text in the line
//      continuation.
TEST_F(HTTPProxyTest, LineContinuationRemoval) {
  SetupClient();
  ExpectRouteRequest();
  ExpectDNSRequest("www.chromium.org", true);
  string text_to_remove("remove this text please");
  ReadFromClient(CreateRequest("http://www.chromium.org/", "1.1",
                               string("Proxy-Connection: stuff\r\n\t") +
                               text_to_remove));
  EXPECT_EQ(string::npos, FindInRequest(text_to_remove));
  EXPECT_NE(string::npos, FindInRequest("Proxy-Connection: close\r\n"));
}

TEST_F(HTTPProxyTest, ConnectSynchronousFailure) {
  SetupClient();
  ExpectAsyncConnect(kServerAddress, kServerPort, false);
  ExpectClientResult();
  SetupConnect();
  ExpectClientError(500, "Could not create socket to connect to server");
}

TEST_F(HTTPProxyTest, ConnectAsyncConnectFailure) {
  SetupConnectAsync();
  ExpectClientResult();
  OnConnectCompletion(false, -1);
  ExpectClientError(500, "Socket connection delayed failure");
}

TEST_F(HTTPProxyTest, ConnectSynchronousSuccess) {
  SetupClient();
  ExpectSyncConnect(kServerAddress, 999);
  ExpectRepeatedServerOutput();
  SetupConnectWithRequest("/", "1.1", "Host: www.chromium.org:999");
  EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
}

TEST_F(HTTPProxyTest, ConnectIPAddresss) {
  SetupClient();
  ExpectSyncConnect(kServerAddress, 999);
  ExpectRepeatedServerOutput();
  ExpectRouteRequest();
  ReadFromClient(CreateRequest("/", "1.1",
                               StringPrintf("Host: %s:999", kServerAddress)));
  EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());
}

TEST_F(HTTPProxyTest, ConnectAsyncConnectSuccess) {
  SetupConnectComplete();
}

TEST_F(HTTPProxyTest, HTTPConnectMethod) {
  SetupClient();
  ExpectAsyncConnect(kServerAddress, kConnectPort, true);
  ExpectConnectTimeout();
  ExpectRouteRequest();
  ReadFromClient(kConnectQuery);
  ExpectRepeatedInputTimeout();
  ExpectClientData();
  OnConnectCompletion(true, kServerFD);
  ExpectInClientResponse("HTTP/1.1 200 OK\r\n\r\n");
}

TEST_F(HTTPProxyTest, TunnelData) {
  SetupConnectComplete();

  // The proxy is waiting for the server to be ready to accept data.
  EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
      .WillOnce(Return(10));
  ExpectServerInput();
  WriteToServer(kServerFD);
  EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
      .WillOnce(ReturnArg<2>());
  ExpectInputTimeout();
  WriteToServer(kServerFD);
  EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());

  // Tunnel a reply back to the client.
  const string server_result("200 OK ... and so on");
  ExpectClientResult();
  ReadFromServer(server_result);
  EXPECT_EQ(server_result,
            string(reinterpret_cast<const char *>(
                GetServerData().GetConstData()),
                   GetServerData().GetLength()));

  // Allow part of the result string to be sent to the client.
  const int part = server_result.length() / 2;
  EXPECT_CALL(sockets(), Send(kClientFD, _, server_result.length(), 0))
      .WillOnce(Return(part));
  ExpectInputTimeout();
  WriteToClient(kClientFD);
  EXPECT_EQ(HTTPProxy::kStateTunnelData, GetProxyState());

  // The Server closes the connection while the client is still reading.
  ExpectInputTimeout();
  ReadFromServer("");
  EXPECT_EQ(HTTPProxy::kStateFlushResponse, GetProxyState());

  // When the last part of the response is written to the client, we close
  // all connections.
  EXPECT_CALL(sockets(), Send(kClientFD, _, server_result.length() - part, 0))
      .WillOnce(ReturnArg<2>());
  ExpectTunnelClose();
  WriteToClient(kClientFD);
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, TunnelDataFailWriteClient) {
  SetupConnectComplete();
  EXPECT_CALL(sockets(), Send(kClientFD, _, _, 0))
      .WillOnce(Return(-1));
  ExpectTunnelClose();
  WriteToClient(kClientFD);
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, TunnelDataFailWriteServer) {
  SetupConnectComplete();
  EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
      .WillOnce(Return(-1));
  ExpectTunnelClose();
  WriteToServer(kServerFD);
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, TunnelDataFailReadServer) {
  SetupConnectComplete();
  EXPECT_CALL(sockets(), Send(kServerFD, _, _, 0))
      .WillOnce(Return(10));
  ExpectServerInput();
  WriteToServer(kServerFD);
  ExpectTunnelClose();
  CauseReadError();
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, TunnelDataFailClientClose) {
  SetupConnectComplete();
  ExpectTunnelClose();
  ReadFromClient("");
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, TunnelDataFailServerClose) {
  SetupConnectComplete();
  ExpectTunnelClose();
  ReadFromServer("");
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

TEST_F(HTTPProxyTest, StopClient) {
  SetupConnectComplete();
  EXPECT_CALL(sockets(), Close(kClientFD))
      .WillOnce(Return(0));
  EXPECT_CALL(sockets(), Close(kServerFD))
      .WillOnce(Return(0));
  ExpectRouteRelease();
  StopClient();
  ExpectClientReset();
  EXPECT_EQ(HTTPProxy::kStateWaitConnection, GetProxyState());
}

}  // namespace shill
