Thanks to visit codestin.com
Credit goes to github.com

Skip to content

HTTPS proxy servers not working with HttpClient #22026

@MaxGrekhov

Description

@MaxGrekhov

I'm writing a proxy checking service. This is a short test case:

using System;
using System.Net;
using System.Net.Http;
using System.Security.Authentication;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace ProxyNetCoreTest
{
    public class WebProxy : IWebProxy
    {
        private readonly Uri _uri;

        public WebProxy(string ip, int port)
        {
            _uri = new Uri("https://" + ip + ":" + port);
        }
        public Uri GetProxy(Uri destination) => _uri;

        public bool IsBypassed(Uri host) => false;

        public ICredentials Credentials { get; set; }
    }

    public class Program
    {
        public static void Main(string[] args)
        {
            Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);
            Test().Wait();
            LogInfo("---===   END   ===---");
            Console.ReadKey();
        }

        public static async Task Test()
        {
            var url = "https://api.ipify.org?format=json";
            string ip = "103.254.16.21";
            int port = 8080;
            var handler = new HttpClientHandler
            {
                Proxy = new WebProxy(ip, port),
                UseCookies = false,
                ServerCertificateCustomValidationCallback = (message, xcert, chain, errors) =>
                {
                    LogInfo("ServerCertificateCustomValidationCallback");
                    return true;
                },
                SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls,
                UseProxy = true
            };
            using (var client = new HttpClient(handler))
            {
                try
                {
                    using (var request = new HttpRequestMessage(HttpMethod.Get, url))
                    using (var response = await client.SendAsync(request, HttpCompletionOption.ResponseContentRead, CancellationToken.None))
                    {
                        var data = await response.Content.ReadAsStringAsync();
                        LogInfo(data);
                    }
                }
                catch (Exception e)
                {
                    while (e != null)
                    {
                        LogError(e.ToString());
                        e = e.InnerException;
                    }
                }
            }
        }

        public static void LogError(string message)
        {
            Console.ForegroundColor = ConsoleColor.Yellow;
            LogInfo(message);
            Console.ResetColor();
        }

        public static void LogInfo(string message)
        {
            Console.WriteLine($"{DateTime.Now:HH:mm:ss}: {message}");
        }
    }
}

It works on Linux Mint 18.1 Serena, but does not work on Windows 10.

Windows 10 output:

C:\Projects\ProxyNetCoreTest\PublishOutput>dotnet ProxyNetCoreTest.dll
19:58:37: System.Net.Http.HttpRequestException: An error occurred while sending the request. ---> System.Net.Http.WinHttpException: A security error occurred
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.WinHttpHandler.<StartRequest>d__105.MoveNext()
   --- End of inner exception stack trace ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.HttpClient.<FinishSendAsync>d__58.MoveNext()
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at ProxyNetCoreTest.Program.<Test>d__1.MoveNext() in C:\Projects\ProxyNetCoreTest\ProxyNetCoreTest\Program.cs:line 58
19:58:37: System.Net.Http.WinHttpException: A security error occurred
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.ConfiguredTaskAwaitable`1.ConfiguredTaskAwaiter.GetResult()
   at System.Net.Http.WinHttpHandler.<StartRequest>d__105.MoveNext()
19:58:37: ---===   END   ===---

Linux Mint 18.1 Serena output:

my-server ProxyTest # dotnet ProxyNetCoreTest.dll
19:59:15: ServerCertificateCustomValidationCallback
19:59:16: {"ip":"103.254.16.21"}
19:59:16: ---===   END   ===---

Windows version does not call ServerCertificateCustomValidationCallback.
PS: On a full framework, I used HttpWebRequest and everything was fine. What is the best way to perform multiple requests(10k-20k+) through different proxy servers? It seems to me that HttpClient is bad for this.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions