Example #1
0
        public override void PostMapRequestHandler(HttpContextBase context)
        {
            base.PostMapRequestHandler(context);

            var ri = context.Items["mubble_RequestItems"] as RequestItems;

            if (ri != null)
            {
                context.RewritePath(ri.OriginalPath);
            }

            //RequestData data = (RequestData)context.Items[_requestDataKey];
            //if (data != null)
            //{
            //    context.RewritePath(data.OriginalPath);
            //    context.Handler = data.HttpHandler;
            //}
        }
Example #2
0
        /// <summary>
        /// Implements the Early Url Localization logic.
        /// <see href="https://docs.google.com/drawings/d/1cH3_PRAFHDz7N41l8Uz7hOIRGpmgaIlJe0fYSIOSZ_Y/edit?usp=sharing"/>
        /// </summary>
        public void ProcessIncoming(
            HttpContextBase context)
        {
            // Is URL explicitly excluded from localization?
            if (!m_urlLocalizer.FilterIncoming(context.Request.Url)) {
                return; } // YES. Continue handling request.

            bool allowRedirect =
                   context.Request.HttpMethod.Equals("GET", StringComparison.OrdinalIgnoreCase)
                || context.Request.HttpMethod.Equals("HEAD", StringComparison.OrdinalIgnoreCase);

            // NO. Is request URL localized?
            string urlNonlocalized;
            string langtag = m_urlLocalizer.ExtractLangTagFromUrl(context, context.Request.RawUrl, UriKind.Relative, true, out urlNonlocalized);
            if (langtag == null)
            {
                // NO.
                // langtag = best match between
                // 1. Inferred user languages (cookie and Accept-Language header)
                // 2. App Languages.
                LanguageTag lt = context.GetInferredLanguage();

                // If redirection allowed...redirect user agent (browser) to localized URL.
                // The principle purpose of this redirection is to ensure the browser is showing the correct URL
                // in its address field.
                if (allowRedirect) {
                    RedirectWithLanguage(context, lt.ToString(), m_urlLocalizer);
                    return;
                }

                // Otherwise, handle the request under the language infered above but without doing the redirect.
                // NB: this will mean that the user agent (browser) won't have the correct URL displayed;
                // however, this typically won't be an issue because we are talking about POST, PUT and DELETE methods
                // here which are typically not shown to the user.
                else {
                    context.SetPrincipalAppLanguageForRequest(lt);
                    return; // Continue handling request.
                }
            }

            // YES. Does langtag EXACTLY match an App Language?
            LanguageTag appLangTag = LanguageHelpers.GetMatchingAppLanguage(langtag);
            if (appLangTag.IsValid()
                && appLangTag.Equals(langtag))
            {
                // YES. Establish langtag as the PAL for the request.
                context.SetPrincipalAppLanguageForRequest(appLangTag);

                // Rewrite URL for this request.
                context.RewritePath(urlNonlocalized);

                // Continue handling request.
                return;
            }

            // NO. Does langtag LOOSELY match an App Language?
            else if (appLangTag.IsValid()
                && !appLangTag.Equals(langtag))
            {
                // YES. Localize URL with matching App Language.
                // Conditionally redirect user agent to localized URL.
                if (allowRedirect) {
                    RedirectWithLanguage(context, appLangTag.ToString(), m_urlLocalizer);
                    return;
                }
            }
            // NO. Do nothing to URL; expect a 404 which corresponds to language not supported.
            // Continue handling request.
        }
Example #3
0
		public virtual void PostMapRequestHandler (HttpContextBase context)
		{
#if !NET_4_0
			if (context == null)
				throw new ArgumentNullException ("context");

			// FIXME: find out what it actually does.
			IHttpHandler h = (IHttpHandler) context.Items [module_identity_key];
			if (h != null)
				context.Handler = h;

			string original_path = context.Items [original_path_key] as string;
			if (!String.IsNullOrEmpty (original_path))
				context.RewritePath (original_path);
#endif
		}
Example #4
0
		public virtual void PostResolveRequestCache (HttpContextBase context)
		{
			if (context == null)
				throw new ArgumentNullException ("context");

			var rd = RouteCollection.GetRouteData (context);
			if (rd == null)
				return; // do nothing

			if (rd.RouteHandler == null)
				throw new InvalidOperationException ("No  IRouteHandler is assigned to the selected route");

			if (rd.RouteHandler is StopRoutingHandler)
				return; //stop further processing
			
			var rc = new RequestContext (context, rd);

			IHttpHandler http = rd.RouteHandler.GetHttpHandler (rc);
			if (http == null)
				throw new InvalidOperationException ("The mapped IRouteHandler did not return an IHttpHandler");
#if NET_4_0
			context.Request.RequestContext = rc;
			context.RemapHandler (http);
#else
			// note: It does not resolve paths using GetVirtualPath():
			//var vpd = RouteCollection.GetVirtualPath (rc, rd.Values);
			//context.RewritePath (vpd.VirtualPath);

			context.Items [original_path_key] = context.Request.Path;

			// default handler (forbidden in MVC/DynamicData projects)
			context.RewritePath ("~/UrlRouting.axd");

			context.Items [module_identity_key] = http;
#endif
		}
Example #5
0
        /// <summary>
        /// Returns information about the requested route.
        /// </summary>
        /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
        /// <returns>
        /// An object that contains the values from the route definition.
        /// </returns>
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            if (DataSettingsHelper.DatabaseIsInstalled() && this.SeoFriendlyUrlsForLanguagesEnabled)
            {
                string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath;
                string applicationPath = httpContext.Request.ApplicationPath;
                if (virtualPath.IsLocalizedUrl(applicationPath, false))
                {
                    //In ASP.NET Development Server, an URL like "http://localhost/Blog.aspx/Categories/BabyFrog" will return
                    //"~/Blog.aspx/Categories/BabyFrog" as AppRelativeCurrentExecutionFilePath.
                    //However, in II6, the AppRelativeCurrentExecutionFilePath is "~/Blog.aspx"
                    //It seems that IIS6 think we're process Blog.aspx page.
                    //So, I'll use RawUrl to re-create an AppRelativeCurrentExecutionFilePath like ASP.NET Development Server.

                    //UNDONE should we do path rewrting here?
                    string rawUrl = httpContext.Request.RawUrl;
                    var newVirtualPath = rawUrl.RemoveLocalizedPathFromRawUrl(applicationPath);
                    if (string.IsNullOrEmpty(newVirtualPath))
                        newVirtualPath = "/";
                    newVirtualPath = newVirtualPath.RemoveApplicationPathFromRawUrl(applicationPath);
                    newVirtualPath = "~" + newVirtualPath;
                    httpContext.RewritePath(newVirtualPath, true);
                }
            }
            RouteData data = base.GetRouteData(httpContext);
            return data;
        }
Example #6
0
		// ensures Umbraco has at least one published node
		// if not, rewrites to splash and return false
		// if yes, return true
		bool EnsureHasContent(UmbracoContext context, HttpContextBase httpContext)
		{
			var store = context.RoutingContext.PublishedContentStore;
			if (!store.HasContent(context))
			{
				LogHelper.Warn<UmbracoModule>("Umbraco has no content");

				httpContext.Response.StatusCode = 503;

				var noContentUrl = "~/config/splashes/noNodes.aspx";
				httpContext.RewritePath(UriUtility.ToAbsolute(noContentUrl));

				return false;
			}
			else
			{
				return true;
			}
		}
Example #7
0
		// ensures Umbraco is ready to handle requests
		// if not, set status to 503 and transfer request, and return false
		// if yes, return true
		bool EnsureIsReady(HttpContextBase httpContext, Uri uri)
		{
			var ready = ApplicationContext.Current.IsReady;

			// ensure we are ready
			if (!ready)
			{
				LogHelper.Warn<UmbracoModule>("Umbraco is not ready");

				if (!UmbracoSettings.EnableSplashWhileLoading)
				{
					// let requests pile up and wait for 10s then show the splash anyway
					ready = ApplicationContext.Current.WaitForReady(10 * 1000);
				}

				if (!ready)
				{
					httpContext.Response.StatusCode = 503;

					var bootUrl = UmbracoSettings.BootSplashPage;
					if (string.IsNullOrWhiteSpace(bootUrl))
						bootUrl = "~/config/splashes/booting.aspx";
					httpContext.RewritePath(UriUtility.ToAbsolute(bootUrl) + "?url=" + HttpUtility.UrlEncode(uri.ToString()));

					return false;
				}
			}

			return true;
		}
Example #8
0
		/// <summary>
		/// Ensures that the request is a document request (i.e. one that the module should handle)
		/// </summary>
		/// <param name="httpContext"></param>
		/// <param name="uri"></param>
		/// <returns></returns>
		bool EnsureDocumentRequest(HttpContextBase httpContext, Uri uri)
		{
			var maybeDoc = true;
			var lpath = uri.AbsolutePath.ToLowerInvariant();

			// handle directory-urls used for asmx
			// legacy - what's the point really?
			if (maybeDoc && GlobalSettings.UseDirectoryUrls)
			{
				int asmxPos = lpath.IndexOf(".asmx/");
				if (asmxPos >= 0)
				{
					// use uri.AbsolutePath, not path, 'cos path has been lowercased
					httpContext.RewritePath(uri.AbsolutePath.Substring(0, asmxPos + 5), // filePath
						uri.AbsolutePath.Substring(asmxPos + 5), // pathInfo
						uri.Query.TrimStart('?'));
					maybeDoc = false;
				}
			}

			// a document request should be
			// /foo/bar/nil
			// /foo/bar/nil/
			// /foo/bar/nil.aspx
			// where /foo is not a reserved path

			// if the path contains an extension that is not .aspx
			// then it cannot be a document request
			if (maybeDoc && lpath.Contains('.') && !lpath.EndsWith(".aspx"))
				maybeDoc = false;

			// at that point, either we have no extension, or it is .aspx

			// if the path is reserved then it cannot be a document request
			if (maybeDoc && GlobalSettings.IsReservedPathOrUrl(lpath))
				maybeDoc = false;

			//NOTE: No need to warn, plus if we do we should log the document, as this message doesn't really tell us anything :)
			//if (!maybeDoc)
			//{
			//	LogHelper.Warn<UmbracoModule>("Not a document");
			//}

			return maybeDoc;
		}
Example #9
0
		/// <summary>
		/// Rewrites to the correct Umbraco handler, either WebForms or Mvc
		/// </summary>		
		/// <param name="context"></param>
        /// <param name="pcr"> </param>
		private static void RewriteToUmbracoHandler(HttpContextBase context, PublishedContentRequest pcr)
		{
			// NOTE: we do not want to use TransferRequest even though many docs say it is better with IIS7, turns out this is
			// not what we need. The purpose of TransferRequest is to ensure that .net processes all of the rules for the newly
			// rewritten url, but this is not what we want!
			// read: http://forums.iis.net/t/1146511.aspx

			string query = pcr.Uri.Query.TrimStart(new[] { '?' });

			string rewritePath;

            if (pcr.RenderingEngine == RenderingEngine.Unknown)
            {
                // Unkwnown means that no template was found. Default to Mvc because Mvc supports hijacking
                // routes which sometimes doesn't require a template since the developer may want full control
                // over the rendering. Can't do it in WebForms, so Mvc it is. And Mvc will also handle what to
                // do if no template or hijacked route is exist.
                pcr.RenderingEngine = RenderingEngine.Mvc;
            }

			switch (pcr.RenderingEngine)
			{
				case RenderingEngine.Mvc:
					// GlobalSettings.Path has already been through IOHelper.ResolveUrl() so it begins with / and vdir (if any)
					rewritePath = GlobalSettings.Path.TrimEnd(new[] { '/' }) + "/RenderMvc";
					// rewrite the path to the path of the handler (i.e. /umbraco/RenderMvc)
					context.RewritePath(rewritePath, "", query, false);

					//if it is MVC we need to do something special, we are not using TransferRequest as this will 
					//require us to rewrite the path with query strings and then reparse the query strings, this would 
					//also mean that we need to handle IIS 7 vs pre-IIS 7 differently. Instead we are just going to create
					//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 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(context);
					break;

				case RenderingEngine.WebForms:
					rewritePath = "~/default.aspx";
					// rewrite the path to the path of the handler (i.e. default.aspx)
					context.RewritePath(rewritePath, "", query, false);
					break;

                default:
                    throw new Exception("Invalid RenderingEngine.");
            }
		}
Example #10
0
		// ensures Umbraco has at least one published node
		// if not, rewrites to splash and return false
		// if yes, return true
	    private static bool EnsureHasContent(UmbracoContext context, HttpContextBase httpContext)
		{
            if (context.ContentCache.HasContent())
		        return true;

            LogHelper.Warn<UmbracoModule>("Umbraco has no content");

			httpContext.Response.StatusCode = 503;

			const string noContentUrl = "~/config/splashes/noNodes.aspx";
			httpContext.RewritePath(UriUtility.ToAbsolute(noContentUrl));

			return false;
		}
        /// <summary>
        /// Returns information about the requested route.
        /// </summary>
        /// <param name="httpContext">An object that encapsulates information about the HTTP request.</param>
        /// <returns>An object that contains the values from the route definition.</returns>
        public override RouteData GetRouteData(HttpContextBase httpContext)
        {
            if (httpContext == null)
            {
                throw new ArgumentNullException("httpContext");
            }

            bool isResource = Regex.Match(httpContext.Request.Url.ToString(), @"\.\w{2,4}$").Success;

            if (isResource)
            {
                return base.GetRouteData(httpContext);
            }

            string virtualPath = httpContext.Request.AppRelativeCurrentExecutionFilePath;

            var parts = virtualPath.Substring(2).Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);
            Guid parseResult;

            if (parts.Length == 0
                || parts[0].ToLower() == "bundles"
                || parts[0].ToLower() == "styles"
                || parts[0].ToLower() == "content"
                || parts[0].ToLower() == "areas"
                || Guid.TryParse(parts[0].ToLower(), out parseResult))
            {
                return base.GetRouteData(httpContext);
            }

            var urlParts = this.Url.Split(new string[] { "/" }, StringSplitOptions.RemoveEmptyEntries);

            bool correctArea = parts.Count() >= 1 ? !urlParts[0].StartsWith("{") ? urlParts[0].ToLower() == parts[0].ToLower() : true : true;

            if (correctArea)
            {
                bool isArea = parts.Count() >= 1 ? urlParts[0].ToLower() == parts[0].ToLower() : false;
                var culturePattern = "/[a-zA-Z]{2}$|/[a-zA-Z]{2}/|/[a-zA-Z]{2}-[a-zA-Z]{2}/";
                var match = Regex.Match(virtualPath.Substring(1), culturePattern);

                if (!match.Success)
                {
                    var newPath = virtualPath.Substring(2).ToLower();

                    if (isArea)
                    {
                        newPath = newPath.IndexOf("/") > -1 ? newPath.Insert(newPath.IndexOf("/") + 1, _culture + "/") : newPath + "/" + _culture;
                    }
                    else
                    {
                        newPath = _culture + "/" + newPath;
                    }

                    newPath = "~/" + newPath;
                    httpContext.RewritePath(newPath, true);
                }
            }

            return base.GetRouteData(httpContext);
        }
        protected virtual bool VerifyNode(ISiteMap siteMap, ISiteMapNode node, HttpContextBase httpContext)
        {
            // Time to delve into the AuthorizeAttribute defined on the node.
            // Let's start by getting all metadata for the controller...
            var controllerType = siteMap.ResolveControllerType(node.Area, node.Controller);
            if (controllerType == null)
                return true;

            var originalPath = httpContext.Request.Path;

            // Find routes for the sitemap node's url
            var routes = this.FindRoutesForNode(node, originalPath, httpContext);
            try
            {
                if (routes == null)
                    return true; // Static URL's will have no route data, therefore return true.

                return this.VerifyController(node, routes, controllerType);
            }
            finally
            {
                // Restore HttpContext
                httpContext.RewritePath(originalPath, true);
            }
        }
        protected virtual RouteData FindRoutesForNode(ISiteMapNode node, string originalPath, HttpContextBase httpContext)
        {
            var routes = mvcContextFactory.GetRoutes();
            var originalRoutes = routes.GetRouteData(httpContext);
            var nodeUrl = node.Url;
            httpContext.RewritePath(nodeUrl, true);

            RouteData routeData = node.GetRouteData(httpContext);
            if (routeData != null)
            {
                foreach (var routeValue in node.RouteValues)
                {
                    routeData.Values[routeValue.Key] = routeValue.Value;
                }
                if (originalRoutes != null && (!routeData.Route.Equals(originalRoutes.Route) || originalPath != nodeUrl || node.Area == String.Empty))
                {
                    routeData.DataTokens.Remove("area");
                    //routeData.DataTokens.Remove("Namespaces");
                    //routeData.Values.Remove("area");
                }
            }
            return routeData;
        }
Example #14
0
        public override void PostResolveRequestCache(HttpContextBase context)
        {
            /*
             * New routes:
             *  Path.format
             */

            // .html == html
            // .xml == xml

            var formats = new Dictionary<string, string>
            {
                { ".html", "html" },
                { ".xml", "xml" },
                { ".media", "media" }
            };

            var format = (string)null;
            var contentPath = (string)null;
            var parameters = (string)null;
            var ci = (IContentItem)null;

            var ri = (RequestItems)null;

            var path = context.Request.AppRelativeCurrentExecutionFilePath.Substring(1);

            if (!path.StartsWith("/@"))
            {
                while (!char.IsLetterOrDigit(path[path.Length - 1]))
                {
                    path = path.Substring(0, path.Length - 1);
                }
                if (!path.Contains('.')) path = path + ".html";

                if ("/default.aspx".Equals(path, StringComparison.CurrentCultureIgnoreCase))
                {
                    ri = new RequestItems
                    {
                        Content = ContentItem.GetResolved("/"),
                        Format = "html",
                        OriginalPath = context.Request.Path
                    };
                }
                else
                {
                    foreach (var key in formats.Keys)
                    {
                        var startIndex = path.IndexOf(key, StringComparison.CurrentCultureIgnoreCase);
                        if (startIndex > -1)
                        {
                            format = formats[key];
                            contentPath = path.Substring(0, startIndex);
                            ci = ContentItem.GetResolved(contentPath);
                            parameters = path.Substring(startIndex + key.Length);

                            ri = new RequestItems
                            {
                                Content = ci,
                                Format = format,
                                OriginalPath = context.Request.Path
                            };
                            break;
                        }
                    }
                }

                if (ri != null)
                {
                    context.Items["mubble_RequestItems"] = ri;

                    var newPath = parameters;

                    if (ci is Article) newPath = "/article" + newPath;
                    else newPath = "/content" + newPath;

                    if (format == "media")
                    {
                        newPath = "/file" + parameters;
                    }

                    context.RewritePath(newPath);
                }
            }

            base.PostResolveRequestCache(context);

            //RouteData routeData = this.RouteCollection.GetRouteData(context);
            //if (routeData != null)
            //{
            //    Type routeHandler = routeData.Route.RouteHandler;
            //    if (routeHandler == null)
            //    {
            //        throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, AtlasWeb.UrlRoutingModule_NoRouteHandler, new object[] { routeData.Route.Url }));
            //    }
            //    IRouteHandler handler = (IRouteHandler)Activator.CreateInstance(routeHandler);
            //    RequestContext requestContext = new RequestContext(context, routeData);
            //    IHttpHandler httpHandler = handler.GetHttpHandler(requestContext);
            //    if (httpHandler == null)
            //    {
            //        throw new InvalidOperationException(string.Format(CultureInfo.CurrentUICulture, AtlasWeb.UrlRoutingModule_NoHttpHandler, new object[] { routeHandler }));
            //    }
            //    RequestData data2 = new RequestData();
            //    data2.OriginalPath = context.Request.Path;
            //    data2.HttpHandler = httpHandler;
            //    context.Items[_requestDataKey] = data2;
            //    context.RewritePath("~/Mvc.axd");
            //}
        }
Example #15
0
        /// <summary>
        /// Rewrites to the default back office page.
        /// </summary>
        /// <param name="context"></param>
        private static void RewriteToBackOfficeHandler(HttpContextBase context)
        {
            // GlobalSettings.Path has already been through IOHelper.ResolveUrl() so it begins with / and vdir (if any)
            var rewritePath = GlobalSettings.Path.TrimEnd(new[] { '/' }) + "/Default";
            // rewrite the path to the path of the handler (i.e. /umbraco/RenderMvc)
            context.RewritePath(rewritePath, "", "", false);

            //if it is MVC we need to do something special, we are not using TransferRequest as this will 
            //require us to rewrite the path with query strings and then reparse the query strings, this would 
            //also mean that we need to handle IIS 7 vs pre-IIS 7 differently. Instead we are just going to create
            //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 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(context);
        }