// 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/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);
}

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<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();
    }
  }
  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_FALSE(proxy_.idle_timeout_);
    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,
                                                proxy_.accept_callback_.get()))
        .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, proxy_.read_client_callback_.get()))
        .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 ExpectDNSFailure(const string &error) {
    EXPECT_CALL(*dns_client_, error())
        .WillOnce(ReturnRef(error));
  }
  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,
                                   proxy_.write_client_callback_.get()))
        .WillOnce(ReturnNew<IOHandler>());
  }
  void ExpectClientResult() {
    ExpectClientData();
    ExpectInputTimeout();
  }
  void ExpectServerInput() {
    EXPECT_CALL(dispatcher(),
                CreateInputHandler(kServerFD,
                                   proxy_.read_server_callback_.get()))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectInputTimeout();
  }
  void ExpectServerOutput() {
    EXPECT_CALL(dispatcher(),
                CreateReadyHandler(kServerFD,
                                   IOHandler::kModeOutput,
                                   proxy_.write_server_callback_.get()))
        .WillOnce(ReturnNew<IOHandler>());
    ExpectInputTimeout();
  }
  void ExpectRepeatedServerOutput() {
    EXPECT_CALL(dispatcher(),
                CreateReadyHandler(kServerFD,
                                   IOHandler::kModeOutput,
                                   proxy_.write_server_callback_.get()))
        .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 GetDNSResult(bool result) {
    proxy_.GetDNSResult(result);
  }
  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));
    EXPECT_CALL(*dns_client_, address())
        .WillOnce(ReturnRef(addr));;
    GetDNSResult(true);
  }
  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());
  }

 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_;
  HTTPProxy proxy_;
  StrictMock<MockSockets> sockets_;
};

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, 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);
  ExpectDNSFailure(not_found_error);
  GetDNSResult(false);
  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, 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
