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 })); }
/// <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); }
/// <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()); }
/// <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); }
private bool IsBaseOf(DomainAndUri domain, Uri uri) => domain.Uri.EndPathWithSlash().IsBaseOf(uri);