Commit 7e995713 authored by Honfika's avatar Honfika

Bypass list implemented + tests

parent e187c558
......@@ -44,6 +44,27 @@ namespace Titanium.Web.Proxy.UnitTests
//proxyManager.SetAutoProxyUrl("http://localhost/proxy.pac");
//CompareUrls();
proxyManager.SetProxyOverride("<-loopback>");
CompareUrls();
proxyManager.SetProxyOverride("<local>");
CompareUrls();
proxyManager.SetProxyOverride("yahoo.com");
CompareUrls();
proxyManager.SetProxyOverride("*.local");
CompareUrls();
proxyManager.SetProxyOverride("http://*.local");
CompareUrls();
proxyManager.SetProxyOverride("<-loopback>;*.local");
CompareUrls();
proxyManager.SetProxyOverride("<-loopback>;*.local;<local>");
CompareUrls();
}
finally
{
......@@ -54,10 +75,12 @@ namespace Titanium.Web.Proxy.UnitTests
private void CompareUrls()
{
var webProxy = WebRequest.GetSystemWebProxy();
var resolver = new WinHttpWebProxyFinder();
resolver.LoadFromIE();
resolver.BypassOnLocal = WebProxy.GetDefaultProxy().BypassProxyOnLocal;
CompareProxy(webProxy, resolver, "http://127.0.0.1");
CompareProxy(webProxy, resolver, "https://127.0.0.1");
CompareProxy(webProxy, resolver, "http://localhost");
CompareProxy(webProxy, resolver, "https://localhost");
......@@ -78,6 +101,10 @@ namespace Titanium.Web.Proxy.UnitTests
CompareProxy(webProxy, resolver, "https://google.com");
CompareProxy(webProxy, resolver, "http://bing.com");
CompareProxy(webProxy, resolver, "https://bing.com");
CompareProxy(webProxy, resolver, "http://yahoo.com");
CompareProxy(webProxy, resolver, "https://yahoo.com");
CompareProxy(webProxy, resolver, "http://test.local");
CompareProxy(webProxy, resolver, "https://test.local");
}
private void CompareProxy(IWebProxy webProxy, WinHttpWebProxyFinder resolver, string url)
......
......@@ -19,8 +19,14 @@ namespace Titanium.Web.Proxy.Helpers
public string ProxyOverride { get; }
public bool BypassLoopback { get; }
public bool BypassOnLocal { get; }
public Dictionary<ProxyProtocolType, HttpSystemProxyValue> Proxies { get; }
public string[] BypassList { get; }
public ProxyInfo(bool? autoDetect, string autoConfigUrl, int? proxyEnable, string proxyServer, string proxyOverride)
{
AutoDetect = autoDetect;
......@@ -33,6 +39,84 @@ namespace Titanium.Web.Proxy.Helpers
{
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x=>x.ProtocolType);
}
if (proxyOverride != null)
{
var overrides = proxyOverride.Split(';');
var overrides2 = new List<string>();
foreach (var overrideHost in overrides)
{
if (overrideHost == "<-loopback>")
{
BypassLoopback = true;
}
else if (overrideHost == "<local>")
{
BypassOnLocal = true;
}
else
{
overrides2.Add(BypassStringEscape(overrideHost));
}
}
if (overrides2.Count > 0)
{
BypassList = overrides2.ToArray();
}
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x => x.ProtocolType);
}
}
private static string BypassStringEscape(string rawString)
{
Match match = new Regex("^(?<scheme>.*://)?(?<host>[^:]*)(?<port>:[0-9]{1,5})?$", RegexOptions.IgnoreCase | RegexOptions.CultureInvariant).Match(rawString);
string empty1;
string rawString1;
string empty2;
if (match.Success)
{
empty1 = match.Groups["scheme"].Value;
rawString1 = match.Groups["host"].Value;
empty2 = match.Groups["port"].Value;
}
else
{
empty1 = string.Empty;
rawString1 = rawString;
empty2 = string.Empty;
}
string str1 = ConvertRegexReservedChars(empty1);
string str2 = ConvertRegexReservedChars(rawString1);
string str3 = ConvertRegexReservedChars(empty2);
if (str1 == string.Empty)
str1 = "(?:.*://)?";
if (str3 == string.Empty)
str3 = "(?::[0-9]{1,5})?";
return "^" + str1 + str2 + str3 + "$";
}
private static string ConvertRegexReservedChars(string rawString)
{
if (rawString.Length == 0)
return rawString;
var stringBuilder = new StringBuilder();
foreach (char ch in rawString)
{
if ("#$()+.?[\\^{|".IndexOf(ch) != -1)
stringBuilder.Append('\\');
else if (ch == 42)
stringBuilder.Append('.');
stringBuilder.Append(ch);
}
return stringBuilder.ToString();
}
public static ProxyProtocolType? ParseProtocolType(string protocolTypeStr)
......
......@@ -226,6 +226,18 @@ namespace Titanium.Web.Proxy.Helpers
}
}
internal void SetProxyOverride(string proxyOverride)
{
var reg = Registry.CurrentUser.OpenSubKey(regKeyInternetSettings, true);
if (reg != null)
{
SaveOriginalProxyConfiguration(reg);
reg.SetValue(regProxyOverride, proxyOverride);
Refresh();
}
}
internal void RestoreOriginalSettings()
{
if (originalValues == null)
......
......@@ -18,12 +18,16 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public ProxyInfo ProxyInfo { get; internal set; }
public bool BypassOnLocal { get; internal set; }
public bool BypassLoopback { get; internal set; }
public bool BypassOnLocal { get; internal set; }
public Uri AutomaticConfigurationScript { get; internal set; }
public bool AutomaticallyDetectSettings { get; internal set; }
private WebProxy Proxy { get; set; }
public WinHttpWebProxyFinder()
{
session = NativeMethods.WinHttp.WinHttpOpen(null, NativeMethods.WinHttp.AccessType.NoProxy, null, null, 0);
......@@ -104,7 +108,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return systemProxy;
}
if (IsBypassedManual(destination))
if (Proxy?.IsBypassed(destination) == true)
return null;
var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme);
......@@ -132,44 +136,9 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
ProxyInfo = pi;
AutomaticallyDetectSettings = pi.AutoDetect == true;
AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl);
}
private bool IsBypassedManual(Uri host)
{
if (host.IsLoopback || BypassOnLocal && IsLocal(host))
return true;
return false;
}
private bool IsLocal(Uri host)
{
try
{
// get host IP addresses
IPAddress[] hostIPs = Dns.GetHostAddresses(host.Host);
// get local IP addresses
IPAddress[] localIPs = Dns.GetHostAddresses(Dns.GetHostName());
// test if any host IP equals to any local IP or to localhost
foreach (IPAddress hostIP in hostIPs)
{
// is localhost
if (IPAddress.IsLoopback(hostIP)) return true;
// is local address
foreach (IPAddress localIP in localIPs)
{
if (hostIP.Equals(localIP)) return true;
}
}
}
catch
{
}
return false;
BypassLoopback = pi.BypassLoopback;
BypassOnLocal = pi.BypassOnLocal;
Proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList);
}
private ProxyInfo GetProxyInfo()
......
......@@ -507,16 +507,20 @@ namespace Titanium.Web.Proxy
var proxyInfo = systemProxySettingsManager.GetProxyInfoFromRegistry();
if (proxyInfo.Proxies != null)
{
var proxies = proxyInfo.Proxies.ToArray();
foreach (var proxy in proxies)
var protocolToRemove = ProxyProtocolType.None;
foreach (var proxy in proxyInfo.Proxies.Values)
{
var value = proxy.Value;
if (value.HostName == "127.0.0.1" && ProxyEndPoints.Any(x => x.Port == value.Port))
if (proxy.HostName == "127.0.0.1" && ProxyEndPoints.Any(x => x.Port == proxy.Port))
{
//do not restore to any of listening address when we quit
systemProxySettingsManager.RemoveProxy(value.ProtocolType, false);
protocolToRemove |= proxy.ProtocolType;
}
}
if (protocolToRemove != ProxyProtocolType.None)
{
//do not restore to any of listening address when we quit
systemProxySettingsManager.RemoveProxy(protocolToRemove, false);
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment