Web.Routing - improve domains management
This commit is contained in:
@@ -236,7 +236,7 @@ namespace Umbraco.Tests.Routing
|
||||
new DomainAndUri(new MockDomain("domain3.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain4.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain1.org"), Uri.UriSchemeHttp), // yes: same site (though bogus setup)
|
||||
}).ToArray();
|
||||
}, true).ToArray();
|
||||
|
||||
Assert.AreEqual(1, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -251,7 +251,7 @@ namespace Umbraco.Tests.Routing
|
||||
new DomainAndUri(new MockDomain("domain3.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain4.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain1.org"), Uri.UriSchemeHttp), // yes: same site (though bogus setup)
|
||||
}).ToArray();
|
||||
}, true).ToArray();
|
||||
|
||||
Assert.AreEqual(1, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -270,7 +270,7 @@ namespace Umbraco.Tests.Routing
|
||||
new DomainAndUri(new MockDomain("domain3.org"), Uri.UriSchemeHttp), // yes: bound site
|
||||
new DomainAndUri(new MockDomain("domain4.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain1.org"), Uri.UriSchemeHttp), // yes: same site (though bogus setup)
|
||||
}).ToArray();
|
||||
}, true).ToArray();
|
||||
|
||||
Assert.AreEqual(3, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
@@ -288,7 +288,7 @@ namespace Umbraco.Tests.Routing
|
||||
new DomainAndUri(new MockDomain("domain3.org"), Uri.UriSchemeHttp), // yes: bound site
|
||||
new DomainAndUri(new MockDomain("domain4.com"), Uri.UriSchemeHttp), // no: not same site
|
||||
new DomainAndUri(new MockDomain("domain1.org"), Uri.UriSchemeHttp), // yes: same site (though bogus setup)
|
||||
}).ToArray();
|
||||
}, true).ToArray();
|
||||
|
||||
Assert.AreEqual(3, output.Count());
|
||||
Assert.Contains("http://domain1.org/", output.Select(d => d.Uri.ToString()).ToArray());
|
||||
|
||||
@@ -64,12 +64,12 @@ namespace Umbraco.Web.Routing
|
||||
return Enumerable.Empty<string>();
|
||||
|
||||
var n = node;
|
||||
var domainUris = DomainHelper.DomainsForNode(n.Id, current);
|
||||
var domainUris = DomainHelper.DomainsForNode(n.Id, current, false);
|
||||
while (domainUris == null && n != null) // n is null at root
|
||||
{
|
||||
// move to parent node
|
||||
n = n.Parent;
|
||||
domainUris = n == null ? null : DomainHelper.DomainsForNode(n.Id, current);
|
||||
domainUris = n == null ? null : DomainHelper.DomainsForNode(n.Id, current, false);
|
||||
}
|
||||
|
||||
var path = "/" + umbracoUrlName;
|
||||
|
||||
@@ -77,10 +77,11 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier.</param>
|
||||
/// <param name="current">The uri, or null.</param>
|
||||
/// <param name="excludeDefault">A value indicating whether to exclude the current/default domain. True by default.</param>
|
||||
/// <returns>The domains and their uris, that match the specified uri, else null.</returns>
|
||||
/// <remarks>If at least a domain is set on the node then the method returns the domains that
|
||||
/// best match the specified uri, else it returns null.</remarks>
|
||||
internal static IEnumerable<DomainAndUri> DomainsForNode(int nodeId, Uri current)
|
||||
internal static IEnumerable<DomainAndUri> DomainsForNode(int nodeId, Uri current, bool excludeDefault = true)
|
||||
{
|
||||
// be safe
|
||||
if (nodeId <= 0)
|
||||
@@ -98,7 +99,7 @@ namespace Umbraco.Web.Routing
|
||||
|
||||
// filter
|
||||
var helper = SiteDomainHelperResolver.Current.Helper;
|
||||
return helper.MapDomains(current, domainAndUris).ToArray();
|
||||
return helper.MapDomains(current, domainAndUris, excludeDefault).ToArray();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -29,8 +29,9 @@ namespace Umbraco.Web.Routing
|
||||
/// </summary>
|
||||
/// <param name="current">The Uri of the current request.</param>
|
||||
/// <param name="domainAndUris">The list of <c>DomainAndUri</c> to filter.</param>
|
||||
/// <param name="excludeDefault">A value indicating whether to exclude the current/default domain.</param>
|
||||
/// <returns>The selected <c>DomainAndUri</c> items.</returns>
|
||||
/// <remarks>The filter must return something, even empty, else an exception will be thrown.</remarks>
|
||||
IEnumerable<DomainAndUri> MapDomains(Uri current, DomainAndUri[] domainAndUris);
|
||||
IEnumerable<DomainAndUri> MapDomains(Uri current, DomainAndUri[] domainAndUris, bool excludeDefault);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,36 +194,41 @@ namespace Umbraco.Web.Routing
|
||||
return MapDomain(domainAndUris, qualifiedSites, currentAuthority);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Filters a list of <c>DomainAndUri</c> to pick those that best matches the current request.
|
||||
/// </summary>
|
||||
/// <param name="current">The Uri of the current request.</param>
|
||||
/// <param name="domainAndUris">The list of <c>DomainAndUri</c> to filter.</param>
|
||||
/// <returns>The selected <c>DomainAndUri</c> items.</returns>
|
||||
/// <remarks>The filter must return something, even empty, else an exception will be thrown.</remarks>
|
||||
public virtual IEnumerable<DomainAndUri> MapDomains(Uri current, DomainAndUri[] domainAndUris)
|
||||
/// <summary>
|
||||
/// Filters a list of <c>DomainAndUri</c> to pick those that best matches the current request.
|
||||
/// </summary>
|
||||
/// <param name="current">The Uri of the current request.</param>
|
||||
/// <param name="domainAndUris">The list of <c>DomainAndUri</c> to filter.</param>
|
||||
/// <param name="excludeDefault">A value indicating whether to exclude the current/default domain.</param>
|
||||
/// <returns>The selected <c>DomainAndUri</c> items.</returns>
|
||||
/// <remarks>The filter must return something, even empty, else an exception will be thrown.</remarks>
|
||||
public virtual IEnumerable<DomainAndUri> MapDomains(Uri current, DomainAndUri[] domainAndUris, bool excludeDefault)
|
||||
{
|
||||
var currentAuthority = current.GetLeftPart(UriPartial.Authority);
|
||||
KeyValuePair<string, string[]>[] candidateSites;
|
||||
IEnumerable<DomainAndUri> ret;
|
||||
KeyValuePair<string, string[]>[] candidateSites = null;
|
||||
IEnumerable<DomainAndUri> ret = domainAndUris;
|
||||
|
||||
using (ConfigReadLock) // so nothing changes between GetQualifiedSites and access to bindings
|
||||
{
|
||||
var qualifiedSites = GetQualifiedSitesInsideLock(current);
|
||||
|
||||
// exclude the current one (avoid producing the absolute equivalent of what GetUrl returns)
|
||||
var hintWithSlash = current.EndPathWithSlash();
|
||||
var hinted = domainAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash));
|
||||
ret = hinted == null ? domainAndUris : domainAndUris.Where(d => d != hinted);
|
||||
|
||||
// exclude the default one (avoid producing a possible duplicate of what GetUrl returns)
|
||||
// only if the default one cannot be the current one ie if hinted is not null
|
||||
if (hinted == null && domainAndUris.Any())
|
||||
if (excludeDefault)
|
||||
{
|
||||
// it is illegal to call MapDomain if domainAndUris is empty
|
||||
// also, domainAndUris should NOT contain current, hence the test on hinted
|
||||
var mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority); // what GetUrl would get
|
||||
ret = ret.Where(d => d != mainDomain);
|
||||
// exclude the current one (avoid producing the absolute equivalent of what GetUrl returns)
|
||||
var hintWithSlash = current.EndPathWithSlash();
|
||||
var hinted = domainAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(hintWithSlash));
|
||||
if (hinted != null)
|
||||
ret = ret.Where(d => d != hinted);
|
||||
|
||||
// exclude the default one (avoid producing a possible duplicate of what GetUrl returns)
|
||||
// only if the default one cannot be the current one ie if hinted is not null
|
||||
if (hinted == null && domainAndUris.Any())
|
||||
{
|
||||
// it is illegal to call MapDomain if domainAndUris is empty
|
||||
// also, domainAndUris should NOT contain current, hence the test on hinted
|
||||
var mainDomain = MapDomain(domainAndUris, qualifiedSites, currentAuthority); // what GetUrl would get
|
||||
ret = ret.Where(d => d != mainDomain);
|
||||
}
|
||||
}
|
||||
|
||||
// we do our best, but can't do the impossible
|
||||
@@ -236,17 +241,21 @@ namespace Umbraco.Web.Routing
|
||||
// if current belongs to a site, pick every element from domainAndUris that also belong
|
||||
// to that site -- or to any site bound to that site
|
||||
|
||||
candidateSites = new[] { currentSite };
|
||||
if (_bindings != null && _bindings.ContainsKey(currentSite.Key))
|
||||
{
|
||||
var boundSites = qualifiedSites.Where(site => _bindings[currentSite.Key].Contains(site.Key));
|
||||
candidateSites = candidateSites.Union(boundSites).ToArray();
|
||||
if (!currentSite.Equals(default(KeyValuePair<string, string[]>)))
|
||||
{
|
||||
candidateSites = new[] { currentSite };
|
||||
if (_bindings != null && _bindings.ContainsKey(currentSite.Key))
|
||||
{
|
||||
var boundSites = qualifiedSites.Where(site => _bindings[currentSite.Key].Contains(site.Key));
|
||||
candidateSites = candidateSites.Union(boundSites).ToArray();
|
||||
|
||||
// .ToArray ensures it is evaluated before the configuration lock is exited
|
||||
}
|
||||
}
|
||||
// .ToArray ensures it is evaluated before the configuration lock is exited
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret.Where(d =>
|
||||
// if we are able to filter, then filter, else return the whole lot
|
||||
return candidateSites == null ? ret : ret.Where(d =>
|
||||
{
|
||||
var authority = d.Uri.GetLeftPart(UriPartial.Authority);
|
||||
return candidateSites.Any(site => site.Value.Contains(authority));
|
||||
|
||||
Reference in New Issue
Block a user