// 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/tools/quic/spdy_utils.h"

#include <string>

#include "base/memory/scoped_ptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_util.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_protocol.h"
#include "net/tools/balsa/balsa_headers.h"
#include "url/gurl.h"

using base::StringPiece;
using std::make_pair;
using std::pair;
using std::string;

namespace net {
namespace tools {

const char* const kV4Host = ":authority";

const char* const kV3Host = ":host";
const char* const kV3Path = ":path";
const char* const kV3Scheme = ":scheme";
const char* const kV3Status = ":status";
const char* const kV3Method = ":method";
const char* const kV3Version = ":version";

void PopulateSpdyHeaderBlock(const BalsaHeaders& headers,
                             SpdyHeaderBlock* block,
                             bool allow_empty_values) {
  for (BalsaHeaders::const_header_lines_iterator hi =
       headers.header_lines_begin();
       hi != headers.header_lines_end();
       ++hi) {
    if ((hi->second.length() == 0) && !allow_empty_values) {
      DVLOG(1) << "Dropping empty header " << hi->first.as_string()
               << " from headers";
      continue;
    }

    // This unfortunately involves loads of copying, but its the simplest way
    // to sort the headers and leverage the framer.
    string name = hi->first.as_string();
    base::StringToLowerASCII(&name);
    SpdyHeaderBlock::iterator it = block->find(name);
    if (it != block->end()) {
      it->second.reserve(it->second.size() + 1 + hi->second.size());
      it->second.append("\0", 1);
      it->second.append(hi->second.data(), hi->second.size());
    } else {
      block->insert(make_pair(name, hi->second.as_string()));
    }
  }
}

void PopulateSpdy3RequestHeaderBlock(const BalsaHeaders& headers,
                                     const string& scheme,
                                     const string& host_and_port,
                                     const string& path,
                                     SpdyHeaderBlock* block) {
  PopulateSpdyHeaderBlock(headers, block, true);
  StringPiece host_header = headers.GetHeader("Host");
  if (!host_header.empty()) {
    DCHECK(host_and_port.empty() || host_header == host_and_port);
    block->insert(make_pair(kV3Host, host_header.as_string()));
  } else {
    block->insert(make_pair(kV3Host, host_and_port));
  }
  block->insert(make_pair(kV3Path, path));
  block->insert(make_pair(kV3Scheme, scheme));

  if (!headers.request_method().empty()) {
    block->insert(make_pair(kV3Method, headers.request_method().as_string()));
  }

  if (!headers.request_version().empty()) {
    (*block)[kV3Version] = headers.request_version().as_string();
  }
}

void PopulateSpdy4RequestHeaderBlock(const BalsaHeaders& headers,
                                     const string& scheme,
                                     const string& host_and_port,
                                     const string& path,
                                     SpdyHeaderBlock* block) {
  PopulateSpdyHeaderBlock(headers, block, true);
  StringPiece host_header = headers.GetHeader("Host");
  if (!host_header.empty()) {
    DCHECK(host_and_port.empty() || host_header == host_and_port);
    block->insert(make_pair(kV4Host, host_header.as_string()));
    // PopulateSpdyHeaderBlock already added the "host" header,
    // which is invalid for SPDY4.
    block->erase("host");
  } else {
    block->insert(make_pair(kV4Host, host_and_port));
  }
  block->insert(make_pair(kV3Path, path));
  block->insert(make_pair(kV3Scheme, scheme));

  if (!headers.request_method().empty()) {
    block->insert(make_pair(kV3Method, headers.request_method().as_string()));
  }
}

void PopulateSpdyResponseHeaderBlock(const BalsaHeaders& headers,
                                     SpdyHeaderBlock* block) {
  string status = headers.response_code().as_string();
  status.append(" ");
  status.append(headers.response_reason_phrase().as_string());
  (*block)[kV3Status] = status;
  (*block)[kV3Version] =
      headers.response_version().as_string();

  // Empty header values are only allowed because this is spdy3.
  PopulateSpdyHeaderBlock(headers, block, true);
}

// static
SpdyHeaderBlock SpdyUtils::RequestHeadersToSpdyHeaders(
    const BalsaHeaders& request_headers) {
  string scheme;
  string host_and_port;
  string path;

  string url = request_headers.request_uri().as_string();
  if (url.empty() || url[0] == '/') {
    path = url;
  } else {
    GURL request_uri(url);
    if (request_headers.request_method() == "CONNECT") {
      path = url;
    } else {
      path = request_uri.path();
      if (!request_uri.query().empty()) {
        path = path + "?" + request_uri.query();
      }
      host_and_port = request_uri.host();
      scheme = request_uri.scheme();
    }
  }

  DCHECK(!scheme.empty());
  DCHECK(!host_and_port.empty());
  DCHECK(!path.empty());

  SpdyHeaderBlock block;
  PopulateSpdy3RequestHeaderBlock(
      request_headers, scheme, host_and_port, path, &block);
  if (block.find("host") != block.end()) {
    block.erase(block.find("host"));
  }
  return block;
}

// static
SpdyHeaderBlock SpdyUtils::RequestHeadersToSpdy4Headers(
    const BalsaHeaders& request_headers) {
  string scheme;
  string host_and_port;
  string path;

  string url = request_headers.request_uri().as_string();
  if (url.empty() || url[0] == '/') {
    path = url;
  } else {
    GURL request_uri(url);
    if (request_headers.request_method() == "CONNECT") {
      path = url;
    } else {
      path = request_uri.path();
      if (!request_uri.query().empty()) {
        path = path + "?" + request_uri.query();
      }
      host_and_port = request_uri.host();
      scheme = request_uri.scheme();
    }
  }

  DCHECK(!scheme.empty());
  DCHECK(!host_and_port.empty());
  DCHECK(!path.empty());

  SpdyHeaderBlock block;
  PopulateSpdy4RequestHeaderBlock(request_headers, scheme, host_and_port, path,
                                  &block);
  if (block.find("host") != block.end()) {
    block.erase(block.find("host"));
  }
  return block;
}

// static
string SpdyUtils::SerializeRequestHeaders(const BalsaHeaders& request_headers) {
  SpdyHeaderBlock block = RequestHeadersToSpdyHeaders(request_headers);
  return SerializeUncompressedHeaders(block);
}

// static
SpdyHeaderBlock SpdyUtils::ResponseHeadersToSpdyHeaders(
    const BalsaHeaders& response_headers) {
  SpdyHeaderBlock block;
  PopulateSpdyResponseHeaderBlock(response_headers, &block);
  return block;
}

// static
string SpdyUtils::SerializeResponseHeaders(
    const BalsaHeaders& response_headers) {
  SpdyHeaderBlock block = ResponseHeadersToSpdyHeaders(response_headers);

  return SerializeUncompressedHeaders(block);
}

// static
string SpdyUtils::SerializeUncompressedHeaders(const SpdyHeaderBlock& headers) {
  size_t length = SpdyFramer::GetSerializedLength(SPDY3, &headers);
  SpdyFrameBuilder builder(length, SPDY3);
  SpdyFramer::WriteHeaderBlock(&builder, SPDY3, &headers);
  scoped_ptr<SpdyFrame> block(builder.take());
  return string(block->data(), length);
}

bool IsSpecialSpdyHeader(SpdyHeaderBlock::const_iterator header,
                            BalsaHeaders* headers) {
  if (header->first.empty() || header->second.empty()) {
    return true;
  }
  const string& header_name = header->first;
  return header_name.c_str()[0] == ':';
}

bool SpdyUtils::FillBalsaRequestHeaders(
    const SpdyHeaderBlock& header_block,
    BalsaHeaders* request_headers) {
  typedef SpdyHeaderBlock::const_iterator BlockIt;

  BlockIt host_it = header_block.find(kV3Host);
  BlockIt path_it = header_block.find(kV3Path);
  BlockIt scheme_it = header_block.find(kV3Scheme);
  BlockIt method_it = header_block.find(kV3Method);
  BlockIt end_it = header_block.end();
  if (host_it == end_it || path_it == end_it || scheme_it == end_it ||
      method_it == end_it) {
    return false;
  }
  string url = scheme_it->second;
  url.append("://");
  url.append(host_it->second);
  url.append(path_it->second);
  request_headers->SetRequestUri(url);
  request_headers->SetRequestMethod(method_it->second);

  BlockIt cl_it = header_block.find("content-length");
  if (cl_it != header_block.end()) {
    int content_length;
    if (!base::StringToInt(cl_it->second, &content_length)) {
      return false;
    }
    request_headers->SetContentLength(content_length);
  }

  for (BlockIt it = header_block.begin(); it != header_block.end(); ++it) {
   if (!IsSpecialSpdyHeader(it, request_headers)) {
     request_headers->AppendHeader(it->first, it->second);
   }
  }

  return true;
}

// The reason phrase should match regexp [\d\d\d [^\r\n]+].  If not, we will
// fail to parse it.
bool ParseReasonAndStatus(StringPiece status_and_reason,
                          BalsaHeaders* headers) {
  if (status_and_reason.size() < 5)
    return false;

  if (status_and_reason[3] != ' ')
    return false;

  const StringPiece status_str = StringPiece(status_and_reason.data(), 3);
  int status;
  if (!base::StringToInt(status_str, &status)) {
    return false;
  }

  headers->SetResponseCode(status_str);
  headers->set_parsed_response_code(status);

  StringPiece reason(status_and_reason.data() + 4,
                     status_and_reason.length() - 4);

  headers->SetResponseReasonPhrase(reason);
  return true;
}

bool SpdyUtils::FillBalsaResponseHeaders(
    const SpdyHeaderBlock& header_block,
    BalsaHeaders* request_headers) {
  typedef SpdyHeaderBlock::const_iterator BlockIt;

  BlockIt status_it = header_block.find(kV3Status);
  BlockIt version_it = header_block.find(kV3Version);
  BlockIt end_it = header_block.end();
  if (status_it == end_it || version_it == end_it) {
    return false;
  }

  if (!ParseReasonAndStatus(status_it->second, request_headers)) {
    return false;
  }
  request_headers->SetResponseVersion(version_it->second);
  for (BlockIt it = header_block.begin(); it != header_block.end(); ++it) {
   if (!IsSpecialSpdyHeader(it, request_headers)) {
     request_headers->AppendHeader(it->first, it->second);
   }
  }
  return true;
}

}  // namespace tools
}  // namespace net
