// Copyright (c) 2013 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 "p2p/http_server/connection_delegate.h"

#include "p2p/common/constants.h"
#include "p2p/common/fake_clock.h"
#include "p2p/common/testutil.h"
#include "p2p/common/util.h"
#include "p2p/http_server/mock_server.h"

#include <arpa/inet.h>
#include <fcntl.h>
#include <sys/types.h>
#include <unistd.h>

#include <map>
#include <string>
#include <vector>

#include <base/command_line.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <base/logging.h>
#include <base/strings/string_number_conversions.h>
#include <base/threading/simple_thread.h>
#include <gtest/gtest.h>

using std::map;
using std::string;
using std::tuple;
using std::vector;

using base::FilePath;
using base::WriteFile;

using p2p::common::FakeClock;
using p2p::testutil::SetExpectedFileSize;
using p2p::testutil::SetupTestDir;
using p2p::testutil::TeardownTestDir;

using testing::_;

namespace {
// DefaultDownloadRate used for the tests in bytes per seconds (5MB/s).
static const int kDefaultDownloadRate = 5 * 1000 * 1000;
}  // namespace

namespace p2p {

namespace http_server {

class ConnectionDelegateTest : public ::testing::Test {
 public:
  ConnectionDelegateTest()
      : testdir_fd_(-1),
      server_fd_(-1),
      client_fd_(-1),
      thread_(NULL),
      delegate_(NULL) {
    ON_CALL(mock_server_, Clock())
      .WillByDefault(testing::Return(&clock_));
    EXPECT_CALL(mock_server_, Clock()).Times(testing::AtLeast(0));
  }

 protected:
  void SetupDelegate() {
    testdir_path_ = SetupTestDir("connection-delegate");
    testdir_fd_ = open(testdir_path_.value().c_str(), O_DIRECTORY);
    if (testdir_fd_ == -1)
      PLOG(ERROR) << "Opening delegate-test temp directory";
    ASSERT_NE(testdir_fd_, -1);

    // Create a TCP server in any port and connect to it. This provides the
    // very same kind of socket ConnectionDelegate will use in the real
    // implementation.
    int servsock = socket(AF_INET, SOCK_STREAM | SOCK_NONBLOCK | SOCK_CLOEXEC,
                          IPPROTO_TCP);
    if (servsock == -1)
      PLOG(ERROR) << "Creating a server socket()";
    ASSERT_NE(servsock, -1);

    client_fd_ = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC,
                        IPPROTO_TCP);
    if (client_fd_ == -1)
      PLOG(ERROR) << "Creating a client socket()";
    ASSERT_NE(client_fd_, -1);

    // Set the socket to listen to a random port.
    struct sockaddr_in server_addr;
    socklen_t server_len = sizeof(server_addr);
    memset(reinterpret_cast<char*>(&server_addr), 0, sizeof(server_addr));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(0);  // any port
    server_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
    ASSERT_NE(-1, bind(servsock,
                       reinterpret_cast<struct sockaddr*>(&server_addr),
                       sizeof(server_addr)));
    // Read back the selected address and port.
    ASSERT_NE(-1, getsockname(servsock,
                              reinterpret_cast<struct sockaddr*>(&server_addr),
                              &server_len));

    ASSERT_NE(listen(servsock, 1), -1);

    // At this point, the server socked will accept the connection and we will
    // get the server side socket once we call accept().
    struct sockaddr_in client_addr;
    socklen_t client_len = sizeof(client_addr);
    ASSERT_NE(-1, connect(client_fd_,
                          reinterpret_cast<struct sockaddr*>(&server_addr),
                          sizeof(server_addr)));

    server_fd_ = accept(servsock,
                        reinterpret_cast<struct sockaddr*>(&client_addr),
                        &client_len);
    if (server_fd_ == -1)
      PLOG(ERROR) << "Accepting the client connection.";
    ASSERT_NE(server_fd_, -1);

    // Tear down the listening server (but keep the server_fd_ socket).
    ASSERT_EQ(close(servsock), 0);

    // Create the Server
    delegate_ = new ConnectionDelegate(
        testdir_fd_, server_fd_, "[addr]", &mock_server_, kDefaultDownloadRate);

    thread_ = new base::DelegateSimpleThread(delegate_, "delegate");
  }

  virtual void TearDown() {
    if (thread_)
      delete thread_;
    // The ConnectionDelegate deletes itself when Run() finishes.

    if (client_fd_ != -1)
      EXPECT_EQ(0, close(client_fd_));
    // The ConnectionDelegate should close the provided file descriptor, thus
    // this close should fail.
    if (server_fd_ != -1)
      EXPECT_EQ(-1, close(server_fd_));
    if (testdir_fd_ != -1)
      EXPECT_EQ(0, close(testdir_fd_));
    if (!testdir_path_.empty())
      TeardownTestDir(testdir_path_);
  }

  // A randomly generated temporary testing directory to put the shared files.
  FilePath testdir_path_;

  // File descriptor to the testdir_path_ directory.
  int testdir_fd_;

  // The server-side fd in the connection (passed to ConnectionDelegate).
  int server_fd_;

  // The client-side fd that a client is using to request the content from the
  // ConnectionDelegate.
  int client_fd_;

  // Thread pool needed to run the ConnectionDelegate.
  base::DelegateSimpleThread* thread_;

  testing::StrictMock<MockServer> mock_server_;
  ConnectionDelegate* delegate_;
  FakeClock clock_;
};

// A class to help building a HTTP Request.
class HTTPRequest {
 public:
  HTTPRequest()
      : method_("GET"),
      http_version_("1.1"),
      uri_("/"),
      host_("127.0.0.1") {
    headers_["User-Agent"] = "HTTPRequest/1.0 (unittester)";
  }

  string ToString() const {
    string res = method_ + " " + uri_ + " HTTP/" + http_version_ + "\r\n" +
        "Host: " + host_ + "\r\n";
    for (const auto& it : headers_)
      res += it.first + ": " + it.second + "\r\n";
    res += "\r\n" + post_data_;
    return res;
  }

  bool Send(int fd) const {
    string req = ToString();
    size_t to_write = req.size();
    const char* p = req.c_str();
    int write_result;
    while (to_write > 0) {
      write_result = write(fd, p, to_write);
      if (write_result < 0 && errno == EAGAIN)
        continue;
      if (write_result <= 0) {
        PLOG(ERROR) << "Error writing to fd " << fd;
        return false;
      }
      to_write -= write_result;
      p += write_result;
    }
    return true;
  }

  string method_;
  string http_version_;  // The HTTP protocol version.
  string uri_;
  string host_;
  map<string, string> headers_;
  string post_data_;
};

class HTTPResponse {
 public:
  explicit HTTPResponse(const string& response)
      : response_(response), valid_(false) {
    const char* p = response_.c_str();
    int len = response_.size();
    if (len == 0)
      return;

    // Parse the header lines until the empty line is reached.
    const char* line = p;
    int line_len = len;
    while (line_len > 0) {
      int i;
      for (i = 0; i < line_len; ++i) {
        if (line[i] == '\n') {
          if (i > 0 && line[i-1] == '\r') {
            // Found \r\n ending line.
            line_len = i + 1;
            break;
          }
          LOG(ERROR) << "Header line doesn't end in \\r\\n.";
          return;
        }
      }
      // Check if the end of the response was reached while parsing the headers.
      if (i == line_len)
        return;

      raw_headers_.push_back(string(line, line_len - 2));
      line += line_len;
      line_len = len - (line - p);
      // Check if the empty header line was found.
      if (line_len >= 2 && line[0] == '\r' && line[1] == '\n')
        break;
    }
    // Check if the header is \r\n
    if (!line_len) {
      LOG(ERROR) << "Missing \\r\\n after the headers.";
      return;
    }

    line += 2;
    if (line < p + len)
      content_ = string(line, len - (line - p));

    // Parse the first response line.
    string first_line = raw_headers_[0];
    if (first_line.substr(0, 5) == "HTTP/") {
      size_t sp_pos = first_line.find(' ');
      if (sp_pos != std::string::npos) {
        http_version_ = first_line.substr(5, sp_pos - 5);
        first_line = first_line.substr(sp_pos + 1);
      }
    }
    http_code_ = atoi(first_line.c_str());

    // Parse the raw_headers.
    for (size_t i = 1; i < raw_headers_.size(); ++i) {
      const string& header = raw_headers_[i];
      const char* header_p = header.c_str();
      const char* sep =
          reinterpret_cast<const char*>(memchr(header_p, ':', header.size()));
      if (!sep || sep[1] != ' ') {
        LOG(ERROR) << "Invalid header: \"" << header << "\".";
        return;
      }
      string key(header_p, sep - header_p);
      string value(sep + 2, header.size() - (sep + 2 - header_p));

      if (headers_.find(key) != headers_.end()) {
        LOG(ERROR) << "The header \"" << key << "\" appears twice in the "
                   << "response.";
        return;
      }
      // TODO(deymo): Support header continuation. See http://crbug.com/246326.
      headers_[key] = value;
    }
    valid_ = true;
  }

  // The original response string.
  string response_;

  // Tells wether the response has a valid (and supported) format.
  bool valid_;

  // The HTTP response code.
  int http_code_;

  string http_version_;

  map<string, string> headers_;

  // The content body.
  string content_;

 private:
  vector<string> raw_headers_;
};

// Read or continue reading a HTTP response from the file descriptor until the
// connection is closed or the "content" part of the HTTP response is at least
// |min_content_size|. If more than |min_content_size| bytes are available to
// read on the file descriptor those will be included in the |response| as well.
// A value of -1 in |min_content_size| will block until the connection is
// closed.
// Returns wether the response was successfully read from the file descriptor
// and the socked was properly close from the other end or the
// |min_content_size| reached.
// The bytes read from the file descriptor are appended to the |response|
// string, allowing the caller to do a partial read of a HTTP response and then
// continue it. For example:
//
//   string resp;
//   // This will at least read the headers:
//   ReadHTTPResponse(some_sock, &resp, 0);
//   // ... do some checking of the headers, read the Content-Length if present.
//   ReadHTTPResponse(some_sock, &resp, expect_content_size);
static bool ReadHTTPResponse(int fd, string* response,
                             int min_content_size = -1) {
  char buf[16 * 1024];  // 16KiB is a reasonable buffer for recv().
  int res;
  do {
    if (min_content_size >= 0) {
      res = recv(fd, buf, sizeof(buf), MSG_DONTWAIT);
      if (res == -1 && errno == EWOULDBLOCK) {
        HTTPResponse ret(*response);
        if (ret.valid_ &&
            ret.content_.size() >= static_cast<size_t>(min_content_size))
          return true;
        // Re-read but block this time.
        res = recv(fd, buf, sizeof(buf), 0);
      }
    } else {
      res = recv(fd, buf, sizeof(buf), 0);
    }
    if (res == -1 && errno == EAGAIN)
      continue;
    if (res == -1) {
      PLOG(ERROR) << "Reading HTTPResponse from fd " << fd;
      return false;
    }
    if (res == 0)
      break;
    response->append(buf, res);
  } while (true);
  return true;
}

// Generates undefined but deterministic printable data.
// Printable data is considered all the ASCII-7 char excluding the first 32
// codes (control characters) and the 128. Thus, this function generates
// ASCII chars in the range 32-127 inclusive.
static void GeneratePrintableData(size_t size, string* output) {
  output->clear();
  output->resize(size);
  for (size_t i = 0; i < size; ++i)
    output->at(i) = static_cast<char>(32 + (45 + i * 131 + i * i * 17) % 95);
}

TEST_F(ConnectionDelegateTest, NoRequestAndClose) {
  SetupDelegate();

  p2p::testutil::TimeBombAbort bomb(60, "Test NoRequestAndClose timeout\n");
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultMalformed));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  EXPECT_EQ(0, close(client_fd_));
  client_fd_ = -1;
  thread_->Join();
}

TEST_F(ConnectionDelegateTest, RequestUnsupportedMode) {
  SetupDelegate();

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultMalformed));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  // Send a HEAD request.
  HTTPRequest req;
  req.method_ = "HEAD";
  req.uri_ = "/non-existent";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(501, resp.http_code_);  // Not Implemented.
}

TEST_F(ConnectionDelegateTest, GetExistentFile) {
  SetupDelegate();

  const string content = "Hello World!";
  WriteFile(testdir_path_.Append("hello.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/hello";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(200, resp.http_code_);
  EXPECT_EQ(content, resp.content_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ(base::IntToString(content.size()), resp.headers_["Content-Length"]);
}

TEST_F(ConnectionDelegateTest, PostExistentFile) {
  SetupDelegate();

  string content;
  GeneratePrintableData(9 * 1000 * 1000 - 1, &content);
  WriteFile(testdir_path_.Append("a.foo.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 8));  // Almost 9 MB served.
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.method_ = "POST";
  req.uri_ = "/a.foo";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(200, resp.http_code_);
  EXPECT_EQ(content, resp.content_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ(base::IntToString(content.size()), resp.headers_["Content-Length"]);
}

TEST_F(ConnectionDelegateTest, GetEmptyFile) {
  SetupDelegate();

  WriteFile(testdir_path_.Append("empty.p2p"), "", 0);

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  // The reported download speed should be 0 in this case, and no
  // kP2PServerServedSuccessfullyMB is reported.
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/empty";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(200, resp.http_code_);
  EXPECT_EQ("", resp.content_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("0", resp.headers_["Content-Length"]);
}

TEST_F(ConnectionDelegateTest, GetRangeOfFile) {
  SetupDelegate();

  string content;
  GeneratePrintableData(60 * 1000, &content);
  WriteFile(testdir_path_.Append("data.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 25));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/data";
  req.headers_["User-Agent"] = "The Unit Tester";
  req.headers_["Range"] = "bytes=15000-17000";
  // An extra header shouldn't affect.
  req.headers_["X-Hello"] = "World";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(206, resp.http_code_);  // Partial content.
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("2001", resp.headers_["Content-Length"]);
  EXPECT_EQ(content.substr(15000, 2001), resp.content_);
}

TEST_F(ConnectionDelegateTest, GetInvalidRangeOfFile) {
  SetupDelegate();

  string content;
  GeneratePrintableData(64 * 1000, &content);
  WriteFile(testdir_path_.Append("data.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultMalformed));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/data";
  // The range starts in the file but the end is after the end of the file.
  req.headers_["Range"] = "bytes=60000-70000";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(416, resp.http_code_);  // Requested Range Not Satisfiable.
  EXPECT_EQ("", resp.content_);
}

TEST_F(ConnectionDelegateTest, GetLastPartOfFile) {
  SetupDelegate();

  string content;
  GeneratePrintableData(5 * 1000, &content);
  WriteFile(testdir_path_.Append("data.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 80));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/data";
  // HTTP headers aren't case sensitive and we should send only one. This tests
  // the parser behaviour.
  req.headers_["User-Agent"] = "The Unit Tester I";
  req.headers_["user-agent"] = "The Unit Tester II";
  req.headers_["UsEr-AgEnT"] = "The Unit Tester III";
  req.headers_["raNGE"] = "bytes=4000-";
  req.headers_["RangE"] = "bytes=4000-";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(206, resp.http_code_);  // Partial content.
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("1000", resp.headers_["Content-Length"]);
  EXPECT_EQ(content.substr(4000, 1000), resp.content_);
}

TEST_F(ConnectionDelegateTest, GetIncompleteFile) {
  if (!util::IsXAttrSupported(FilePath("/tmp"))) {
    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
                 << "Please update your system to support this feature.";
    return;
  }

  SetupDelegate();

  string content;
  GeneratePrintableData(50 * 1000, &content);
  WriteFile(testdir_path_.Append("data.p2p"), content.c_str(), content.size());
  ASSERT_TRUE(SetExpectedFileSize(testdir_path_.Append("data.p2p"),
                                  100 * 1000));

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseInterrupted));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedInterruptedMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/data";
  req.Send(client_fd_);
  // Request the whole file (100KB), but try to read only the first 50KB.
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp, 50 * 1000));
  // Disconnect.
  close(client_fd_);
  client_fd_ = -1;
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(200, resp.http_code_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("100000", resp.headers_["Content-Length"]);
  EXPECT_EQ(content, resp.content_);
}

TEST_F(ConnectionDelegateTest, GetPartOfIncompleteFile) {
  if (!util::IsXAttrSupported(FilePath("/tmp"))) {
    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
                 << "Please update your system to support this feature.";
    return;
  }

  SetupDelegate();

  string content;
  GeneratePrintableData(5 * 1000, &content);
  WriteFile(testdir_path_.Append("data.p2p"), content.c_str(), content.size());
  ASSERT_TRUE(SetExpectedFileSize(testdir_path_.Append("data.p2p"), 10 * 1000));

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  // Total file size is 10KB, but actual file size is 5KB. A range starting
  // at 2KB should be reported as 20%.
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 20));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/data";
  req.headers_["Range"] = "bytes=2000-4999";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  // Disconnect.
  close(client_fd_);
  client_fd_ = -1;
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(206, resp.http_code_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("3000", resp.headers_["Content-Length"]);
  EXPECT_EQ(content.substr(2000, 3000), resp.content_);
}

TEST_F(ConnectionDelegateTest, GetNonExistentFile) {
  SetupDelegate();

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultNotFound));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/hello";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(404, resp.http_code_);
}

TEST_F(ConnectionDelegateTest, URIArgumentsNotParsed) {
  SetupDelegate();

  const string content = "Hello World!";
  WriteFile(testdir_path_.Append("hello.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultNotFound));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/hello?world";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(404, resp.http_code_);
}

TEST_F(ConnectionDelegateTest, URIUsesRelativePath) {
  SetupDelegate();

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultMalformed));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "//etc/passwd";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(400, resp.http_code_);  // Bad request.
}

TEST_F(ConnectionDelegateTest, MalformedInversedRange) {
  SetupDelegate();

  const string content = "Hello World!";
  WriteFile(testdir_path_.Append("hello.p2p"), content.c_str(), content.size());

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultMalformed));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/hello";
  // Request an inverted range.
  req.headers_["Range"] = "bytes=9-5";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  EXPECT_EQ(400, resp.http_code_);  // Bad request.
}

// Tests that the ConnectionDelegate properly blocks when the end of the file
// is missing and continues serving the file when more data is available.
TEST_F(ConnectionDelegateTest, Waiting) {
  if (!util::IsXAttrSupported(FilePath("/tmp"))) {
    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
                 << "Please update your system to support this feature.";
    return;
  }

  SetupDelegate();

  // The file starts with 50kB on disk, but expected total size of 100kB. The
  // file is then extended to 75kB and finally to 100kB.
  string content;
  GeneratePrintableData(100 * 1000, &content);
  WriteFile(testdir_path_.Append("wait.p2p"), content.c_str(), 50 * 1000);
  ASSERT_TRUE(SetExpectedFileSize(testdir_path_.Append("wait.p2p"),
                                  100 * 1000));

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 0));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, _));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/wait";
  req.Send(client_fd_);
  string text_resp;
  // Expect to read the first 50kB with a valid HTTP response for the
  // total size of 100kB.
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp, 50 * 1000));

  HTTPResponse resp(text_resp);
  ASSERT_TRUE(resp.valid_);
  ASSERT_EQ(200, resp.http_code_);
  EXPECT_EQ("application/octet-stream", resp.headers_["Content-Type"]);
  EXPECT_EQ("100000", resp.headers_["Content-Length"]);

  // Extend the file to 75kB.
  int fd = open(testdir_path_.Append("wait.p2p").value().c_str(),
                O_WRONLY | O_APPEND);
  EXPECT_NE(fd, -1);
  EXPECT_EQ(25 * 1000, write(fd, content.c_str() + 50 * 1000, 25 * 1000));

  // Expect to reach 75kB on the reader side.
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp, 75 * 1000));

  HTTPResponse middle_resp(text_resp);
  ASSERT_TRUE(middle_resp.valid_);
  EXPECT_EQ(middle_resp.content_.size(), 75 * 1000);

  // Extend the file to its total expected size and expect the server to close
  // the connection right after serving the total size.
  EXPECT_EQ(25 * 1000, write(fd, content.c_str() + 75 * 1000, 25 * 1000));
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));

  EXPECT_EQ(0, close(fd));
  thread_->Join();

  HTTPResponse full_resp(text_resp);
  ASSERT_TRUE(full_resp.valid_);
  EXPECT_EQ(full_resp.content_.size(), 100 * 1000);
  EXPECT_EQ(full_resp.content_, content);
}

TEST_F(ConnectionDelegateTest, LimitDownloadSpeed) {
  if (!util::IsXAttrSupported(FilePath("/tmp"))) {
    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
                 << "Please update your system to support this feature.";
    return;
  }

  SetupDelegate();

  string content;
  GeneratePrintableData(50 * 1000 * 1000, &content);
  WriteFile(testdir_path_.Append("50mb.p2p"), content.c_str(), content.size());
  ASSERT_TRUE(SetExpectedFileSize(testdir_path_.Append("50mb.p2p"),
                                  content.size()));

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 50));
  // The reported download speed should be the maximum default speed used in
  // this test (kDefaultDownloadRate).
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, 5000));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/50mb";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));
  thread_->Join();

  // Don't need to parse the response. Just expect it to have the 50MB plus the
  // header size.
  EXPECT_GE(text_resp.size(), 50 * 1000 * 1000);

  // Since the file was already complete at the begining of the test, the
  // sleeping time should be only 10s (50MB / 5 MB/s). A minimum tolerance is
  // added to avoid floating-point errors.
  EXPECT_GE(clock_.GetSleptTime().InSecondsF(), 9.999);
  EXPECT_LE(clock_.GetSleptTime().InSecondsF(), 10.001);
}

TEST_F(ConnectionDelegateTest, DisregardTimeWaitingFromTransferBudget) {
  if (!util::IsXAttrSupported(FilePath("/tmp"))) {
    LOG(WARNING) << "Skipping test because /tmp does not support xattr. "
                 << "Please update your system to support this feature.";
    return;
  }

  SetupDelegate();

  string content;
  GeneratePrintableData(25 * 1000 * 1000, &content);
  WriteFile(testdir_path_.Append("50mb.p2p"), content.c_str(), content.size());
  ASSERT_TRUE(SetExpectedFileSize(testdir_path_.Append("50mb.p2p"),
                                  50 * 1000 * 1000));

  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRequestResult,
      p2p::util::kP2PRequestResultResponseSent));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerServedSuccessfullyMB, 50));
  // The reported download speed should be the maximum default speed used in
  // this test (kDefaultDownloadRate).
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerDownloadSpeedKBps, 5000));
  EXPECT_CALL(mock_server_, ReportServerMessage(
      p2p::util::kP2PServerRangeBeginPercentage, 0));
  EXPECT_CALL(mock_server_, ConnectionTerminated(delegate_));

  thread_->Start();
  HTTPRequest req;
  req.uri_ = "/50mb";
  req.Send(client_fd_);
  string text_resp;
  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp, 25 * 1000 * 1000));

  // At this point, the ConnectionDelegate is waiting on data to be read from
  // the file, but EOF is reached so it will try to call clock->Sleep() to
  // sleep for a second waiting for data to be ready. After the last byte is
  // sent to the socket, the ConnectionDelegate waits to reach the right
  // speed and once EOF on the input is reached it will wait again until some
  // data is ready to read from there. To ensure we saw at least one Sleep()
  // call because of the later condition, block twice until Sleep() is called.
  clock_.BlockUntilSleepIsCalled();
  clock_.BlockUntilSleepIsCalled();

  // Extend the file to its total expected size and expect the server to close
  // the connection right after serving the total size.
  int fd = open(testdir_path_.Append("50mb.p2p").value().c_str(),
                O_WRONLY | O_APPEND);
  EXPECT_NE(fd, -1);
  EXPECT_EQ(content.size(), write(fd, content.c_str(), content.size()));
  EXPECT_EQ(0, close(fd));

  EXPECT_TRUE(ReadHTTPResponse(client_fd_, &text_resp));

  thread_->Join();

  // Don't need to parse the response. Just expect it to have the 50MB plus the
  // header size.
  EXPECT_GE(text_resp.size(), 50 * 1000 * 1000);
}

}  // namespace http_server

}  // namespace p2p
