Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed incorrect node url being returned when no suitable domain exist… #10845

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 6 additions & 7 deletions src/Umbraco.Core/Routing/DomainUtilities.cs
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ public static DomainAndUri SelectDomain(IEnumerable<Domain> domains, Uri uri, st
}

// 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();

Expand All @@ -199,10 +199,6 @@ public static DomainAndUri SelectDomain(IEnumerable<Domain> domains, Uri uri, st
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;
}

Expand All @@ -212,12 +208,15 @@ public static DomainAndUri SelectDomain(IEnumerable<Domain> domains, Uri uri, st
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
Expand Down
16 changes: 2 additions & 14 deletions src/Umbraco.Core/Routing/SiteDomainMapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -336,8 +336,7 @@ private DomainAndUri MapDomain(IReadOnlyCollection<DomainAndUri> domainAndUris,
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
Expand All @@ -350,18 +349,7 @@ private DomainAndUri MapDomain(IReadOnlyCollection<DomainAndUri> domainAndUris,
: 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;
}

Expand Down
7 changes: 7 additions & 0 deletions src/Umbraco.Core/Routing/UrlProviderExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,13 @@ private static async Task<Attempt<UrlInfo>> DetectCollisionAsync(ILogger logger,
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();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,7 @@ public void MapDomainWithScheme()
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),
Expand Down