/// <summary>
        /// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
        /// </summary>
        /// <param name="pcr">The <c>PublishedContentRequest</c>.</param>		
        /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
        public bool TrySetDocument(PublishedContentRequest pcr)
        {
            LogHelper.Debug<LookupByLegacy404>("Looking for a page to handle 404.");

            // TODO - replace the whole logic and stop calling into library!
            var error404 = global::umbraco.library.GetCurrentNotFoundPageId();
            var id = int.Parse(error404);

            IPublishedContent content = null;

            if (id > 0)
            {
                LogHelper.Debug<LookupByLegacy404>("Got id={0}.", () => id);

                content = pcr.RoutingContext.PublishedContentStore.GetDocumentById(
                        pcr.RoutingContext.UmbracoContext,
                        id);

                if (content == null)
                    LogHelper.Debug<LookupByLegacy404>("Could not find content with that id.");
                else
                    LogHelper.Debug<LookupByLegacy404>("Found corresponding content.");
            }
            else
            {
                LogHelper.Debug<LookupByLegacy404>("Got nothing.");
            }

            pcr.PublishedContent = content;
            pcr.Is404 = true;
            return content != null;
        }
		public PublishedContentRequestBuilder(PublishedContentRequest publishedContentRequest)
		{
			if (publishedContentRequest == null) throw new ArgumentNullException("publishedContentRequest");
			_publishedContentRequest = publishedContentRequest;
			_umbracoContext = publishedContentRequest.RoutingContext.UmbracoContext;
			_routingContext = publishedContentRequest.RoutingContext;
		}
        [TestCase("http://domain1.com/en/bar/nil", "en-US", 100111)] // ok, alias includes "en/"
        public void Lookup_By_Url_Alias_And_Domain(string inputUrl, string expectedCulture, int expectedNode)
        {
            SetDomains1();

            var routingContext = GetRoutingContext(inputUrl);
            var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
            var pcr = new PublishedContentRequest(url, routingContext);
            // must lookup domain
            pcr.Engine.FindDomain();

            if (expectedNode > 0)
                Assert.AreEqual(expectedCulture, pcr.Culture.Name);

            var finder = new ContentFinderByUrlAlias();
            var result = finder.TryFindContent(pcr);

            if (expectedNode > 0)
            {
                Assert.IsTrue(result);
                Assert.AreEqual(pcr.PublishedContent.Id, expectedNode);
            }
            else
            {
                Assert.IsFalse(result);
            }
        }
		/// <summary>
		/// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
		/// </summary>
		/// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>		
		/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
		public bool TryFindContent(PublishedContentRequest docRequest)
        {
            IPublishedContent node = null;
			var path = docRequest.Uri.GetAbsolutePathDecoded();

            var nodeId = -1;
			if (path != "/") // no id if "/"
            {
				var noSlashPath = path.Substring(1);

                if (!Int32.TryParse(noSlashPath, out nodeId))
                    nodeId = -1;

                if (nodeId > 0)
                {
					LogHelper.Debug<ContentFinderByIdPath>("Id={0}", () => nodeId);
                    node = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(nodeId);

                    if (node != null)
                    {
						docRequest.PublishedContent = node;
						LogHelper.Debug<ContentFinderByIdPath>("Found node with id={0}", () => docRequest.PublishedContent.Id);
                    }
                    else
                    {
                        nodeId = -1; // trigger message below
                    }
                }
            }

            if (nodeId == -1)
				LogHelper.Debug<ContentFinderByIdPath>("Not a node id");

            return node != null;
        }
        /// <summary>
        /// For each request, this function checks to see if its a virtual Blog URL targeted to 
        /// Authors, Categories, Tags & RSS and routes accordingly
        /// </summary>
        /// <param name="contentRequest"></param>
        /// <returns>True for a virtual URL or false for an exsting CMS Page</returns>
        public bool TryFindContent(PublishedContentRequest contentRequest)
        {
            string fullUri = contentRequest.Uri.AbsolutePath;
            Regex reg = new Regex("author|category|tag|rss");
            if (reg.IsMatch(fullUri)) { //Simple regex match to see if it's a possible url to redirect. If not, lets not worry about the overhead and just return false
                if (uQuery.GetNodesByType("BlogEntry").Where(r => r.Url.StartsWith(fullUri, StringComparison.InvariantCultureIgnoreCase)).Count() > 0) {
                    //We've found a match to a blog entry, so no need to redirect

                    return false;
                }

                //Get All Blog listings. This should only be a handful at Max
                var allNodes = uQuery.GetNodesByType("BlogListing").OrderByDescending(n => n.Level);

                foreach (var node in allNodes) {

                    string parentUri = node.Url;
                    bool isChild = fullUri.StartsWith(parentUri, StringComparison.InvariantCultureIgnoreCase);

                    if (isChild) {
                        //Its a virtual URL that is a child of a Blog listing.
                        contentRequest.PublishedContent = new UmbracoHelper(UmbracoContext.Current).TypedContent(node.Id);

                        return true;
                    }
                }
            }

            return false;
        }
Exemple #6
0
		protected override void OnPreInit(EventArgs e)
		{
			base.OnPreInit(e);

			// handle the infamous umbDebugShowTrace, etc
			Page.Trace.IsEnabled &= GlobalSettings.DebugMode && !String.IsNullOrWhiteSpace(Request["umbDebugShowTrace"]);

			// get the document request and the page
			_docRequest = UmbracoContext.Current.PublishedContentRequest;
			_upage = _docRequest.UmbracoPage;

			//we need to check this for backwards compatibility in case people still arent' using master pages
			if (UmbracoSettings.UseAspNetMasterPages)
			{
				var args = new RequestInitEventArgs()
				{
					Page = _upage,
					PageId = _upage.PageID,
					Context = Context
				};
				FireBeforeRequestInit(args);

				//if we are cancelling then return and don't proceed
				if (args.Cancel) return;

				this.MasterPageFile = template.GetMasterPageName(_upage.Template);

				// reset the friendly path so it's used by forms, etc.			
				Context.RewritePath(UmbracoContext.Current.OriginalRequestUrl.PathAndQuery);

				//fire the init finished event
				FireAfterRequestInit(args);	
			}
			
		}
		/// <summary>
		/// Tries to find an Umbraco document for a <c>PublishedContentRequest</c> and a route.
		/// </summary>
		/// <param name="docreq">The document request.</param>
		/// <param name="route">The route.</param>
		/// <returns>The document node, or null.</returns>
        protected IPublishedContent LookupDocumentNode(PublishedContentRequest docreq, string route)
        {
			LogHelper.Debug<LookupByNiceUrl>("Test route \"{0}\"", () => route);

			// first ask the cache for a node
			// return '0' if in preview mode
        	var nodeId = !docreq.RoutingContext.UmbracoContext.InPreviewMode
							? docreq.RoutingContext.UmbracoContext.RoutesCache.GetNodeId(route)
        	             	: 0;

			// if a node was found, get it by id and ensure it exists
			// else clear the cache
            IPublishedContent node = null;
            if (nodeId > 0)
            {
				node = docreq.RoutingContext.PublishedContentStore.GetDocumentById(
					docreq.RoutingContext.UmbracoContext,
					nodeId);

                if (node != null)
                {
                    docreq.PublishedContent = node;
					LogHelper.Debug<LookupByNiceUrl>("Cache hit, id={0}", () => nodeId);
                }
                else
                {
                    docreq.RoutingContext.UmbracoContext.RoutesCache.ClearNode(nodeId);
                }
            }

			// if we still have no node, get it by route
            if (node == null)
            {
				LogHelper.Debug<LookupByNiceUrl>("Cache miss, query");
				node = docreq.RoutingContext.PublishedContentStore.GetDocumentByRoute(
					docreq.RoutingContext.UmbracoContext,
					route);

                if (node != null)
                {
                    docreq.PublishedContent = node;
					LogHelper.Debug<LookupByNiceUrl>("Query matches, id={0}", () => docreq.DocumentId);

					var iscanon = _doDomainLookup && !DomainHelper.ExistsDomainInPath(docreq.Domain, node.Path);
					if (!iscanon)
						LogHelper.Debug<LookupByNiceUrl>("Non canonical url");

					// do not store if previewing or if non-canonical
					if (!docreq.RoutingContext.UmbracoContext.InPreviewMode && iscanon)
						docreq.RoutingContext.UmbracoContext.RoutesCache.Store(docreq.DocumentId, route);
                    
                }
                else
                {
					LogHelper.Debug<LookupByNiceUrl>("Query does not match");
                }
            }

            return node;
        }
	    /// <summary>
		/// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
		/// </summary>
		/// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>		
		/// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
		public virtual bool TrySetDocument(PublishedContentRequest docRequest)
        {
			string route;
			if (docRequest.HasDomain)
				route = docRequest.Domain.RootNodeId.ToString() + DomainHelper.PathRelativeToDomain(docRequest.DomainUri, docRequest.Uri.GetAbsolutePathDecoded());
			else
				route = docRequest.Uri.GetAbsolutePathDecoded();

			var node = LookupDocumentNode(docRequest, route);
            return node != null;
        }
        public override bool TryFindContent(PublishedContentRequest contentRequest)
        {
            // eg / or /path/to/whatever
            var url = contentRequest.Uri.GetAbsolutePathDecoded();

            var mdRoot = "/" + MarkdownLogic.BaseUrl;
            if (url.StartsWith("/projects/umbraco-pro/contour/documentation"))
                mdRoot = "/projects";

            // ensure it's a md url
            if (url.StartsWith(mdRoot) == false)
                return false; // not for us

            // find the root content
            var node = FindContent(contentRequest, mdRoot);
            if (node == null)
                return false;

            // kill those old urls
            foreach (var s in new []{ "master", "v480" })
                if (url.StartsWith(mdRoot + "/" + s))
                {
                    url = url.Replace(mdRoot + "/" + s, mdRoot);
                    contentRequest.SetRedirectPermanent(url);
                    return true;
                }

            // find the md file
            var mdFilepath = FindMarkdownFile(url);
            if (mdFilepath == null)
            {
                // clear the published content (that was set by FindContent) to cause a 404, and in
                // both case return 'true' because there's no point other finders try to handle the request
                contentRequest.PublishedContent = null;
                return true;
            }

            // set the context vars
            var httpContext = contentRequest.RoutingContext.UmbracoContext.HttpContext;
            httpContext.Items[MarkdownLogic.MarkdownPathKey] = mdFilepath;
            httpContext.Items["topicTitle"] = string.Join(" - ", httpContext.Request.RawUrl
                .Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries)
                .Skip(1)
                .Reverse());

            // override the template
            const string altTemplate = "DocumentationSubpage";
            var templateIsSet = contentRequest.TrySetTemplate(altTemplate);
            //httpContext.Trace.Write("Markdown Files Handler",
            //    string.Format("Template changed to: '{0}' is {1}", altTemplate, templateIsSet));

            // be happy
            return true;
        }
		public void Lookup_By_Url_Alias(string urlAsString, int nodeMatch)
		{
			var routingContext = GetRoutingContext(urlAsString);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var docRequest = new PublishedContentRequest(url, routingContext);
			var lookup = new LookupByAlias();
			
			var result = lookup.TrySetDocument(docRequest);

			Assert.IsTrue(result);
			Assert.AreEqual(docRequest.DocumentId, nodeMatch);
		}
		public void Match_Document_By_Url(string urlString, int expectedId)
		{
			var routingContext = GetRoutingContext(urlString);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl;	//very important to use the cleaned up umbraco url		
			var docreq = new PublishedContentRequest(url, routingContext);			
			var lookup = new LookupByNiceUrl();

			var result = lookup.TrySetDocument(docreq);

			Assert.IsTrue(result);
			Assert.AreEqual(expectedId, docreq.DocumentId);
		}
 private string GetTemplateAliasByContentAccept(PublishedContentRequest docRequest)
 {
     HttpContext context = HttpContext.Current;
     string template = null;
     if (ConfigurationManager.AppSettings.AllKeys.Contains("WG2K.Hypermedia.Templates." + context.Request.ContentType))
         template = ConfigurationManager.AppSettings["WG2K.Hypermedia.Templates." + context.Request.ContentType];
     if (template != null)
     {
         return template;
     }
     return "unknown";
 }
		/// <summary>
		/// Initializes a new instance of the <see cref="PublishedContentRequestEngine"/> class with a content request.
		/// </summary>
		/// <param name="pcr">The content request.</param>
		public PublishedContentRequestEngine(PublishedContentRequest pcr)
		{
			_pcr = pcr;
			_routingContext = pcr.RoutingContext;

			var umbracoContext = _routingContext.UmbracoContext;
			if (_routingContext == null) throw new ArgumentException("pcr.RoutingContext is null.");
			if (umbracoContext == null) throw new ArgumentException("pcr.RoutingContext.UmbracoContext is null.");
			if (umbracoContext.RoutingContext != _routingContext) throw new ArgumentException("RoutingContext confusion.");
			// no! not set yet.
			//if (umbracoContext.PublishedContentRequest != _pcr) throw new ArgumentException("PublishedContentRequest confusion.");
		}
        //NOTE: This is the manual way we could assign culture this but I think there's more logic for edge case scenarios in Umbraco's Prepare method.
        // I've just left this code here as an example
        protected override void PreparePublishedContentRequest(PublishedContentRequest publishedContentRequest)
        {
            //if (_hostsAndIds.Any(x => x.Item2 == publishedContentRequest.PublishedContent.Parent.Id))
            //{
            //    var hostAndId = _hostsAndIds.Single(x => x.Item2 == publishedContentRequest.PublishedContent.Parent.Id);
            //    var domain = Domain.GetDomain(hostAndId.Item1);
            //    publishedContentRequest.Culture = new CultureInfo(domain.Language.CultureAlias);
            //}

            base.PreparePublishedContentRequest(publishedContentRequest);

        }
		public void Lookup_By_Id(string urlAsString, int nodeMatch)
		{
			var routingContext = GetRoutingContext(urlAsString);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var docRequest = new PublishedContentRequest(url, routingContext);
			var lookup = new ContentFinderByIdPath();
		

			var result = lookup.TryFindContent(docRequest);

			Assert.IsTrue(result);
			Assert.AreEqual(docRequest.PublishedContent.Id, nodeMatch);
		}
		public void Match_Document_By_Url(string urlString, int expectedId)
		{
			var routingContext = GetRoutingContext(urlString);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl;	//very important to use the cleaned up umbraco url		
			var docreq = new PublishedContentRequest(url, routingContext);			
			var lookup = new ContentFinderByNiceUrl();
            SettingsForTests.HideTopLevelNodeFromPath = false;

			var result = lookup.TryFindContent(docreq);

			Assert.IsTrue(result);
			Assert.AreEqual(expectedId, docreq.PublishedContent.Id);
		}
        public bool TryFindContent(PublishedContentRequest request)
        {
            //Get the requested URL path + query
            var path = request.Uri.PathAndQuery.ToLower();

            //Check the table
            var matchedRedirect = RedirectRepository.FindRedirect(path);
            if (matchedRedirect == null) return false;

            //Found one, set the 301 redirect on the request and return
            request.SetRedirectPermanent(matchedRedirect.NewUrl);
            return true;
        }
        public async Task<bool> TryFindContentAsync(PublishedContentRequest pcr)
        {
            var path = (string)pcr.RouteData.Values["_umbracoRoute"];

            var content = await _contentCache.GetByRouteAsync(false, path);
            
            if (content != null)
            {                
                pcr.PublishedContent = content;
                return true;                
            }

            return false;
        }
        /// <summary>
        /// The prepare slug.
        /// </summary>
        /// <param name="contentRequest">
        /// The content request.
        /// </param>
        /// <returns>
        /// The <see cref="string"/>.
        /// </returns>
        private static string PrepareSlug(PublishedContentRequest contentRequest)
        {
            var slug = contentRequest.Uri.AbsolutePath.EnsureNotStartsOrEndsWith('/');

            // Check if there were any overrides to the slug in the merchello.config
            var prefix = MerchelloConfiguration.Current.GetProductSlugCulturePrefix(contentRequest.Culture.Name);

            if (prefix.IsNullOrWhiteSpace()) return slug;

            // enforce the prefix is present in the slug
            return !slug.StartsWith(prefix) ?
                string.Empty :
                slug.Replace(prefix, string.Empty).EnsureNotStartsOrEndsWith('/');
        }
Exemple #20
0
        public void Initialize(PublishedContentRequest pcr)
        {
            if (Initialized) return;

            PublishedContentRequest = pcr;

            ////TODO: This name/etc. is temporary from old testing
            //AltTemplate = _httpContextAccessor.HttpContext.Request.Query["altTemplate"];
            //if (string.IsNullOrEmpty(AltTemplate))
            //{
            //    AltTemplate = "Umbraco";
            //}

            Initialized = true;
        }
        /// <summary>
        /// Tries to find a <see cref="IProductContent"/> by it's unique slug.
        /// </summary>
        /// <param name="contentRequest">
        /// The content request.
        /// </param>
        /// <returns>
        /// A value indicating whether or not the product was found by slug.
        /// </returns>        
        public bool TryFindContent(PublishedContentRequest contentRequest)
        {
            if (contentRequest.Uri.AbsolutePath == "/") return false;

            var slug = PrepareSlug(contentRequest);

            // this can happen if there is a prefix configured in the merchello.config which does not exist in the Uri
            if (slug.IsNullOrWhiteSpace()) return false;

            // This may have a db fallback so we want this content finder to happen after Umbraco's content finders.
            var content = Merchello.TypedProductContentBySlug(slug);
            if (content == null) return false;

            contentRequest.PublishedContent = content;
            return true;
        }
		[TestCase("/some/other/page.aspx?umbPageId=1046", 1046)] //TODO: Should this match??
		public void Lookup_By_Page_Id(string urlAsString, int nodeMatch)
		{		
			var routingContext = GetRoutingContext(urlAsString);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var docRequest = new PublishedContentRequest(url, routingContext);
			var lookup = new LookupByPageIdQuery();			

			//we need to manually stub the return output of HttpContext.Request["umbPageId"]
			routingContext.UmbracoContext.HttpContext.Request.Stub(x => x["umbPageID"])
				.Return(routingContext.UmbracoContext.HttpContext.Request.QueryString["umbPageID"]);

			var result = lookup.TrySetDocument(docRequest);

			Assert.IsTrue(result);
			Assert.AreEqual(docRequest.DocumentId, nodeMatch);
		}
		public void Match_Document_By_Url_With_Template(string urlAsString)
		{
			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.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var docRequest = new PublishedContentRequest(url, routingContext);
			var lookup = new LookupByNiceUrlAndTemplate();

			var result = lookup.TrySetDocument(docRequest);

			Assert.IsTrue(result);
			Assert.IsNotNull(docRequest.PublishedContent);
			Assert.IsNotNull(docRequest.Template);
			Assert.AreEqual("blah".ToUpperInvariant(), docRequest.Template.Alias.ToUpperInvariant());
		}
        public async void RouteUmbracoContentAsync_Umbraco_Context_Initialized()
        {
            var router = new UmbracoRouter(Mock.Of<IRouter>());
            var httpCtxAccessor = new Mock<IHttpContextAccessor>();
            var httpContext = new Mock<HttpContext>();
            httpContext.Setup(context => context.Request).Returns(Mock.Of<HttpRequest>());
            httpCtxAccessor.Setup(accessor => accessor.HttpContext).Returns(httpContext.Object);
            var umbCtx = new UmbracoContext(httpCtxAccessor.Object);
            var urlProvider = new UrlProvider(umbCtx, Enumerable.Empty<IUrlProvider>());
            var routingCtx = new RoutingContext(Enumerable.Empty<IContentFinder>(), Mock.Of<ILastChanceContentFinder>(), urlProvider);
            var pcr = new PublishedContentRequest(routingCtx, Mock.Of<ITemplateService>(), Mock.Of<ILoggerFactory>(), httpCtxAccessor.Object);

            var result = await router.RouteUmbracoContentAsync(umbCtx, pcr, new RouteData());

            Assert.Equal(true, umbCtx.Initialized);
            Assert.Equal(false, result);
        }
Exemple #25
0
        internal async Task<bool> RouteUmbracoContentAsync(UmbracoContext umbCtx, PublishedContentRequest pcr, RouteData routeData)
        {
            //Initialize the context, this will be called a few times but the initialize logic
            // only executes once. There might be a nicer way to do this but the RouteContext and 
            // other request scoped instances are not available yet.
            umbCtx.Initialize(pcr);

            //Prepare the request if it hasn't already been done
            if (pcr.IsPrepared == false)
            {                
                if (await pcr.PrepareAsync(routeData))
                {
                    if (umbCtx.HasContent == false) return false;
                }
            }
            return umbCtx.HasContent;            
        }
		/// <summary>
		/// Tries to find an Umbraco document for a <c>PublishedContentRequest</c> and a route.
		/// </summary>
		/// <param name="docreq">The document request.</param>
		/// <param name="route">The route.</param>
		/// <returns>The document node, or null.</returns>
        protected IPublishedContent FindContent(PublishedContentRequest docreq, string route)
        {
			LogHelper.Debug<ContentFinderByNiceUrl>("Test route \"{0}\"", () => route);

		    var node = docreq.RoutingContext.UmbracoContext.ContentCache.GetByRoute(route);
            if (node != null)
            {
                docreq.PublishedContent = node;
                LogHelper.Debug<ContentFinderByNiceUrl>("Got content, id={0}", () => node.Id);
            }
            else
            {
                LogHelper.Debug<ContentFinderByNiceUrl>("No match.");
            }

		    return node;
        }
Exemple #27
0
 public bool TryFindContent(PublishedContentRequest contentRequest)
 {
     if (!contentRequest.HasDomain) return false;
     var contentCache = contentRequest.RoutingContext.UmbracoContext.ContentCache;
     var domainRoot = contentCache.GetById(contentRequest.Domain.RootNodeId);
     //var firstSegment = contentRequest.Uri.AbsolutePath.Split(new[] { '/' },
     //  StringSplitOptions.RemoveEmptyEntries).First();
     //var root = domainRoot.Children.FirstOrDefault(x => x.UrlName == firstSegment);
     // root = root ?? domainRoot;
     var page = domainRoot.Descendants().FirstOrDefault(x => x.Name == "404");
     if (page == null) return false;
     contentRequest.PublishedContent = page;
     var wcd = umbraco.cms.businesslogic.web.Domain.GetDomainsById(domainRoot.Id, true).SingleOrDefault(x => x.IsWildcard);
     if (wcd != null)
         contentRequest.Culture = new CultureInfo(wcd.Language.CultureAlias);
     return true;
 }
		public void DoNotPolluteCache()
		{
            SettingsForTests.UseDirectoryUrls = true;
            SettingsForTests.HideTopLevelNodeFromPath = false; // ignored w/domains            
            var requestMock = Mock.Get(UmbracoSettings.RequestHandler);
            requestMock.Setup(x => x.UseDomainPrefixes).Returns(true);

			InitializeLanguagesAndDomains();
			SetDomains1();

			RoutingContext routingContext;
			string url = "http://domain1.com/1001-1/1001-1-1";
			
			// get the nice url for 100111
			routingContext = GetRoutingContext(url);
			Assert.AreEqual("http://domain2.com/1001-1-1/", routingContext.UrlProvider.GetUrl(100111, true));

			// check that the proper route has been cached
		    var cache = routingContext.UmbracoContext.ContentCache.InnerCache as PublishedContentCache;
            if (cache == null) throw new Exception("Unsupported IPublishedContentCache, only the Xml one is supported.");
		    var cachedRoutes = cache.RoutesCache.GetCachedRoutes();
			Assert.AreEqual("10011/1001-1-1", cachedRoutes[100111]);

			// route a rogue url
			url = "http://domain1.com/1001-1/1001-1-1";
			var uri = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var pcr = new PublishedContentRequest(uri, routingContext);
			pcr.Engine.FindDomain();
			Assert.IsTrue(pcr.HasDomain);

			// check that it's been routed
			var lookup = new ContentFinderByNiceUrl();
			var result = lookup.TryFindContent(pcr);
			Assert.IsTrue(result);
			Assert.AreEqual(100111, pcr.PublishedContent.Id);

			// has the cache been polluted?
            cachedRoutes = cache.RoutesCache.GetCachedRoutes();
			Assert.AreEqual("10011/1001-1-1", cachedRoutes[100111]); // no
			//Assert.AreEqual("1001/1001-1/1001-1-1", cachedRoutes[100111]); // yes

			// what's the nice url now?
			Assert.AreEqual("http://domain2.com/1001-1-1/", routingContext.UrlProvider.GetUrl(100111)); // good
			//Assert.AreEqual("http://domain1.com/1001-1/1001-1-1", routingContext.NiceUrlProvider.GetNiceUrl(100111, true)); // bad
		}
		public void Match_Document_By_Url_With_Template(string urlAsString)
		{
            var template = CreateTemplate("test");
            var altTemplate = CreateTemplate("blah");
			var routingContext = GetRoutingContext(urlAsString, template);
			var url = routingContext.UmbracoContext.CleanedUmbracoUrl; //very important to use the cleaned up umbraco url
			var docRequest = new PublishedContentRequest(url, routingContext);
			var lookup = new ContentFinderByNiceUrlAndTemplate();

		    SettingsForTests.HideTopLevelNodeFromPath = false;

			var result = lookup.TryFindContent(docRequest);

			Assert.IsTrue(result);
			Assert.IsNotNull(docRequest.PublishedContent);
			Assert.IsNotNull(docRequest.TemplateAlias);
			Assert.AreEqual("blah".ToUpperInvariant(), docRequest.TemplateAlias.ToUpperInvariant());
		}
        private static bool TryRedirect(PublishedContentRequest contentRequest, bool includeQuery)
        {
            bool redirect = false;
            string path = string.Format("{0}{1}{2}", contentRequest.Uri.Authority
                                                   , contentRequest.Uri.AbsolutePath
                                                   , includeQuery ? contentRequest.Uri.Query : String.Empty
                                       );

            RedirectInfo redirectInfo;

            if (RedirectFromTo.TryGetValue(path, out redirectInfo) && !string.IsNullOrWhiteSpace(redirectInfo.To))
            {
                contentRequest.SetRedirect(redirectInfo.To, redirectInfo.StatusCode);
                redirect = true;
            }

            return redirect;
        }
        // notes
        //
        // at the moment we load the legacy INotFoundHandler
        // excluding those that have been replaced by proper finders,
        // and run them.

        /// <summary>
        /// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
        /// </summary>
        /// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>
        /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
        public bool TryFindContent(PublishedContentRequest docRequest)
        {
            HandlePageNotFound(docRequest);
            return(docRequest.HasPublishedContent);
        }
        // notes
        //
        // at the moment we load the legacy INotFoundHandler
        // excluding those that have been replaced by proper finders,
        // and run them.

        /// <summary>
        /// Tries to find and assign an Umbraco document to a <c>PublishedContentRequest</c>.
        /// </summary>
        /// <param name="docRequest">The <c>PublishedContentRequest</c>.</param>
        /// <returns>A value indicating whether an Umbraco document was found and assigned.</returns>
        public bool TrySetDocument(PublishedContentRequest docRequest)
        {
            HandlePageNotFound(docRequest);
            return(docRequest.HasNode);
        }
        //FIXME: this is temporary and should be obsoleted

        void HandlePageNotFound(PublishedContentRequest docRequest)
        {
            var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();

            LogHelper.Debug <LookupByNotFoundHandlers>("Running for legacy url='{0}'.", () => url);

            foreach (var handler in GetNotFoundHandlers())
            {
                IPublishedContentLookup lookup = null;

                LogHelper.Debug <LookupByNotFoundHandlers>("Handler '{0}'.", () => handler.GetType().FullName);

                // replace with our own implementation
                if (handler is global::umbraco.SearchForAlias)
                {
                    lookup = new LookupByAlias();
                }
                else if (handler is global::umbraco.SearchForProfile)
                {
                    lookup = new LookupByProfile();
                }
                else if (handler is global::umbraco.SearchForTemplate)
                {
                    lookup = new LookupByNiceUrlAndTemplate();
                }
                else if (handler is global::umbraco.handle404)
                {
                    lookup = new LookupByLegacy404();
                }

                if (lookup != null)
                {
                    LogHelper.Debug <LookupByNotFoundHandlers>("Replace handler '{0}' by new lookup '{1}'.", () => handler.GetType().FullName, () => lookup.GetType().FullName);
                    if (lookup.TrySetDocument(docRequest))
                    {
                        // do NOT set docRequest.PublishedContent again here as
                        // it would clear any template that the finder might have set
                        LogHelper.Debug <LookupByNotFoundHandlers>("Lookup '{0}' found node with id={1}.", () => lookup.GetType().FullName, () => docRequest.PublishedContent.Id);
                        if (docRequest.Is404)
                        {
                            LogHelper.Debug <LookupByNotFoundHandlers>("Lookup '{0}' set status to 404.", () => lookup.GetType().FullName);
                        }

                        // if we found a document, break, don't look at more handler -- we're done
                        break;
                    }

                    // if we did not find a document, continue, look at other handlers
                    continue;
                }

                // else it's a legacy handler, run

                if (handler.Execute(url) && handler.redirectID > 0)
                {
                    docRequest.PublishedContent = docRequest.RoutingContext.PublishedContentStore.GetDocumentById(
                        docRequest.RoutingContext.UmbracoContext,
                        handler.redirectID);

                    if (!docRequest.HasNode)
                    {
                        LogHelper.Debug <LookupByNotFoundHandlers>("Handler '{0}' found node with id={1} which is not valid.", () => handler.GetType().FullName, () => handler.redirectID);
                        break;
                    }

                    LogHelper.Debug <LookupByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handler.GetType().FullName, () => handler.redirectID);

                    if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
                    {
                        LogHelper.Debug <LookupByNotFoundHandlers>("Handler '{0}' set status code to 404.", () => handler.GetType().FullName);
                        docRequest.Is404 = true;
                    }

                    //// check for caching
                    //if (handler.CacheUrl)
                    //{
                    //    if (url.StartsWith("/"))
                    //        url = "/" + url;

                    //    var cacheKey = (currentDomain == null ? "" : currentDomain.Name) + url;
                    //    var culture = currentDomain == null ? null : currentDomain.Language.CultureAlias;
                    //    SetCache(cacheKey, new CacheEntry(handler.redirectID.ToString(), culture));

                    //    HttpContext.Current.Trace.Write("NotFoundHandler",
                    //        string.Format("Added to cache '{0}', {1}.", url, handler.redirectID));
                    //}

                    // if we found a document, break, don't look at more handler -- we're done
                    break;
                }

                // if we did not find a document, continue, look at other handlers
            }
        }
        private static void HandlePageNotFound(PublishedContentRequest docRequest)
        {
            var url = NotFoundHandlerHelper.GetLegacyUrlForNotFoundHandlers();

            LogHelper.Debug <ContentFinderByNotFoundHandlers>("Running for legacy url='{0}'.", () => url);

            foreach (var handler in NotFoundHandlerHelper.GetNotFoundHandlers())
            {
                var handlerName = handler.GetType().FullName;
                LogHelper.Debug <ContentFinderByNotFoundHandlers>("Handler '{0}'.", () => handlerName);

                var finder = NotFoundHandlerHelper.SubsituteFinder(handler);
                if (finder != null)
                {
                    var finderName = finder.GetType().FullName;
                    LogHelper.Debug <ContentFinderByNotFoundHandlers>("Replace handler '{0}' by new finder '{1}'.", () => handlerName, () => finderName);

                    // can't find a document => continue with other handlers
                    if (finder.TryFindContent(docRequest) == false)
                    {
                        continue;
                    }

                    // found a document => break, don't run other handlers, we're done

                    // in theory an IContentFinder can return true yet set no document
                    // but none of the substitued finders (see SubstituteFinder) do it.

                    // do NOT set docRequest.PublishedContent again here
                    // as it would clear any template that the finder might have set

                    LogHelper.Debug <ContentFinderByNotFoundHandlers>("Finder '{0}' found node with id={1}.", () => finderName, () => docRequest.PublishedContent.Id);
                    if (docRequest.Is404)
                    {
                        LogHelper.Debug <ContentFinderByNotFoundHandlers>("Finder '{0}' set status to 404.", () => finderName);
                    }

                    LogHelper.Debug <ContentFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => docRequest.PublishedContent.Id);
                    break;
                }

                // else it's a legacy handler: run

                // can't find a document => continue with other handlers
                if (handler.Execute(url) == false || handler.redirectID <= 0)
                {
                    continue;
                }

                // found a document ID => ensure it's a valid document
                var redirectId = handler.redirectID;
                docRequest.PublishedContent = docRequest.RoutingContext.UmbracoContext.ContentCache.GetById(redirectId);

                if (docRequest.HasPublishedContent == false)
                {
                    // the handler said it could handle the url, and returned a content ID
                    // yet that content ID is invalid... should we run the other handlers?
                    // I don't think so, not here, let the "last chance" finder take care.
                    // so, break.

                    LogHelper.Debug <ContentFinderByNotFoundHandlers>("Handler '{0}' found node with id={1} which is not valid.", () => handlerName, () => redirectId);
                    break;
                }

                // found a valid document => break, don't run other handlers, we're done

                LogHelper.Debug <ContentFinderByNotFoundHandlers>("Handler '{0}' found valid node with id={1}.", () => handlerName, () => redirectId);

                if (docRequest.RoutingContext.UmbracoContext.HttpContext.Response.StatusCode == 404)
                {
                    LogHelper.Debug <ContentFinderByNotFoundHandlers>("Handler '{0}' set status code to 404.", () => handlerName);
                    docRequest.Is404 = true;
                }

                break;
            }
        }