Force upstream proxy for WinHTTP
This commit is contained in:
40
Program.cs
40
Program.cs
@@ -313,8 +313,16 @@ static class WinHttpHelper
|
|||||||
[DllImport("kernel32.dll", SetLastError = true)]
|
[DllImport("kernel32.dll", SetLastError = true)]
|
||||||
static extern IntPtr GlobalFree(IntPtr hMem);
|
static extern IntPtr GlobalFree(IntPtr hMem);
|
||||||
|
|
||||||
|
static readonly Uri ForcedUpstreamProxy = ReadForcedUpstreamProxy();
|
||||||
|
|
||||||
public static Uri GetProxyForUrl(Uri url)
|
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);
|
IntPtr session = WinHttpOpen("proxy", WINHTTP_ACCESS_TYPE_NO_PROXY, null, null, 0);
|
||||||
if (session == IntPtr.Zero)
|
if (session == IntPtr.Zero)
|
||||||
{
|
{
|
||||||
@@ -331,15 +339,23 @@ static class WinHttpHelper
|
|||||||
if (WinHttpGetIEProxyConfigForCurrentUser(out ieConfig))
|
if (WinHttpGetIEProxyConfigForCurrentUser(out ieConfig))
|
||||||
{
|
{
|
||||||
var autoConfigUrl = PtrToString(ieConfig.lpszAutoConfigUrl);
|
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
|
var options = new WINHTTP_AUTOPROXY_OPTIONS
|
||||||
{
|
{
|
||||||
dwFlags = 0,
|
dwFlags = 0,
|
||||||
dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A,
|
dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DHCP | WINHTTP_AUTO_DETECT_TYPE_DNS_A,
|
||||||
lpszAutoConfigUrl = ieConfig.lpszAutoConfigUrl,
|
lpszAutoConfigUrl = hasSupportedAutoConfigUrl ? ieConfig.lpszAutoConfigUrl : IntPtr.Zero,
|
||||||
fAutoLogonIfChallenged = true
|
fAutoLogonIfChallenged = true
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!string.IsNullOrWhiteSpace(autoConfigUrl))
|
if (hasSupportedAutoConfigUrl)
|
||||||
options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
|
options.dwFlags |= WINHTTP_AUTOPROXY_CONFIG_URL;
|
||||||
if (ieConfig.fAutoDetect)
|
if (ieConfig.fAutoDetect)
|
||||||
options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
|
options.dwFlags |= WINHTTP_AUTOPROXY_AUTO_DETECT;
|
||||||
@@ -453,6 +469,26 @@ static class WinHttpHelper
|
|||||||
return uri;
|
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)
|
static void FreeWinHttpProxyInfo(WINHTTP_PROXY_INFO info)
|
||||||
{
|
{
|
||||||
if (info.lpszProxy != IntPtr.Zero)
|
if (info.lpszProxy != IntPtr.Zero)
|
||||||
|
|||||||
Reference in New Issue
Block a user