// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "net/base/proxy_string_util.h"

#include <string>
#include <string_view>
#include <vector>

#include "base/check.h"
#include "base/notreached.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "build/buildflag.h"
#include "net/base/proxy_server.h"
#include "net/base/url_util.h"
#include "net/http/http_util.h"
#include "net/net_buildflags.h"
#include "url/third_party/mozilla/url_parse.h"

namespace net {

namespace {

// Parses the proxy type from a PAC string, to a ProxyServer::Scheme.
// This mapping is case-insensitive. If no type could be matched
// returns SCHEME_INVALID.
ProxyServer::Scheme GetSchemeFromPacTypeInternal(std::string_view type) {
  if (base::EqualsCaseInsensitiveASCII(type, "proxy")) {
    return ProxyServer::SCHEME_HTTP;
  }
  if (base::EqualsCaseInsensitiveASCII(type, "socks")) {
    // Default to v4 for compatibility. This is because the SOCKS4 vs SOCKS5
    // notation didn't originally exist, so if a client returns SOCKS they
    // really meant SOCKS4.
    return ProxyServer::SCHEME_SOCKS4;
  }
  if (base::EqualsCaseInsensitiveASCII(type, "socks4")) {
    return ProxyServer::SCHEME_SOCKS4;
  }
  if (base::EqualsCaseInsensitiveASCII(type, "socks5")) {
    return ProxyServer::SCHEME_SOCKS5;
  }
  if (base::EqualsCaseInsensitiveASCII(type, "https")) {
    return ProxyServer::SCHEME_HTTPS;
  }

  return ProxyServer::SCHEME_INVALID;
}

std::string ConstructHostPortString(std::string_view hostname, uint16_t port) {
  DCHECK(!hostname.empty());
  DCHECK((hostname.front() == '[' && hostname.back() == ']') ||
         hostname.find(":") == std::string_view::npos);

  return base::StrCat({hostname, ":", base::NumberToString(port)});
}

std::tuple<std::string_view, std::string_view>
PacResultElementToSchemeAndHostPort(std::string_view pac_result_element) {
  // Trim the leading/trailing whitespace.
  pac_result_element = HttpUtil::TrimLWS(pac_result_element);

  // Input should match:
  // ( <type> 1*(LWS) <host-and-port> )

  // Start by finding the first space (if any).
  size_t space = 0;
  for (; space < pac_result_element.size(); space++) {
    if (HttpUtil::IsLWS(pac_result_element[space])) {
      break;
    }
  }
  // Everything to the left of the space is the scheme.
  std::string_view scheme = pac_result_element.substr(0, space);

  // And everything to the right of the space is the
  // <host>[":" <port>].
  std::string_view host_and_port = pac_result_element.substr(space);
  return std::make_tuple(scheme, host_and_port);
}

}  // namespace

ProxyChain PacResultElementToProxyChain(std::string_view pac_result_element) {
  // Proxy chains are not supported in PAC strings, so this is just parsed
  // as a single server.
  auto [type, host_and_port] =
      PacResultElementToSchemeAndHostPort(pac_result_element);
  if (base::EqualsCaseInsensitiveASCII(type, "direct") &&
      host_and_port.empty()) {
    return ProxyChain::Direct();
  }
  return ProxyChain(PacResultElementToProxyServer(pac_result_element));
}

ProxyServer PacResultElementToProxyServer(std::string_view pac_result_element) {
  auto [type, host_and_port] =
      PacResultElementToSchemeAndHostPort(pac_result_element);
  ProxyServer::Scheme scheme = GetSchemeFromPacTypeInternal(type);
  return ProxySchemeHostAndPortToProxyServer(scheme, host_and_port);
}

std::string ProxyServerToPacResultElement(const ProxyServer& proxy_server) {
  switch (proxy_server.scheme()) {
    case ProxyServer::SCHEME_HTTP:
      return std::string("PROXY ") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_SOCKS4:
      // For compatibility send SOCKS instead of SOCKS4.
      return std::string("SOCKS ") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_SOCKS5:
      return std::string("SOCKS5 ") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_HTTPS:
      return std::string("HTTPS ") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_QUIC:
      return std::string("QUIC ") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    default:
      // Got called with an invalid scheme.
      NOTREACHED();
  }
}

ProxyChain ProxyUriToProxyChain(std::string_view uri,
                                ProxyServer::Scheme default_scheme,
                                bool is_quic_allowed) {
  // If uri is direct, return direct proxy chain.
  uri = HttpUtil::TrimLWS(uri);
  size_t colon = uri.find("://");
  if (colon != std::string_view::npos &&
      base::EqualsCaseInsensitiveASCII(uri.substr(0, colon), "direct")) {
    if (!uri.substr(colon + 3).empty()) {
      return ProxyChain();  // Invalid -- Direct chain cannot have a host/port.
    }
    return ProxyChain::Direct();
  }
  return ProxyChain(
      ProxyUriToProxyServer(uri, default_scheme, is_quic_allowed));
}

ProxyServer ProxyUriToProxyServer(std::string_view uri,
                                  ProxyServer::Scheme default_scheme,
                                  bool is_quic_allowed) {
  // We will default to |default_scheme| if no scheme specifier was given.
  ProxyServer::Scheme scheme = default_scheme;

  // Trim the leading/trailing whitespace.
  uri = HttpUtil::TrimLWS(uri);

  // Check for [<scheme> "://"]
  size_t colon = uri.find(':');
  if (colon != std::string_view::npos && uri.size() - colon >= 3 &&
      uri[colon + 1] == '/' && uri[colon + 2] == '/') {
    scheme = GetSchemeFromUriScheme(uri.substr(0, colon), is_quic_allowed);
    uri = uri.substr(colon + 3);  // Skip past the "://"
  }

  // Now parse the <host>[":"<port>].
  return ProxySchemeHostAndPortToProxyServer(scheme, uri);
}

std::string ProxyServerToProxyUri(const ProxyServer& proxy_server) {
  switch (proxy_server.scheme()) {
    case ProxyServer::SCHEME_HTTP:
      // Leave off "http://" since it is our default scheme.
      return ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_SOCKS4:
      return std::string("socks4://") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_SOCKS5:
      return std::string("socks5://") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_HTTPS:
      return std::string("https://") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    case ProxyServer::SCHEME_QUIC:
      return std::string("quic://") +
             ConstructHostPortString(proxy_server.GetHost(),
                                     proxy_server.GetPort());
    default:
      // Got called with an invalid scheme.
      NOTREACHED();
  }
}

ProxyServer ProxySchemeHostAndPortToProxyServer(
    ProxyServer::Scheme scheme,
    std::string_view host_and_port) {
  // Trim leading/trailing space.
  host_and_port = HttpUtil::TrimLWS(host_and_port);

  if (scheme == ProxyServer::SCHEME_INVALID) {
    return ProxyServer();
  }

  url::Component username_component;
  url::Component password_component;
  url::Component hostname_component;
  url::Component port_component;
  url::ParseAuthority(host_and_port, url::Component(0, host_and_port.size()),
                      url::ParserMode::kSpecialURL, &username_component,
                      &password_component, &hostname_component,
                      &port_component);
  if (username_component.is_valid() || password_component.is_valid() ||
      hostname_component.is_empty()) {
    return ProxyServer();
  }

  std::string_view hostname =
      host_and_port.substr(hostname_component.begin, hostname_component.len);

  // Reject inputs like "foo:". /url parsing and canonicalization code generally
  // allows it and treats it the same as a URL without a specified port, but
  // Chrome has traditionally disallowed it in proxy specifications.
  if (port_component.is_valid() && port_component.is_empty()) {
    return ProxyServer();
  }
  std::string_view port =
      port_component.is_nonempty()
          ? host_and_port.substr(port_component.begin, port_component.len)
          : "";

  return ProxyServer::FromSchemeHostAndPort(scheme, hostname, port);
}

ProxyServer::Scheme GetSchemeFromUriScheme(std::string_view scheme,
                                           bool is_quic_allowed) {
  if (base::EqualsCaseInsensitiveASCII(scheme, "http")) {
    return ProxyServer::SCHEME_HTTP;
  }
  if (base::EqualsCaseInsensitiveASCII(scheme, "socks4")) {
    return ProxyServer::SCHEME_SOCKS4;
  }
  if (base::EqualsCaseInsensitiveASCII(scheme, "socks")) {
    return ProxyServer::SCHEME_SOCKS5;
  }
  if (base::EqualsCaseInsensitiveASCII(scheme, "socks5")) {
    return ProxyServer::SCHEME_SOCKS5;
  }
  if (base::EqualsCaseInsensitiveASCII(scheme, "https")) {
    return ProxyServer::SCHEME_HTTPS;
  }
#if BUILDFLAG(ENABLE_QUIC_PROXY_SUPPORT)
  if (is_quic_allowed && base::EqualsCaseInsensitiveASCII(scheme, "quic")) {
    return ProxyServer::SCHEME_QUIC;
  }
#endif  // BUILDFLAG(ENABLE_QUIC_PROXY_SUPPORT)
  return ProxyServer::SCHEME_INVALID;
}

ProxyChain MultiProxyUrisToProxyChain(std::string_view uris,
                                      ProxyServer::Scheme default_scheme,
                                      bool is_quic_allowed) {
#if BUILDFLAG(ENABLE_BRACKETED_PROXY_URIS)
  uris = HttpUtil::TrimLWS(uris);
  if (uris.empty()) {
    return ProxyChain();
  }

  bool has_multi_proxy_brackets = uris.front() == '[' && uris.back() == ']';
  // Remove `[]` if present
  if (has_multi_proxy_brackets) {
    uris = HttpUtil::TrimLWS(uris.substr(1, uris.size() - 2));
  }

  std::vector<ProxyServer> proxy_server_list;
  std::vector<std::string_view> uris_list = base::SplitStringPiece(
      uris, " ", base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
  size_t number_of_proxy_uris = uris_list.size();
  bool has_invalid_format =
      number_of_proxy_uris > 1 && !has_multi_proxy_brackets;

  // If uris list is empty or has invalid formatting for multi-proxy chains, an
  // invalid `ProxyChain` should be returned.
  if (uris_list.empty() || has_invalid_format) {
    return ProxyChain();
  }

  for (const auto& uri : uris_list) {
    // If direct is found, it MUST be the only uri in the list. Otherwise, it is
    // an invalid `ProxyChain()`.
    if (base::EqualsCaseInsensitiveASCII(uri, "direct://")) {
      return number_of_proxy_uris > 1 ? ProxyChain() : ProxyChain::Direct();
    }

    proxy_server_list.push_back(
        ProxyUriToProxyServer(uri, default_scheme, is_quic_allowed));
  }

  return ProxyChain(std::move(proxy_server_list));
#else
  // This function should not be called in non-debug modes.
  NOTREACHED();
#endif  // !BUILDFLAG(ENABLE_BRACKETED_PROXY_URIS)
}
}  // namespace net
