Force upstream proxy for WinHTTP

This commit is contained in:
2026-04-09 20:05:14 +03:00
parent 8e51bd45fc
commit 4503b2a1c1

View File

@@ -313,8 +313,16 @@ static class WinHttpHelper
[DllImport("kernel32.dll", SetLastError = true)]
static extern IntPtr GlobalFree(IntPtr hMem);
static readonly Uri ForcedUpstreamProxy = ReadForcedUpstreamProxy();
public static Uri GetProxyForUrl(Uri url)
{
if (ForcedUpstreamProxy != null)
{
Log.Info($"Using forced upstream proxy {ForcedUpstreamProxy.Host}:{ForcedUpstreamProxy.Port} for {url}");
return ForcedUpstreamProxy;
}
IntPtr session = WinHttpOpen("proxy", WINHTTP_ACCESS_TYPE_NO_PROXY, null, null, 0);
if (session == IntPtr.Zero)
{
@@ -331,15 +339,23 @@ static class WinHttpHelper
if (WinHttpGetIEProxyConfigForCurrentUser(out ieConfig))
{
var autoConfigUrl = PtrToString(ieConfig.lpszAutoConfigUrl);
bool hasSupportedAutoConfigUrl = !string.IsNullOrWhiteSpace(autoConfigUrl)
&& (autoConfigUrl.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|| autoConfigUrl.StartsWith("https://", StringComparison.OrdinalIgnoreCase));
if (!string.IsNullOrWhiteSpace(autoConfigUrl) && !hasSupportedAutoConfigUrl)
{
Log.Warn($"IE PAC URL has unsupported scheme for WinHTTP: {autoConfigUrl}");
}
var options = new WINHTTP_AUTOPROXY_OPTIONS
{
dwFlags = 0,
dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A,
lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl,
lpszAutoConfigUrl = hasSupportedAutoConfigUrl ? ieConfig.lpszAutoConfigUrl : IntPtr.Zero,
fAutoLogonIfChallenged = true
};
if (!string.IsNullOrWhiteSpace(autoConfigUrl))
if (hasSupportedAutoConfigUrl)
options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
if (ieConfig.fAutoDetect)
options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
@@ -453,6 +469,26 @@ static class WinHttpHelper
return uri;
}
static Uri ReadForcedUpstreamProxy()
{
var value = Environment.GetEnvironmentVariable("UPSTREAM_PROXY");
if (string.IsNullOrWhiteSpace(value))
return null;
var normalized = value.StartsWith("http://", StringComparison.OrdinalIgnoreCase)
|| value.StartsWith("https://", StringComparison.OrdinalIgnoreCase)
? value
: "http://" + value;
if (!Uri.TryCreate(normalized, UriKind.Absolute, out var uri) || string.IsNullOrWhiteSpace(uri.Host))
{
Log.Error($"Invalid UPSTREAM_PROXY value: '{value}'");
return null;
}
return uri;
}
static void FreeWinHttpProxyInfo(WINHTTP_PROXY_INFO info)
{
if (info.lpszProxy != IntPtr.Zero)