diff --git a/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs new file mode 100644 index 0000000000..52bb68d6ec --- /dev/null +++ b/src/Umbraco.Web/Routing/ContentFinderByLegacy404.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; + +using umbraco; +using umbraco.interfaces; + +namespace Umbraco.Web.Routing +{ + /// + /// Provides an implementation of that runs the legacy 404 logic. + /// + /// Should be used as a last chance finder. + internal class ContentFinderByLegacy404 : IContentFinder + { + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TryFindDocument(PublishedContentRequest pcr) + { + LogHelper.Debug("Looking for a page to handler 404."); + + var error404 = global::umbraco.library.GetCurrentNotFoundPageId(); + var id = int.Parse(error404); + + IPublishedContent content = null; + + if (id > 0) + { + LogHelper.Debug("Got id={1}.", () => id); + + content = pcr.RoutingContext.PublishedContentStore.GetDocumentById( + pcr.RoutingContext.UmbracoContext, + id); + + if (content == null) + LogHelper.Debug("Could not find content with that id."); + else + LogHelper.Debug("Found corresponding content."); + } + else + { + LogHelper.Debug("Got nothing."); + } + + pcr.PublishedContent = content; + return content != null; + } + } +} diff --git a/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandler.cs b/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandler.cs new file mode 100644 index 0000000000..019c16e95b --- /dev/null +++ b/src/Umbraco.Web/Routing/ContentFinderByNotFoundHandler.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; + +using Umbraco.Core; +using Umbraco.Core.Logging; +using Umbraco.Core.Models; + +using umbraco; +using umbraco.interfaces; + +namespace Umbraco.Web.Routing +{ + /// + /// Provides an implementation of that runs a legacy NotFoundHandler. + /// + /// Provided for backward compatibility. + internal class ContentFinderByNotFoundHandler : IContentFinder + { + /// + /// Tries to find and assign an Umbraco document to a PublishedContentRequest. + /// + /// The PublishedContentRequest. + /// A value indicating whether an Umbraco document was found and assigned. + public bool TryFindDocument(PublishedContentRequest pcr) + { + var type = typeof(Thandler); + var handler = GetHandler(type); + + if (handler == null) + return false; + + var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); + + if (handler.Execute(url) && handler.redirectID > 0) + { + LogHelper.Debug>("Handler '{0}' returned id={1}.", () => type.FullName, () => handler.redirectID); + + var content = pcr.RoutingContext.PublishedContentStore.GetDocumentById( + pcr.RoutingContext.UmbracoContext, + handler.redirectID); + + if (content == null) + LogHelper.Debug>("Could not find content with that id."); + else + LogHelper.Debug>("Found corresponding content."); + + pcr.PublishedContent = content; + return content != null; + } + else + { + LogHelper.Debug>("Handler '{0}' returned nothing.", () => type.FullName); + return false; + } + } + + INotFoundHandler GetHandler(Type type) + { + try + { + return Activator.CreateInstance(type) as INotFoundHandler; + } + catch (Exception e) + { + LogHelper.Error>(string.Format("Error instanciating handler {0}, ignoring.", type.FullName), e); + return null; + } + } + } +} diff --git a/src/Umbraco.Web/Routing/ContentFinderByProfile.cs b/src/Umbraco.Web/Routing/ContentFinderByProfile.cs index 3722e9005e..e842e5939e 100644 --- a/src/Umbraco.Web/Routing/ContentFinderByProfile.cs +++ b/src/Umbraco.Web/Routing/ContentFinderByProfile.cs @@ -15,7 +15,6 @@ namespace Umbraco.Web.Routing /// This should rather be done with a rewriting rule. There would be multiple profile pages in multi-sites/multi-langs setups. /// We keep it for backward compatility reasons. /// - //[ResolutionWeight(40)] internal class ContentFinderByProfile : ContentFinderByNiceUrl { /// diff --git a/src/Umbraco.Web/Routing/ContentLastChanceFinder.cs b/src/Umbraco.Web/Routing/ContentLastChanceFinder.cs index 9294c772e2..e8d5d90b15 100644 --- a/src/Umbraco.Web/Routing/ContentLastChanceFinder.cs +++ b/src/Umbraco.Web/Routing/ContentLastChanceFinder.cs @@ -47,62 +47,13 @@ namespace Umbraco.Web.Routing //FIXME: this is temporary and should be obsoleted - string GetLegacyUrlForNotFoundHandlers(PublishedContentRequest docRequest) - { - // that's not backward-compatible because when requesting "/foo.aspx" - // 4.9 : url = "foo.aspx" - // 4.10 : url = "/foo" - //return docRequest.Uri.AbsolutePath; - - // so we have to run the legacy code for url preparation :-( - - // code from requestModule.UmbracoRewrite - string tmp = HttpContext.Current.Request.Path.ToLower(); - - // note: requestModule.UmbracoRewrite also does some confusing stuff - // with stripping &umbPage from the querystring?! ignored. - - // code from requestHandler.cleanUrl - string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); - if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) - tmp = tmp.Substring(root.Length); - tmp = tmp.TrimEnd('/'); - if (tmp == "/default.aspx") - tmp = string.Empty; - else if (tmp == root) - tmp = string.Empty; - - // code from UmbracoDefault.Page_PreInit - if (tmp != "" && HttpContext.Current.Request["umbPageID"] == null) - { - string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); - int result; - if (int.TryParse(tryIntParse, out result)) - tmp = tmp.Replace(".aspx", string.Empty); - } - else if (!string.IsNullOrEmpty(HttpContext.Current.Request["umbPageID"])) - { - int result; - if (int.TryParse(HttpContext.Current.Request["umbPageID"], out result)) - { - tmp = HttpContext.Current.Request["umbPageID"]; - } - } - - // code from requestHandler.ctor - if (tmp != "") - tmp = tmp.Substring(1); - - return tmp; - } - IPublishedContent HandlePageNotFound(PublishedContentRequest docRequest) { LogHelper.Debug("Running for url='{0}'.", () => docRequest.Uri.AbsolutePath); //XmlNode currentPage = null; IPublishedContent currentPage = null; - var url = GetLegacyUrlForNotFoundHandlers(docRequest); + var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers(); foreach (var handler in GetNotFoundHandlers()) { @@ -165,7 +116,7 @@ namespace Umbraco.Web.Routing if (assemblyName == "umbraco" && (ns + "." + typeName) != "umbraco.handle404") { - // skip those that are in umbraco.dll because we have replaced them with IDocumentLookups + // skip those that are in umbraco.dll because we have replaced them with IContentFinder // but do not skip "handle404" as that's the built-in legacy final handler, and for the time // being people will have it in their config. continue; diff --git a/src/Umbraco.Web/Routing/IContentFinder.cs b/src/Umbraco.Web/Routing/IContentFinder.cs index 34d5c959d9..d9d70c5edd 100644 --- a/src/Umbraco.Web/Routing/IContentFinder.cs +++ b/src/Umbraco.Web/Routing/IContentFinder.cs @@ -11,6 +11,6 @@ namespace Umbraco.Web.Routing /// The PublishedContentRequest. /// A value indicating whether an Umbraco document was found and assigned. /// Optionally, can also assign the template or anything else on the document request, although that is not required. - bool TryFindDocument(PublishedContentRequest docRequest); + bool TryFindDocument(PublishedContentRequest contentRequest); } } \ No newline at end of file diff --git a/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs new file mode 100644 index 0000000000..8ce6a864a2 --- /dev/null +++ b/src/Umbraco.Web/Routing/NotFoundHandlerHelper.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Web; + +namespace Umbraco.Web.Routing +{ + // provides internal access to legacy url -- should get rid of it eventually + internal static class NotFoundHandlerHelper + { + const string ContextKey = "Umbraco.Web.Routing.NotFoundHandlerHelper.Url"; + + public static string GetLegacyUrlForNotFoundHandlers() + { + // that's not backward-compatible because when requesting "/foo.aspx" + // 4.9 : url = "foo.aspx" + // 4.10 : url = "/foo" + //return pcr.Uri.AbsolutePath; + + // so we have to run the legacy code for url preparation :-( + + var httpContext = HttpContext.Current; + + if (httpContext == null) + return ""; + + var url = httpContext.Items[ContextKey] as string; + if (url != null) + return url; + + // code from requestModule.UmbracoRewrite + string tmp = httpContext.Request.Path.ToLower(); + + // note: requestModule.UmbracoRewrite also does some confusing stuff + // with stripping &umbPage from the querystring?! ignored. + + // code from requestHandler.cleanUrl + string root = Umbraco.Core.IO.SystemDirectories.Root.ToLower(); + if (!string.IsNullOrEmpty(root) && tmp.StartsWith(root)) + tmp = tmp.Substring(root.Length); + tmp = tmp.TrimEnd('/'); + if (tmp == "/default.aspx") + tmp = string.Empty; + else if (tmp == root) + tmp = string.Empty; + + // code from UmbracoDefault.Page_PreInit + if (tmp != "" && httpContext.Request["umbPageID"] == null) + { + string tryIntParse = tmp.Replace("/", "").Replace(".aspx", string.Empty); + int result; + if (int.TryParse(tryIntParse, out result)) + tmp = tmp.Replace(".aspx", string.Empty); + } + else if (!string.IsNullOrEmpty(httpContext.Request["umbPageID"])) + { + int result; + if (int.TryParse(httpContext.Request["umbPageID"], out result)) + { + tmp = httpContext.Request["umbPageID"]; + } + } + + // code from requestHandler.ctor + if (tmp != "") + tmp = tmp.Substring(1); + + httpContext.Items[ContextKey] = tmp; + return tmp; + } + } +} diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 89aa20aafc..6ef4b120ba 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -325,8 +325,11 @@ + + +