Ejemplo n.º 1
0
        internal UrlInfo GetUrlFromRoute(
            string route,
            IUmbracoContext umbracoContext,
            int id,
            Uri current,
            UrlMode mode,
            string culture)
        {
            if (string.IsNullOrWhiteSpace(route))
            {
                _logger.LogDebug(
                    "Couldn't find any page with nodeId={NodeId}. This is most likely caused by the page not being published.",
                    id);
                return(null);
            }

            // extract domainUri and path
            // route is /<path> or <domainRootId>/<path>
            var          pos       = route.IndexOf('/');
            var          path      = pos == 0 ? route : route.Substring(pos);
            DomainAndUri domainUri = pos == 0
                ? null
                : DomainUtilities.DomainForNode(umbracoContext.PublishedSnapshot.Domains, _siteDomainMapper, int.Parse(route.Substring(0, pos), CultureInfo.InvariantCulture), current, culture);

            var defaultCulture = _localizationService.GetDefaultLanguageIsoCode();

            if (domainUri is not null || string.IsNullOrEmpty(culture) || culture.Equals(defaultCulture, StringComparison.InvariantCultureIgnoreCase))
            {
                var url = AssembleUrl(domainUri, path, current, mode).ToString();
                return(UrlInfo.Url(url, culture));
            }

            return(null);
        }
Ejemplo n.º 2
0
 /// <summary>
 /// Initializes a new instance of the <see cref="PublishedRequest"/> class.
 /// </summary>
 public PublishedRequest(Uri uri, string absolutePathDecoded, IPublishedContent publishedContent, bool isInternalRedirect, ITemplate template, DomainAndUri domain, string culture, string redirectUrl, int?responseStatusCode, IReadOnlyList <string> cacheExtensions, IReadOnlyDictionary <string, string> headers, bool setNoCacheHeader, bool ignorePublishedContentCollisions)
 {
     Uri = uri ?? throw new ArgumentNullException(nameof(uri));
     AbsolutePathDecoded = absolutePathDecoded ?? throw new ArgumentNullException(nameof(absolutePathDecoded));
     PublishedContent    = publishedContent;
     IsInternalRedirect  = isInternalRedirect;
     Template            = template;
     Domain             = domain;
     Culture            = culture;
     RedirectUrl        = redirectUrl;
     ResponseStatusCode = responseStatusCode;
     CacheExtensions    = cacheExtensions;
     Headers            = headers;
     SetNoCacheHeader   = setNoCacheHeader;
     IgnorePublishedContentCollisions = ignorePublishedContentCollisions;
 }
Ejemplo n.º 3
0
        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, _requestSettings));
        }
Ejemplo n.º 4
0
 private static bool MatchesCulture(DomainAndUri domain, string?culture)
 => culture == null || domain.Culture.InvariantEquals(culture);
Ejemplo n.º 5
0
 private static bool IsBaseOf(DomainAndUri domain, Uri uri)
 => domain.Uri.EndPathWithSlash().IsBaseOf(uri);
Ejemplo n.º 6
0
        /// <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.
            _logger.LogDebug("{TracePrefix}Uri={RequestUri}", tracePrefix, request.Uri);
            var          umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
            IDomainCache domainsCache   = umbracoContext.PublishedSnapshot.Domains;
            var          domains        = domainsCache.GetAll(includeWildcards: 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(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
                _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
                _logger.LogDebug("{TracePrefix}Matches no domain", tracePrefix);

                request.SetCulture(defaultCulture ?? CultureInfo.CurrentUICulture.Name);
            }

            _logger.LogDebug("{TracePrefix}Culture={CultureName}", tracePrefix, request.Culture);

            return(request.Domain != null);
        }