fix(opcuaclient): keep the configured IPv6 zone index through the endpoint rewrite (#819)
.NET's Uri parses a zone ([fe80::1%eth0]) but drops it from Host, Authority, AbsoluteUri and ToString(); only DnsSafeHost/IdnHost carry it. The shared OpcUaEndpointUrlRewriter rebuilt the URL through UriBuilder, so the zone was lost and link-local endpoints were unroutable. The SDK dials new Uri(EndpointUrl).IdnHost (TcpByteTransport -> DnsEndPoint), which keeps it, so splicing the zone back into the string is enough. Kept verbatim (%eth0, %4, or RFC 6874 %25eth0) so the session dials exactly what GetEndpoints reached. Applies to the driver, the AdminUI browser and the Client CLI/UI (all share the rewriter).
This commit is contained in:
+4
-2
@@ -42,8 +42,10 @@ public sealed class EndpointSelectorRewriteParityTests
|
||||
[InlineData("opc.tcp://plc-a:4840/Server", "opc.tcp://PLC-A:4840/", "opc.tcp://plc-a:4840/Server")]
|
||||
// A real rewrite keeps the advertised path's percent-escaping intact.
|
||||
[InlineData("opc.tcp://a:4840/x%20y?q=1", "opc.tcp://b:1/", "opc.tcp://b:1/x%20y?q=1")]
|
||||
// An IPv6 zone index on the configured host is dropped (UriBuilder behaviour, same in both copies).
|
||||
[InlineData("opc.tcp://internal-host:4840/OtOpcUa", "opc.tcp://[fe80::1%25eth0]:4841", "opc.tcp://[fe80::1]:4841/OtOpcUa")]
|
||||
// #819: an IPv6 zone index on the configured host is KEPT, verbatim (it used to be dropped — UriBuilder behaviour,
|
||||
// preserved deliberately through #812 — leaving link-local endpoints unroutable).
|
||||
[InlineData("opc.tcp://internal-host:4840/OtOpcUa", "opc.tcp://[fe80::1%25eth0]:4841", "opc.tcp://[fe80::1%25eth0]:4841/OtOpcUa")]
|
||||
[InlineData("opc.tcp://internal-host:4840/OtOpcUa", "opc.tcp://[fe80::1%eth0]:4841", "opc.tcp://[fe80::1%eth0]:4841/OtOpcUa")]
|
||||
public void SelectBest_rewrites_exactly_as_before(string advertised, string configured, string expected)
|
||||
{
|
||||
Select(advertised, configured).ShouldBe(expected);
|
||||
|
||||
Reference in New Issue
Block a user