Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 15, 2026

Description

HttpClient now accepts socks5h:// proxy URIs. Previously, attempts to use this scheme threw NotSupportedException with message "Only the 'http', 'https', 'socks4', 'socks4a' and 'socks5' schemes are allowed for proxies."

The socks5h scheme is a cURL convention indicating SOCKS5 with DNS resolution handled by the proxy. Our implementation treats it identically to socks5 since we already forward hostnames to the proxy by default.

Changes

  • HttpUtilities.SocketsHttpHandler.cs: Added socks5h to IsSocksScheme()
  • SocksHelper.cs: Added socks5h case to EstablishSocksTunnelAsync(), routing to SOCKS5 handler
  • HttpEnvironmentProxy.cs: Added parsing for socks5h:// prefix in environment variables
  • Strings.resx: Updated error message to include socks5h in supported schemes list
  • Tests: Extended SocksProxyTest and HttpEnvironmentProxyTest to cover socks5h scheme

Example

using var handler = new SocketsHttpHandler();
handler.Proxy = new WebProxy("socks5h://username:password@proxy.example.com:1080");
using HttpClient client = new HttpClient(handler);
var response = await client.GetStringAsync("http://ifconfig.me/ip");

Type of change

  • Bug fix (non-breaking change which fixes an issue)

Testing

Unit tests covering proxy scheme validation and environment variable parsing pass with new socks5h test cases included.

Original prompt

This section details on the original issue you should resolve

<issue_title>HttpClient not support SOCKS5H proxy</issue_title>
<issue_description>### Description

   在 System.Net.Http.HttpConnectionPoolManager.SendAsync(HttpRequestMessage request, Boolean async, Boolean doRequestAuth, CancellationToken cancellationToken)
   在 System.Net.Http.HttpConnectionHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   在 System.Net.Http.HttpMessageHandlerStage.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   在 System.Net.Http.Metrics.MetricsHandler.SendAsync(HttpRequestMessage request, Boolean async, CancellationToken cancellationToken)
   在 System.Net.Http.HttpMessageHandlerStage.SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
   在 System.Net.Http.DiagnosticsHandler.<SendAsyncCore>d__10.MoveNext()
   在 System.Runtime.CompilerServices.ConfiguredValueTaskAwaitable`1.ConfiguredValueTaskAwaiter.GetResult()
   在 System.Net.Http.RedirectHandler.<SendAsync>d__4.MoveNext()
   在 System.Net.Http.SocketsHttpHandler.<<SendAsync>g__CreateHandlerAndSendAsync|115_0>d.MoveNext()
   在 System.Net.Http.HttpClient.<GetStringAsyncCore>d__41.MoveNext()
   在 ConsoleApp1.Program.<Main>d__0.MoveNext() 在 C:\Users\ali\Desktop\ConsoleApp1\ConsoleApp1\Program.cs 中: 第 15 行


Only the 'http', 'https', 'socks4', 'socks4a' and 'socks5' schemes are allowed for proxies.

Reproduction Steps

using var handler = new SocketsHttpHandler();
handler.Proxy = new WebProxy("socks5h://username:password@ip:port");
using HttpClient client = new HttpClient(handler);
var response = await client.GetStringAsync("http://ifconfig.me/ip");

Expected behavior

normal request

Actual behavior

throw an exception

Only the 'http', 'https', 'socks4', 'socks4a' and 'socks5' schemes are allowed for proxies.

Regression?

No response

Known Workarounds

No response

Configuration

No response

Other information

No response</issue_description>

Comments on the Issue (you are @copilot in this section)

@MihaZupan https://en.wikipedia.org/wiki/SOCKS > Since clients are allowed to use either resolved addresses or domain names, a convention from [cURL](https://en.wikipedia.org/wiki/CURL) exists to label the domain name variant of SOCKS5 "socks5h", and the other simply "socks5". A similar convention exists between SOCKS4a and SOCKS4.

TIL socks5h is a thing.
I think it'd be fine to add with the same behavior as our socks5 support, but I would not change our socks5 logic to resolve addresses locally. We can treat both the same and always forward the host to the proxy, the user always has the option to do the name resolution locally before making the request.</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Co-authored-by: MihaZupan <25307628+MihaZupan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix HttpClient to support SOCKS5H proxy Add support for socks5h proxy scheme Jan 15, 2026
Copilot AI requested a review from MihaZupan January 15, 2026 16:14
@MihaZupan MihaZupan added this to the 11.0.0 milestone Jan 15, 2026
@MihaZupan MihaZupan marked this pull request as ready for review January 15, 2026 16:38
Copilot AI review requested due to automatic review settings January 15, 2026 16:38
@dotnet-policy-service
Copy link
Contributor

Tagging subscribers to this area: @karelz, @dotnet/ncl
See info in area-owners.md if you want to be subscribed.

Copy link
Member

@MihaZupan MihaZupan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As long as tests are passing this LGTM

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

Co-authored-by: Stephen Toub <stoub@microsoft.com>
@MihaZupan MihaZupan enabled auto-merge (squash) January 22, 2026 14:14
@MihaZupan MihaZupan merged commit b6e2338 into main Jan 22, 2026
88 of 89 checks passed
@jkotas jkotas deleted the copilot/fix-httpclient-socks5h-support branch January 24, 2026 03:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

HttpClient not support SOCKS5H proxy

3 participants