private static bool IsBaseOf(DomainAndUri domain, Uri uri) => domain.Uri.EndPathWithSlash().IsBaseOf(uri);
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode) { Uri uri; // ignore vdir at that point, UriFromUmbraco will do it if (mode == UrlProviderMode.AutoLegacy) { mode = UmbracoConfig.For.UmbracoSettings().RequestHandler.UseDomainPrefixes ? UrlProviderMode.Absolute : UrlProviderMode.Auto; } if (domainUri == null) // no domain was found { if (current == null) mode = UrlProviderMode.Relative; // best we can do switch (mode) { case UrlProviderMode.Absolute: uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path); break; case UrlProviderMode.Relative: case UrlProviderMode.Auto: uri = new Uri(path, UriKind.Relative); break; default: throw new ArgumentOutOfRangeException("mode"); } } else // a domain was found { if (mode == UrlProviderMode.Auto) { if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) mode = UrlProviderMode.Relative; else mode = UrlProviderMode.Absolute; } switch (mode) { case UrlProviderMode.Absolute: uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); break; case UrlProviderMode.Relative: uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); break; default: throw new ArgumentOutOfRangeException("mode"); } } // UriFromUmbraco will handle vdir // meaning it will add vdir into domain urls too! return UriUtility.UriFromUmbraco(uri); }
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode) { Uri uri; // ignore vdir at that point, UriFromUmbraco will do it if (mode == UrlProviderMode.AutoLegacy) { mode = _requestSettings.UseDomainPrefixes ? UrlProviderMode.Absolute : UrlProviderMode.Auto; } if (domainUri == null) // no domain was found { if (current == null) { mode = UrlProviderMode.Relative; // best we can do } switch (mode) { case UrlProviderMode.Absolute: uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path); break; case UrlProviderMode.Relative: case UrlProviderMode.Auto: uri = new Uri(path, UriKind.Relative); break; default: throw new ArgumentOutOfRangeException("mode"); } } else // a domain was found { if (mode == UrlProviderMode.Auto) { if (current != null && domainUri.Uri.GetLeftPart(UriPartial.Authority) == current.GetLeftPart(UriPartial.Authority)) { mode = UrlProviderMode.Relative; } else { mode = UrlProviderMode.Absolute; } } switch (mode) { case UrlProviderMode.Absolute: uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); break; case UrlProviderMode.Relative: uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); break; default: throw new ArgumentOutOfRangeException("mode"); } } // UriFromUmbraco will handle vdir // meaning it will add vdir into domain urls too! return(UriUtility.UriFromUmbraco(uri)); }
private static DomainAndUri MapDomain(DomainAndUri[] domainAndUris, Dictionary<string, string[]> qualifiedSites, string currentAuthority) { if (domainAndUris == null) throw new ArgumentNullException("domainAndUris"); if (!domainAndUris.Any()) throw new ArgumentException("Cannot be empty.", "domainAndUris"); // we do our best, but can't do the impossible if (qualifiedSites == null) return domainAndUris.First(); // find a site that contains the current authority var currentSite = qualifiedSites.FirstOrDefault(site => site.Value.Contains(currentAuthority)); // if current belongs to a site - try to pick the first element // from domainAndUris that also belongs to that site var ret = currentSite.Equals(default(KeyValuePair<string, string[]>)) ? null : 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.First(); return ret; }
/// <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 = null; IEnumerable<DomainAndUri> ret = domainAndUris; using (ConfigReadLock) // so nothing changes between GetQualifiedSites and access to bindings { var qualifiedSites = GetQualifiedSitesInsideLock(current); if (excludeDefault) { // 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 if (qualifiedSites == null) return ret; // find a site that contains the current authority var currentSite = qualifiedSites.FirstOrDefault(site => site.Value.Contains(currentAuthority)); // 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 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 } } } // 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)); }); }
/// <summary> /// Filters a list of <c>DomainAndUri</c> to pick one 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>.</returns> /// <remarks> /// <para>If the filter is invoked then <paramref name="domainAndUris"/> is _not_ empty and /// <paramref name="current"/> is _not_ null, and <paramref name="current"/> could not be /// matched with anything in <paramref name="domainAndUris"/>.</para> /// <para>The filter _must_ return something else an exception will be thrown.</para> /// </remarks> public virtual DomainAndUri MapDomain(Uri current, DomainAndUri[] domainAndUris) { var currentAuthority = current.GetLeftPart(UriPartial.Authority); var qualifiedSites = GetQualifiedSites(current); return MapDomain(domainAndUris, qualifiedSites, currentAuthority); }
Uri AssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlMode mode) { Uri uri; // ignore vdir at that point, UriFromUmbraco will do it if (domainUri == null) // no domain was found { if (current == null) { mode = UrlMode.Relative; // best we can do } switch (mode) { case UrlMode.Absolute: uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path); break; case UrlMode.Relative: case UrlMode.Auto: uri = new Uri(path, UriKind.Relative); break; default: throw new ArgumentOutOfRangeException(nameof(mode)); } } else // a domain was found { if (mode == UrlMode.Auto) { //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 = UrlMode.Relative; } else { mode = UrlMode.Absolute; } } switch (mode) { case UrlMode.Absolute: uri = new Uri(CombinePaths(domainUri.Uri.GetLeftPart(UriPartial.Path), path)); break; case UrlMode.Relative: uri = new Uri(CombinePaths(domainUri.Uri.AbsolutePath, path), UriKind.Relative); break; default: throw new ArgumentOutOfRangeException(nameof(mode)); } } // UriFromUmbraco will handle vdir // meaning it will add vdir into domain URLs too! return(UriUtility.UriFromUmbraco(uri, _globalSettings, _requestSettings)); }