diff --git a/src/Flurl.Http/FlurlHttp.cs b/src/Flurl.Http/FlurlHttp.cs index 7c633c5d..bfd69cba 100644 --- a/src/Flurl.Http/FlurlHttp.cs +++ b/src/Flurl.Http/FlurlHttp.cs @@ -48,6 +48,6 @@ public static IFlurlClientBuilder ConfigureClientForUrl(string url) { /// /// Builds a cache key consisting of URL scheme, host, and port. This is the default client caching strategy. /// - public static string BuildClientNameByHost(IFlurlRequest req) => $"{req.Url.Scheme}|{req.Url.Host}|{req.Url.Port}"; + public static string BuildClientNameByHost(IFlurlRequest req) => $"{req.Url?.Scheme}|{req.Url?.Host}|{req.Url?.Port}"; } } \ No newline at end of file diff --git a/src/Flurl.Http/FlurlRequest.cs b/src/Flurl.Http/FlurlRequest.cs index ca9762b4..c98e6649 100644 --- a/src/Flurl.Http/FlurlRequest.cs +++ b/src/Flurl.Http/FlurlRequest.cs @@ -115,6 +115,7 @@ public IFlurlClient Client { set { _client = value; Settings.Parent = _client?.Settings; + SyncBaseUrl(_client, this); SyncHeaders(_client, this); } } @@ -163,6 +164,19 @@ internal static void SyncHeaders(IFlurlClient client, IFlurlRequest request) { } } + /// + /// Prepends client.BaseUrl to this.Url, but only if this.Url isn't already a valid, absolute URL. + /// + private static void SyncBaseUrl(IFlurlClient client, IFlurlRequest request) { + if (string.IsNullOrEmpty(client?.BaseUrl)) + return; + + if (request.Url == null) + request.Url = client.BaseUrl; + else if (!Url.IsValid(request.Url)) + request.Url = Url.Combine(client.BaseUrl, request.Url); + } + private void ApplyCookieJar(CookieJar jar) { _jar = jar; if (jar == null) diff --git a/test/Flurl.Test/Http/GlobalConfigTests.cs b/test/Flurl.Test/Http/GlobalConfigTests.cs index fecd033b..73ffb61d 100644 --- a/test/Flurl.Test/Http/GlobalConfigTests.cs +++ b/test/Flurl.Test/Http/GlobalConfigTests.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Flurl.Http; +using Flurl.Http.Testing; using NUnit.Framework; namespace Flurl.Test.Http @@ -74,5 +75,23 @@ public void can_configure_client_for_url() { Assert.AreEqual(123, cli2.Settings.Timeout.Value.TotalSeconds); Assert.AreNotEqual(123, cli3.Settings.Timeout.Value.TotalSeconds); } + + [Test] // #803 + public async Task can_prepend_global_base_url() { + FlurlHttp.Clients.WithDefaults(builder => + builder.ConfigureHttpClient(cli => cli.BaseAddress = new Uri("https://api.com"))); + + using var test = new HttpTest(); + + await "".GetAsync(); + await "/path/1".GetAsync(); + await "path/2".GetAsync(); + await "https://other.com/path/3".GetAsync(); + + test.ShouldHaveCalled("https://api.com/").Times(1); + test.ShouldHaveCalled("https://api.com/path/1").Times(1); + test.ShouldHaveCalled("https://api.com/path/2").Times(1); + test.ShouldHaveCalled("https://other.com/path/3").Times(1); + } } }