// Copyright (c) 2012 The Chromium 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 "net/test/embedded_test_server/http_request.h"

#include <algorithm>

#include "base/logging.h"
#include "base/strings/string_util.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "net/http/http_chunked_decoder.h"
#include "url/gurl.h"

namespace net {
namespace test_server {

namespace {

size_t kRequestSizeLimit = 64 * 1024 * 1024;  // 64 mb.

// Helper function used to trim tokens in http request headers.
std::string Trim(const std::string& value) {
  std::string result;
  base::TrimString(value, " \t", &result);
  return result;
}

}  // namespace

HttpRequest::HttpRequest() : method(METHOD_UNKNOWN),
                             has_content(false) {
}

HttpRequest::~HttpRequest() {
}

GURL HttpRequest::GetURL() const {
  // TODO(svaldez): Use real URL from the EmbeddedTestServer.
  return GURL("http://localhost" + relative_url);
}

HttpRequestParser::HttpRequestParser()
    : http_request_(new HttpRequest()),
      buffer_position_(0),
      state_(STATE_HEADERS),
      declared_content_length_(0) {
}

HttpRequestParser::~HttpRequestParser() {
}

void HttpRequestParser::ProcessChunk(const base::StringPiece& data) {
  data.AppendToString(&buffer_);
  DCHECK_LE(buffer_.size() + data.size(), kRequestSizeLimit) <<
      "The HTTP request is too large.";
}

std::string HttpRequestParser::ShiftLine() {
  size_t eoln_position = buffer_.find("\r\n", buffer_position_);
  DCHECK_NE(std::string::npos, eoln_position);
  const int line_length = eoln_position - buffer_position_;
  std::string result = buffer_.substr(buffer_position_, line_length);
  buffer_position_ += line_length + 2;
  return result;
}

HttpRequestParser::ParseResult HttpRequestParser::ParseRequest() {
  DCHECK_NE(STATE_ACCEPTED, state_);
  // Parse the request from beginning. However, entire request may not be
  // available in the buffer.
  if (state_ == STATE_HEADERS) {
    if (ParseHeaders() == ACCEPTED)
      return ACCEPTED;
  }
  // This should not be 'else if' of the previous block, as |state_| can be
  // changed in ParseHeaders().
  if (state_ == STATE_CONTENT) {
    if (ParseContent() == ACCEPTED)
      return ACCEPTED;
  }
  return WAITING;
}

HttpRequestParser::ParseResult HttpRequestParser::ParseHeaders() {
  // Check if the all request headers are available.
  if (buffer_.find("\r\n\r\n", buffer_position_) == std::string::npos)
    return WAITING;

  // Parse request's the first header line.
  // Request main main header, eg. GET /foobar.html HTTP/1.1
  std::string request_headers;
  {
    const std::string header_line = ShiftLine();
    http_request_->all_headers += header_line + "\r\n";
    std::vector<std::string> header_line_tokens = base::SplitString(
        header_line, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL);
    DCHECK_EQ(3u, header_line_tokens.size());
    // Method.
    http_request_->method_string = header_line_tokens[0];
    http_request_->method =
        GetMethodType(base::ToLowerASCII(header_line_tokens[0]));
    // Address.
    // Don't build an absolute URL as the parser does not know (should not
    // know) anything about the server address.
    GURL url(header_line_tokens[1]);
    if (url.is_valid()) {
      http_request_->relative_url = url.path();
    } else if (header_line_tokens[1][0] == '/') {
      http_request_->relative_url = header_line_tokens[1];
    } else {
      http_request_->relative_url = "/" + header_line_tokens[1];
    }

    // Protocol.
    const std::string protocol = base::ToLowerASCII(header_line_tokens[2]);
    CHECK(protocol == "http/1.0" || protocol == "http/1.1") <<
        "Protocol not supported: " << protocol;
  }

  // Parse further headers.
  {
    std::string header_name;
    while (true) {
      std::string header_line = ShiftLine();
      if (header_line.empty())
        break;

      http_request_->all_headers += header_line + "\r\n";
      if (header_line[0] == ' ' || header_line[0] == '\t') {
        // Continuation of the previous multi-line header.
        std::string header_value =
            Trim(header_line.substr(1, header_line.size() - 1));
        http_request_->headers[header_name] += " " + header_value;
      } else {
        // New header.
        size_t delimiter_pos = header_line.find(":");
        DCHECK_NE(std::string::npos, delimiter_pos) << "Syntax error.";
        header_name = Trim(header_line.substr(0, delimiter_pos));
        std::string header_value = Trim(header_line.substr(
            delimiter_pos + 1,
            header_line.size() - delimiter_pos - 1));
        http_request_->headers[header_name] = header_value;
      }
    }
  }

  // Headers done. Is any content data attached to the request?
  declared_content_length_ = 0;
  if (http_request_->headers.count("Content-Length") > 0) {
    http_request_->has_content = true;
    const bool success = base::StringToSizeT(
        http_request_->headers["Content-Length"],
        &declared_content_length_);
    if (!success) {
      declared_content_length_ = 0;
      LOG(WARNING) << "Malformed Content-Length header's value.";
    }
  } else if (http_request_->headers.count("Transfer-Encoding") > 0) {
    if (http_request_->headers["Transfer-Encoding"] == "chunked") {
      http_request_->has_content = true;
      chunked_decoder_.reset(new HttpChunkedDecoder());
      state_ = STATE_CONTENT;
      return WAITING;
    }
  }
  if (declared_content_length_ == 0) {
    // No content data, so parsing is finished.
    state_ = STATE_ACCEPTED;
    return ACCEPTED;
  }

  // The request has not yet been parsed yet, content data is still to be
  // processed.
  state_ = STATE_CONTENT;
  return WAITING;
}

HttpRequestParser::ParseResult HttpRequestParser::ParseContent() {
  const size_t available_bytes = buffer_.size() - buffer_position_;
  if (chunked_decoder_.get()) {
    int bytes_written = chunked_decoder_->FilterBuf(
        const_cast<char*>(buffer_.data()) + buffer_position_, available_bytes);
    http_request_->content.append(buffer_.data() + buffer_position_,
                                  bytes_written);

    if (chunked_decoder_->reached_eof()) {
      buffer_ =
          buffer_.substr(buffer_.size() - chunked_decoder_->bytes_after_eof());
      buffer_position_ = 0;
      state_ = STATE_ACCEPTED;
      return ACCEPTED;
    }
    buffer_ = "";
    buffer_position_ = 0;
    state_ = STATE_CONTENT;
    return WAITING;
  }

  const size_t fetch_bytes = std::min(
      available_bytes,
      declared_content_length_ - http_request_->content.size());
  http_request_->content.append(buffer_.data() + buffer_position_,
                                fetch_bytes);
  buffer_position_ += fetch_bytes;

  if (declared_content_length_ == http_request_->content.size()) {
    state_ = STATE_ACCEPTED;
    return ACCEPTED;
  }

  state_ = STATE_CONTENT;
  return WAITING;
}

scoped_ptr<HttpRequest> HttpRequestParser::GetRequest() {
  DCHECK_EQ(STATE_ACCEPTED, state_);
  scoped_ptr<HttpRequest> result = http_request_.Pass();

  // Prepare for parsing a new request.
  state_ = STATE_HEADERS;
  http_request_.reset(new HttpRequest());
  buffer_.clear();
  buffer_position_ = 0;
  declared_content_length_ = 0;

  return result.Pass();
}

HttpMethod HttpRequestParser::GetMethodType(const std::string& token) const {
  if (token == "get") {
    return METHOD_GET;
  } else if (token == "head") {
    return METHOD_HEAD;
  } else if (token == "post") {
    return METHOD_POST;
  } else if (token == "put") {
    return METHOD_PUT;
  } else if (token == "delete") {
    return METHOD_DELETE;
  } else if (token == "patch") {
    return METHOD_PATCH;
  } else if (token == "connect") {
    return METHOD_CONNECT;
  }
  LOG(WARNING) << "Method not implemented: " << token;
  return METHOD_GET;
}

}  // namespace test_server
}  // namespace net
