diff --git a/source/Halibut/ServiceEndPoint.cs b/source/Halibut/ServiceEndPoint.cs
index 7da00d51..4d160aa0 100644
--- a/source/Halibut/ServiceEndPoint.cs
+++ b/source/Halibut/ServiceEndPoint.cs
@@ -76,6 +76,14 @@ public ServiceEndPoint(Uri baseUri, string? remoteThumbprint, ProxyDetails? prox
public ProxyDetails? Proxy { get; }
+ ///
+ /// When set, TCP connections will be made to the host and port of this URI instead of those in
+ /// , while the original host is still used for TLS SNI.
+ /// This is equivalent to curl's --resolve flag and is useful when routing through a local proxy
+ /// (e.g. Toxiproxy) while preserving the correct TLS handshake.
+ ///
+ public Uri? ForceResolveHost { get; set; }
+
public bool IsWebSocketEndpoint => IsWebSocketAddress(BaseUri);
public override string ToString() => baseUriString;
diff --git a/source/Halibut/Transport/TcpConnectionFactory.cs b/source/Halibut/Transport/TcpConnectionFactory.cs
index 0e9c3ffd..b61e190e 100644
--- a/source/Halibut/Transport/TcpConnectionFactory.cs
+++ b/source/Halibut/Transport/TcpConnectionFactory.cs
@@ -79,19 +79,21 @@ await ssl.AuthenticateAsClientAsync(
internal static async Task CreateConnectedTcpClientAsync(ServiceEndPoint endPoint, HalibutTimeoutsAndLimits halibutTimeoutsAndLimits, IStreamFactory streamFactory, ILog log, CancellationToken cancellationToken)
{
TcpClient client;
+ var connectHost = endPoint.ForceResolveHost?.Host ?? endPoint.BaseUri.Host;
+ var connectPort = endPoint.ForceResolveHost?.Port ?? endPoint.BaseUri.Port;
if (endPoint.Proxy is null)
{
client = CreateTcpClientAsync(halibutTimeoutsAndLimits);
- await client.ConnectWithTimeoutAsync(endPoint.BaseUri, endPoint.TcpClientConnectTimeout, cancellationToken);
+ await client.ConnectWithTimeoutAsync(connectHost, connectPort, endPoint.TcpClientConnectTimeout, cancellationToken);
}
else
{
log.Write(EventType.Diagnostic, "Creating a proxy client");
-
+
client = await new ProxyClientFactory(streamFactory)
.CreateProxyClient(log, endPoint.Proxy)
.WithTcpClientFactory(() => CreateTcpClientAsync(halibutTimeoutsAndLimits))
- .CreateConnectionAsync(endPoint.BaseUri.Host, endPoint.BaseUri.Port, endPoint.TcpClientConnectTimeout, cancellationToken);
+ .CreateConnectionAsync(connectHost, connectPort, endPoint.TcpClientConnectTimeout, cancellationToken);
}
return client;
}