diff --git a/Program.cs b/Program.cs index eac06bd..48317b4 100644 --- a/Program.cs +++ b/Program.cs @@ -236,21 +236,72 @@ class WinHttpProxy : IWebProxy static class WinHttpHelper { [DllImport("winhttp.dll", SetLastError = true)] - static extern bool WinHttpGetIEProxyConfigForCurrentUser(out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG config); + static extern bool WinHttpGetIEProxyConfigForCurrentUser( + out WINHTTP_CURRENT_USER_IE_PROXY_CONFIG config); public static Uri GetProxyForUrl(Uri url) { - WinHttpGetIEProxyConfigForCurrentUser(out var cfg); + if (!WinHttpGetIEProxyConfigForCurrentUser(out var cfg)) + return url; - if (!string.IsNullOrEmpty(cfg.lpszProxy)) + string proxy = PtrToString(cfg.lpszProxy); + + if (string.IsNullOrWhiteSpace(proxy)) + return url; + + string selectedProxy = ParseProxy(proxy, url.Scheme); + + if (string.IsNullOrEmpty(selectedProxy)) + return url; + + return new Uri(NormalizeProxy(selectedProxy)); + } + + // ===== helpers ===== + + static string PtrToString(IntPtr ptr) + { + if (ptr == IntPtr.Zero) + return null; + + return Marshal.PtrToStringUni(ptr); + } + + static string ParseProxy(string proxy, string scheme) + { + // варианты: + // "proxy:8080" + // "http=proxy:8080;https=proxy2:8080" + + if (!proxy.Contains("=")) + return proxy; + + var entries = proxy.Split(';', StringSplitOptions.RemoveEmptyEntries); + + foreach (var entry in entries) { - var parts = cfg.lpszProxy.Split(':'); - return new Uri($"http://{parts[0]}:{parts[1]}"); + var parts = entry.Split('=', 2); + if (parts.Length != 2) + continue; + + if (parts[0].Equals(scheme, StringComparison.OrdinalIgnoreCase)) + return parts[1]; } - return url; // direct + // fallback — берём первый + return entries[0].Split('=')[1]; } + static string NormalizeProxy(string proxy) + { + if (!proxy.StartsWith("http://") && !proxy.StartsWith("https://")) + return "http://" + proxy; + + return proxy; + } + + // ===== struct ===== + struct WINHTTP_CURRENT_USER_IE_PROXY_CONFIG { public bool fAutoDetect;