diff --git a/OpenNest.Data/RemoteNestRepository.cs b/OpenNest.Data/RemoteNestRepository.cs index 16c676b0..89062520 100644 --- a/OpenNest.Data/RemoteNestRepository.cs +++ b/OpenNest.Data/RemoteNestRepository.cs @@ -38,14 +38,7 @@ public sealed class RemoteNestRepository : INestRepository, IDisposable { _httpClient = httpClient; _ownsClient = false; - var url = (baseUrl ?? "").Trim().TrimEnd('/'); - if (!Uri.TryCreate(url, UriKind.Absolute, out var baseUri) - || (baseUri.Scheme != Uri.UriSchemeHttp && baseUri.Scheme != Uri.UriSchemeHttps)) - { - throw new ArgumentException($"Invalid nest server URL: '{baseUrl}'", nameof(baseUrl)); - } - // Keep the trailing slash so relative combines replace no path segment. - _baseUri = new Uri(baseUri.AbsoluteUri.TrimEnd('/') + "/"); + _baseUri = ServerUrl.ParseBase(baseUrl, nameof(baseUrl)); } private Uri Url(string relative) => new(_baseUri, relative); diff --git a/OpenNest.Data/ServerUrl.cs b/OpenNest.Data/ServerUrl.cs new file mode 100644 index 00000000..0b4d25a1 --- /dev/null +++ b/OpenNest.Data/ServerUrl.cs @@ -0,0 +1,21 @@ +namespace OpenNest.Data; + +/// Base-address validation shared by the nest server's HTTP clients. +internal static class ServerUrl +{ + /// + /// Returns the absolute http(s) base address with exactly one trailing slash, so + /// relative combines replace no path segment. Throws for any other address. + /// + public static Uri ParseBase(string? baseUrl, string paramName) + { + var url = (baseUrl ?? "").Trim().TrimEnd('/'); + if (!Uri.TryCreate(url, UriKind.Absolute, out var baseUri) + || (baseUri.Scheme != Uri.UriSchemeHttp && baseUri.Scheme != Uri.UriSchemeHttps)) + { + throw new ArgumentException($"Invalid nest server URL: '{baseUrl}'", paramName); + } + + return new Uri(baseUri.AbsoluteUri.TrimEnd('/') + "/"); + } +}