Skip to content

Commit e6bd161

Browse files
committed
custom tunnel should not break ConfigurationOptions.ToString()
1 parent 6b20bba commit e6bd161

File tree

4 files changed

+22
-6
lines changed

4 files changed

+22
-6
lines changed

src/StackExchange.Redis/Configuration/Tunnel.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ public abstract class Tunnel
2121
/// <remarks><c>null</c> should be returned if a socket is not required for this endpoint.</remarks>
2222
public virtual ValueTask<EndPoint?> GetSocketConnectEndpointAsync(EndPoint endpoint, CancellationToken cancellationToken) => new(endpoint);
2323

24+
internal virtual bool IsInbuilt => false; // only inbuilt tunnels get added to config strings
25+
2426
/// <summary>
2527
/// Allows modification of a <see cref="Socket"/> between creation and connection.
2628
/// Passed in is the endpoint we're connecting to, which type of connection it is, and the socket itself.
@@ -33,8 +35,6 @@ public abstract class Tunnel
3335
/// the entire data flow can be intercepted, providing entire custom transports.
3436
/// </summary>
3537
public virtual ValueTask<Stream?> BeforeAuthenticateAsync(EndPoint endpoint, ConnectionType connectionType, Socket? socket, CancellationToken cancellationToken) => default;
36-
/// <inheritdoc/>
37-
public abstract override string ToString();
3838

3939
private sealed class HttpProxyTunnel : Tunnel
4040
{
@@ -102,6 +102,7 @@ static void SafeAbort(object? obj)
102102
return default; // no need for custom stream wrapper here
103103
}
104104

105+
internal override bool IsInbuilt => true;
105106
public override string ToString() => "http:" + Format.ToString(Proxy);
106107
}
107108

src/StackExchange.Redis/ConfigurationOptions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,7 @@ public string ToString(bool includePassword)
731731
Append(sb, OptionKeys.ConfigCheckSeconds, configCheckSeconds);
732732
Append(sb, OptionKeys.ResponseTimeout, responseTimeout);
733733
Append(sb, OptionKeys.DefaultDatabase, DefaultDatabase);
734-
if (Tunnel is Tunnel tunnel)
734+
if (Tunnel is { IsInbuilt: true } tunnel)
735735
{
736736
Append(sb, OptionKeys.Tunnel, tunnel.ToString());
737737
}

src/StackExchange.Redis/PublicAPI/PublicAPI.Shipped.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -182,7 +182,6 @@ StackExchange.Redis.Configuration.DefaultOptionsProvider.ClientName.get -> strin
182182
StackExchange.Redis.Configuration.DefaultOptionsProvider.DefaultOptionsProvider() -> void
183183
StackExchange.Redis.Configuration.Tunnel
184184
StackExchange.Redis.Configuration.Tunnel.Tunnel() -> void
185-
override abstract StackExchange.Redis.Configuration.Tunnel.ToString() -> string!
186185
static StackExchange.Redis.Configuration.Tunnel.HttpProxy(System.Net.EndPoint! proxy) -> StackExchange.Redis.Configuration.Tunnel!
187186
virtual StackExchange.Redis.Configuration.Tunnel.BeforeAuthenticateAsync(System.Net.EndPoint! endpoint, StackExchange.Redis.ConnectionType connectionType, System.Net.Sockets.Socket? socket, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask<System.IO.Stream?>
188187
virtual StackExchange.Redis.Configuration.Tunnel.BeforeSocketConnectAsync(System.Net.EndPoint! endPoint, StackExchange.Redis.ConnectionType connectionType, System.Net.Sockets.Socket? socket, System.Threading.CancellationToken cancellationToken) -> System.Threading.Tasks.ValueTask

tests/StackExchange.Redis.Tests/Config.cs

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
using System;
1+
using StackExchange.Redis.Configuration;
2+
using System;
23
using System.Globalization;
34
using System.IO;
45
using System.IO.Pipelines;
@@ -613,7 +614,7 @@ public async Task MutableOptions()
613614
}
614615

615616
[Fact]
616-
public void HttpTunnel()
617+
public void HttpTunnelCanRoundtrip()
617618
{
618619
var config = ConfigurationOptions.Parse("127.0.0.1:6380,tunnel=http:somewhere:22");
619620
var ip = Assert.IsType<IPEndPoint>(Assert.Single(config.EndPoints));
@@ -626,4 +627,19 @@ public void HttpTunnel()
626627
var cs = config.ToString();
627628
Assert.Equal("127.0.0.1:6380,tunnel=http:somewhere:22", cs);
628629
}
630+
631+
private class CustomTunnel : Tunnel { }
632+
633+
[Fact]
634+
public void CustomTunnelCanRoundtripMinusTunnel()
635+
{
636+
// we don't expect to be able to parse custom tunnels, but we should still be able to round-trip
637+
// the rest of the config, which means ignoring them *in both directions* (unless first party)
638+
var options = ConfigurationOptions.Parse("127.0.0.1,Ssl=true");
639+
options.Tunnel = new CustomTunnel();
640+
var cs = options.ToString();
641+
Assert.Equal("127.0.0.1,ssl=True", cs);
642+
options = ConfigurationOptions.Parse(cs);
643+
Assert.Null(options.Tunnel);
644+
}
629645
}

0 commit comments

Comments
 (0)