Open SlavaC1 opened 3 weeks ago
WebRequest.GetSystemWebProxy()
delegates to HttpClient.DefaultProxy
. You can use this static property instead.
@huoyaoyuan does it work correctly on both Windows and Linux and also with PAC files?
No. PAC files are processed with WinHttp on Windows and CFProxyAutoConfigurationResultCallback on MacOS. On Linux only the HTTP(S)_PROXY environment variables are supported and I can't find conventional way to use PAC with it.
Thanks a lot for your reply
PAC
is evil IMHO as it requires executing script. That may work well for browsers but it sucks for everything else. as @huoyaoyuan correctly stated, on Linux the only option is API call to set it explicitly or environment variables
I'm trying to use HttpClient to use default proxy as defined in Windows, meaning without any parameters. I'm trying to connect to an address that requires proxy which is defined in Windows. When connecting from browser I have no problems. When connecting from my sample app from HttpClient I get:
System.AggregateException: One or more errors occurred. (A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (pressqa.printopt.org:443)) ---> System.Net.Http.HttpRequestException: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. (pressqa.printopt.org:443) ---> System.Net.Sockets.SocketException (10060): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond. at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.ThrowException(SocketError error, CancellationToken cancellationToken) at System.Net.Sockets.Socket.AwaitableSocketAsyncEventArgs.System.Threading.Tasks.Sources.IValueTaskSource.GetResult(Int16 token) at System.Net.Sockets.Socket.<ConnectAsync>g__WaitForConnectWithCancellation|285_0(AwaitableSocketAsyncEventArgs saea, ValueTask connectTask, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) --- End of inner exception stack trace --- at System.Net.Http.HttpConnectionPool.ConnectToTcpHostAsync(String host, Int32 port, HttpRequestMessage initialRequest, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.ConnectAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.CreateHttp11ConnectionAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken) at System.Net.Http.HttpConnectionPool.AddHttp11ConnectionAsync(QueueItem queueItem) at System.Threading.Tasks.TaskCompletionSourceWithCancellation
1.WaitWithCancellationAsync(CancellationToken cancellationToken)
at System.Net.Http.HttpConnectionPool.SendWithVersionDetectionAndRetryAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
at System.Net.Http.RedirectHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
at System.Net.Http.HttpClient.1.GetResultCore(Boolean waitCompletionNotification) at ProxyProvider.Program.Main(String[] args) in D:\Personal\CodeTests\dotnet\Proxy\ProxyProvider\Program.cs:line 40
Any ideas?
I did some more tests and it seems like on Linux HttpClient picks up the default proxy correctly, but not on Windows. I used both HttpClientHandler and SocketsHttpHandler and I see the same behavior.
What is your code and configuration @SlavaC1? If the proxy is configured on Windows in setting, there should not be anything you need to do.
I have Windows and Linux systems both configured with the same proxy address. When running HttpClient.DefaultProxy.GetProxy(testUri)
on both, I get the same correct proxy.
Now I'm trying to connect to some address behind the proxy like this:
using var client = new HttpClient();
var res = client.GetAsync(new Uri("https://some.address.com", UriKind.Absolute)).Result;
On Linux I connect without problems, but on Windows I get the timeout.
Following "workaround" works correctly on both systems:
using var handler = new SocketsHttpHandler();
handler.Proxy = new WebProxy(HttpClient.DefaultProxy.GetProxy(new Uri("http://printos.com", UriKind.RelativeOrAbsolute)));
using var client = new HttpClient(handler, true);
var res = client.GetAsync(new Uri("https://some.address.com", UriKind.Absolute)).Result;
res.EnsureSuccessStatusCode();
If the proxy is configured in system it should just work e.g. there is no need to set it explicitly.
@wfurt this is also what I understand, but unfortunately the results are different. Could be that I'm missing some configuration? Or the proxy is defined differently on Windows somehow?
what do you see in Settings? You can also set the environment for testing. That would take precedence over Windows setting AFAIK. As @huoyaoyuan mentioned, we get the actual info by calling windows functions. You can inspect the created object in debugger. Perhaps there will be some clue.
This issue has been marked needs-author-action
and may be missing some important information.
This issue has been automatically marked no-recent-activity
because it has not had any activity for 14 days. It will be closed if no further activity occurs within 14 more days. Any new comment (by anyone, not necessarily the author) will remove no-recent-activity
.
We are using .NET 8 in our project that should run on Windows and Linux. On some of our systems proxy is defined as a specific URL and on some as a PAC script. We want to be able to get the correct proxy regardless the method it is defined on this specific system.
I understood that at least on Windows we can use WebRequest.GetSystemWebProxy() to get the correct proxy address even it is defined in PAC file, but this API is deprecated and HttpClient is advised to be used instead, but I couldn't find equivalent API that achieves the same result. Also if I understood correctly, WebRequest.GetSystemWebProxy() does not support PAC files on Linux.
Please advise what is the correct way to get the proxy setting on both Windows and Linux systems regardless if it's PAC file or not.