NO_PROXY ignored by .NET Core 3.0 on Windows
Asked Answered
O

2

6

We are trying to get proxy functionality to work in a .NET Core 3.0 (or 3.1) app on Windows. What we find is that the HTTPS_PROXY and HTTP_PROXY variables are recognized and processed as expected, but the default proxy does not appear to honor the NO_PROXY variable. Here is sample code:

 HttpClient client = new HttpClient();
 IWebProxy myProxy = HttpClient.DefaultProxy;
 Uri target = new Uri(args[0]);
 Uri proxy = myProxy.GetProxy(target);
 Console.WriteLine($"Target proxy for {target} is {proxy} {myProxy.IsBypassed(target)}");

If I run this from PowerShell as such:

if (-not $env:path.Contains('c:\data\src')) {
    $env:path = "$env:Path;C:\data\src\Local\DefaultProxy\bin\Debug\netcoreapp3.0"
}
$env:HTTPS_PROXY = 'http://10.11.10.10'
$env:NO_PROXY = '*'
DefaultProxy https://www.contoso.com

I get:

Target proxy for https://www.contoso.com/ is http://10.11.10.10/ False

I expect to get blank and true.

What should I change so that I can use NO_PROXY to exclude domains from the default proxy?

Olsson answered 30/6, 2020 at 14:36 Comment(2)
context? github.com/dotnet/runtime/issues/29147 github.com/dotnet/runtime/issues/29371Azalea
Yes. That post shows the intent of .Net Core 3.0 to support these variables. I am trying to get it to work as I interpret the documentation.Olsson
O
16

I pulled the code for System.Net.Http.HttpEnvironmentProxy in .NET Core 3.1 (and in latest main development branch) and read through it, mainly through the IsMatchInBypassList method. There is no support for wildcards like asterisk (*) in NO_PROXY, hence this will not work at all. Also, the call to GetProxy completely ignores the NO_PROXY values.

To achieve the "wildcard" behavior, domains in the NO_PROXY list need to be prefixed with a dot (.), which is standard, but not particularly well documented. I can use this information to change my interpretation of the documentation and get better results.

So, if I modify the PowerShell code as follows:

$env:HTTPS_PROXY = 'http://10.11.10.10'
$env:NO_PROXY = '.contoso.com'
DefaultProxy https://www.contoso.com

Then I get:

Target proxy for https://www.contoso.com/ is http://10.11.10.10/ True

Presumably the DefaultProxy logic will use the IsBypassed result of true to stop proxy on the NO_PROXY list.

Olsson answered 30/6, 2020 at 17:58 Comment(2)
I'd upvote this 1,000 times if I could! Your finding in the ASP.NET Core HttpEnvironmentProxy code was the key to solving everything. Our default internal config used * (wildcard) in the NO_PROXY list. That turned out to be the source of why ASP.NET Core 3.1 and later was being mis-routing requests through proxy in spite of being listed in NO_PROXY. The .EndsWith() call on line 246 of HttpEnvironmentProxy.cs was the key to the whole mystery.Nucleoprotein
I believe this should be marked as accepted. Thanks for the research! I edited the answer to clarify a bit and added a link to the current code so that the answer stays relevant even beyond .NET Core 3.1. I summarized the changes in the edit's description.Prudential
A
1

there is never a "standard" in the no_proxy. In Linux, most applications recognized it as lower_case. Sure, in Windows, it is always case-insensitive. But when it comes to wildcard matching or regex matching, there is no standard at all. Each application works its own way as it see fit, for no_proxy.

Awfully answered 29/6, 2021 at 18:15 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.