// 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.

// This file implements a simple HTTP server. It can exhibit odd behavior
// that's useful for testing. For example, it's useful to test that
// the updater can continue a connection if it's dropped, or that it
// handles very slow data transfers.

// To use this, simply make an HTTP connection to localhost:port and
// GET a url.

#include <err.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
#include <netinet/in.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>

#include <algorithm>
#include <string>
#include <vector>

#include <base/logging.h>
#include <base/strings/string_split.h>
#include <base/strings/string_util.h>
#include <base/strings/stringprintf.h>

#include "update_engine/http_common.h"


// HTTP end-of-line delimiter; sorry, this needs to be a macro.
#define EOL "\r\n"

using std::min;
using std::string;
using std::vector;


namespace chromeos_update_engine {

static const char* kListeningMsgPrefix = "listening on port ";

enum {
  RC_OK = 0,
  RC_BAD_ARGS,
  RC_ERR_READ,
  RC_ERR_SETSOCKOPT,
  RC_ERR_BIND,
  RC_ERR_LISTEN,
  RC_ERR_GETSOCKNAME,
  RC_ERR_REPORT,
};

struct HttpRequest {
  HttpRequest()
      : start_offset(0), end_offset(0), return_code(kHttpResponseOk) {}
  string host;
  string url;
  off_t start_offset;
  off_t end_offset;  // non-inclusive, zero indicates unspecified.
  HttpResponseCode return_code;
};

bool ParseRequest(int fd, HttpRequest* request) {
  string headers;
  do {
    char buf[1024];
    ssize_t r = read(fd, buf, sizeof(buf));
    if (r < 0) {
      perror("read");
      exit(RC_ERR_READ);
    }
    headers.append(buf, r);
  } while (!EndsWith(headers, EOL EOL, true));

  LOG(INFO) << "got headers:\n--8<------8<------8<------8<----\n"
            << headers
            << "\n--8<------8<------8<------8<----";

  // Break header into lines.
  std::vector<string> lines;
  base::SplitStringUsingSubstr(
      headers.substr(0, headers.length() - strlen(EOL EOL)), EOL, &lines);

  // Decode URL line.
  std::vector<string> terms;
  base::SplitStringAlongWhitespace(lines[0], &terms);
  CHECK_EQ(terms.size(), static_cast<vector<string>::size_type>(3));
  CHECK_EQ(terms[0], "GET");
  request->url = terms[1];
  LOG(INFO) << "URL: " << request->url;

  // Decode remaining lines.
  size_t i;
  for (i = 1; i < lines.size(); i++) {
    std::vector<string> terms;
    base::SplitStringAlongWhitespace(lines[i], &terms);

    if (terms[0] == "Range:") {
      CHECK_EQ(terms.size(), static_cast<vector<string>::size_type>(2));
      string &range = terms[1];
      LOG(INFO) << "range attribute: " << range;
      CHECK(StartsWithASCII(range, "bytes=", true) &&
            range.find('-') != string::npos);
      request->start_offset = atoll(range.c_str() + strlen("bytes="));
      // Decode end offset and increment it by one (so it is non-inclusive).
      if (range.find('-') < range.length() - 1)
        request->end_offset = atoll(range.c_str() + range.find('-') + 1) + 1;
      request->return_code = kHttpResponsePartialContent;
      std::string tmp_str = base::StringPrintf("decoded range offsets: "
                                               "start=%jd end=",
                                               (intmax_t)request->start_offset);
      if (request->end_offset > 0)
        base::StringAppendF(&tmp_str, "%jd (non-inclusive)",
                            (intmax_t)request->end_offset);
      else
        base::StringAppendF(&tmp_str, "unspecified");
      LOG(INFO) << tmp_str;
    } else if (terms[0] == "Host:") {
      CHECK_EQ(terms.size(), static_cast<vector<string>::size_type>(2));
      request->host = terms[1];
      LOG(INFO) << "host attribute: " << request->host;
    } else {
      LOG(WARNING) << "ignoring HTTP attribute: `" << lines[i] << "'";
    }
  }

  return true;
}

string Itoa(off_t num) {
  char buf[100] = {0};
  snprintf(buf, sizeof(buf), "%" PRIi64, num);
  return buf;
}

// Writes a string into a file. Returns total number of bytes written or -1 if a
// write error occurred.
ssize_t WriteString(int fd, const string& str) {
  const size_t total_size = str.size();
  size_t remaining_size = total_size;
  char const *data = str.data();

  while (remaining_size) {
    ssize_t written = write(fd, data, remaining_size);
    if (written < 0) {
      perror("write");
      LOG(INFO) << "write failed";
      return -1;
    }
    data += written;
    remaining_size -= written;
  }

  return total_size;
}

// Writes the headers of an HTTP response into a file.
ssize_t WriteHeaders(int fd, const off_t start_offset, const off_t end_offset,
                     HttpResponseCode return_code) {
  ssize_t written = 0, ret;

  ret = WriteString(fd,
                    string("HTTP/1.1 ") + Itoa(return_code) + " " +
                    GetHttpResponseDescription(return_code) +
                    EOL
                    "Content-Type: application/octet-stream" EOL);
  if (ret < 0)
    return -1;
  written += ret;

  // Compute content legnth.
  const off_t content_length = end_offset - start_offset;;

  // A start offset that equals the end offset indicates that the response
  // should contain the full range of bytes in the requested resource.
  if (start_offset || start_offset == end_offset) {
    ret = WriteString(fd,
                      string("Accept-Ranges: bytes" EOL
                             "Content-Range: bytes ") +
                      Itoa(start_offset == end_offset ? 0 : start_offset) +
                      "-" + Itoa(end_offset - 1) + "/" + Itoa(end_offset) +
                      EOL);
    if (ret < 0)
      return -1;
    written += ret;
  }

  ret = WriteString(fd, string("Content-Length: ") + Itoa(content_length) +
                    EOL EOL);
  if (ret < 0)
    return -1;
  written += ret;

  return written;
}

// Writes a predetermined payload of lines of ascending bytes to a file. The
// first byte of output is appropriately offset with respect to the request line
// length.  Returns the number of successfully written bytes.
size_t WritePayload(int fd, const off_t start_offset, const off_t end_offset,
                    const char first_byte, const size_t line_len) {
  CHECK_LE(start_offset, end_offset);
  CHECK_GT(line_len, static_cast<size_t>(0));

  LOG(INFO) << "writing payload: " << line_len << "-byte lines starting with `"
            << first_byte << "', offset range " << start_offset << " -> "
            << end_offset;

  // Populate line of ascending characters.
  string line;
  line.reserve(line_len);
  char byte = first_byte;
  size_t i;
  for (i = 0; i < line_len; i++)
    line += byte++;

  const size_t total_len = end_offset - start_offset;
  size_t remaining_len = total_len;
  bool success = true;

  // If start offset is not aligned with line boundary, output partial line up
  // to the first line boundary.
  size_t start_modulo = start_offset % line_len;
  if (start_modulo) {
    string partial = line.substr(start_modulo, remaining_len);
    ssize_t ret = WriteString(fd, partial);
    if ((success = (ret >= 0 && (size_t) ret == partial.length())))
      remaining_len -= partial.length();
  }

  // Output full lines up to the maximal line boundary below the end offset.
  while (success && remaining_len >= line_len) {
    ssize_t ret = WriteString(fd, line);
    if ((success = (ret >= 0 && (size_t) ret == line_len)))
      remaining_len -= line_len;
  }

  // Output a partial line up to the end offset.
  if (success && remaining_len) {
    string partial = line.substr(0, remaining_len);
    ssize_t ret = WriteString(fd, partial);
    if ((success = (ret >= 0 && (size_t) ret == partial.length())))
      remaining_len -= partial.length();
  }

  return (total_len - remaining_len);
}

// Write default payload lines of the form 'abcdefghij'.
inline size_t WritePayload(int fd, const off_t start_offset,
                           const off_t end_offset) {
  return WritePayload(fd, start_offset, end_offset, 'a', 10);
}

// Send an empty response, then kill the server.
void HandleQuit(int fd) {
  WriteHeaders(fd, 0, 0, kHttpResponseOk);
  LOG(INFO) << "pid(" << getpid() <<  "): HTTP server exiting ...";
  exit(RC_OK);
}


// Generates an HTTP response with payload corresponding to requested offsets
// and length.  Optionally, truncate the payload at a given length and add a
// pause midway through the transfer.  Returns the total number of bytes
// delivered or -1 for error.
ssize_t HandleGet(int fd, const HttpRequest& request, const size_t total_length,
                  const size_t truncate_length, const int sleep_every,
                  const int sleep_secs) {
  ssize_t ret;
  size_t written = 0;

  // Obtain start offset, make sure it is within total payload length.
  const size_t start_offset = request.start_offset;
  if (start_offset >= total_length) {
    LOG(WARNING) << "start offset (" << start_offset
                 << ") exceeds total length (" << total_length
                 << "), generating error response ("
                 << kHttpResponseReqRangeNotSat << ")";
    return WriteHeaders(fd, total_length, total_length,
                        kHttpResponseReqRangeNotSat);
  }

  // Obtain end offset, adjust to fit in total payload length and ensure it does
  // not preceded the start offset.
  size_t end_offset = (request.end_offset > 0 ?
                       request.end_offset : total_length);
  if (end_offset < start_offset) {
    LOG(WARNING) << "end offset (" << end_offset << ") precedes start offset ("
                 << start_offset << "), generating error response";
    return WriteHeaders(fd, 0, 0, kHttpResponseBadRequest);
  }
  if (end_offset > total_length) {
    LOG(INFO) << "requested end offset (" << end_offset
              << ") exceeds total length (" << total_length << "), adjusting";
    end_offset = total_length;
  }

  // Generate headers
  LOG(INFO) << "generating response header: range=" << start_offset << "-"
            << (end_offset - 1) << "/" << (end_offset - start_offset)
            << ", return code=" << request.return_code;
  if ((ret = WriteHeaders(fd, start_offset, end_offset,
                          request.return_code)) < 0)
    return -1;
  LOG(INFO) << ret << " header bytes written";
  written += ret;

  // Compute payload length, truncate as necessary.
  size_t payload_length = end_offset - start_offset;
  if (truncate_length > 0 && truncate_length < payload_length) {
    LOG(INFO) << "truncating request payload length (" << payload_length
              << ") at " << truncate_length;
    payload_length = truncate_length;
    end_offset = start_offset + payload_length;
  }

  LOG(INFO) << "generating response payload: range=" << start_offset << "-"
            << (end_offset - 1) << "/" << (end_offset - start_offset);

  // Decide about optional midway delay.
  if (truncate_length > 0 && sleep_every > 0 && sleep_secs >= 0 &&
      start_offset % (truncate_length * sleep_every) == 0) {
    const off_t midway_offset = start_offset + payload_length / 2;

    if ((ret = WritePayload(fd, start_offset, midway_offset)) < 0)
      return -1;
    LOG(INFO) << ret << " payload bytes written (first chunk)";
    written += ret;

    LOG(INFO) << "sleeping for " << sleep_secs << " seconds...";
    sleep(sleep_secs);

    if ((ret = WritePayload(fd, midway_offset, end_offset)) < 0)
      return -1;
    LOG(INFO) << ret << " payload bytes written (second chunk)";
    written += ret;
  } else {
    if ((ret = WritePayload(fd, start_offset, end_offset)) < 0)
      return -1;
    LOG(INFO) << ret << " payload bytes written";
    written += ret;
  }

  LOG(INFO) << "response generation complete, " << written
            << " total bytes written";
  return written;
}

ssize_t HandleGet(int fd, const HttpRequest& request,
                  const size_t total_length) {
  return HandleGet(fd, request, total_length, 0, 0, 0);
}

// Handles /redirect/<code>/<url> requests by returning the specified
// redirect <code> with a location pointing to /<url>.
void HandleRedirect(int fd, const HttpRequest& request) {
  LOG(INFO) << "Redirecting...";
  string url = request.url;
  CHECK_EQ(static_cast<size_t>(0), url.find("/redirect/"));
  url.erase(0, strlen("/redirect/"));
  string::size_type url_start = url.find('/');
  CHECK_NE(url_start, string::npos);
  HttpResponseCode code = StringToHttpResponseCode(url.c_str());
  url.erase(0, url_start);
  url = "http://" + request.host + url;
  const char *status = GetHttpResponseDescription(code);
  if (!status)
    CHECK(false) << "Unrecognized redirection code: " << code;
  LOG(INFO) << "Code: " << code << " " << status;
  LOG(INFO) << "New URL: " << url;

  ssize_t ret;
  if ((ret = WriteString(fd, "HTTP/1.1 " + Itoa(code) + " " +
                         status + EOL)) < 0)
    return;
  WriteString(fd, "Location: " + url + EOL);
}

// Generate a page not found error response with actual text payload. Return
// number of bytes written or -1 for error.
ssize_t HandleError(int fd, const HttpRequest& request) {
  LOG(INFO) << "Generating error HTTP response";

  ssize_t ret;
  size_t written = 0;

  const string data("This is an error page.");

  if ((ret = WriteHeaders(fd, 0, data.size(), kHttpResponseNotFound)) < 0)
    return -1;
  written += ret;

  if ((ret = WriteString(fd, data)) < 0)
    return -1;
  written += ret;

  return written;
}

// Generate an error response if the requested offset is nonzero, up to a given
// maximal number of successive failures.  The error generated is an "Internal
// Server Error" (500).
ssize_t HandleErrorIfOffset(int fd, const HttpRequest& request,
                            size_t end_offset, int max_fails) {
  static int num_fails = 0;

  if (request.start_offset > 0 && num_fails < max_fails) {
    LOG(INFO) << "Generating error HTTP response";

    ssize_t ret;
    size_t written = 0;

    const string data("This is an error page.");

    if ((ret = WriteHeaders(fd, 0, data.size(),
                            kHttpResponseInternalServerError)) < 0)
      return -1;
    written += ret;

    if ((ret = WriteString(fd, data)) < 0)
      return -1;
    written += ret;

    num_fails++;
    return written;
  } else {
    num_fails = 0;
    return HandleGet(fd, request, end_offset);
  }
}

void HandleDefault(int fd, const HttpRequest& request) {
  const off_t start_offset = request.start_offset;
  const string data("unhandled path");
  const size_t size = data.size();
  ssize_t ret;

  if ((ret = WriteHeaders(fd, start_offset, size, request.return_code)) < 0)
    return;
  WriteString(fd, (start_offset < static_cast<off_t>(size) ?
                   data.substr(start_offset) : ""));
}


// Break a URL into terms delimited by slashes.
class UrlTerms {
 public:
  UrlTerms(string &url, size_t num_terms) {
    // URL must be non-empty and start with a slash.
    CHECK_GT(url.size(), static_cast<size_t>(0));
    CHECK_EQ(url[0], '/');

    // Split it into terms delimited by slashes, omitting the preceeding slash.
    base::SplitStringDontTrim(url.substr(1), '/', &terms);

    // Ensure expected length.
    CHECK_EQ(terms.size(), num_terms);
  }

  inline string Get(const off_t index) const {
    return terms[index];
  }
  inline const char *GetCStr(const off_t index) const {
    return Get(index).c_str();
  }
  inline int GetInt(const off_t index) const {
    return atoi(GetCStr(index));
  }
  inline long GetLong(const off_t index) const {
    return atol(GetCStr(index));
  }

 private:
  std::vector<string> terms;
};

void HandleConnection(int fd) {
  HttpRequest request;
  ParseRequest(fd, &request);

  string &url = request.url;
  LOG(INFO) << "pid(" << getpid() <<  "): handling url " << url;
  if (url == "/quitquitquit") {
    HandleQuit(fd);
  } else if (StartsWithASCII(url, "/download/", true)) {
    const UrlTerms terms(url, 2);
    HandleGet(fd, request, terms.GetLong(1));
  } else if (StartsWithASCII(url, "/flaky/", true)) {
    const UrlTerms terms(url, 5);
    HandleGet(fd, request, terms.GetLong(1), terms.GetLong(2), terms.GetLong(3),
              terms.GetLong(4));
  } else if (url.find("/redirect/") == 0) {
    HandleRedirect(fd, request);
  } else if (url == "/error") {
    HandleError(fd, request);
  } else if (StartsWithASCII(url, "/error-if-offset/", true)) {
    const UrlTerms terms(url, 3);
    HandleErrorIfOffset(fd, request, terms.GetLong(1), terms.GetInt(2));
  } else {
    HandleDefault(fd, request);
  }

  close(fd);
}

}  // namespace chromeos_update_engine

using namespace chromeos_update_engine;


void usage(const char *prog_arg) {
  fprintf(
      stderr,
      "Usage: %s [ FILE ]\n"
      "Once accepting connections, the following is written to FILE (or "
      "stdout):\n"
      "\"%sN\" (where N is an integer port number)\n",
      basename(prog_arg), kListeningMsgPrefix);
}

int main(int argc, char** argv) {
  // Check invocation.
  if (argc > 2)
    errx(RC_BAD_ARGS, "unexpected number of arguments (use -h for usage)");

  // Parse (optional) argument.
  int report_fd = STDOUT_FILENO;
  if (argc == 2) {
    if (!strcmp(argv[1], "-h")) {
      usage(argv[0]);
      exit(RC_OK);
    }

    report_fd = open(argv[1], O_WRONLY | O_CREAT, 00644);
  }

  // Ignore SIGPIPE on write() to sockets.
  signal(SIGPIPE, SIG_IGN);

  int listen_fd = socket(AF_INET, SOCK_STREAM, 0);
  if (listen_fd < 0)
    LOG(FATAL) << "socket() failed";

  struct sockaddr_in server_addr = sockaddr_in();
  server_addr.sin_family = AF_INET;
  server_addr.sin_addr.s_addr = INADDR_ANY;
  server_addr.sin_port = 0;

  {
    // Get rid of "Address in use" error
    int tr = 1;
    if (setsockopt(listen_fd, SOL_SOCKET, SO_REUSEADDR, &tr,
                   sizeof(int)) == -1) {
      perror("setsockopt");
      exit(RC_ERR_SETSOCKOPT);
    }
  }

  // Bind the socket and set for listening.
  if (bind(listen_fd, reinterpret_cast<struct sockaddr *>(&server_addr),
           sizeof(server_addr)) < 0) {
    perror("bind");
    exit(RC_ERR_BIND);
  }
  if (listen(listen_fd, 5) < 0) {
    perror("listen");
    exit(RC_ERR_LISTEN);
  }

  // Check the actual port.
  struct sockaddr_in bound_addr = sockaddr_in();
  socklen_t bound_addr_len = sizeof(bound_addr);
  if (getsockname(listen_fd, reinterpret_cast<struct sockaddr*>(&bound_addr),
                  &bound_addr_len) < 0) {
    perror("getsockname");
    exit(RC_ERR_GETSOCKNAME);
  }
  in_port_t port = ntohs(bound_addr.sin_port);

  // Output the listening port, indicating that the server is processing
  // requests. IMPORTANT! (a) the format of this message is as expected by some
  // unit tests, avoid unilateral changes; (b) it is necessary to flush/sync the
  // file to prevent the spawning process from waiting indefinitely for this
  // message.
  string listening_msg = base::StringPrintf("%s%hu", kListeningMsgPrefix, port);
  LOG(INFO) << listening_msg;
  CHECK_EQ(write(report_fd, listening_msg.c_str(), listening_msg.length()),
           static_cast<int>(listening_msg.length()));
  CHECK_EQ(write(report_fd, "\n", 1), 1);
  if (report_fd == STDOUT_FILENO)
    fsync(report_fd);
  else
    close(report_fd);

  while (1) {
    LOG(INFO) << "pid(" << getpid() <<  "): waiting to accept new connection";
    int client_fd = accept(listen_fd, NULL, NULL);
    LOG(INFO) << "got past accept";
    if (client_fd < 0)
      LOG(FATAL) << "ERROR on accept";
    HandleConnection(client_fd);
  }
  return 0;
}
