diff --git a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs
index 2b9f05681a..975ab16cbf 100644
--- a/src/Umbraco.Tests/Routing/LookupByAliasTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByAliasTests.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Tests.Routing
public void Lookup_By_Url_Alias(string urlAsString, int nodeMatch)
{
var routingContext = GetRoutingContext(urlAsString);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docRequest = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByAlias();
diff --git a/src/Umbraco.Tests/Routing/LookupByIdTests.cs b/src/Umbraco.Tests/Routing/LookupByIdTests.cs
index 0432c7ac9b..9c9078daff 100644
--- a/src/Umbraco.Tests/Routing/LookupByIdTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByIdTests.cs
@@ -22,7 +22,7 @@ namespace Umbraco.Tests.Routing
public void Lookup_By_Id(string urlAsString, int nodeMatch)
{
var routingContext = GetRoutingContext(urlAsString);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docRequest = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByIdPath();
diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs
index fea585627a..72ad748283 100644
--- a/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlAndTemplateTests.cs
@@ -25,7 +25,7 @@ namespace Umbraco.Tests.Routing
var template = Template.MakeNew("test", new User(0));
var altTemplate = Template.MakeNew("blah", new User(0));
var routingContext = GetRoutingContext(urlAsString, template);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docRequest = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByNiceUrlAndTemplate();
diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs
index 0ff27ddce6..8cd7c1fd3e 100644
--- a/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlTests.cs
@@ -39,7 +39,7 @@ namespace Umbraco.Tests.Routing
public void Match_Document_By_Url_Hide_Top_Level(string urlString, int expectedId)
{
var routingContext = GetRoutingContext(urlString);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docreq = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByNiceUrl();
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
@@ -66,7 +66,7 @@ namespace Umbraco.Tests.Routing
public void Match_Document_By_Url(string urlString, int expectedId)
{
var routingContext = GetRoutingContext(urlString);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docreq = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByNiceUrl();
diff --git a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs
index 123992b81f..9a0e708b32 100644
--- a/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByNiceUrlWithDomainsTests.cs
@@ -157,7 +157,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
var routingContext = GetRoutingContext(url);
- var uri = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docreq = new PublishedContentRequest(uri, routingContext);
// must lookup domain else lookup by url fails
@@ -196,7 +196,7 @@ namespace Umbraco.Tests.Routing
ConfigurationManager.AppSettings.Set("umbracoHideTopLevelNodeFromPath", "true");
var routingContext = GetRoutingContext(url);
- var uri = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docreq = new PublishedContentRequest(uri, routingContext);
// must lookup domain else lookup by url fails
diff --git a/src/Umbraco.Tests/Routing/LookupByPageIdQueryTests.cs b/src/Umbraco.Tests/Routing/LookupByPageIdQueryTests.cs
index 43a490e2a5..00ec7a0565 100644
--- a/src/Umbraco.Tests/Routing/LookupByPageIdQueryTests.cs
+++ b/src/Umbraco.Tests/Routing/LookupByPageIdQueryTests.cs
@@ -26,7 +26,7 @@ namespace Umbraco.Tests.Routing
public void Lookup_By_Page_Id(string urlAsString, int nodeMatch)
{
var routingContext = GetRoutingContext(urlAsString);
- var url = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docRequest = new PublishedContentRequest(url, routingContext);
var lookup = new LookupByPageIdQuery();
diff --git a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
index 7ce816644c..306a02bb5b 100644
--- a/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
+++ b/src/Umbraco.Tests/Routing/RenderRouteHandlerTests.cs
@@ -50,13 +50,13 @@ namespace Umbraco.Tests.Routing
var route = RouteTable.Routes["Umbraco_default"];
var routeData = new RouteData() { Route = route };
var routingContext = GetRoutingContext("~/dummy-page", template, routeData);
- var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.UmbracoUrl, routingContext)
+ var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.CleanedUmbracoUrl, routingContext)
{
PublishedContent = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1174),
Template = template
};
- var handler = new RenderRouteHandler(new TestControllerFactory());
+ var handler = new RenderRouteHandler(new TestControllerFactory(), routingContext.UmbracoContext);
handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest);
Assert.AreEqual("RenderMvc", routeData.Values["controller"].ToString());
@@ -74,13 +74,13 @@ namespace Umbraco.Tests.Routing
var route = RouteTable.Routes["Umbraco_default"];
var routeData = new RouteData() {Route = route};
var routingContext = GetRoutingContext("~/dummy-page", template, routeData);
- var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.UmbracoUrl, routingContext)
+ var docRequest = new PublishedContentRequest(routingContext.UmbracoContext.CleanedUmbracoUrl, routingContext)
{
PublishedContent = routingContext.PublishedContentStore.GetDocumentById(routingContext.UmbracoContext, 1172),
Template = template
};
- var handler = new RenderRouteHandler(new TestControllerFactory());
+ var handler = new RenderRouteHandler(new TestControllerFactory(), routingContext.UmbracoContext);
handler.GetHandlerForRoute(routingContext.UmbracoContext.HttpContext.Request.RequestContext, docRequest);
Assert.AreEqual("CustomDocument", routeData.Values["controller"].ToString());
diff --git a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
index e503f1f71a..c00e97eb15 100644
--- a/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
+++ b/src/Umbraco.Tests/Routing/UmbracoModuleTests.cs
@@ -1,17 +1,47 @@
using System;
using System.Configuration;
using System.IO;
+using System.Threading;
using System.Xml;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
+using Umbraco.Web.Routing;
+using umbraco.BusinessLogic;
using umbraco.IO;
using umbraco.cms.businesslogic.cache;
using umbraco.cms.businesslogic.template;
namespace Umbraco.Tests.Routing
{
+ [TestFixture, RequiresSTA]
+ public class PublishedContentRequestBuilderTests : BaseRoutingTest
+ {
+
+ //[Test]
+ //public void Alt_Template()
+ //{
+ // var template = Template.MakeNew("test", new User(0));
+ // var altTemplate = Template.MakeNew("alt", new User(0));
+ // var umbracoContext = GetUmbracoContext("/home?altTemplate=" + altTemplate.Alias, template.Id);
+ // // create the new document request since we're rendering a document on the front-end
+ // var docreq = PublishedContentRequest.CreateForFrontEndRequest(umbracoContext);
+
+ // //create the searcher
+ // var searcher = new PublishedContentRequestBuilder(docreq);
+ // //find domain
+ // searcher.LookupDomain();
+ // // redirect if it has been flagged
+ // Assert.IsFalse(docreq.IsRedirect);
+
+ // //find the document, found will be true if the doc request has found BOTH a node and a template
+ // var found = searcher.LookupDocument();
+
+ //}
+
+ }
+
[TestFixture, RequiresSTA]
public class UmbracoModuleTests : BaseRoutingTest
{
diff --git a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs
index 7f4b68d2bd..cf35c429d7 100644
--- a/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs
+++ b/src/Umbraco.Tests/Routing/UrlsWithNestedDomains.cs
@@ -42,7 +42,7 @@ namespace Umbraco.Tests.Routing
// route a rogue url
url = "http://domain1.com/1001-1/1001-1-1";
- var uri = routingContext.UmbracoContext.UmbracoUrl; //very important to use the cleaned up umbraco url
+ var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
var docreq = new PublishedContentRequest(uri, routingContext);
var builder = new PublishedContentRequestBuilder(docreq);
builder.LookupDomain();
diff --git a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
index 30b036685f..0303609a5b 100644
--- a/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
+++ b/src/Umbraco.Web/HtmlHelperRenderExtensions.cs
@@ -337,7 +337,7 @@ namespace Umbraco.Web
Mandate.ParameterNotNullOrEmpty(action, "action");
Mandate.ParameterNotNullOrEmpty(controllerName, "controllerName");
- var formAction = UmbracoContext.Current.RequestUrl.ToString();
+ var formAction = UmbracoContext.Current.OriginalRequestUrl.ToString();
return html.RenderForm(formAction, FormMethod.Post, htmlAttributes, controllerName, action, area, additionalRouteVals);
}
diff --git a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs
index a6fda62175..f0ae3607a6 100644
--- a/src/Umbraco.Web/Mvc/RenderRouteHandler.cs
+++ b/src/Umbraco.Web/Mvc/RenderRouteHandler.cs
@@ -18,10 +18,33 @@ namespace Umbraco.Web.Mvc
public RenderRouteHandler(IControllerFactory controllerFactory)
{
+ if (controllerFactory == null) throw new ArgumentNullException("controllerFactory");
_controllerFactory = controllerFactory;
}
+ ///
+ /// Contructor generally used for unit testing
+ ///
+ ///
+ ///
+ internal RenderRouteHandler(IControllerFactory controllerFactory, UmbracoContext umbracoContext)
+ {
+ if (controllerFactory == null) throw new ArgumentNullException("controllerFactory");
+ if (umbracoContext == null) throw new ArgumentNullException("umbracoContext");
+ _controllerFactory = controllerFactory;
+ _umbracoContext = umbracoContext;
+ }
+
private readonly IControllerFactory _controllerFactory;
+ private readonly UmbracoContext _umbracoContext;
+
+ ///
+ /// Returns the current UmbracoContext
+ ///
+ public UmbracoContext UmbracoContext
+ {
+ get { return _umbracoContext ?? UmbracoContext.Current; }
+ }
#region IRouteHandler Members
@@ -33,11 +56,11 @@ namespace Umbraco.Web.Mvc
///
public IHttpHandler GetHttpHandler(RequestContext requestContext)
{
- if (UmbracoContext.Current == null)
- {
+ if (UmbracoContext == null)
+ {
throw new NullReferenceException("There is not current UmbracoContext, it must be initialized before the RenderRouteHandler executes");
}
- var docRequest = UmbracoContext.Current.PublishedContentRequest;
+ var docRequest = UmbracoContext.PublishedContentRequest;
if (docRequest == null)
{
throw new NullReferenceException("There is not current PublishedContentRequest, it must be initialized before the RenderRouteHandler executes");
@@ -52,7 +75,7 @@ namespace Umbraco.Web.Mvc
//put essential data into the data tokens, the 'umbraco' key is required to be there for the view engine
requestContext.RouteData.DataTokens.Add("umbraco", renderModel); //required for the RenderModelBinder
requestContext.RouteData.DataTokens.Add("umbraco-doc-request", docRequest); //required for RenderMvcController
- requestContext.RouteData.DataTokens.Add("umbraco-context", UmbracoContext.Current); //required for UmbracoTemplatePage
+ requestContext.RouteData.DataTokens.Add("umbraco-context", UmbracoContext); //required for UmbracoTemplatePage
return GetHandlerForRoute(requestContext, docRequest);
@@ -256,6 +279,11 @@ namespace Umbraco.Web.Mvc
{
requestContext.RouteData.Values["action"] = routeDef.ActionName;
}
+
+ // reset the friendly path so in the controllers and anything occuring after this point in time,
+ //the URL is reset back to the original request.
+ requestContext.HttpContext.RewritePath(UmbracoContext.OriginalRequestUrl.PathAndQuery);
+
return new MvcHandler(requestContext);
}
}
diff --git a/src/Umbraco.Web/Routing/NiceUrlProvider.cs b/src/Umbraco.Web/Routing/NiceUrlProvider.cs
index b11bd4ae26..4bf2df22a1 100644
--- a/src/Umbraco.Web/Routing/NiceUrlProvider.cs
+++ b/src/Umbraco.Web/Routing/NiceUrlProvider.cs
@@ -48,7 +48,7 @@ namespace Umbraco.Web.Routing
public string GetNiceUrl(int nodeId)
{
var absolute = UmbracoSettings.UseDomainPrefixes || this.EnforceAbsoluteUrls;
- return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
+ return GetNiceUrl(nodeId, _umbracoContext.CleanedUmbracoUrl, absolute);
}
///
@@ -60,7 +60,7 @@ namespace Umbraco.Web.Routing
/// The url is absolute or relative depending on the current url, unless absolute is true, in which case the url is always absolute.
public string GetNiceUrl(int nodeId, bool absolute)
{
- return GetNiceUrl(nodeId, _umbracoContext.UmbracoUrl, absolute);
+ return GetNiceUrl(nodeId, _umbracoContext.CleanedUmbracoUrl, absolute);
}
///
@@ -145,7 +145,7 @@ namespace Umbraco.Web.Routing
public IEnumerable GetAllAbsoluteNiceUrls(int nodeId)
{
- return GetAllAbsoluteNiceUrls(nodeId, _umbracoContext.UmbracoUrl);
+ return GetAllAbsoluteNiceUrls(nodeId, _umbracoContext.CleanedUmbracoUrl);
}
///
diff --git a/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs b/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs
index cda85667a2..1259b22fdb 100644
--- a/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs
+++ b/src/Umbraco.Web/Routing/PublishedContentNotFoundHandler.cs
@@ -27,7 +27,7 @@ namespace Umbraco.Web.Routing
response.Write("Page not found
");
response.Write("");
- response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.ClientUrl)));
+ response.Write(string.Format(reason, HttpUtility.HtmlEncode(UmbracoContext.Current.OriginalRequestUrl)));
response.Write("
This page can be replaced with a custom 404. Check the documentation for \"custom 404\".
");
response.Write("This page is intentionally left ugly ;-)
");
diff --git a/src/Umbraco.Web/Routing/PublishedContentRequest.cs b/src/Umbraco.Web/Routing/PublishedContentRequest.cs
index 3d4918d396..d3bfd1e0ef 100644
--- a/src/Umbraco.Web/Routing/PublishedContentRequest.cs
+++ b/src/Umbraco.Web/Routing/PublishedContentRequest.cs
@@ -1,6 +1,8 @@
using System;
using System.Linq;
using System.Text;
+using System.Threading;
+using System.Web;
using System.Xml;
using System.Globalization;
using System.Diagnostics;
@@ -25,10 +27,108 @@ namespace Umbraco.Web.Routing
///
internal class PublishedContentRequest
{
+
+ ///
+ /// This creates a PublishedContentRequest and assigns it to the current HttpContext and then proceeds to
+ /// process the request using the PublishedContentRequestBuilder. If everything is successful, the callback
+ /// method will be called.
+ ///
+ ///
+ ///
+ ///
+ ///
+ internal static void ProcessRequest(HttpContextBase httpContext, UmbracoContext umbracoContext, Uri uri, Action onSuccess)
+ {
+ if (umbracoContext == null)
+ throw new NullReferenceException("The UmbracoContext.Current is null, ProcessRequest cannot proceed unless there is a current UmbracoContext");
+ if (uri == null) throw new ArgumentNullException("uri");
+ if (umbracoContext.RoutingContext == null)
+ throw new NullReferenceException("The UmbracoContext.RoutingContext has not been assigned, ProcessRequest cannot proceed unless there is a RoutingContext assigned to the UmbracoContext");
+
+ var docreq = new PublishedContentRequest(uri, umbracoContext.RoutingContext);
+ //assign back since this is a front-end request
+ umbracoContext.PublishedContentRequest = docreq;
+
+ // note - at that point the original legacy module did something do handle IIS custom 404 errors
+ // ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support
+ // "directory urls" without having to do wildcard mapping to ASP.NET on old IIS. This is a pain
+ // to maintain and probably not used anymore - removed as of 06/2012. @zpqrtbnk.
+ //
+ // to trigger Umbraco's not-found, one should configure IIS and/or ASP.NET custom 404 errors
+ // so that they point to a non-existing page eg /redirect-404.aspx
+ // TODO: SD: We need more information on this for when we release 4.10.0 as I'm not sure what this means.
+
+ //create the searcher
+ var searcher = new PublishedContentRequestBuilder(docreq);
+ //find domain
+ searcher.LookupDomain();
+ // redirect if it has been flagged
+ if (docreq.IsRedirect)
+ httpContext.Response.Redirect(docreq.RedirectUrl, true);
+ //set the culture on the thread
+ Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = docreq.Culture;
+ //find the document, found will be true if the doc request has found BOTH a node and a template
+ // though currently we don't use this value.
+ var found = searcher.LookupDocument();
+ //this could be called in the LookupDocument method, but I've just put it here for clarity.
+ searcher.DetermineRenderingEngine();
+
+ //TODO: here we should launch an event so that people can modify the doc request to do whatever they want.
+
+ // redirect if it has been flagged
+ if (docreq.IsRedirect)
+ httpContext.Response.Redirect(docreq.RedirectUrl, true);
+
+ // handle 404
+ if (docreq.Is404)
+ {
+ httpContext.Response.StatusCode = 404;
+
+ if (!docreq.HasNode)
+ {
+ httpContext.RemapHandler(new PublishedContentNotFoundHandler());
+ return;
+ }
+
+ // else we have a document to render
+ // not having a template is ok here, MVC will take care of it
+ }
+
+ // just be safe - should never ever happen
+ if (!docreq.HasNode)
+ throw new Exception("No document to render.");
+
+ // render even though we might have no template
+ // to give MVC a chance to hijack routes
+ // pass off to our handlers (mvc or webforms)
+
+ // assign the legacy page back to the docrequest
+ // handlers like default.aspx will want it and most macros currently need it
+ docreq.UmbracoPage = new page(docreq);
+
+ // these two are used by many legacy objects
+ httpContext.Items["pageID"] = docreq.DocumentId;
+ httpContext.Items["pageElements"] = docreq.UmbracoPage.Elements;
+
+ if (onSuccess != null)
+ onSuccess(docreq);
+ }
+
+
+ ///
+ /// Create a content request for a specific URL
+ ///
+ ///
+ ///
public PublishedContentRequest(Uri uri, RoutingContext routingContext)
{
+ if (uri == null) throw new ArgumentNullException("uri");
+ if (routingContext == null) throw new ArgumentNullException("routingContext");
+
this.Uri = uri;
RoutingContext = routingContext;
+
+ //set default
RenderingEngine = RenderingEngine.Mvc;
}
diff --git a/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs b/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs
index e8cfbd856b..4c0b61214d 100644
--- a/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs
+++ b/src/Umbraco.Web/Routing/PublishedContentRequestBuilder.cs
@@ -100,7 +100,7 @@ namespace Umbraco.Web.Routing
LogHelper.Debug("{0}Uri=\"{1}\"", () => tracePrefix, () => _publishedContentRequest.Uri);
// try to find a domain matching the current request
- var domainAndUri = DomainHelper.DomainMatch(Domain.GetDomains(), _umbracoContext.UmbracoUrl, false);
+ var domainAndUri = DomainHelper.DomainMatch(Domain.GetDomains(), _umbracoContext.CleanedUmbracoUrl, false);
// handle domain
if (domainAndUri != null)
diff --git a/src/Umbraco.Web/UmbracoContext.cs b/src/Umbraco.Web/UmbracoContext.cs
index a0ff73230b..caa62575a9 100644
--- a/src/Umbraco.Web/UmbracoContext.cs
+++ b/src/Umbraco.Web/UmbracoContext.cs
@@ -51,21 +51,12 @@ namespace Umbraco.Web
Application = applicationContext;
RoutesCache = routesCache;
- // set the urls
- this.RequestUrl = httpContext.Request.Url;
- //RawUrl gets preserved across rewrites
- this.ClientUrl = UriUtility.ToFullUrl(httpContext.Request.RawUrl, httpContext);
-
- //// from IIS Rewrite Module documentation:
- //// "The URL Rewrite Module preserves the original requested URL path in the following server variables:
- //// - HTTP_X_ORIGINAL_URL – this server variable contains the original URL in decoded format;
- //// - UNENCODED_URL – this server variable contains the original URL exactly as it was requested by a Web client, with all original encoding preserved."
- ////
- //// see also http://forums.iis.net/t/1152581.aspx
- ////
- //var iisOrig = httpContext.Request.ServerVariables["HTTP_X_ORIGINAL_URL"];
- //if (!string.IsNullOrWhiteSpace(iisOrig))
- // this.ClientUrl = new Uri(iisOrig);
+ // set the urls...
+ //original request url
+ this.OriginalRequestUrl = httpContext.Request.Url;
+ //cleaned request url
+ this.CleanedUmbracoUrl = UriUtility.UriToUmbraco(this.OriginalRequestUrl);
+
}
///
@@ -114,35 +105,17 @@ namespace Umbraco.Web
public ApplicationContext Application { get; private set; }
internal IRoutesCache RoutesCache { get; private set; }
-
- ///
- /// Gets/sets the original URL of the request
- ///
- internal Uri ClientUrl { get; set; }
-
- private Uri _requestUrl;
-
- ///
- /// Gets the uri that is handled by ASP.NET after server-side rewriting took place.
- ///
- internal Uri RequestUrl
- {
- get
- {
- return _requestUrl;
- }
- set
- {
- _requestUrl = value;
- this.UmbracoUrl = UriUtility.UriToUmbraco(_requestUrl);
- }
- }
+
+ ///
+ /// Gets the uri that is handled by ASP.NET after server-side rewriting took place.
+ ///
+ internal Uri OriginalRequestUrl { get; private set; }
///
/// Gets the cleaned up url that is handled by Umbraco.
///
/// That is, lowercase, no trailing slash after path, no .aspx...
- internal Uri UmbracoUrl { get; private set; }
+ internal Uri CleanedUmbracoUrl { get; private set; }
private Func _xmlDelegate;
diff --git a/src/Umbraco.Web/UmbracoModule.cs b/src/Umbraco.Web/UmbracoModule.cs
index 8368563990..0a84dbf9f0 100644
--- a/src/Umbraco.Web/UmbracoModule.cs
+++ b/src/Umbraco.Web/UmbracoModule.cs
@@ -37,7 +37,7 @@ namespace Umbraco.Web
{
// do not process if client-side request
if (IsClientSideRequest(httpContext.Request.Url))
- return;
+ return;
// ok, process
@@ -76,11 +76,15 @@ namespace Umbraco.Web
if (IsClientSideRequest(httpContext.Request.Url))
return;
- var umbracoContext = UmbracoContext.Current;
- var routingContext = umbracoContext.RoutingContext;
+ if (UmbracoContext.Current == null)
+ throw new NullReferenceException("The UmbracoContext.Current is null, ProcessRequest cannot proceed unless there is a current UmbracoContext");
+ if (UmbracoContext.Current.RoutingContext == null)
+ throw new NullReferenceException("The UmbracoContext.RoutingContext has not been assigned, ProcessRequest cannot proceed unless there is a RoutingContext assigned to the UmbracoContext");
+
+ var umbracoContext = UmbracoContext.Current;
// do not process but remap to handler if it is a base rest request
- if (BaseRest.BaseRestHandler.IsBaseRestRequest(umbracoContext.RequestUrl))
+ if (BaseRest.BaseRestHandler.IsBaseRestRequest(umbracoContext.OriginalRequestUrl))
{
httpContext.RemapHandler(new BaseRest.BaseRestHandler());
return;
@@ -92,80 +96,17 @@ namespace Umbraco.Web
// ok, process
- var uri = umbracoContext.RequestUrl;
+ var uri = umbracoContext.OriginalRequestUrl;
- // legacy - no idea what this is
+ // legacy - no idea what this is but does something with the query strings
LegacyCleanUmbPageFromQueryString(ref uri);
- // create the new document request since we're rendering a document on the front-end
- var docreq = new PublishedContentRequest(
- umbracoContext.UmbracoUrl, //very important to use this url! it is the path only lowercased version of the current URL.
- routingContext);
- //assign the document request to the umbraco context now that we know its a front end request
- umbracoContext.PublishedContentRequest = docreq;
-
- // note - at that point the original legacy module did something do handle IIS custom 404 errors
- // ie pages looking like /anything.aspx?404;/path/to/document - I guess the reason was to support
- // "directory urls" without having to do wildcard mapping to ASP.NET on old IIS. This is a pain
- // to maintain and probably not used anymore - removed as of 06/2012. @zpqrtbnk.
- //
- // to trigger Umbraco's not-found, one should configure IIS and/or ASP.NET custom 404 errors
- // so that they point to a non-existing page eg /redirect-404.aspx
- // TODO: SD: We need more information on this for when we release 4.10.0 as I'm not sure what this means.
-
- //create the searcher
- var searcher = new PublishedContentRequestBuilder(docreq);
- //find domain
- searcher.LookupDomain();
- // redirect if it has been flagged
- if (docreq.IsRedirect)
- httpContext.Response.Redirect(docreq.RedirectUrl, true);
- //set the culture on the thread
- Thread.CurrentThread.CurrentUICulture = Thread.CurrentThread.CurrentCulture = docreq.Culture;
- //find the document, found will be true if the doc request has found BOTH a node and a template
- // though currently we don't use this value.
- var found = searcher.LookupDocument();
- //this could be called in the LookupDocument method, but I've just put it here for clarity.
- searcher.DetermineRenderingEngine();
-
- //TODO: here we should launch an event so that people can modify the doc request to do whatever they want.
-
- // redirect if it has been flagged
- if (docreq.IsRedirect)
- httpContext.Response.Redirect(docreq.RedirectUrl, true);
-
- // handle 404
- if (docreq.Is404)
- {
- httpContext.Response.StatusCode = 404;
-
- if (!docreq.HasNode)
- {
- httpContext.RemapHandler(new PublishedContentNotFoundHandler());
- return;
- }
-
- // else we have a document to render
- // not having a template is ok here, MVC will take care of it
- }
-
- // just be safe - should never ever happen
- if (!docreq.HasNode)
- throw new Exception("No document to render.");
-
- // render even though we might have no template
- // to give MVC a chance to hijack routes
- // pass off to our handlers (mvc or webforms)
-
- // assign the legacy page back to the docrequest
- // handlers like default.aspx will want it and most macros currently need it
- docreq.UmbracoPage = new page(docreq);
-
- // these two are used by many legacy objects
- httpContext.Items["pageID"] = docreq.DocumentId;
- httpContext.Items["pageElements"] = docreq.UmbracoPage.Elements;
-
- RewriteToUmbracoHandler(HttpContext.Current, uri.Query, docreq.RenderingEngine);
+ //process the request and on success, call the callback method: RewriteToUmbracoHandler
+ PublishedContentRequest.ProcessRequest(
+ httpContext,
+ umbracoContext,
+ umbracoContext.CleanedUmbracoUrl, //very important to use this url! it is the path only lowercased version of the current URL.
+ docreq => RewriteToUmbracoHandler(HttpContext.Current, uri.Query, docreq.RenderingEngine));
}
///
@@ -210,7 +151,7 @@ namespace Umbraco.Web
///
internal bool EnsureUmbracoRoutablePage(UmbracoContext context, HttpContextBase httpContext)
{
- var uri = context.RequestUrl;
+ var uri = context.OriginalRequestUrl;
// ensure this is a document request
if (!EnsureDocumentRequest(httpContext, uri))
@@ -378,7 +319,7 @@ namespace Umbraco.Web
//then we should be rendering the MVC stuff in that location.
rewritePath = "~/"
+ GlobalSettings.Path.TrimStart(new[] { '~', '/' }).TrimEnd(new[] { '/' })
- + "/RenderMvc" + currentQuery;
+ + "/RenderMvc";
//First we rewrite the path to the path of the handler (i.e. default.aspx or /umbraco/RenderMvc )
context.RewritePath(rewritePath, "", currentQuery.TrimStart(new[] { '?' }), false);
@@ -388,14 +329,17 @@ namespace Umbraco.Web
//an instance of the UrlRoutingModule and call it's PostResolveRequestCache method. This does:
// * Looks up the route based on the new rewritten URL
// * Creates the RequestContext with all route parameters and then executes the correct handler that matches the route
- //we could have re-written this functionality, but the code inside the PostResolveRequestCache is exactly what we want.
+ //we also cannot re-create this functionality because the setter for the HttpContext.Request.RequestContext is internal
+ //so really, this is pretty much the only way without using Server.TransferRequest and if we did that, we'd have to rethink
+ //a bunch of things!
+
var urlRouting = new UrlRoutingModule();
urlRouting.PostResolveRequestCache(new HttpContextWrapper(context));
break;
case RenderingEngine.WebForms:
default:
- rewritePath = "~/default.aspx" + currentQuery;
+ rewritePath = "~/default.aspx";
//First we rewrite the path to the path of the handler (i.e. default.aspx or /umbraco/RenderMvc )
context.RewritePath(rewritePath, "", currentQuery.TrimStart(new[] { '?' }), false);
diff --git a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs
index 7a73e510f6..273f135793 100644
--- a/src/Umbraco.Web/umbraco.presentation/default.aspx.cs
+++ b/src/Umbraco.Web/umbraco.presentation/default.aspx.cs
@@ -65,7 +65,7 @@ namespace umbraco
this.MasterPageFile = template.GetMasterPageName(_upage.Template);
// reset the friendly path so it's used by forms, etc.
- Context.RewritePath(UmbracoContext.Current.RequestUrl.PathAndQuery);
+ Context.RewritePath(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery);
//fire the init finished event
FireAfterRequestInit(args);
diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/uQuery-Nodes.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/uQuery-Nodes.cs
index 65c1913442..371357fc47 100644
--- a/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/uQuery-Nodes.cs
+++ b/src/Umbraco.Web/umbraco.presentation/umbraco/uQuery/uQuery-Nodes.cs
@@ -204,7 +204,7 @@ namespace umbraco
{
var uri = new Uri(url, UriKind.RelativeOrAbsolute);
if (!uri.IsAbsoluteUri)
- uri = uri.MakeAbsolute(Umbraco.Web.UmbracoContext.Current.UmbracoUrl);
+ uri = uri.MakeAbsolute(Umbraco.Web.UmbracoContext.Current.CleanedUmbracoUrl);
uri = Umbraco.Web.UriUtility.UriToUmbraco(uri);
var docreq = new Umbraco.Web.Routing.PublishedContentRequest(uri, Umbraco.Web.UmbracoContext.Current.RoutingContext);