зеркало из https://github.com/mozilla/gecko-dev.git
200 строки
5.5 KiB
C++
200 строки
5.5 KiB
C++
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
#ifndef mozilla_netwerk_base_proxy_config_h
|
|
#define mozilla_netwerk_base_proxy_config_h
|
|
|
|
#include <map>
|
|
|
|
#include "nsCRT.h"
|
|
#include "nsString.h"
|
|
#include "nsTArray.h"
|
|
|
|
// NOTE: This file is inspired by Chromium's code.
|
|
// https://source.chromium.org/chromium/chromium/src/+/main:net/proxy_resolution/proxy_config.h.
|
|
|
|
namespace mozilla {
|
|
namespace net {
|
|
|
|
// ProxyServer stores the {type, host, port} of a proxy server.
|
|
// ProxyServer is immutable.
|
|
class ProxyServer final {
|
|
public:
|
|
enum class ProxyType {
|
|
DIRECT = 0,
|
|
HTTP,
|
|
HTTPS,
|
|
SOCKS,
|
|
SOCKS4,
|
|
SOCKS5,
|
|
FTP,
|
|
// DEFAULT is a special type used on windows only.
|
|
DEFAULT
|
|
};
|
|
|
|
ProxyServer() = default;
|
|
|
|
ProxyServer(ProxyType aType, const nsACString& aHost, int32_t aPort)
|
|
: mType(aType), mHost(aHost), mPort(aPort) {}
|
|
|
|
const nsCString& Host() const { return mHost; }
|
|
|
|
int32_t Port() const { return mPort; }
|
|
|
|
ProxyType Type() const { return mType; }
|
|
|
|
void ToHostAndPortStr(nsACString& aOutput) {
|
|
aOutput.Truncate();
|
|
if (mType == ProxyType::DIRECT) {
|
|
return;
|
|
}
|
|
|
|
aOutput.Assign(mHost);
|
|
if (mPort != -1) {
|
|
aOutput.Append(':');
|
|
aOutput.AppendInt(mPort);
|
|
}
|
|
}
|
|
|
|
bool operator==(const ProxyServer& aOther) const {
|
|
return mType == aOther.mType && mHost == aOther.mHost &&
|
|
mPort == aOther.mPort;
|
|
}
|
|
|
|
bool operator!=(const ProxyServer& aOther) const {
|
|
return !(*this == aOther);
|
|
}
|
|
|
|
private:
|
|
ProxyType mType{ProxyType::DIRECT};
|
|
nsCString mHost;
|
|
int32_t mPort{-1};
|
|
};
|
|
|
|
// This class includes the information about proxy configuration.
|
|
// It contains enabled proxy servers, exception list, and the url of PAC
|
|
// script.
|
|
class ProxyConfig {
|
|
public:
|
|
struct ProxyRules {
|
|
ProxyRules() = default;
|
|
~ProxyRules() = default;
|
|
|
|
std::map<ProxyServer::ProxyType, ProxyServer> mProxyServers;
|
|
};
|
|
|
|
struct ProxyBypassRules {
|
|
ProxyBypassRules() = default;
|
|
~ProxyBypassRules() = default;
|
|
|
|
CopyableTArray<nsCString> mExceptions;
|
|
};
|
|
|
|
ProxyConfig() = default;
|
|
ProxyConfig(const ProxyConfig& config);
|
|
~ProxyConfig() = default;
|
|
|
|
ProxyRules& Rules() { return mRules; }
|
|
|
|
const ProxyRules& Rules() const { return mRules; }
|
|
|
|
ProxyBypassRules& ByPassRules() { return mBypassRules; }
|
|
|
|
const ProxyBypassRules& ByPassRules() const { return mBypassRules; }
|
|
|
|
void SetPACUrl(const nsACString& aUrl) { mPACUrl = aUrl; }
|
|
|
|
const nsCString& PACUrl() const { return mPACUrl; }
|
|
|
|
static ProxyServer::ProxyType ToProxyType(const char* aType) {
|
|
if (!aType) {
|
|
return ProxyServer::ProxyType::DIRECT;
|
|
}
|
|
|
|
if (nsCRT::strcasecmp(aType, "http") == 0) {
|
|
return ProxyServer::ProxyType::HTTP;
|
|
}
|
|
if (nsCRT::strcasecmp(aType, "https") == 0) {
|
|
return ProxyServer::ProxyType::HTTPS;
|
|
}
|
|
if (nsCRT::strcasecmp(aType, "socks") == 0) {
|
|
return ProxyServer::ProxyType::SOCKS;
|
|
}
|
|
if (nsCRT::strcasecmp(aType, "socks4") == 0) {
|
|
return ProxyServer::ProxyType::SOCKS4;
|
|
}
|
|
if (nsCRT::strcasecmp(aType, "socks5") == 0) {
|
|
return ProxyServer::ProxyType::SOCKS5;
|
|
}
|
|
if (nsCRT::strcasecmp(aType, "ftp") == 0) {
|
|
return ProxyServer::ProxyType::FTP;
|
|
}
|
|
|
|
return ProxyServer::ProxyType::DIRECT;
|
|
}
|
|
|
|
static void SetProxyResult(const char* aType, const nsACString& aHostPort,
|
|
nsACString& aResult) {
|
|
aResult.AssignASCII(aType);
|
|
aResult.Append(' ');
|
|
aResult.Append(aHostPort);
|
|
}
|
|
|
|
static void SetProxyResultDirect(nsACString& aResult) {
|
|
// For whatever reason, a proxy is not to be used.
|
|
aResult.AssignLiteral("DIRECT");
|
|
}
|
|
|
|
static void ProxyStrToResult(const nsACString& aSpecificProxy,
|
|
const nsACString& aDefaultProxy,
|
|
const nsACString& aSocksProxy,
|
|
nsACString& aResult) {
|
|
if (!aSpecificProxy.IsEmpty()) {
|
|
SetProxyResult("PROXY", aSpecificProxy,
|
|
aResult); // Protocol-specific proxy.
|
|
} else if (!aDefaultProxy.IsEmpty()) {
|
|
SetProxyResult("PROXY", aDefaultProxy, aResult); // Default proxy.
|
|
} else if (!aSocksProxy.IsEmpty()) {
|
|
SetProxyResult("SOCKS", aSocksProxy, aResult); // SOCKS proxy.
|
|
} else {
|
|
SetProxyResultDirect(aResult); // Direct connection.
|
|
}
|
|
}
|
|
|
|
void GetProxyString(const nsACString& aScheme, nsACString& aResult) {
|
|
SetProxyResultDirect(aResult);
|
|
|
|
nsAutoCString specificProxy;
|
|
nsAutoCString defaultProxy;
|
|
nsAutoCString socksProxy;
|
|
nsAutoCString prefix;
|
|
ToLowerCase(aScheme, prefix);
|
|
ProxyServer::ProxyType type = ProxyConfig::ToProxyType(prefix.get());
|
|
for (auto& [key, value] : mRules.mProxyServers) {
|
|
// Break the loop if we found a specific proxy.
|
|
if (key == type) {
|
|
value.ToHostAndPortStr(specificProxy);
|
|
break;
|
|
} else if (key == ProxyServer::ProxyType::DEFAULT) {
|
|
value.ToHostAndPortStr(defaultProxy);
|
|
} else if (key == ProxyServer::ProxyType::SOCKS) {
|
|
value.ToHostAndPortStr(socksProxy);
|
|
}
|
|
}
|
|
|
|
ProxyStrToResult(specificProxy, defaultProxy, socksProxy, aResult);
|
|
}
|
|
|
|
private:
|
|
nsCString mPACUrl;
|
|
ProxyRules mRules;
|
|
ProxyBypassRules mBypassRules;
|
|
};
|
|
|
|
} // namespace net
|
|
} // namespace mozilla
|
|
|
|
#endif // mozilla_netwerk_base_proxy_config_h
|