Merge pull request #10845 from vsilvar/v9/bugfix/10827_incorrect_url_when_domain_not_set

Fixed incorrect node url being returned when no suitable domain exist…
This commit is contained in:
Mole
2021-09-06 09:38:00 +02:00
committed by GitHub
4 changed files with 16 additions and 24 deletions

View File

@@ -190,7 +190,7 @@ namespace Umbraco.Cms.Core.Routing
}
// look for domains that would be the base of the uri
var baseDomains = SelectByBase(considerForBaseDomains, uri);
var baseDomains = SelectByBase(considerForBaseDomains, uri, culture);
if (baseDomains.Count > 0) // found, return
return baseDomains.First();
@@ -199,10 +199,6 @@ namespace Umbraco.Cms.Core.Routing
if (filter != null)
{
var domainAndUri = filter(cultureDomains ?? domainsAndUris, uri, culture, defaultCulture);
// if still nothing, pick the first one?
// no: move that constraint to the filter, but check
if (domainAndUri == null)
throw new InvalidOperationException("The filter returned null.");
return domainAndUri;
}
@@ -212,12 +208,15 @@ namespace Umbraco.Cms.Core.Routing
private static bool IsBaseOf(DomainAndUri domain, Uri uri)
=> domain.Uri.EndPathWithSlash().IsBaseOf(uri);
private static IReadOnlyCollection<DomainAndUri> SelectByBase(IReadOnlyCollection<DomainAndUri> domainsAndUris, Uri uri)
private static bool MatchesCulture(DomainAndUri domain, string culture)
=> culture == null || domain.Culture == culture;
private static IReadOnlyCollection<DomainAndUri> SelectByBase(IReadOnlyCollection<DomainAndUri> domainsAndUris, Uri uri, string culture)
{
// look for domains that would be the base of the uri
// ie current is www.example.com/foo/bar, look for domain www.example.com
var currentWithSlash = uri.EndPathWithSlash();
var baseDomains = domainsAndUris.Where(d => IsBaseOf(d, currentWithSlash)).ToList();
var baseDomains = domainsAndUris.Where(d => IsBaseOf(d, currentWithSlash) && MatchesCulture(d, culture)).ToList();
// if none matches, try again without the port
// ie current is www.example.com:1234/foo/bar, look for domain www.example.com

View File

@@ -336,8 +336,7 @@ namespace Umbraco.Cms.Core.Routing
if (qualifiedSites == null)
{
return domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(culture))
?? domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(defaultCulture))
?? domainAndUris.First();
?? domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(defaultCulture));
}
// find a site that contains the current authority
@@ -350,18 +349,7 @@ namespace Umbraco.Cms.Core.Routing
: domainAndUris.FirstOrDefault(d => currentSite.Value.Contains(d.Uri.GetLeftPart(UriPartial.Authority)));
// no match means that either current does not belong to a site, or the site it belongs to
// does not contain any of domainAndUris. Yet we have to return something. here, it becomes
// a bit arbitrary.
// look through sites in order and pick the first domainAndUri that belongs to a site
ret = ret ?? qualifiedSites
.Where(site => site.Key != currentSite.Key)
.Select(site => domainAndUris.FirstOrDefault(domainAndUri => site.Value.Contains(domainAndUri.Uri.GetLeftPart(UriPartial.Authority))))
.FirstOrDefault(domainAndUri => domainAndUri != null);
// random, really
ret = ret ?? domainAndUris.FirstOrDefault(x => x.Culture.InvariantEquals(culture)) ?? domainAndUris.First();
// does not contain any of domainAndUris.
return ret;
}

View File

@@ -247,6 +247,13 @@ namespace Umbraco.Extensions
return Attempt.Succeed(urlInfo);
}
// collisions with a different culture of the same content can never be routed.
if (!culture.InvariantEquals(pcr.Culture))
{
var urlInfo = UrlInfo.Message(textService.Localize("content", "routeErrorCannotRoute"), culture);
return Attempt.Succeed(urlInfo);
}
// no collision
return Attempt<UrlInfo>.Fail();
}

View File

@@ -191,9 +191,7 @@ namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Routing
siteDomainMapper.AddSite("site3", "domain3.com", "domain3.net", "domain3.org");
siteDomainMapper.AddSite("site4", "https://domain4.com", "https://domain4.net", "https://domain4.org");
// this works, but it's purely by chance / arbitrary
// don't use the www in tests here!
var current = new Uri("https://www.domain1.com/foo/bar");
var current = new Uri("https://domain1.com/foo/bar");
Domain[] domains = new[]
{
new Domain(1, "domain2.com", -1, s_cultureFr, false),