From 69bea7324c1f77d1673e09096177c93268aa912e Mon Sep 17 00:00:00 2001 From: Anthony Stivers Date: Sat, 16 Feb 2019 19:14:46 -0500 Subject: [PATCH 1/2] Trim trailing `/` from hostUrl --- Refit.Tests/InterfaceStubGenerator.cs | 2 +- Refit.Tests/RefitStubs.Net46.cs | 32 +++++++++++++++++++++++++++ Refit.Tests/RefitStubs.NetCore2.cs | 32 +++++++++++++++++++++++++++ Refit.Tests/RestService.cs | 19 ++++++++++++++++ Refit/RestService.cs | 2 +- 5 files changed, 85 insertions(+), 2 deletions(-) diff --git a/Refit.Tests/InterfaceStubGenerator.cs b/Refit.Tests/InterfaceStubGenerator.cs index 12bea541e..25ecca9cf 100644 --- a/Refit.Tests/InterfaceStubGenerator.cs +++ b/Refit.Tests/InterfaceStubGenerator.cs @@ -123,7 +123,7 @@ public void GenerateTemplateInfoForInterfaceListSmokeTest() .ToList(); var result = fixture.GenerateTemplateInfoForInterfaceList(input); - Assert.Equal(10, result.ClassList.Count); + Assert.Equal(11, result.ClassList.Count); } [Fact] diff --git a/Refit.Tests/RefitStubs.Net46.cs b/Refit.Tests/RefitStubs.Net46.cs index 85a1f2dfa..68e2ec8e4 100644 --- a/Refit.Tests/RefitStubs.Net46.cs +++ b/Refit.Tests/RefitStubs.Net46.cs @@ -1083,6 +1083,38 @@ public virtual Task> GetRemoteFileWithMetadata(string filena } } +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedITrimTrailingForwardSlashApi : ITrimTrailingForwardSlashApi + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedITrimTrailingForwardSlashApi(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + public virtual Task Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + namespace Refit.Tests { using Refit.Tests.RefitInternalGenerated; diff --git a/Refit.Tests/RefitStubs.NetCore2.cs b/Refit.Tests/RefitStubs.NetCore2.cs index 85a1f2dfa..68e2ec8e4 100644 --- a/Refit.Tests/RefitStubs.NetCore2.cs +++ b/Refit.Tests/RefitStubs.NetCore2.cs @@ -1083,6 +1083,38 @@ public virtual Task> GetRemoteFileWithMetadata(string filena } } +namespace Refit.Tests +{ + using Refit.Tests.RefitInternalGenerated; + + /// + [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] + [global::System.Diagnostics.DebuggerNonUserCode] + [Preserve] + [global::System.Reflection.Obfuscation(Exclude=true)] + partial class AutoGeneratedITrimTrailingForwardSlashApi : ITrimTrailingForwardSlashApi + { + /// + public HttpClient Client { get; protected set; } + readonly IRequestBuilder requestBuilder; + + /// + public AutoGeneratedITrimTrailingForwardSlashApi(HttpClient client, IRequestBuilder requestBuilder) + { + Client = client; + this.requestBuilder = requestBuilder; + } + + /// + public virtual Task Get() + { + var arguments = new object[] { }; + var func = requestBuilder.BuildRestResultFuncForMethod("Get", new Type[] { }); + return (Task)func(Client, arguments); + } + } +} + namespace Refit.Tests { using Refit.Tests.RefitInternalGenerated; diff --git a/Refit.Tests/RestService.cs b/Refit.Tests/RestService.cs index c09fbc3d9..2e5c7639a 100644 --- a/Refit.Tests/RestService.cs +++ b/Refit.Tests/RestService.cs @@ -131,6 +131,14 @@ public interface IBodylessApi Task Head(); } + public interface ITrimTrailingForwardSlashApi + { + HttpClient Client { get; } + + [Get("/someendpoint")] + Task Get(); + } + public class HttpBinGet { public Dictionary Args { get; set; } @@ -1187,5 +1195,16 @@ public async Task CanSerializeContentAsXml() mockHttp.VerifyNoOutstandingExpectation(); } + + [Fact] + public void ShouldTrimTrailingForwardSlashFromBaseUrl() + { + var expectedBaseAddress = "http://example.com/api"; + var inputBaseAddress = "http://example.com/api/"; + + var fixture = RestService.For(inputBaseAddress); + + Assert.Equal(fixture.Client.BaseAddress.AbsoluteUri, expectedBaseAddress); + } } } diff --git a/Refit/RestService.cs b/Refit/RestService.cs index 82f86af2d..0ea08e3e1 100644 --- a/Refit/RestService.cs +++ b/Refit/RestService.cs @@ -49,7 +49,7 @@ public static T For(string hostUrl, RefitSettings settings) } } - var client = new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl) }; + var client = new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl.TrimEnd('/')) }; return For(client, settings); } From 4c864fe53dd38d2957d9a4c69e82b95e2e174a2f Mon Sep 17 00:00:00 2001 From: Anthony Stivers Date: Sat, 16 Feb 2019 19:56:32 -0500 Subject: [PATCH 2/2] Use null-conditional operator to prevent NRE --- Refit/RestService.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Refit/RestService.cs b/Refit/RestService.cs index 0ea08e3e1..fb5f3df28 100644 --- a/Refit/RestService.cs +++ b/Refit/RestService.cs @@ -49,7 +49,7 @@ public static T For(string hostUrl, RefitSettings settings) } } - var client = new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl.TrimEnd('/')) }; + var client = new HttpClient(innerHandler ?? new HttpClientHandler()) { BaseAddress = new Uri(hostUrl?.TrimEnd('/')) }; return For(client, settings); }