DEV Community

Cover image for C# HttpClient proxy: WebProxy, auth, SOCKS5 and rotation
Andrew
Andrew

Posted on Originally published at proxymint.com

C# HttpClient proxy: WebProxy, auth, SOCKS5 and rotation

Originally published on proxymint.

C# HttpClient proxy setup for .NET 8 and 10: WebProxy credentials, SOCKS5, environment proxies, IHttpClientFactory, rotation and the 407 and https:// traps.

TL;DR

  • A WebProxy on the handler is the whole setup. Create new WebProxy("http://HOST:PORT") with a NetworkCredential on its Credentials property, assign it to SocketsHttpHandler.Proxy or HttpClientHandler.Proxy with UseProxy = true, and pass the handler to HttpClient.
  • Credentials in the proxy URL are ignored by WebProxy. new WebProxy("http://USERNAME:PASSWORD@HOST:PORT") still gets a 407. The HTTPS_PROXY environment variable is the one place where user:pass in the address is read as credentials.
  • SOCKS5 works from .NET 6 with a socks5:// address. socks5h:// throws NotSupportedException, but .NET's socks5 already sends the hostname, so DNS resolves at the proxy.
  • Never write https:// in the proxy address. On .NET 8 and 10 it means TLS to the proxy itself, so an ordinary proxy port either stalls until the timeout or fails at once with an SSL error.

Key takeaways

  • Keep one long-lived HttpClient per proxy. Handler properties freeze after the first request, and a new client per request repeats the 407 round trip, the TLS handshake and the socket setup.
  • Set ConnectTimeout on SocketsHttpHandler. A wrong proxy address then fails in seconds, as a TaskCanceledException whose inner TimeoutException names ConnectTimeout, instead of after the 100-second HttpClient default.
  • Write BypassList entries as regular expressions. Escape the dots and allow an optional port, for example \.internal\.example(:\d+)?$, because a wildcard like *.corp throws.
  • Check rotation with and without connection reuse. Compare a pooled client with PooledConnectionLifetime = TimeSpan.Zero against an https:// IP echo endpoint, next to a direct call.

Read the full guide on proxymint, with the commands, tables and sources.

Top comments (0)