diff --git a/src/Umbraco.Tests/Routing/UrlProviderTests.cs b/src/Umbraco.Tests/Routing/UrlProviderTests.cs index 070c68468a..038211b86a 100644 --- a/src/Umbraco.Tests/Routing/UrlProviderTests.cs +++ b/src/Umbraco.Tests/Routing/UrlProviderTests.cs @@ -159,7 +159,7 @@ namespace Umbraco.Tests.Routing [Test] public void Get_Url_For_Culture_Variant_With_Current_Url() { - const string currentUri = "http://example.com/fr/test"; + const string currentUri = "http://example.fr/test"; var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true); @@ -180,8 +180,8 @@ namespace Umbraco.Tests.Routing if (contentId != 9876) return Enumerable.Empty(); return new[] { - new Domain(2, "example.com/en", 9876, CultureInfo.GetCultureInfo("en-US"), false, true), //default - new Domain(3, "example.com/fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false, true) + new Domain(2, "example.us", 9876, CultureInfo.GetCultureInfo("en-US"), false, true), //default + new Domain(3, "example.fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false, true) }; }); @@ -201,8 +201,7 @@ namespace Umbraco.Tests.Routing var url = umbracoContext.UrlProvider.GetUrl(1234, "fr-FR"); - //the current uri is the culture specific domain we want, so the result is a relative path since we are on the culture specific domain - Assert.AreEqual("/fr/home/test-fr/", url); + Assert.AreEqual("/home/test-fr/", url); } /// @@ -211,7 +210,7 @@ namespace Umbraco.Tests.Routing [Test] public void Get_Url_For_Culture_Variant_Non_Current_Url() { - const string currentUri = "http://example.com/en/test"; + const string currentUri = "http://example.us/test"; var globalSettings = Mock.Get(TestObjects.GetGlobalSettings()); //this will modify the IGlobalSettings instance stored in the container globalSettings.Setup(x => x.UseDirectoryUrls).Returns(true); @@ -232,8 +231,8 @@ namespace Umbraco.Tests.Routing if (contentId != 9876) return Enumerable.Empty(); return new[] { - new Domain(2, "example.com/en", 9876, CultureInfo.GetCultureInfo("en-US"), false, true), //default - new Domain(3, "example.com/fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false, true) + new Domain(2, "example.us", 9876, CultureInfo.GetCultureInfo("en-US"), false, true), //default + new Domain(3, "example.fr", 9876, CultureInfo.GetCultureInfo("fr-FR"), false, true) }; }); @@ -254,7 +253,7 @@ namespace Umbraco.Tests.Routing var url = umbracoContext.UrlProvider.GetUrl(1234, "fr-FR"); //the current uri is not the culture specific domain we want, so the result is an absolute path to the culture specific domain - Assert.AreEqual("http://example.com/fr/home/test-fr/", url); + Assert.AreEqual("http://example.fr/home/test-fr/", url); } [Test] diff --git a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs index 0ea0c950da..6a01250221 100644 --- a/src/Umbraco.Web/Routing/DefaultUrlProvider.cs +++ b/src/Umbraco.Web/Routing/DefaultUrlProvider.cs @@ -168,8 +168,9 @@ namespace Umbraco.Web.Routing else // a domain was found { if (mode == UrlProviderMode.Auto) - { - if (current != null && current.GetLeftPart(UriPartial.Path).InvariantStartsWith(domainUri.Uri.GetLeftPart(UriPartial.Path))) + { + //this check is a little tricky, we can't just compare domains + if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) mode = UrlProviderMode.Relative; else mode = UrlProviderMode.Absolute; diff --git a/src/Umbraco.Web/Routing/DomainHelper.cs b/src/Umbraco.Web/Routing/DomainHelper.cs index db051c20c5..76a0845113 100644 --- a/src/Umbraco.Web/Routing/DomainHelper.cs +++ b/src/Umbraco.Web/Routing/DomainHelper.cs @@ -125,6 +125,8 @@ namespace Umbraco.Web.Routing DomainAndUri domainAndUri; if (current == null) { + //match either by culture (if specified) or default + //get the default domain or the one matching the culture if specified domainAndUri = domainsAndUris.FirstOrDefault(x => culture.IsNullOrWhiteSpace() ? x.IsDefault : x.Culture.Name.InvariantEquals(culture)); @@ -133,25 +135,32 @@ namespace Umbraco.Web.Routing if (domainAndUri == null) domainAndUri = domainsAndUris.First(); // take the first one by default (what else can we do?) + } + else if (!culture.IsNullOrWhiteSpace()) + { + //match by culture + + domainAndUri = domainsAndUris.FirstOrDefault(x => x.Culture.Name.InvariantEquals(culture)); + if (domainAndUri == null) + throw new InvalidOperationException($"No domain was found by the specified culture '{culture}'"); + return domainAndUri; } else - { + { + //try to match by current, else filter + // look for the first domain that would be the base of the current url // ie current is www.example.com/foo/bar, look for domain www.example.com var currentWithSlash = current.EndPathWithSlash(); domainAndUri = domainsAndUris - .FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash)); - //is culture specified? if so this will need to match too - if (domainAndUri != null && (culture.IsNullOrWhiteSpace() || domainAndUri.Culture.Name.InvariantEquals(culture))) - return domainAndUri; + .FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash)); + if (domainAndUri != null) return domainAndUri; // if none matches, try again without the port // ie current is www.example.com:1234/foo/bar, look for domain www.example.com domainAndUri = domainsAndUris - .FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash.WithoutPort())); - //is culture specified? if so this will need to match too - if (domainAndUri != null && (culture.IsNullOrWhiteSpace() || domainAndUri.Culture.Name.InvariantEquals(culture))) - return domainAndUri; + .FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash.WithoutPort())); + if (domainAndUri != null) return domainAndUri; // if none matches, then try to run the filter to pick a domain if (filter != null)