private Uri UmbracoAssembleUrl(DomainAndUri domainUri, string path, Uri current, UrlProviderMode mode)
        {
            // This method is private in umbraco, but we want to use their!
            DefaultUrlProvider provider = ActivatorHelper.CreateInstance <DefaultUrlProvider>();

            return(ActivatorHelper.GetPrivateMethodReturnValueOfInstance <Uri>(
                       instance: provider,
                       methodName: "AssembleUrl",
                       methodArguments: new object[] { domainUri, path, current, mode }));
        }
Example #2
0
        /// <summary>
        /// Finds the domain matching the specified uri using the domain service.
        /// </summary>
        /// <param name="current">The uri, or null.</param>
        /// <returns>The domain</returns>
        public static IDomain FindDomainForUri(Uri current)
        {
            var domains = ApplicationContext.Current.Services.DomainService.GetAll(false);

            if (domains == null || !domains.Any())
            {
                return(null);
            }
            DomainAndUri domain = DomainForUri(domains, current);

            return(domain?.UmbracoDomain);
        }
        /// <summary>
        /// Finds the domain matching the specified uri using the domain service.
        /// </summary>
        /// <param name="domainService"></param>
        /// <param name="current">The uri, or null.</param>
        /// <returns>The domain</returns>
        public static Domain FindDomainForUri(IDomainService domainService, Uri current)
        {
            var domains = domainService.GetAll(false);

            if (domains == null)
            {
                return(null);
            }
            DomainAndUri domain = SelectDomain(domains.Select(x => new Domain(x.Id, x.DomainName, x.RootContentId.GetValueOrDefault(), x.LanguageIsoCode, x.IsWildcard)), current);

            return(domain);
        }
Example #4
0
        /// <summary>
        /// Returns the <see cref="DomainAndUri"/> for the specified <paramref name="content"/> node, or <c>null</c> if
        /// not found. The domain will be determined either from the node it self or one of it's ancestors.
        /// </summary>
        /// <param name="content">Ther node.</param>
        /// <param name="current">The URI of the request.</param>
        /// <param name="culture">The culture code of the request.</param>
        /// <returns>An instance of <see cref="DomainAndUri"/> representing the domain, or <c>null</c> if not domain was found.</returns>
        public DomainAndUri DomainForNode(IPublishedContent content, Uri current, string culture = null)
        {
            while (content != null)
            {
                DomainAndUri domain = DomainForNode(content.Id, current, culture);
                if (domain != null)
                {
                    return(domain);
                }

                content = content.Parent;
            }

            return(null);
        }
        private DomainAndUri DomainForNode(int contentId, Uri current, string isoCode)
        {
            // sanitize the list to have proper uris for comparison (scheme, path end with /)
            // we need to end with / because example.com/foo cannot match example.com/foobar
            // we need to order so example.com/foo matches before example.com/
            string scheme = current == null ? Uri.UriSchemeHttp : current.Scheme;

            IEnumerable <IDomain> domains = _domainService.GetAssignedDomains(
                contentId: contentId,
                includeWildcards: false);

            // No domains so return null
            if (domains.Any() == false)
            {
                return(null);
            }

            DomainAndUri[] domainsAndUris = domains
                                            .Where(d => d.IsWildcard == false)
                                            //.Select(SanitizeForBackwardCompatibility) // Not needed because we have pre-4.10+
                                            .Select(d => new DomainAndUri(d, scheme))
                                            .OrderByDescending(d => d.Uri.ToString())
                                            .ToArray();

            // this is easier than umbraco's approach
            // because for this localization it's only allowed to have one culture per hostname
            // maybe we have to change this for the future...

            // look for the first domain that would be the base of the current url and has same the iso code
            // ie current is www.example.com/foo/bar, look for domain www.example.com
            DomainAndUri domainAndUri = TryGetDomainByUriAndIsoCode(
                domainsAndUris: domainsAndUris,
                current: current,
                isoCode: isoCode);

            // if nothing found we get at least the correct language
            if (domainAndUri == null)
            {
                domainAndUri = domainsAndUris.FirstOrDefault(
                    o => o.UmbracoDomain.LanguageIsoCode == isoCode);
            }

            return(domainAndUri);
        }
        public void Builds_All_Values()
        {
            IPublishedRequestBuilder sut = GetBuilder();

            IPublishedContent content  = Mock.Of <IPublishedContent>(x => x.Id == 1);
            ITemplate         template = Mock.Of <ITemplate>(x => x.Id == 1);

            string[] cacheExt  = new[] { "must-revalidate" };
            var      auCulture = "en-AU";
            var      usCulture = "en-US";
            var      domain    = new DomainAndUri(
                new Domain(1, "test", 2, auCulture, false), new Uri("https://example.com/en-au"));
            IReadOnlyDictionary <string, string> headers = new Dictionary <string, string> {
                ["Hello"] = "world"
            };
            var redirect = "https://test.com";

            sut
            .SetNoCacheHeader(true)
            .SetCacheExtensions(cacheExt)
            .SetDomain(domain)
            .SetCulture(usCulture)
            .SetHeaders(headers)
            .SetInternalRedirect(content)
            .SetRedirect(redirect)
            .SetTemplate(template);

            IPublishedRequest request = sut.Build();

            Assert.AreEqual(true, request.SetNoCacheHeader);
            Assert.AreEqual(cacheExt, request.CacheExtensions);
            Assert.AreEqual(usCulture, request.Culture);
            Assert.AreEqual(domain, request.Domain);
            Assert.AreEqual(headers, request.Headers);
            Assert.AreEqual(true, request.IsInternalRedirect);
            Assert.AreEqual(content, request.PublishedContent);
            Assert.AreEqual(redirect, request.RedirectUrl);
            Assert.AreEqual(302, request.ResponseStatusCode);
            Assert.AreEqual(template, request.Template);
            Assert.AreEqual(_baseUri, request.Uri);
        }
        /// <summary>
        /// Assembles the URL with the found hostname.
        /// </summary>
        /// <param name="route">The route.</param>
        /// <param name="current">The current.</param>
        /// <param name="mode">The mode.</param>
        /// <param name="isoCode">The iso code.</param>
        /// <returns></returns>
        internal string AssembleUrl(
            string route,
            Uri current,
            UrlProviderMode mode,
            string isoCode)
        {
            // extract domainUri and path
            // route is /<path> or <domainRootId>/<path>
            int    pos  = route.IndexOf('/');
            string path = pos == 0 ? route : route.Substring(pos);

            DomainAndUri domainUri = pos == 0 ? null : this.DomainForNode(
                contentId: int.Parse(route.Substring(0, pos)),
                current: current,
                isoCode: isoCode);

            return(UmbracoAssembleUrl(
                       domainUri: domainUri,
                       path: path,
                       current: current,
                       mode: mode).ToString());
        }
Example #8
0
        /// <summary>
        /// Finds the domain that best matches a specified uri, into a group of domains.
        /// </summary>
        /// <param name="domains">The group of domains.</param>
        /// <param name="current">The uri, or null.</param>
        /// <returns>The domain and its normalized uri, that best matches the specified uri.</returns>
        /// <remarks>Copied from Umbraco core, since it's an internal method there.</remarks>
        /// <see>
        ///     <cref>https://github.com/umbraco/Umbraco-CMS/blob/22bd6cd989e2596b69339d9b344e14bcc759e82b/src/Umbraco.Web/Routing/DomainHelper.cs#L117</cref>
        /// </see>
        private static DomainAndUri DomainForUri(IEnumerable <IDomain> domains, Uri current)
        {
            // sanitize the list to have proper uris for comparison (scheme, path end with /)
            // we need to end with / because example.com/foo cannot match example.com/foobar
            // we need to order so example.com/foo matches before example.com/
            string scheme = current == null ? Uri.UriSchemeHttp : current.Scheme;

            DomainAndUri[] domainsAndUris = domains
                                            .Select(x => new DomainAndUri(SanitizeForBackwardCompatibility(x), scheme))
                                            .OrderByDescending(d => d.Uri.ToString())
                                            .ToArray();

            // Just return null if there are no domains
            if (domainsAndUris.Length == 0)
            {
                return(null);
            }

            // take the first one by default (what else can we do?)
            if (current == null)
            {
                return(domainsAndUris[0]);
            }

            // look for the first domain that would be the base of the current url
            // ie current is www.example.com/foo/bar, look for domain www.example.com
            Uri          currentWithSlash = current.EndPathWithSlash();
            DomainAndUri domainAndUri     = domainsAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash));

            if (domainAndUri != null)
            {
                return(domainAndUri);
            }

            // if none matches, try again without the port
            // ie current is www.example.com:1234/foo/bar, look for domain www.example.com
            domainAndUri = domainsAndUris.FirstOrDefault(d => d.Uri.EndPathWithSlash().IsBaseOf(currentWithSlash.WithoutPort()));
            return(domainAndUri);
        }
Example #9
0
 private bool IsBaseOf(DomainAndUri domain, Uri uri) => domain.Uri.EndPathWithSlash().IsBaseOf(uri);