private bool BuildPageUrlPath(Guid pageId, CultureInfo culture, UrlSpace urlSpace, StringBuilder result)
        {
            IPage page = PageManager.GetPageById(pageId);

            if (page == null)
            {
                return(false);
            }

            Guid parentPageId = PageManager.GetParentId(pageId);

            if (parentPageId == Guid.Empty)
            {
                return(BuildRootPageUrl(page, culture, urlSpace, result));
            }

            if (!BuildPageUrlPath(parentPageId, culture, urlSpace, result))
            {
                return(false);
            }

            Verify.That(result.Length >= 1, "Parent page urls is empty");

            AppendSlash(result);
            result.Append(page.UrlTitle);

            return(true);
        }
        private bool BuildRootPageUrl(IPage rootPage, CultureInfo cultureInfo, UrlSpace urlSpace, StringBuilder result)
        {
            var bindings = GetHostnameBindings();

            bool knownHostname = urlSpace.Hostname != null &&
                                 bindings.Any(b => b.Hostname == urlSpace.Hostname);

            IHostnameBinding hostnameBinding = null;

            // Searching for a hostname binding matching either the root page, or current hostname/UrlSpace
            if (!urlSpace.ForceRelativeUrls && knownHostname)
            {
                Guid   pageId      = rootPage.Id;
                string host        = urlSpace.Hostname;
                string cultureName = cultureInfo.Name;

                hostnameBinding =
                    bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Hostname == host && b.Culture == cultureName)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Culture == cultureName)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId && b.Hostname == host)
                    ?? bindings.FirstOrDefault(b => b.HomePageId == pageId);

                if (hostnameBinding != null)
                {
                    if (hostnameBinding.Hostname != urlSpace.Hostname)
                    {
                        result.AppendFormat("http{0}://", hostnameBinding.EnforceHttps ? "s" : "")
                        .Append(hostnameBinding.Hostname);
                    }
                }
                else
                {
                    hostnameBinding = bindings.FirstOrDefault(b => b.Hostname == urlSpace.Hostname);
                }
            }

            result.Append(UrlUtils.PublicRootPath);

            string cultureUrlMapping = DataLocalizationFacade.GetUrlMappingName(cultureInfo);

            if (cultureUrlMapping != string.Empty &&
                (hostnameBinding == null ||
                 hostnameBinding.IncludeCultureInUrl ||
                 hostnameBinding.Culture != cultureInfo.Name))
            {
                result.Append("/").Append(cultureUrlMapping);
            }


            AppendSlash(result);

            if (rootPage.UrlTitle != string.Empty &&
                (hostnameBinding == null || hostnameBinding.IncludeHomePageInUrl || hostnameBinding.HomePageId != rootPage.Id))
            {
                result.Append(rootPage.UrlTitle);
            }

            return(true);
        }
예제 #3
0
            private static string GetCacheKey(string host, CultureInfo culture, Guid rootPageId)
            {
                var urlSpace = new UrlSpace();

                string hostnameKey = urlSpace.ForceRelativeUrls ? string.Empty : host;

                return(CachePrefix + hostnameKey + rootPageId + culture.Name + PublicationScope);
            }
예제 #4
0
        public static Dictionary <string, Guid> GetMappingsFromSiteMap()
        {
            var result = new Dictionary <string, Guid>();

            var urlSpace = new UrlSpace();

            // TODO: support for multiple languages as well
            var hostnameBindings = DataFacade.GetData <IHostnameBinding>().ToList();

            var rootToHostnameMap = hostnameBindings.ToDictionary(h => h.HomePageId, h => h.Hostname);

            foreach (var cultureInfo in DataLocalizationFacade.ActiveLocalizationCultures.ToArray())
            {
                using (new DataScope(DataScopeIdentifier.Public, cultureInfo))
                {
                    var pages = DataFacade.GetData <IPage>().ToList();

                    foreach (var page in pages)
                    {
                        var url = PageUrls.BuildUrl(new PageUrlData(page), UrlKind.Public, urlSpace);
                        if (url != null && !result.ContainsKey(url))
                        {
                            result.Add(url, page.Id);
                        }

                        var rootPageId = GetRootPageId(page.Id);

                        string hostname;
                        if (rootToHostnameMap.TryGetValue(rootPageId, out hostname))
                        {
                            if (urlSpace.Hostname != hostname)
                            {
                                var hostnameBasedUrlSpace = new UrlSpace {
                                    ForceRelativeUrls = false, Hostname = hostname
                                };
                                url = PageUrls.BuildUrl(new PageUrlData(page), UrlKind.Public, hostnameBasedUrlSpace);
                            }

                            if (url != null)
                            {
                                if (url.StartsWith("/"))
                                {
                                    url = "http://{0}{1}".FormatWith(hostname, url);
                                }

                                if (!result.ContainsKey(url))
                                {
                                    result.Add(url, page.Id);
                                }
                            }
                        }
                    }
                }
            }

            return(result);
        }
예제 #5
0
        private static string GetPagePreviewUrl(PageUrlData pageUrlData)
        {
            var urlSpace = new UrlSpace {
                ForceRelativeUrls = true
            };

            return(PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace)
                   ?? PageUrls.BuildUrl(pageUrlData, UrlKind.Renderer, urlSpace));
        }
        private static string RemoveUrlMarkers(string filePath, UrlSpace urlSpace)
        {
            if (urlSpace.ForceRelativeUrls && filePath.Contains(UrlMarker_RelativeUrl))
            {
                filePath = filePath.Replace(UrlMarker_RelativeUrl, string.Empty);
            }

            if (filePath == string.Empty)
            {
                filePath = "/";
            }

            return(filePath);
        }
        private string BuildPublicUrl(PageUrlData pageUrlData, UrlSpace urlSpace)
        {
            var cultureInfo      = pageUrlData.LocalizationScope;
            var publicationScope = pageUrlData.PublicationScope;

            var pageUrlPath = new StringBuilder();

            using (new DataScope(publicationScope, cultureInfo))
            {
                if (!BuildPageUrlPath(pageUrlData.PageId, cultureInfo, urlSpace, pageUrlPath))
                {
                    return(null);
                }
            }

            if (publicationScope == PublicationScope.Unpublished)
            {
                AppendUrlPart(pageUrlPath, UrlMarker_Unpublished);
            }

            if (urlSpace.ForceRelativeUrls)
            {
                AppendUrlPart(pageUrlPath, UrlMarker_RelativeUrl);
            }

            if (!string.IsNullOrEmpty(UrlSuffix) &&
                pageUrlPath[pageUrlPath.Length - 1] != '/')
            {
                pageUrlPath.Append(UrlSuffix);
            }

            if (!string.IsNullOrEmpty(pageUrlData.PathInfo))
            {
                AppendPathInfo(pageUrlPath, pageUrlData.PathInfo);
            }


            string url = pageUrlPath.ToString();

            if (pageUrlData.QueryParameters != null)
            {
                var urlWithQuery = new UrlBuilder(url);
                urlWithQuery.AddQueryParameters(pageUrlData.QueryParameters);

                return(urlWithQuery);
            }

            return(url);
        }
예제 #8
0
        private static string GetPagePreviewUrl(PageUrlData pageUrlData)
        {
            var httpContext = HttpContext.Current;

            var urlSpace = new UrlSpace();

            if (HostnameBindingsFacade.GetBindingForCurrentRequest() != null ||
                HostnameBindingsFacade.GetAliasBinding(httpContext) != null)
            {
                urlSpace.ForceRelativeUrls = true;
            }

            return(PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace)
                   ?? PageUrls.BuildUrl(pageUrlData, UrlKind.Renderer, urlSpace));
        }
예제 #9
0
        public PageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
        {
            _publicationScope  = publicationScope;
            _localizationScope = localizationScope;

            var localeMappedName = DataLocalizationFacade.GetUrlMappingName(localizationScope) ?? string.Empty;

            _forceRelativeUrls = urlSpace != null && urlSpace.ForceRelativeUrls;

            if (!_forceRelativeUrls &&
                urlSpace != null &&
                urlSpace.Hostname != null)
            {
                List <IHostnameBinding> hostnameBindings = DataFacade.GetData <IHostnameBinding>().ToList();

                _hostnameBinding = hostnameBindings.FirstOrDefault(b => b.Hostname == urlSpace.Hostname);

                bool knownHostname = _hostnameBinding != null;

                if (knownHostname)
                {
                    _hostnameBindings = hostnameBindings;

                    _urlSpace = urlSpace;
                }
            }

            if (_hostnameBinding != null &&
                !_hostnameBinding.IncludeCultureInUrl &&
                _hostnameBinding.Culture == localizationScope.Name)
            {
                _friendlyUrlPrefix = UrlUtils.PublicRootPath;

                if (!localeMappedName.IsNullOrEmpty())
                {
                    _friendlyUrlPrefixWithLanguageCode = UrlUtils.PublicRootPath + "/" + localeMappedName;
                }
            }
            else
            {
                _friendlyUrlPrefix = UrlUtils.PublicRootPath + (localeMappedName.IsNullOrEmpty() ? string.Empty : "/" + localeMappedName);
            }

            UrlSuffix = DataFacade.GetData <IUrlConfiguration>().Select(c => c.PageUrlSuffix).FirstOrDefault() ?? string.Empty;
        }
예제 #10
0
        public string ToPublicUrl(string internalPageUrl, UrlSpace urlSpace)
        {
            PageUrlData pageUrlData;
            string      anchor;

            try
            {
                anchor      = new UrlBuilder(internalPageUrl).Anchor;
                pageUrlData = PageUrls.UrlProvider.ParseInternalUrl(internalPageUrl);
            }
            catch
            {
                Log.LogWarning(LogTitle, "Failed to parse url '{0}'", internalPageUrl);
                return(null);
            }

            if (pageUrlData == null)
            {
                return(null);
            }

            // While viewing pages in "unpublished" scope, all the links should also be in the same scope
            if (DataScopeManager.CurrentDataScope == DataScopeIdentifier.Administrated)
            {
                pageUrlData.PublicationScope = PublicationScope.Unpublished;
            }

            string publicPageUrl = PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);

            if (publicPageUrl == null)
            {
                // We have this situation if page does not exist
                return(null);
            }

            if (!anchor.IsNullOrEmpty())
            {
                publicPageUrl += "#" + anchor;
            }

            return(publicPageUrl);
        }
예제 #11
0
        public string ToPublicUrl(string internalDataUrl, UrlSpace urlSpace)
        {
            object keyValue = ExtractKeyValue(internalDataUrl);

            if (keyValue == null)
            {
                return(null);
            }

            var data = DataFacade.TryGetDataByUniqueKey(_type, keyValue);

            if (data == null)
            {
                return(null);
            }

            var pageUrlData = DataUrls.TryGetPageUrlData(data.ToDataReference());

            return(pageUrlData != null?PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace) : null);
        }
예제 #12
0
        private static void RenderPage(IPage page)
        {
            var context = HttpContext.Current;

            if (context == null)
            {
                return;
            }

            var urlSpace = new UrlSpace(context)
            {
                ForceRelativeUrls = false
            };
            var url = PageUrls.BuildUrl(page, UrlKind.Public, urlSpace)
                      ?? PageUrls.BuildUrl(page, UrlKind.Renderer, urlSpace);

            if (string.IsNullOrEmpty(url))
            {
                return;
            }

            var    requestUrl = context.Request.Url;
            string hostName   = requestUrl.Host;

            if (!url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                string serverUrl = new UrlBuilder(requestUrl.ToString()).ServerUrl;

                url = UrlUtils.Combine(serverUrl, url);
            }

            string cookies = context.Request.Headers["Cookie"];

            string responseBody, errorMessage;
            var    result = RenderPage(hostName, url, cookies, out responseBody, out errorMessage);

            if (result != PageRenderingResult.Successful && Interlocked.Increment(ref _errorCounter) <= MaxRenderErrorsToLog)
            {
                Log.LogWarning(LogTitle, $"Failed to render page '{url}' with the goal of collecting dymanic url providers. Result: {result}; Error: {errorMessage}");
            }
        }
예제 #13
0
        private static void RenderPage(IPage page)
        {
            var context = HttpContext.Current;

            if (context == null)
            {
                return;
            }

            var urlSpace = new UrlSpace(context)
            {
                ForceRelativeUrls = true
            };
            var url = PageUrls.BuildUrl(page, UrlKind.Public, urlSpace)
                      ?? PageUrls.BuildUrl(page, UrlKind.Renderer, urlSpace);

            if (string.IsNullOrEmpty(url))
            {
                return;
            }

            var    requestUrl = context.Request.Url;
            string hostName   = requestUrl.Host;

            if (!url.StartsWith("http", StringComparison.InvariantCultureIgnoreCase))
            {
                string serverUrl = new UrlBuilder(requestUrl.ToString()).ServerUrl;

                url = UrlUtils.Combine(serverUrl, url);
            }

            string cookies = context.Request.Headers["Cookie"];

            string responseBody, errorMessage;
            var    result = RenderPage(hostName, url, cookies, out responseBody, out errorMessage);

            // TODO: log errors if any
        }
        public string ToPublicUrl(string internalDataUrl, UrlSpace urlSpace)
        {
            object keyValue = ExtractKeyValue(internalDataUrl);

            if (keyValue == null)
            {
                return(null);
            }

            var data = DataFacade.TryGetDataByUniqueKey(_type, keyValue);

            if (data == null)
            {
                return(null);
            }

            var pageUrlData = DataUrls.TryGetPageUrlData(data.ToDataReference());

            if (internalDataUrl.IndexOf("?", StringComparison.Ordinal) > 0)
            {
                var parameters = new UrlBuilder(internalDataUrl).GetQueryParameters();

                if (parameters.HasKeys())
                {
                    if (pageUrlData.QueryParameters == null)
                    {
                        pageUrlData.QueryParameters = parameters;
                    }
                    else
                    {
                        pageUrlData.QueryParameters.Add(parameters);
                    }
                }
            }

            return(pageUrlData != null?PageUrls.BuildUrl(pageUrlData, UrlKind.Public, urlSpace) : null);
        }
예제 #15
0
        public PageUrlData ParseUrl(string absoluteUrl, out UrlKind urlKind)
        {
            Verify.ArgumentNotNullOrEmpty(absoluteUrl, "absoluteUrl");

            // Converting links
            // "http://localhost" to "http://localhost/"
            // "http://localhost?..." to "http://localhost/?..."
            if ((absoluteUrl.Count(c => c == '/') == 2) && absoluteUrl.Contains("//"))
            {
                int questionMarkIndex = absoluteUrl.IndexOf('?');
                if (questionMarkIndex > 0)
                {
                    absoluteUrl = absoluteUrl.Insert(questionMarkIndex, "/");
                }
                else
                {
                    absoluteUrl += "/";
                }
            }

            Uri uri = new Uri(absoluteUrl);

            string hostname = uri.DnsSafeHost;

            if (!IsKnownHostname(hostname))
            {
                urlKind = UrlKind.Undefined;
                return(null);
            }

            string serverUrl   = new UrlBuilder(absoluteUrl).ServerUrl;
            string relativeUrl = absoluteUrl.Substring(serverUrl.Length - 1);

            var urlSpace = new UrlSpace(hostname, relativeUrl);

            return(ParseUrl(relativeUrl, urlSpace, out urlKind));
        }
예제 #16
0
        public string BuildUrl(PageUrlData pageUrlData, UrlKind urlKind, UrlSpace urlSpace)
        {
            Verify.ArgumentCondition(urlKind != UrlKind.Undefined, "urlKind", "Url kind is undefined");

            /*var page = pageUrlData.Data;
             * Verify.ArgumentCondition(page != null, "urlData", "Failed to get page from UrlData<IPage>");*/

            if (urlKind == UrlKind.Public)
            {
                return(BuildPublicUrl(pageUrlData, urlSpace));
            }

            if (urlKind == UrlKind.Renderer)
            {
                return(BuildRenderUrl(pageUrlData));
            }

            if (urlKind == UrlKind.Internal)
            {
                return(BuildInternalUrl(pageUrlData));
            }

            throw new NotImplementedException("Only 'Public' and 'Internal' url types are supported.");
        }
예제 #17
0
        private static Map BuildMap(UrlSpace urlSpace)
        {
            using (DebugLoggingScope.MethodInfoScope)
            {
                var publicationScope = DataScopeManager.CurrentDataScope.ToPublicationScope();
                var localizationScope = LocalizationScopeManager.CurrentLocalizationScope;

                Log.LogVerbose(LogTitle, string.Format("Building page structure in the publication scope '{0}' with the localization scope '{1}'", publicationScope, localizationScope));

                var urlToIdLookup = new Dictionary<string, Guid>();
                var idToUrlLookup = new Dictionary<Guid, string>();

                var pagesData = new SitemapBuildingData();

                var pageToToChildElementsTable = new Hashtable<Guid, List<PageTreeInfo>>();
                foreach (IPage page in pagesData.Pages)
                {
                    IPageStructure pageStructure = pagesData.StructureById[page.Id];

                    if (pageStructure == null)
                    {
                        Log.LogWarning(LogTitle, "Failed to find PageStructure data. Page ID is '{0}'".FormatWith(page.Id));
                        continue;
                    }

                    int localOrdering = pageStructure.LocalOrdering;

                    var pageElement = new XElement(ElementNames.Page,
                         new XAttribute(AttributeNames.Id, page.Id),
                         new XAttribute(AttributeNames.Title, page.Title),
                         (string.IsNullOrEmpty(page.MenuTitle) ? null : new XAttribute(AttributeNames.MenuTitle, page.MenuTitle)),
                         new XAttribute(AttributeNames.UrlTitle, page.UrlTitle),
                         new XAttribute(AttributeNames.Description, page.Description ?? string.Empty),
                         new XAttribute(AttributeNames.ChangedDate, page.ChangeDate),
                         new XAttribute(AttributeNames.ChangedBy, page.ChangedBy ?? string.Empty));

                    var list = pageToToChildElementsTable[pageStructure.ParentId];

                    if (list == null)
                    {
                        list = new List<PageTreeInfo>();
                        pageToToChildElementsTable[pageStructure.ParentId] = list;
                    }

                    list.Add(new PageTreeInfo
                    {
                        ID = page.Id,
                        LocalOrdering = localOrdering,
                        Element = pageElement
                    });
                }

                var root = new XElement("root");

                BuildXmlStructure(root, Guid.Empty, pageToToChildElementsTable, 100);

#pragma warning disable 612
                var pageUrlBuilder = PageUrls.UrlProvider.CreateUrlBuilder(publicationScope, localizationScope, urlSpace);
                BuildFolderPaths(pagesData, root.Elements(), pageUrlBuilder, urlToIdLookup);
#pragma warning restore 612

                foreach (var urlLookupEntry in urlToIdLookup)
                {
                    idToUrlLookup.Add(urlLookupEntry.Value, urlLookupEntry.Key);
                }

                var lowerCaseUrlToIdLookup = new Dictionary<string, Guid>();

                foreach (KeyValuePair<string, Guid> keyValuePair in urlToIdLookup)
                {
                    string loweredUrl = keyValuePair.Key.ToLowerInvariant();

                    if (lowerCaseUrlToIdLookup.ContainsKey(loweredUrl))
                    {
                        if (!_knownNotUniqueUrls.Contains(loweredUrl))
                        {
                            lock (_knownNotUniqueUrls)
                            {
                                _knownNotUniqueUrls.Add(loweredUrl);
                            }
                            Log.LogError(LogTitle, "Multiple pages share the same path '{0}'. Page ID: '{1}'. Duplicates are ignored.".FormatWith(loweredUrl, keyValuePair.Value));
                        }
                        
                        continue;
                    }

                    lowerCaseUrlToIdLookup.Add(loweredUrl, keyValuePair.Value);
                }

                return new Map
                           {
                               IdToUrlLookup = idToUrlLookup,
                               UrlToIdLookup = urlToIdLookup,
                               LowerCaseUrlToIdLookup = lowerCaseUrlToIdLookup,
                               RootPagesLookup = root.Elements(),
                               PageUrlBuilder = pageUrlBuilder
                           };
            }
        }
예제 #18
0
        public string ToPublicUrl(string internalMediaUrl, UrlSpace urlSpace)
        {
            int openBracketIndex = internalMediaUrl.IndexOf("(", StringComparison.Ordinal);

            if (openBracketIndex < 0)
            {
                return(null);
            }

            int closingBracketOffset = internalMediaUrl.IndexOf(")", openBracketIndex + 1, StringComparison.Ordinal);

            if (closingBracketOffset < 0)
            {
                return(null);
            }

            Guid mediaId;


            string mediaStore;
            string mediaIdStr = internalMediaUrl.Substring(openBracketIndex + 1, closingBracketOffset - openBracketIndex - 1);

            int semicolonOffset = mediaIdStr.IndexOf(":", StringComparison.Ordinal);

            if (semicolonOffset > 0)
            {
                mediaStore = mediaIdStr.Substring(0, semicolonOffset);
                mediaIdStr = mediaIdStr.Substring(semicolonOffset + 1);
            }
            else
            {
                mediaStore = DefaultMediaStore;
            }

            if (!Guid.TryParse(mediaIdStr, out mediaId))
            {
                return(null);
            }

            UrlBuilder parsedOldUrl;

            try
            {
                parsedOldUrl = new UrlBuilder(internalMediaUrl);
            }
            catch
            {
                Log.LogWarning(LogTitle, "Failed to parse url '{0}'".FormatWith(internalMediaUrl));
                return(null);
            }

            NameValueCollection queryParams = parsedOldUrl.GetQueryParameters();

            return(MediaUrls.BuildUrl(
                       new MediaUrlData
            {
                MediaId = mediaId,
                MediaStore = mediaStore,
                QueryParameters = queryParams
            },
                       UrlKind.Public));
        }
예제 #19
0
        /// <exclude />
        public override RouteData GetRouteData(HttpContextBase context)
        {
            if (!SystemSetupFacade.IsSystemFirstTimeInitialized)
            {
                return(null);
            }

            string localPath = context.Request.Url.LocalPath;

            var urlProvider = PageUrls.UrlProvider;

            if (UrlUtils.IsAdminConsoleRequest(localPath) || IsRenderersPath(localPath))
            {
                return(null);
            }

            string currentUrl = context.Request.Url.OriginalString;

            UrlKind urlKind;

            PageUrlData pageUrlData = urlProvider.ParseUrl(currentUrl, out urlKind);

            if (pageUrlData == null || urlKind == UrlKind.Renderer)
            {
                return(null);
            }

            var urlSpace = new UrlSpace(context);

            // Redirecting friendly urls to public urls
            if (urlKind == UrlKind.Friendly || urlKind == UrlKind.Redirect || urlKind == UrlKind.Internal)
            {
                if (pageUrlData.PathInfo == "/")
                {
                    pageUrlData.PathInfo = null;
                }

                string publicUrl = urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);
                if (publicUrl == null)
                {
                    if (urlKind != UrlKind.Internal)
                    {
                        return(null);
                    }
                    // Rendering internal url if public url is missing
                }
                else
                {
                    return(GetRedirectRoute(publicUrl));
                }
            }

            Verify.That(urlKind == UrlKind.Public || urlKind == UrlKind.Internal, "Unexpected url kind '{0}", urlKind);

            bool isPublicUrl = urlKind == UrlKind.Public;


            if (isPublicUrl)
            {
                // If url ends with a trailing slash - doing a redirect. F.e. http://localhost/a/ -> http://localhost/a
                if (pageUrlData.PathInfo == "/")
                {
                    pageUrlData.PathInfo = null;
                    return(GetRedirectRoute(urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace)));
                }

                // Checking casing in url, so the same page will not appear as a few pages by a crawler
                string correctUrl = urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);
                Verify.IsNotNull(correctUrl, "Failed to rebuild a public url from url '{0}'", currentUrl);

                string originalFilePath = new UrlBuilder(currentUrl).RelativeFilePath;
                string correctFilePath  = new UrlBuilder(correctUrl).RelativeFilePath;

                string decodedOriginalPath    = HttpUtility.UrlDecode(originalFilePath);
                string decodedCorrectFilePath = HttpUtility.UrlDecode(correctFilePath);

                if (!urlSpace.ForceRelativeUrls &&
                    (originalFilePath.Length != correctFilePath.Length &&
                     decodedOriginalPath != correctFilePath &&
                     decodedOriginalPath != decodedCorrectFilePath) ||
                    (string.Compare(originalFilePath, correctFilePath, false, CultureInfo.InvariantCulture) != 0 &&
                     string.Compare(originalFilePath, correctFilePath, true, CultureInfo.InvariantCulture) == 0) &&
                    decodedOriginalPath != decodedCorrectFilePath)
                {
                    // redirect to a url with right casing
                    return(GetRedirectRoute(correctUrl));
                }
            }

            // GetRouteData may be executed multiple times
            if (!context.Items.Contains(HttpContextItem_C1PageUrl))
            {
                PageUrlData = pageUrlData;
            }

            var data = new RouteData(this, new C1PageRouteHandler(pageUrlData));

            data.Values.Add(RouteData_PageUrl, pageUrlData);

            return(data);
        }
예제 #20
0
 public IPageUrlBuilder CreateUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
 {
     return(new PageUrlBuilder(publicationScope, localizationScope, urlSpace));
 }
예제 #21
0
        public PageUrlData ParseUrl(string relativeUrl, UrlSpace urlSpace, out UrlKind urlKind)
        {
            if (IsInternalUrl(relativeUrl))
            {
                return(ParseInternalUrl(relativeUrl, out urlKind));
            }

            var urlBuilder = new UrlBuilder(relativeUrl);

            // Structure of a public url:
            // http://<hostname>[/ApplicationVirtualPath]{/languageCode}[/Path to a page][/c1mode(unpublished)][/c1mode(relative)][UrlSuffix]{/PathInfo}


            string filePathAndPathInfo = HttpUtility.UrlDecode(urlBuilder.FullPath);

            filePathAndPathInfo = RemoveUrlMarkers(filePathAndPathInfo, urlSpace);

            string pathWithoutLanguageCode;

            IHostnameBinding hostnameBinding = urlSpace.ForceRelativeUrls ? null : GetHostnameBindings().FirstOrDefault(b => b.Hostname == urlSpace.Hostname);

            CultureInfo locale = GetCultureInfo(filePathAndPathInfo, hostnameBinding, out pathWithoutLanguageCode);

            if (locale == null)
            {
                urlKind = UrlKind.Undefined;
                return(null);
            }

            var publicationScope = PublicationScope.Published;

            if (filePathAndPathInfo.Contains(UrlMarker_Unpublished))
            {
                publicationScope = PublicationScope.Unpublished;

                pathWithoutLanguageCode = pathWithoutLanguageCode.Replace(UrlMarker_Unpublished, string.Empty);
                if (pathWithoutLanguageCode == string.Empty)
                {
                    pathWithoutLanguageCode = "/";
                }
            }

            using (new DataScope(publicationScope, locale))
            {
                bool   isObsolete    = false;
                string pathToResolve = pathWithoutLanguageCode;

                // Supporting obsolete "*.aspx" urls
                if (!string.Equals(UrlSuffix, ".aspx", StringComparison.OrdinalIgnoreCase) &&
                    (pathToResolve.Contains(".aspx/") || pathToResolve.EndsWith(".aspx")))
                {
                    pathToResolve = pathToResolve.Replace(".aspx", UrlSuffix);
                    isObsolete    = true;
                }

                PageUrlData data = ParsePagePath(pathToResolve, publicationScope, locale, hostnameBinding);
                if (data != null)
                {
                    urlKind = !isObsolete ? UrlKind.Public : UrlKind.Redirect;
                    data.QueryParameters = urlBuilder.GetQueryParameters();
                    return(data);
                }

                Guid friendlyUrlPageId = ParseFriendlyUrlPath(pathWithoutLanguageCode);
                if (friendlyUrlPageId != Guid.Empty)
                {
                    urlKind = UrlKind.Friendly;
                    return(new PageUrlData(friendlyUrlPageId, publicationScope, locale)
                    {
                        QueryParameters = urlBuilder.GetQueryParameters()
                    });
                }
            }

            urlKind = UrlKind.Undefined;
            return(null);
        }
예제 #22
0
        /// <exclude />
        public override RouteData GetRouteData(HttpContextBase context)
        {
            if (!SystemSetupFacade.IsSystemFirstTimeInitialized)
            {
                return null;
            }

            string localPath = context.Request.Url.LocalPath;

            var urlProvider = PageUrls.UrlProvider;

            if (UrlUtils.IsAdminConsoleRequest(localPath) || IsRenderersPath(localPath))
            {
                return null;
            }

            string currentUrl = context.Request.Url.OriginalString;

            UrlKind urlKind;

            PageUrlData pageUrlData = urlProvider.ParseUrl(currentUrl, out urlKind);
            if (pageUrlData == null || urlKind == UrlKind.Renderer)
            {
                return null;
            }

            var urlSpace = new UrlSpace(context);

            // Redirecting friendly urls to public urls
            if (urlKind == UrlKind.Friendly || urlKind == UrlKind.Redirect || urlKind == UrlKind.Internal)
            {
                if(pageUrlData.PathInfo == "/")
                {
                    pageUrlData.PathInfo = null;
                }

                string publicUrl = urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);
                if(publicUrl == null)
                {
                    if (urlKind != UrlKind.Internal)
                    {
                        return null;
                    }
                    // Rendering internal url if public url is missing
                }
                else
                {
                    return GetRedirectRoute(publicUrl);
                }
            }

            Verify.That(urlKind == UrlKind.Public || urlKind == UrlKind.Internal, "Unexpected url kind '{0}", urlKind);

            bool isPublicUrl = urlKind == UrlKind.Public;


            if (isPublicUrl)
            {
                // If url ends with a trailing slash - doing a redirect. F.e. http://localhost/a/ -> http://localhost/a
                if (pageUrlData.PathInfo == "/")
                {
                    pageUrlData.PathInfo = null;
                    return GetRedirectRoute(urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace));
                }

                // Checking casing in url, so the same page will not appear as a few pages by a crawler
                string correctUrl = urlProvider.BuildUrl(pageUrlData, UrlKind.Public, urlSpace);
                Verify.IsNotNull(correctUrl, "Failed to rebuild a public url from url '{0}'", currentUrl);

                string originalFilePath = new UrlBuilder(currentUrl).RelativeFilePath;
                string correctFilePath = new UrlBuilder(correctUrl).RelativeFilePath;

                string decodedOriginalPath = HttpUtility.UrlDecode(originalFilePath);
                string decodedCorrectFilePath = HttpUtility.UrlDecode(correctFilePath);

                if (!urlSpace.ForceRelativeUrls 
                    && (originalFilePath.Length != correctFilePath.Length
                        && decodedOriginalPath != correctFilePath
                        && decodedOriginalPath != decodedCorrectFilePath)
                    || (string.Compare(originalFilePath, correctFilePath, false, CultureInfo.InvariantCulture) != 0 
                        && string.Compare(originalFilePath, correctFilePath, true, CultureInfo.InvariantCulture) == 0)
                        && decodedOriginalPath != decodedCorrectFilePath)
                {
                    // redirect to a url with right casing
                    return GetRedirectRoute(correctUrl);
                }
            }

            // GetRouteData may be executed multiple times
            if (!context.Items.Contains(HttpContextItem_C1PageUrl))
            {
                PageUrlData = pageUrlData;
            }

            var data = new RouteData(this, new C1PageRouteHandler(pageUrlData));
            data.Values.Add(RouteData_PageUrl, pageUrlData);

            return data;
        }
예제 #23
0
        private static Map GetMap(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
        {
            Verify.ArgumentNotNull(localizationScope, "localizationScope");
            Verify.ArgumentNotNull(urlSpace, "urlSpace");

            if (System.Transactions.Transaction.Current != null)
            {
                var exceptionToLog = new Exception("It is not safe to use PageStructureInfo/SiteMap functionality in transactional context. Method Composite.Data.PageManager can be used instead.");
                Log.LogWarning(typeof(PageStructureInfo).Name, exceptionToLog);
            }

            var scopeKey = GetScopeKey(publicationScope, localizationScope, urlSpace);
            Map map = _generatedMaps[scopeKey];

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

            // Using different sync roots for different datascopes
            //object buildingLock = _buildingLock[scopeKey.First == DataScopeIdentifier.Public.Name ? 0 : 1];

            // NOTE: Do not using a lock because it could because GetAssociatedPageIds is used inside transactions on some sites and it causes deadlocks 

            // lock (buildingLock)
            {
                map = _generatedMaps[scopeKey];
                if (map != null)
                {
                    return map;
                }


                Version version = _versions[scopeKey];
                if (version == null)
                {
                    lock (_updatingLock)
                    {
                        version = _versions[scopeKey];
                        if (version == null)
                        {
                            _versions.Add(scopeKey, version = new Version());
                        }
                    }
                }

                Thread.MemoryBarrier();
                int currentVersion = version.VersionNumber;
                Thread.MemoryBarrier();

                using(new DataScope(publicationScope, localizationScope))
                {
                    map = BuildMap(urlSpace);
                }

                lock (_updatingLock)
                {
                    if (_versions[scopeKey].VersionNumber == currentVersion)
                    {
                        _generatedMaps.Remove(scopeKey);
                        _generatedMaps.Add(scopeKey, map);
                    }
                }

                return map;
            }
        }
예제 #24
0
        private static Tuple<PublicationScope, string, string> GetScopeKey(PublicationScope publicationScope, CultureInfo cultureInfo, UrlSpace urlSpace)
        {
            string hostnameScopeKey = urlSpace.ForceRelativeUrls ? "relative urls" : urlSpace.Hostname;

            return new Tuple<PublicationScope, string, string>(publicationScope, cultureInfo.Name, hostnameScopeKey);
        }
예제 #25
0
 public static IPageUrlBuilder GetPageUrlBuilder(PublicationScope publicationScope, CultureInfo localizationScope, UrlSpace urlSpace)
 {
     return GetMap(publicationScope, localizationScope, urlSpace).PageUrlBuilder;
 }