// Copyright 2018 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 "base/strings/string_number_conversions.h"
#include "net/base/elements_upload_data_stream.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h"
#include "net/base/upload_bytes_element_reader.h"
#include "net/cert/cert_status_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "net/http/http_util.h"
#include "net/ssl/ssl_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_info.h"
#include "net/url_request/url_request_context.h"

#include "net/tools/quic/quic_http_proxy_backend_stream.h"

namespace net {

// This is the Size of the buffer that consumes the response from the Backend
// The response is consumed upto 64KB at a time to avoid a large response
// from hogging resources from smaller responses.
const int QuicHttpProxyBackendStream::kBufferSize = 64000;
/*502 Bad Gateway
  The server was acting as a gateway or proxy and received an
  invalid response from the upstream server.*/
const int QuicHttpProxyBackendStream::kProxyHttpBackendError = 502;
// Hop-by-hop headers (small-caps). These are removed when sent to the backend.
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html
// not Trailers per URL above;
// http://www.rfc-editor.org/errata_search.php?eid=4522
const std::set<std::string> QuicHttpProxyBackendStream::kHopHeaders = {
    "connection",
    "proxy-connection",  // non-standard but still sent by libcurl and rejected
                         // by e.g. google
    "keep-alive", "proxy-authenticate", "proxy-authorization",
    "te",       // canonicalized version of "TE"
    "trailer",  // not Trailers per URL above;
                // http://www.rfc-editor.org/errata_search.php?eid=4522
    "transfer-encoding", "upgrade",
};
const std::string QuicHttpProxyBackendStream::kDefaultQuicPeerIP = "Unknown";

QuicHttpProxyBackendStream::QuicHttpProxyBackendStream(
    QuicHttpProxyBackend* proxy_context)
    : proxy_context_(proxy_context),
      delegate_(nullptr),
      quic_peer_ip_(kDefaultQuicPeerIP),
      url_request_(nullptr),
      buf_(base::MakeRefCounted<IOBuffer>(kBufferSize)),
      response_completed_(false),
      headers_set_(false),
      quic_response_(new quic::QuicBackendResponse()) {}

QuicHttpProxyBackendStream::~QuicHttpProxyBackendStream() {}

void QuicHttpProxyBackendStream::Initialize(
    quic::QuicConnectionId quic_connection_id,
    quic::QuicStreamId quic_stream_id,
    std::string quic_peer_ip) {
  quic_connection_id_ = quic_connection_id;
  quic_stream_id_ = quic_stream_id;
  quic_peer_ip_ = quic_peer_ip;
  if (!quic_proxy_task_runner_.get()) {
    quic_proxy_task_runner_ = proxy_context_->GetProxyTaskRunner();
  } else {
    DCHECK_EQ(quic_proxy_task_runner_, proxy_context_->GetProxyTaskRunner());
  }

  quic_response_->set_response_type(
      quic::QuicBackendResponse::BACKEND_ERR_RESPONSE);
}

void QuicHttpProxyBackendStream::set_delegate(
    quic::QuicSimpleServerBackend::RequestHandler* delegate) {
  delegate_ = delegate;
  delegate_task_runner_ = base::SequencedTaskRunnerHandle::Get();
}

bool QuicHttpProxyBackendStream::SendRequestToBackend(
    const spdy::SpdyHeaderBlock* incoming_request_headers,
    const std::string& incoming_body) {
  DCHECK(proxy_context_->IsBackendInitialized())
      << " The quic-backend-proxy-context should be initialized";

  // Get Path From the Incoming Header Block
  spdy::SpdyHeaderBlock::const_iterator it =
      incoming_request_headers->find(":path");

  GURL url = proxy_context_->backend_url();
  std::string backend_spec = url.spec();
  if (it != incoming_request_headers->end()) {
    if (url.path().compare("/") == 0) {
      backend_spec.pop_back();
    }
    backend_spec.append(it->second.as_string());
  }

  url_ = GURL(backend_spec.c_str());
  if (!url_.is_valid()) {
    LOG(ERROR) << "Invalid URL received from QUIC client " << backend_spec;
    return false;
  }
  LOG(INFO) << "QUIC Proxy Making a request to the Backed URL: " + url_.spec();

  // Set the Method From the Incoming Header Block
  std::string method = "";
  it = incoming_request_headers->find(":method");
  if (it != incoming_request_headers->end()) {
    method.append(it->second.as_string());
  }
  if (ValidateHttpMethod(method) != true) {
    LOG(INFO) << "Unknown Request Type received from QUIC client " << method;
    return false;
  }
  CopyHeaders(incoming_request_headers);
  if (method_type_ == "POST" || method_type_ == "PUT" ||
      method_type_ == "PATCH") {
    // Upload content must be set
    if (!incoming_body.empty()) {
      std::unique_ptr<UploadElementReader> reader(new UploadBytesElementReader(
          incoming_body.data(), incoming_body.size()));
      SetUpload(
          ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
    }
  }
  // Start the request on the backend thread
  bool posted = quic_proxy_task_runner_->PostTask(
      FROM_HERE,
      base::BindOnce(&QuicHttpProxyBackendStream::SendRequestOnBackendThread,
                     weak_factory_.GetWeakPtr()));
  return posted;
}

void QuicHttpProxyBackendStream::CopyHeaders(
    const spdy::SpdyHeaderBlock* incoming_request_headers) {
  // Set all the request headers
  // Add or append the X-Forwarded-For Header and X-Real-IP
  for (spdy::SpdyHeaderBlock::const_iterator it =
           incoming_request_headers->begin();
       it != incoming_request_headers->end(); ++it) {
    std::string key = it->first.as_string();
    std::string value = it->second.as_string();
    // Ignore the spdy headers
    if (!key.empty() && key[0] != ':') {
      // Remove hop-by-hop headers
      if (base::Contains(kHopHeaders, key)) {
        LOG(INFO) << "QUIC Proxy Ignoring Hop-by-hop Request Header: " << key
                  << ":" << value;
      } else {
        LOG(INFO) << "QUIC Proxy Copying to backend Request Header: " << key
                  << ":" << value;
        AddRequestHeader(key, value);
      }
    }
  }
  // ToDo append proxy ip when x_forwarded_for header already present
  AddRequestHeader("X-Forwarded-For", quic_peer_ip_);
}

bool QuicHttpProxyBackendStream::ValidateHttpMethod(std::string method) {
  // Http method is a token, just as header name.
  if (!net::HttpUtil::IsValidHeaderName(method))
    return false;
  method_type_ = method;
  return true;
}

bool QuicHttpProxyBackendStream::AddRequestHeader(std::string name,
                                                  std::string value) {
  if (!net::HttpUtil::IsValidHeaderName(name) ||
      !net::HttpUtil::IsValidHeaderValue(value)) {
    return false;
  }
  request_headers_.SetHeader(name, value);
  return true;
}

void QuicHttpProxyBackendStream::SetUpload(
    std::unique_ptr<net::UploadDataStream> upload) {
  DCHECK(!upload_);
  upload_ = std::move(upload);
}

void QuicHttpProxyBackendStream::SendRequestOnBackendThread() {
  DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  url_request_ = proxy_context_->GetURLRequestContext()->CreateRequest(
      url_, net::DEFAULT_PRIORITY, this, MISSING_TRAFFIC_ANNOTATION);
  url_request_->set_method(method_type_);
  url_request_->SetExtraRequestHeaders(request_headers_);
  if (upload_) {
    url_request_->set_upload(std::move(upload_));
  }
  url_request_->Start();
  VLOG(1) << "Quic Proxy Sending Request to Backend for quic_conn_id: "
          << quic_connection_id_ << " quic_stream_id: " << quic_stream_id_
          << " backend_req_id: " << url_request_->identifier()
          << " url: " << url_;
}

void QuicHttpProxyBackendStream::OnReceivedRedirect(
    net::URLRequest* request,
    const net::RedirectInfo& redirect_info,
    bool* defer_redirect) {
  DCHECK_EQ(request, url_request_.get());
  DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  // Do not defer redirect, retry again from the proxy with the new url
  *defer_redirect = false;
  LOG(ERROR) << "Received Redirect from Backend "
             << " BackendReqId: " << request->identifier() << " redirectUrl: "
             << redirect_info.new_url.possibly_invalid_spec().c_str()
             << " RespCode " << request->GetResponseCode();
}

void QuicHttpProxyBackendStream::OnCertificateRequested(
    net::URLRequest* request,
    net::SSLCertRequestInfo* cert_request_info) {
  DCHECK_EQ(request, url_request_.get());
  DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  // Continue the SSL handshake without a client certificate.
  request->ContinueWithCertificate(nullptr, nullptr);
}

void QuicHttpProxyBackendStream::OnSSLCertificateError(
    net::URLRequest* request,
    int net_error,
    const net::SSLInfo& ssl_info,
    bool fatal) {
  request->Cancel();
  OnResponseCompleted();
}

void QuicHttpProxyBackendStream::OnResponseStarted(net::URLRequest* request,
                                                   int net_error) {
  DCHECK_EQ(request, url_request_.get());
  DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  // It doesn't make sense for the request to have IO pending at this point.
  DCHECK_NE(net::ERR_IO_PENDING, net_error);
  if (net_error != net::OK) {
    LOG(ERROR) << "OnResponseStarted Error from Backend "
               << url_request_->identifier() << " url: "
               << url_request_->url().possibly_invalid_spec().c_str()
               << " RespError " << net::ErrorToString(net_error);
    OnResponseCompleted();
    return;
  }
  // Initialite the first read
  ReadOnceTask();
}

void QuicHttpProxyBackendStream::ReadOnceTask() {
  // Initiate a read for a max of kBufferSize
  // This avoids a request with a large response from starving
  // requests with smaller responses
  int bytes_read = url_request_->Read(buf_.get(), kBufferSize);
  OnReadCompleted(url_request_.get(), bytes_read);
}

// In the case of net::ERR_IO_PENDING,
// OnReadCompleted callback will be called by URLRequest
void QuicHttpProxyBackendStream::OnReadCompleted(net::URLRequest* unused,
                                                 int bytes_read) {
  DCHECK_EQ(url_request_.get(), unused);
  LOG(INFO) << "OnReadCompleted Backend with"
            << " ReqId: " << url_request_->identifier() << " RespCode "
            << url_request_->GetResponseCode() << " RcvdBytesCount "
            << bytes_read << " RcvdTotalBytes " << data_received_.size();

  if (bytes_read > 0) {
    data_received_.append(buf_->data(), bytes_read);
    // More data to be read, send a task to self
    quic_proxy_task_runner_->PostTask(
        FROM_HERE, base::BindOnce(&QuicHttpProxyBackendStream::ReadOnceTask,
                                  weak_factory_.GetWeakPtr()));
  } else if (bytes_read != net::ERR_IO_PENDING) {
    quic_response_->set_response_type(
        quic::QuicBackendResponse::REGULAR_RESPONSE);
    OnResponseCompleted();
  }
}

/* Response from Backend complete, send the last chunk of data with fin=true to
 * the corresponding quic stream */
void QuicHttpProxyBackendStream::OnResponseCompleted() {
  DCHECK(!response_completed_);
  LOG(INFO) << "Quic Proxy Received Response from Backend for quic_conn_id: "
            << quic_connection_id_ << " quic_stream_id: " << quic_stream_id_
            << " backend_req_id: " << url_request_->identifier()
            << " url: " << url_;

  // ToDo Stream the response
  spdy::SpdyHeaderBlock response_headers;
  if (quic_response_->response_type() !=
      quic::QuicBackendResponse::BACKEND_ERR_RESPONSE) {
    response_headers = getAsQuicHeaders(url_request_->response_headers(),
                                        url_request_->GetResponseCode(),
                                        data_received_.size());
    quic_response_->set_headers(std::move(response_headers));
    quic_response_->set_body(std::move(data_received_));
  } else {
    response_headers =
        getAsQuicHeaders(url_request_->response_headers(),
                         kProxyHttpBackendError, data_received_.size());
    quic_response_->set_headers(std::move(response_headers));
  }
  response_completed_ = true;
  ReleaseRequest();

  // Send the response back to the quic client on the quic/main thread
  if (delegate_ != nullptr) {
    delegate_task_runner_->PostTask(
        FROM_HERE,
        base::BindOnce(
            &QuicHttpProxyBackendStream::SendResponseOnDelegateThread,
            base::Unretained(this)));
  }
}

void QuicHttpProxyBackendStream::SendResponseOnDelegateThread() {
  DCHECK(delegate_ != nullptr);
  // Proxy currently does not support push resources
  std::list<quic::QuicBackendResponse::ServerPushInfo> empty_resources;
  delegate_->OnResponseBackendComplete(quic_response_.get(), empty_resources);
}

void QuicHttpProxyBackendStream::CancelRequest() {
  DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  if (quic_proxy_task_runner_.get())
    DCHECK(quic_proxy_task_runner_->BelongsToCurrentThread());
  delegate_ = nullptr;
  if (url_request_.get()) {
    url_request_->CancelWithError(ERR_ABORTED);
    ReleaseRequest();
  }
}

void QuicHttpProxyBackendStream::ReleaseRequest() {
  url_request_.reset();
  buf_ = nullptr;
}

quic::QuicBackendResponse* QuicHttpProxyBackendStream::GetBackendResponse()
    const {
  return quic_response_.get();
}

// Copy Backend Response headers to Quic response headers
spdy::SpdyHeaderBlock QuicHttpProxyBackendStream::getAsQuicHeaders(
    net::HttpResponseHeaders* resp_headers,
    int response_code,
    uint64_t response_decoded_body_size) {
  DCHECK(!headers_set_);
  bool response_body_encoded = false;
  spdy::SpdyHeaderBlock quic_response_headers;
  // Add spdy headers: Status, version need : before the header
  quic_response_headers[":status"] = base::NumberToString(response_code);
  headers_set_ = true;
  // Returns an empty array if |headers| is nullptr.
  if (resp_headers != nullptr) {
    size_t iter = 0;
    std::string header_name;
    std::string header_value;
    while (resp_headers->EnumerateHeaderLines(&iter, &header_name,
                                              &header_value)) {
      header_name = base::ToLowerASCII(header_name);
      // Do not copy status again since status needs a ":" before the header
      // name
      if (header_name.compare("status") != 0) {
        if (header_name.compare("content-encoding") != 0) {
          // Remove hop-by-hop headers
          if (base::Contains(kHopHeaders, header_name)) {
            LOG(INFO) << "Quic Proxy Ignoring Hop-by-hop Response Header: "
                      << header_name << ":" << header_value;
          } else {
            LOG(INFO) << " Quic Proxy Copying Response Header: " << header_name
                      << ":" << header_value;
            quic_response_headers.AppendValueOrAddHeader(header_name,
                                                         header_value);
          }
        } else {
          response_body_encoded = true;
        }
      }
    }  // while
    // Currently URLRequest class does not support ability to disable decoding,
    // response body (gzip, deflate etc. )
    // Instead of re-encoding the body, we send decode body to the quic client
    // and re-write the content length to the original body size
    if (response_body_encoded) {
      LOG(INFO) << " Quic Proxy Rewriting the Content-Length Header since "
                   "the response was encoded : "
                << response_decoded_body_size;
      quic_response_headers["content-length"] =
          base::NumberToString(response_decoded_body_size);
    }
  }
  return quic_response_headers;
}
}  // namespace net
