Summary
.NET has support for reading the NO_PROXY environment variable, but does not support CIDR/subnet notation within this variable.
I happened to run into this in our work VMs which set NO_PROXY as 127.0.0.0/8 plus some other internal corporate URLs, with all outbound traffic going via a proxy. The lack of support for 127.0.0.0/8 was the root cause of an issue that caused .NET Aspire to fail to start up: all of the internal 127.0.0.1 requests it used to talk to services tried to go via our proxy, which returned an error when asked to proxy a loopback address.
Of course, you can work around this by adding 127.0.0.1 directly to the environment variable, but I thought it would be worth logging this as a potential enhancement. Other tools like curl do respect CIDR notation, as can be seen in
$ HTTPS_PROXY=https://some-proxy.com:8080 NO_PROXY=127.0.0.0/8 curl -v https://127.0.0.1
Minimal reproduction
Here is an example featuring some reflection hacks to get an instance of HttpEnvironmentProxy to demonstrate the issue:
#:property PublishAot=false
using System.Net;
using System.Reflection;
Environment.SetEnvironmentVariable("HTTP_PROXY", "http://proxy.example:8080");
var target = new Uri("http://127.0.0.1/");
Test("127.0.0.0/8", target); // CIDR range containing 127.0.0.1
Test("127.0.0.1", target); // exact host
void Test(string noProxy, Uri uri)
{
Environment.SetEnvironmentVariable("NO_PROXY", noProxy);
IWebProxy proxy = CreateEnvProxy();
Console.WriteLine($"NO_PROXY = {noProxy,-14} IsBypassed({uri}) = {proxy.IsBypassed(uri)}");
}
IWebProxy CreateEnvProxy()
{
// Sorry... the type is internal, but I thought IsBypassed was the single best way to demonstrate the issue.
Type t = typeof(HttpClient).Assembly.GetType("System.Net.Http.HttpEnvironmentProxy")!;
MethodInfo tryCreate = t.GetMethod("TryCreate", BindingFlags.Public | BindingFlags.Static)!;
object?[] args = { null };
tryCreate.Invoke(null, args);
return (IWebProxy)args[0]!;
}
The output of this program is
NO_PROXY = 127.0.0.0/8 IsBypassed(http://127.0.0.1/) = False
NO_PROXY = 127.0.0.1 IsBypassed(http://127.0.0.1/) = True
Summary
.NET has support for reading the
NO_PROXYenvironment variable, but does not support CIDR/subnet notation within this variable.I happened to run into this in our work VMs which set
NO_PROXYas127.0.0.0/8plus some other internal corporate URLs, with all outbound traffic going via a proxy. The lack of support for127.0.0.0/8was the root cause of an issue that caused .NET Aspire to fail to start up: all of the internal127.0.0.1requests it used to talk to services tried to go via our proxy, which returned an error when asked to proxy a loopback address.Of course, you can work around this by adding
127.0.0.1directly to the environment variable, but I thought it would be worth logging this as a potential enhancement. Other tools likecurldo respect CIDR notation, as can be seen inMinimal reproduction
Here is an example featuring some reflection hacks to get an instance of
HttpEnvironmentProxyto demonstrate the issue:The output of this program is