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);
+ }
}
}