Wednesday, 9 April 2008

BypassProxyOnLocal - a bug in .Net ?

If you have a local proxy server on your computer ( that you wish to use when doing FTP communications, all you need do is set BypassProxyOnLocal = false right?

There may be many important reasons for using a local proxy, such as caching and security etc.

Here's an example:

WebProxy proxy = new WebProxy("", 3128);

proxy.BypassProxyOnLocal = true;
bool a = proxy.IsBypassed(new Uri(""));
bool b = proxy.IsBypassed(new Uri(""));
// a=true, b=true (ok)

proxy.BypassProxyOnLocal = false;
bool c = proxy.IsBypassed(new Uri(""));
bool d = proxy.IsBypassed(new Uri(""));
// c=true, d=true (???)

Why is the proxy being bypassed when I told it not to?
The local proxy is always bypassed when when the proxy is on a loopback address. Why?

Setting BypassProxyOnLocal to false should NOT bypass the proxy for local addresses. So let's see what MSDN Library has to say about IsBypassed method:

If BypassProxyOnLocal is true, requests to local Internet resources do not use
the proxy server. Local requests are identified by the lack of a period (.) in
the URI, as in http://webserver/, or access the local server, including
http://localhost, http://loopback, or When BypassProxyOnLocal
is false, all Internet requests are made through the proxy server.

Here is the WebProxy.IsBypassed source code:

public bool IsBypassed(Uri host)
GlobalLog.Print("WebProxy#" + ValidationHelper.HashString(this) + "::IsBypassed() destination:" + ValidationHelper.ToString(host));

if (host == null)
throw new ArgumentNullException("host");

AutoWebProxyState autoWebProxyState;
bool result = IsBypassedAuto(host, out autoWebProxyState);
if (autoWebProxyState==AutoWebProxyState.ExecutionSuccess) {
return result;

return IsBypassedManual(host);

private bool IsBypassedManual(Uri host) {
if (host.IsLoopback) {
return true; // bypass localhost from using a proxy.
return (_ProxyAddress==null && _ProxyHostAddresses==null) (_BypassOnLocal && IsLocal(host)) IsMatchInBypassList(host) IsLocalInProxyHash(host);