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

#include <base/strings/stringprintf.h>
#include <gtest/gtest.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/net/ip_address.h"
#include "shill/net/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_(nullptr),
        dns_servers_(kDNSServers, kDNSServers + 2),
        dns_client_(nullptr),
        device_info_(
            new NiceMock<MockDeviceInfo>(&control_, nullptr, nullptr, nullptr)),
        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_ = nullptr;
    dns_client_ = nullptr;
    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(string());
  }

 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_;
  std::unique_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
