tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

ProxyConfig.h (5611B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* This Source Code Form is subject to the terms of the Mozilla Public
      3 * License, v. 2.0. If a copy of the MPL was not distributed with this
      4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      5 
      6 #ifndef mozilla_netwerk_base_proxy_config_h
      7 #define mozilla_netwerk_base_proxy_config_h
      8 
      9 #include <map>
     10 
     11 #include "nsCRT.h"
     12 #include "nsString.h"
     13 #include "nsTArray.h"
     14 
     15 // NOTE: This file is inspired by Chromium's code.
     16 // https://source.chromium.org/chromium/chromium/src/+/main:net/proxy_resolution/proxy_config.h.
     17 
     18 namespace mozilla {
     19 namespace net {
     20 
     21 // ProxyServer stores the {type, host, port} of a proxy server.
     22 // ProxyServer is immutable.
     23 class ProxyServer final {
     24 public:
     25  enum class ProxyType {
     26    DIRECT = 0,
     27    HTTP,
     28    HTTPS,
     29    SOCKS,
     30    SOCKS4,
     31    SOCKS5,
     32    FTP,
     33    // DEFAULT is a special type used on windows only.
     34    DEFAULT
     35  };
     36 
     37  ProxyServer() = default;
     38 
     39  ProxyServer(ProxyType aType, const nsACString& aHost, int32_t aPort)
     40      : mType(aType), mHost(aHost), mPort(aPort) {}
     41 
     42  const nsCString& Host() const { return mHost; }
     43 
     44  int32_t Port() const { return mPort; }
     45 
     46  ProxyType Type() const { return mType; }
     47 
     48  void ToHostAndPortStr(nsACString& aOutput) {
     49    aOutput.Truncate();
     50    if (mType == ProxyType::DIRECT) {
     51      return;
     52    }
     53 
     54    aOutput.Assign(mHost);
     55    if (mPort != -1) {
     56      aOutput.Append(':');
     57      aOutput.AppendInt(mPort);
     58    }
     59  }
     60 
     61  bool operator==(const ProxyServer& aOther) const {
     62    return mType == aOther.mType && mHost == aOther.mHost &&
     63           mPort == aOther.mPort;
     64  }
     65 
     66  bool operator!=(const ProxyServer& aOther) const {
     67    return !(*this == aOther);
     68  }
     69 
     70 private:
     71  ProxyType mType{ProxyType::DIRECT};
     72  nsCString mHost;
     73  int32_t mPort{-1};
     74 };
     75 
     76 // This class includes the information about proxy configuration.
     77 // It contains enabled proxy servers, exception list, and the url of PAC
     78 // script.
     79 class ProxyConfig {
     80 public:
     81  struct ProxyRules {
     82    ProxyRules() = default;
     83    ~ProxyRules() = default;
     84 
     85    std::map<ProxyServer::ProxyType, ProxyServer> mProxyServers;
     86  };
     87 
     88  struct ProxyBypassRules {
     89    ProxyBypassRules() = default;
     90    ~ProxyBypassRules() = default;
     91 
     92    CopyableTArray<nsCString> mExceptions;
     93  };
     94 
     95  ProxyConfig() = default;
     96  ProxyConfig(const ProxyConfig& config);
     97  ~ProxyConfig() = default;
     98 
     99  ProxyRules& Rules() { return mRules; }
    100 
    101  const ProxyRules& Rules() const { return mRules; }
    102 
    103  ProxyBypassRules& ByPassRules() { return mBypassRules; }
    104 
    105  const ProxyBypassRules& ByPassRules() const { return mBypassRules; }
    106 
    107  void SetPACUrl(const nsACString& aUrl) { mPACUrl = aUrl; }
    108 
    109  const nsCString& PACUrl() const { return mPACUrl; }
    110 
    111  static ProxyServer::ProxyType ToProxyType(const char* aType) {
    112    if (!aType) {
    113      return ProxyServer::ProxyType::DIRECT;
    114    }
    115 
    116    if (nsCRT::strcasecmp(aType, "http") == 0) {
    117      return ProxyServer::ProxyType::HTTP;
    118    }
    119    if (nsCRT::strcasecmp(aType, "https") == 0) {
    120      return ProxyServer::ProxyType::HTTPS;
    121    }
    122    if (nsCRT::strcasecmp(aType, "socks") == 0) {
    123      return ProxyServer::ProxyType::SOCKS;
    124    }
    125    if (nsCRT::strcasecmp(aType, "socks4") == 0) {
    126      return ProxyServer::ProxyType::SOCKS4;
    127    }
    128    if (nsCRT::strcasecmp(aType, "socks5") == 0) {
    129      return ProxyServer::ProxyType::SOCKS5;
    130    }
    131    if (nsCRT::strcasecmp(aType, "ftp") == 0) {
    132      return ProxyServer::ProxyType::FTP;
    133    }
    134 
    135    return ProxyServer::ProxyType::DIRECT;
    136  }
    137 
    138  static void SetProxyResult(const char* aType, const nsACString& aHostPort,
    139                             nsACString& aResult) {
    140    aResult.AssignASCII(aType);
    141    aResult.Append(' ');
    142    aResult.Append(aHostPort);
    143  }
    144 
    145  static void SetProxyResultDirect(nsACString& aResult) {
    146    // For whatever reason, a proxy is not to be used.
    147    aResult.AssignLiteral("DIRECT");
    148  }
    149 
    150  static void ProxyStrToResult(const nsACString& aSpecificProxy,
    151                               const nsACString& aDefaultProxy,
    152                               const nsACString& aSocksProxy,
    153                               nsACString& aResult) {
    154    if (!aSpecificProxy.IsEmpty()) {
    155      SetProxyResult("PROXY", aSpecificProxy,
    156                     aResult);  // Protocol-specific proxy.
    157    } else if (!aDefaultProxy.IsEmpty()) {
    158      SetProxyResult("PROXY", aDefaultProxy, aResult);  // Default proxy.
    159    } else if (!aSocksProxy.IsEmpty()) {
    160      SetProxyResult("SOCKS", aSocksProxy, aResult);  // SOCKS proxy.
    161    } else {
    162      SetProxyResultDirect(aResult);  // Direct connection.
    163    }
    164  }
    165 
    166  void GetProxyString(const nsACString& aScheme, nsACString& aResult) {
    167    SetProxyResultDirect(aResult);
    168 
    169    nsAutoCString specificProxy;
    170    nsAutoCString defaultProxy;
    171    nsAutoCString socksProxy;
    172    nsAutoCString prefix;
    173    ToLowerCase(aScheme, prefix);
    174    ProxyServer::ProxyType type = ProxyConfig::ToProxyType(prefix.get());
    175    for (auto& [key, value] : mRules.mProxyServers) {
    176      // Break the loop if we found a specific proxy.
    177      if (key == type) {
    178        value.ToHostAndPortStr(specificProxy);
    179        break;
    180      } else if (key == ProxyServer::ProxyType::DEFAULT) {
    181        value.ToHostAndPortStr(defaultProxy);
    182      } else if (key == ProxyServer::ProxyType::SOCKS) {
    183        value.ToHostAndPortStr(socksProxy);
    184      }
    185    }
    186 
    187    ProxyStrToResult(specificProxy, defaultProxy, socksProxy, aResult);
    188  }
    189 
    190 private:
    191  nsCString mPACUrl;
    192  ProxyRules mRules;
    193  ProxyBypassRules mBypassRules;
    194 };
    195 
    196 }  // namespace net
    197 }  // namespace mozilla
    198 
    199 #endif  // mozilla_netwerk_base_proxy_config_h