From d89a57cb9edb529dd2c466a9961bc4a46d575624 Mon Sep 17 00:00:00 2001 From: Tudor Stanciu Date: Fri, 10 Oct 2025 00:35:57 +0300 Subject: [PATCH] fix: update RealApiBaseUrl and improve URL handling in BitipClient --- .../Bitip.Client.Tests/TestConfiguration.cs | 2 +- .../Bitip.Client/Helpers/UriNormalizer.cs | 43 +++++++++++++++++++ .../Bitip.Client/Services/BitipClient.cs | 2 +- 3 files changed, 45 insertions(+), 2 deletions(-) diff --git a/src/clients/dotnet/Bitip.Client.Tests/TestConfiguration.cs b/src/clients/dotnet/Bitip.Client.Tests/TestConfiguration.cs index 8d5af56..1a18635 100644 --- a/src/clients/dotnet/Bitip.Client.Tests/TestConfiguration.cs +++ b/src/clients/dotnet/Bitip.Client.Tests/TestConfiguration.cs @@ -15,7 +15,7 @@ namespace Bitip.Client.Tests /// /// Real Bitip API base URL for integration tests. /// - public const string RealApiBaseUrl = "http://localhost:5172/api/"; + public const string RealApiBaseUrl = "http://localhost:5172"; /// /// Real API key for integration tests. diff --git a/src/clients/dotnet/Bitip.Client/Helpers/UriNormalizer.cs b/src/clients/dotnet/Bitip.Client/Helpers/UriNormalizer.cs index 242b2d1..1dd3671 100644 --- a/src/clients/dotnet/Bitip.Client/Helpers/UriNormalizer.cs +++ b/src/clients/dotnet/Bitip.Client/Helpers/UriNormalizer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2025 Tudor Stanciu using System; +using System.Linq; namespace Bitip.Client.Helpers { @@ -13,5 +14,47 @@ namespace Bitip.Client.Helpers var address = trimmed.EndsWith("/") ? trimmed : $"{trimmed}/"; return new Uri(address); } + + public static Uri EnsureTrailingSlash(string url, string suffix) + { + if (url is null) throw new ArgumentNullException(nameof(url)); + if (url is null) throw new ArgumentNullException(nameof(url)); + if (string.IsNullOrWhiteSpace(suffix)) return EnsureTrailingSlash(url); + + var normalizedSuffix = suffix.Trim('/'); + if (normalizedSuffix.Length == 0) return EnsureTrailingSlash(url); + + // Get last non-empty segment from the url + var parts = url.Split('/', StringSplitOptions.RemoveEmptyEntries); + var lastSegment = parts.Length == 0 ? string.Empty : parts.Last(); + + if (!string.Equals(lastSegment, normalizedSuffix, StringComparison.OrdinalIgnoreCase)) + { + url = PathCombine(url, normalizedSuffix); + } + + return EnsureTrailingSlash(url); + } + + /// + /// Combines multiple URL segments into a single path, ensuring proper slashes. + /// + public static string PathCombine(params string[] segments) // Move it to Netmash + { + var parts = segments + .Where(s => !string.IsNullOrEmpty(s)) + .Select(s => s.Trim()) + .ToArray(); + if (parts.Length == 0) return string.Empty; + if (parts.Length == 1) return parts[0]; + + var result = parts[0].TrimEnd('/'); + for (int i = 1; i < parts.Length; i++) + { + var seg = parts[i].Trim('/'); + if (seg.Length > 0) result += "/" + seg; + } + return result; + } } } diff --git a/src/clients/dotnet/Bitip.Client/Services/BitipClient.cs b/src/clients/dotnet/Bitip.Client/Services/BitipClient.cs index f08e0e6..20d4b9a 100644 --- a/src/clients/dotnet/Bitip.Client/Services/BitipClient.cs +++ b/src/clients/dotnet/Bitip.Client/Services/BitipClient.cs @@ -22,7 +22,7 @@ namespace Bitip.Client.Services public BitipClient(HttpClient httpClient, IOptions options) { - httpClient.BaseAddress = UriNormalizer.EnsureTrailingSlash(options.Value.BaseUrl); + httpClient.BaseAddress = UriNormalizer.EnsureTrailingSlash(options.Value.BaseUrl, "/api"); httpClient.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json")); httpClient.DefaultRequestHeaders.Add(ApiKeys.HttpHeader, options.Value.ApiKey);