private void AddToCacheIfDeepestRoute(IPublishedContent content, string route) { var domainRootNodeId = route.StartsWith("/") ? -1 : int.Parse(route.Substring(0, route.IndexOf('/'))); // so we have a route that maps to a content... say "1234/path/to/content" - however, there could be a // domain set on "to" and route "4567/content" would also map to the same content - and due to how // urls computing work (by walking the tree up to the first domain we find) it is that second route // that would be returned - the "deepest" route - and that is the route we want to cache, *not* the // longer one - so make sure we don't cache the wrong route var deepest = DomainUtilities.ExistsDomainInPath(_domainCache.GetAll(false), content.Path, domainRootNodeId) == false; if (deepest) { _routesCache.Store(content.Id, route, true); // trusted route } }
/// <summary> /// Finds the site root (if any) matching the http request, and updates the PublishedRequest accordingly. /// </summary> /// <returns>A value indicating whether a domain was found.</returns> internal bool FindDomain(IPublishedRequestBuilder request) { const string tracePrefix = "FindDomain: "; // note - we are not handling schemes nor ports here. if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, request.Uri); } IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext(); IDomainCache? domainsCache = umbracoContext.PublishedSnapshot.Domains; var domains = domainsCache?.GetAll(false).ToList(); // determines whether a domain corresponds to a published document, since some // domains may exist but on a document that has been unpublished - as a whole - or // that is not published for the domain's culture - in which case the domain does // not apply bool IsPublishedContentDomain(Domain domain) { // just get it from content cache - optimize there, not here IPublishedContent?domainDocument = umbracoContext.PublishedSnapshot.Content?.GetById(domain.ContentId); // not published - at all if (domainDocument == null) { return(false); } // invariant - always published if (!domainDocument.ContentType.VariesByCulture()) { return(true); } // variant, ensure that the culture corresponding to the domain's language is published return(domain.Culture is not null && domainDocument.Cultures.ContainsKey(domain.Culture)); } domains = domains?.Where(IsPublishedContentDomain).ToList(); var defaultCulture = domainsCache?.DefaultCulture; // try to find a domain matching the current request DomainAndUri?domainAndUri = DomainUtilities.SelectDomain(domains, request.Uri, defaultCulture: defaultCulture); // handle domain - always has a contentId and a culture if (domainAndUri != null) { // matching an existing domain if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug( "{TracePrefix}Matches domain={Domain}, rootId={RootContentId}, culture={Culture}", tracePrefix, domainAndUri.Name, domainAndUri.ContentId, domainAndUri.Culture); } request.SetDomain(domainAndUri); // canonical? not implemented at the moment // if (...) // { // _pcr.RedirectUrl = "..."; // return true; // } } else { // not matching any existing domain if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("{TracePrefix}Matches no domain", tracePrefix); } request.SetCulture(defaultCulture ?? CultureInfo.CurrentUICulture.Name); } if (_logger.IsEnabled(LogLevel.Debug)) { _logger.LogDebug("{TracePrefix}Culture={CultureName}", tracePrefix, request.Culture); } return(request.Domain != null); }