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