Commit 6493ea87 authored by justcoding121's avatar justcoding121 Committed by justcoding121

Merge pull request #273 from honfika/develop

Bypass list implemented + tests
parents e187c558 7e995713
...@@ -44,6 +44,27 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -44,6 +44,27 @@ namespace Titanium.Web.Proxy.UnitTests
//proxyManager.SetAutoProxyUrl("http://localhost/proxy.pac"); //proxyManager.SetAutoProxyUrl("http://localhost/proxy.pac");
//CompareUrls(); //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 finally
{ {
...@@ -54,10 +75,12 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -54,10 +75,12 @@ namespace Titanium.Web.Proxy.UnitTests
private void CompareUrls() private void CompareUrls()
{ {
var webProxy = WebRequest.GetSystemWebProxy(); var webProxy = WebRequest.GetSystemWebProxy();
var resolver = new WinHttpWebProxyFinder(); var resolver = new WinHttpWebProxyFinder();
resolver.LoadFromIE(); 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, "http://localhost");
CompareProxy(webProxy, resolver, "https://localhost"); CompareProxy(webProxy, resolver, "https://localhost");
...@@ -78,6 +101,10 @@ namespace Titanium.Web.Proxy.UnitTests ...@@ -78,6 +101,10 @@ namespace Titanium.Web.Proxy.UnitTests
CompareProxy(webProxy, resolver, "https://google.com"); CompareProxy(webProxy, resolver, "https://google.com");
CompareProxy(webProxy, resolver, "http://bing.com"); CompareProxy(webProxy, resolver, "http://bing.com");
CompareProxy(webProxy, resolver, "https://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) private void CompareProxy(IWebProxy webProxy, WinHttpWebProxyFinder resolver, string url)
......
...@@ -19,8 +19,14 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -19,8 +19,14 @@ namespace Titanium.Web.Proxy.Helpers
public string ProxyOverride { get; } public string ProxyOverride { get; }
public bool BypassLoopback { get; }
public bool BypassOnLocal { get; }
public Dictionary<ProxyProtocolType, HttpSystemProxyValue> Proxies { get; } public Dictionary<ProxyProtocolType, HttpSystemProxyValue> Proxies { get; }
public string[] BypassList { get; }
public ProxyInfo(bool? autoDetect, string autoConfigUrl, int? proxyEnable, string proxyServer, string proxyOverride) public ProxyInfo(bool? autoDetect, string autoConfigUrl, int? proxyEnable, string proxyServer, string proxyOverride)
{ {
AutoDetect = autoDetect; AutoDetect = autoDetect;
...@@ -33,6 +39,84 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -33,6 +39,84 @@ namespace Titanium.Web.Proxy.Helpers
{ {
Proxies = GetSystemProxyValues(proxyServer).ToDictionary(x=>x.ProtocolType); 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) public static ProxyProtocolType? ParseProtocolType(string protocolTypeStr)
......
...@@ -226,6 +226,18 @@ namespace Titanium.Web.Proxy.Helpers ...@@ -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() internal void RestoreOriginalSettings()
{ {
if (originalValues == null) if (originalValues == null)
......
...@@ -18,12 +18,16 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -18,12 +18,16 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
public ProxyInfo ProxyInfo { get; internal set; } 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 Uri AutomaticConfigurationScript { get; internal set; }
public bool AutomaticallyDetectSettings { get; internal set; } public bool AutomaticallyDetectSettings { get; internal set; }
private WebProxy Proxy { get; set; }
public WinHttpWebProxyFinder() public WinHttpWebProxyFinder()
{ {
session = NativeMethods.WinHttp.WinHttpOpen(null, NativeMethods.WinHttp.AccessType.NoProxy, null, null, 0); session = NativeMethods.WinHttp.WinHttpOpen(null, NativeMethods.WinHttp.AccessType.NoProxy, null, null, 0);
...@@ -104,7 +108,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -104,7 +108,7 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
return systemProxy; return systemProxy;
} }
if (IsBypassedManual(destination)) if (Proxy?.IsBypassed(destination) == true)
return null; return null;
var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme); var protocolType = ProxyInfo.ParseProtocolType(destination.Scheme);
...@@ -132,44 +136,9 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp ...@@ -132,44 +136,9 @@ namespace Titanium.Web.Proxy.Helpers.WinHttp
ProxyInfo = pi; ProxyInfo = pi;
AutomaticallyDetectSettings = pi.AutoDetect == true; AutomaticallyDetectSettings = pi.AutoDetect == true;
AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl); AutomaticConfigurationScript = pi.AutoConfigUrl == null ? null : new Uri(pi.AutoConfigUrl);
} BypassLoopback = pi.BypassLoopback;
BypassOnLocal = pi.BypassOnLocal;
private bool IsBypassedManual(Uri host) Proxy = new WebProxy(new Uri("http://localhost"), BypassOnLocal, pi.BypassList);
{
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;
} }
private ProxyInfo GetProxyInfo() private ProxyInfo GetProxyInfo()
......
...@@ -507,16 +507,20 @@ namespace Titanium.Web.Proxy ...@@ -507,16 +507,20 @@ namespace Titanium.Web.Proxy
var proxyInfo = systemProxySettingsManager.GetProxyInfoFromRegistry(); var proxyInfo = systemProxySettingsManager.GetProxyInfoFromRegistry();
if (proxyInfo.Proxies != null) if (proxyInfo.Proxies != null)
{ {
var proxies = proxyInfo.Proxies.ToArray(); var protocolToRemove = ProxyProtocolType.None;
foreach (var proxy in proxies) foreach (var proxy in proxyInfo.Proxies.Values)
{ {
var value = proxy.Value; if (proxy.HostName == "127.0.0.1" && ProxyEndPoints.Any(x => x.Port == proxy.Port))
if (value.HostName == "127.0.0.1" && ProxyEndPoints.Any(x => x.Port == value.Port))
{ {
//do not restore to any of listening address when we quit protocolToRemove |= proxy.ProtocolType;
systemProxySettingsManager.RemoveProxy(value.ProtocolType, false);
} }
} }
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