less allocations with AbsolutePathDecoded. removes more aspx checks, adds UmbracoRouteValueTransformerTests, adds interface for IRoutableDocumentFilter

This commit is contained in:
Shannon
2021-01-13 11:08:48 +11:00
parent 456cb00a2d
commit d1df6c4719
24 changed files with 255 additions and 74 deletions

View File

@@ -49,7 +49,7 @@ namespace Umbraco.Web.Routing
}
IPublishedContent node = null;
var path = frequest.Uri.GetAbsolutePathDecoded();
var path = frequest.AbsolutePathDecoded;
var nodeId = -1;

View File

@@ -51,8 +51,8 @@ namespace Umbraco.Web.Routing
}
var route = frequest.Domain != null
? frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded())
: frequest.Uri.GetAbsolutePathDecoded();
? frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.AbsolutePathDecoded)
: frequest.AbsolutePathDecoded;
IRedirectUrl redirectUrl = _redirectUrlService.GetMostRecentRedirectUrl(route, frequest.Culture);

View File

@@ -44,11 +44,11 @@ namespace Umbraco.Web.Routing
string route;
if (frequest.Domain != null)
{
route = frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.Uri.GetAbsolutePathDecoded());
route = frequest.Domain.ContentId + DomainUtilities.PathRelativeToDomain(frequest.Domain.Uri, frequest.AbsolutePathDecoded);
}
else
{
route = frequest.Uri.GetAbsolutePathDecoded();
route = frequest.AbsolutePathDecoded;
}
IPublishedContent node = FindContent(frequest, route);

View File

@@ -60,7 +60,7 @@ namespace Umbraco.Web.Routing
umbCtx.Content,
frequest.Domain != null ? frequest.Domain.ContentId : 0,
frequest.Culture,
frequest.Uri.GetAbsolutePathDecoded());
frequest.AbsolutePathDecoded);
if (node != null)
{

View File

@@ -49,7 +49,7 @@ namespace Umbraco.Web.Routing
/// <remarks>If successful, also assigns the template.</remarks>
public override bool TryFindContent(IPublishedRequestBuilder frequest)
{
var path = frequest.Uri.GetAbsolutePathDecoded();
var path = frequest.AbsolutePathDecoded;
if (frequest.Domain != null)
{

View File

@@ -364,9 +364,7 @@ namespace Umbraco.Web.Routing
/// <returns>The path part relative to the uri of the domain.</returns>
/// <remarks>Eg the relative part of <c>/foo/bar/nil</c> to domain <c>example.com/foo</c> is <c>/bar/nil</c>.</remarks>
public static string PathRelativeToDomain(Uri domainUri, string path)
{
return path.Substring(domainUri.GetAbsolutePathDecoded().Length).EnsureStartsWith('/');
}
=> path.Substring(domainUri.GetAbsolutePathDecoded().Length).EnsureStartsWith('/');
#endregion
}

View File

@@ -18,6 +18,11 @@ namespace Umbraco.Web.Routing
/// <remarks>The cleaned up Uri has no virtual directory, no trailing slash, no .aspx extension, etc.</remarks>
Uri Uri { get; }
/// <summary>
/// Gets the decoded absolute path of the <see cref="Uri"/>
/// </summary>
string AbsolutePathDecoded { get; }
/// <summary>
/// Gets the <see cref="DomainAndUri"/> assigned (if any)
/// </summary>

View File

@@ -3,6 +3,7 @@ using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Net;
using Umbraco.Core;
using Umbraco.Core.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
@@ -26,12 +27,16 @@ namespace Umbraco.Web.Routing
public PublishedRequestBuilder(Uri uri, IFileService fileService)
{
Uri = uri;
AbsolutePathDecoded = uri.GetAbsolutePathDecoded();
_fileService = fileService;
}
/// <inheritdoc/>
public Uri Uri { get; }
/// <inheritdoc/>
public string AbsolutePathDecoded { get; }
/// <inheritdoc/>
public DomainAndUri Domain { get; private set; }

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Text;
using Umbraco.Core;
using Umbraco.Core.Configuration;
@@ -88,6 +88,10 @@ namespace Umbraco.Web
// ie no virtual directory, no .aspx, lowercase...
public Uri UriToUmbraco(Uri uri)
{
// TODO: Ideally we do this witout so many string allocations, we can use
// techniques like StringSegment and Span. This is critical code that executes on every request.
// not really sure we need ToLower.
// note: no need to decode uri here because we're returning a uri
// so it will be re-encoded anyway
var path = uri.GetSafeAbsolutePath();
@@ -95,23 +99,11 @@ namespace Umbraco.Web
path = path.ToLower();
path = ToAppRelative(path); // strip vdir if any
//we need to check if the path is /default.aspx because this will occur when using a
//web server pre IIS 7 when requesting the root document
//if this is the case we need to change it to '/'
if (path.StartsWith("/default.aspx", StringComparison.InvariantCultureIgnoreCase))
{
string rempath = path.Substring("/default.aspx".Length, path.Length - "/default.aspx".Length);
path = rempath.StartsWith("/") ? rempath : "/" + rempath;
}
if (path != "/")
{
path = path.TrimEnd('/');
}
//if any part of the path contains .aspx, replace it with nothing.
//sometimes .aspx is not at the end since we might have /home/sub1.aspx/customtemplate
path = path.Replace(".aspx", "");
return uri.Rewrite(path);
}

View File

@@ -61,7 +61,9 @@ namespace Umbraco.Core
public static string GetSafeAbsolutePath(this Uri uri)
{
if (uri.IsAbsoluteUri)
{
return uri.AbsolutePath;
}
// cannot get .AbsolutePath on relative uri (InvalidOperation)
var s = uri.OriginalString;

View File

@@ -61,7 +61,7 @@ namespace Umbraco.Web.Routing
}
else
{
var route = frequest.Uri.GetAbsolutePathDecoded();
var route = frequest.AbsolutePathDecoded;
var pos = route.LastIndexOf('/');
IPublishedContent node = null;
while (pos > 1)

View File

@@ -9,7 +9,7 @@
<PackageReference Include="MiniProfiler.AspNetCore" Version="4.2.1" />
<PackageReference Include="Moq" Version="4.13.1" />
<PackageReference Include="AutoFixture.NUnit3" Version="4.14.0" />
<PackageReference Include="Moq" Version="4.14.5" />
<PackageReference Include="Moq" Version="4.15.2" />
<PackageReference Include="nunit" Version="3.12.0" />
</ItemGroup>

View File

@@ -59,7 +59,7 @@
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.7" />
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="3.1.8" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.7.1" />
<PackageReference Include="Moq" Version="4.14.6" />
<PackageReference Include="Moq" Version="4.15.2" />
<PackageReference Include="nunit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0">
<PrivateAssets>all</PrivateAssets>

View File

@@ -79,13 +79,13 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing
}
[TestCase("Index", "RenderNotFound", null, false)]
[TestCase("index", "Render", "Index", true)]
[TestCase("Index", "Render1", "Index", true)]
[TestCase("Index", "render2", "Index", true)]
[TestCase("NotFound", "Render", "Index", true)]
[TestCase("NotFound", "Render1", "Index", true)]
[TestCase("NotFound", "Render2", "Index", true)]
[TestCase("Custom", "Render1", "Custom", true)]
[TestCase("index", "Render", nameof(RenderController.Index), true)]
[TestCase("Index", "Render1", nameof(RenderController.Index), true)]
[TestCase("Index", "render2", nameof(Render2Controller.Index), true)]
[TestCase("NotFound", "Render", nameof(RenderController.Index), true)]
[TestCase("NotFound", "Render1", nameof(Render1Controller.Index), true)]
[TestCase("NotFound", "Render2", nameof(Render2Controller.Index), true)]
[TestCase("Custom", "Render1", nameof(Render1Controller.Custom), true)]
public void Matches_Controller(string action, string controller, string resultAction, bool matches)
{
var evaluator = new HijackedRouteEvaluator(

View File

@@ -0,0 +1,170 @@
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.ViewEngines;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Logging.Abstractions;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Extensions;
using Umbraco.Tests.TestHelpers;
using Umbraco.Web;
using Umbraco.Web.Common.Controllers;
using Umbraco.Web.Common.Routing;
using Umbraco.Web.PublishedCache;
using Umbraco.Web.Routing;
using Umbraco.Web.Website.Controllers;
using Umbraco.Web.Website.Routing;
namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing
{
[TestFixture]
public class UmbracoRouteValueTransformerTests
{
private IOptions<GlobalSettings> GetGlobalSettings() => Options.Create(new GlobalSettings());
private UmbracoRouteValueTransformer GetTransformerWithRunState(
IUmbracoContextAccessor ctx,
IRoutableDocumentFilter filter = null,
IPublishedRouter router = null,
IUmbracoRouteValuesFactory routeValuesFactory = null)
=> GetTransformer(ctx, Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run), filter, router, routeValuesFactory);
private UmbracoRouteValueTransformer GetTransformer(
IUmbracoContextAccessor ctx,
IRuntimeState state,
IRoutableDocumentFilter filter = null,
IPublishedRouter router = null,
IUmbracoRouteValuesFactory routeValuesFactory = null)
{
var transformer = new UmbracoRouteValueTransformer(
new NullLogger<UmbracoRouteValueTransformer>(),
ctx,
router ?? Mock.Of<IPublishedRouter>(),
GetGlobalSettings(),
TestHelper.GetHostingEnvironment(),
state,
routeValuesFactory ?? Mock.Of<IUmbracoRouteValuesFactory>(),
filter ?? Mock.Of<IRoutableDocumentFilter>(x => x.IsDocumentRequest(It.IsAny<string>()) == true));
return transformer;
}
private IUmbracoContext GetUmbracoContext(bool hasContent)
{
IPublishedContentCache publishedContent = Mock.Of<IPublishedContentCache>(x => x.HasContent() == hasContent);
var uri = new Uri("http://example.com");
IUmbracoContext umbracoContext = Mock.Of<IUmbracoContext>(x =>
x.Content == publishedContent
&& x.OriginalRequestUrl == uri
&& x.CleanedUmbracoUrl == uri);
return umbracoContext;
}
private UmbracoRouteValues GetRouteValues(IPublishedRequest request)
=> new UmbracoRouteValues(
request,
ControllerExtensions.GetControllerName<TestController>(),
typeof(TestController));
private IUmbracoRouteValuesFactory GetRouteValuesFactory(IPublishedRequest request)
=> Mock.Of<IUmbracoRouteValuesFactory>(x => x.Create(It.IsAny<HttpContext>(), It.IsAny<RouteValueDictionary>(), It.IsAny<IPublishedRequest>()) == GetRouteValues(request));
private IPublishedRouter GetRouter(IPublishedRequest request)
=> Mock.Of<IPublishedRouter>(x => x.RouteRequestAsync(It.IsAny<IPublishedRequestBuilder>(), It.IsAny<RouteRequestOptions>()) == Task.FromResult(request));
[Test]
public async Task Noop_When_Runtime_Level_Not_Run()
{
UmbracoRouteValueTransformer transformer = GetTransformer(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == null),
Mock.Of<IRuntimeState>());
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(0, result.Count);
}
[Test]
public async Task Noop_When_No_Umbraco_Context()
{
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == null));
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(0, result.Count);
}
[Test]
public async Task Noop_When_Not_Document_Request()
{
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == Mock.Of<IUmbracoContext>()),
Mock.Of<IRoutableDocumentFilter>(x => x.IsDocumentRequest(It.IsAny<string>()) == false));
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(0, result.Count);
}
[Test]
public async Task NoContentController_Values_When_No_Content()
{
IUmbracoContext umbracoContext = GetUmbracoContext(false);
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == umbracoContext));
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(2, result.Count);
Assert.AreEqual(ControllerExtensions.GetControllerName<RenderNoContentController>(), result["controller"]);
Assert.AreEqual(nameof(RenderNoContentController.Index), result["action"]);
}
[Test]
public async Task Assigns_PublishedRequest_To_UmbracoContext()
{
IUmbracoContext umbracoContext = GetUmbracoContext(true);
IPublishedRequest request = Mock.Of<IPublishedRequest>();
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == umbracoContext),
router: GetRouter(request),
routeValuesFactory: GetRouteValuesFactory(request));
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(request, umbracoContext.PublishedRequest);
}
[Test]
public async Task Assigns_Values_To_RouteValueDictionary()
{
IUmbracoContext umbracoContext = GetUmbracoContext(true);
IPublishedRequest request = Mock.Of<IPublishedRequest>();
UmbracoRouteValues routeValues = GetRouteValues(request);
UmbracoRouteValueTransformer transformer = GetTransformerWithRunState(
Mock.Of<IUmbracoContextAccessor>(x => x.UmbracoContext == umbracoContext),
router: GetRouter(request),
routeValuesFactory: GetRouteValuesFactory(request));
RouteValueDictionary result = await transformer.TransformAsync(new DefaultHttpContext(), new RouteValueDictionary());
Assert.AreEqual(routeValues.ControllerName, result["controller"]);
Assert.AreEqual(routeValues.ActionName, result["action"]);
}
private class TestController : RenderController
{
public TestController(ILogger<RenderController> logger, ICompositeViewEngine compositeViewEngine, IUmbracoContextAccessor umbracoContextAccessor)
: base(logger, compositeViewEngine, umbracoContextAccessor)
{
}
}
}
}

View File

@@ -1,4 +1,4 @@
using System;
using System;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.AspNetCore.Routing;
@@ -18,16 +18,17 @@ using Umbraco.Web.Website.Routing;
namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing
{
[TestFixture]
public class UmbracoRouteValuesFactoryTests
{
private UmbracoRouteValuesFactory GetFactory(IPublishedRouter router, out UmbracoRenderingDefaults renderingDefaults)
private UmbracoRouteValuesFactory GetFactory(out Mock<IPublishedRouter> publishedRouter, out UmbracoRenderingDefaults renderingDefaults)
{
var builder = new PublishedRequestBuilder(new Uri("https://example.com"), Mock.Of<IFileService>());
builder.SetPublishedContent(Mock.Of<IPublishedContent>());
IPublishedRequest request = builder.Build();
var publishedRouter = new Mock<IPublishedRouter>();
publishedRouter = new Mock<IPublishedRouter>();
publishedRouter.Setup(x => x.UpdateRequestToNotFound(It.IsAny<IPublishedRequest>()))
.Returns((IPublishedRequest r) => builder)
.Verifiable();
@@ -53,12 +54,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing
builder.SetPublishedContent(Mock.Of<IPublishedContent>());
IPublishedRequest request = builder.Build();
var publishedRouter = new Mock<IPublishedRouter>();
publishedRouter.Setup(x => x.UpdateRequestToNotFound(It.IsAny<IPublishedRequest>()))
.Returns((IPublishedRequest r) => builder)
.Verifiable();
UmbracoRouteValuesFactory factory = GetFactory(publishedRouter.Object, out _);
UmbracoRouteValuesFactory factory = GetFactory(out Mock<IPublishedRouter> publishedRouter, out _);
UmbracoRouteValues result = factory.Create(new DefaultHttpContext(), new RouteValueDictionary(), request);
@@ -74,7 +70,7 @@ namespace Umbraco.Tests.UnitTests.Umbraco.Web.Website.Routing
builder.SetTemplate(Mock.Of<ITemplate>());
IPublishedRequest request = builder.Build();
UmbracoRouteValuesFactory factory = GetFactory(Mock.Of<IPublishedRouter>(), out UmbracoRenderingDefaults renderingDefaults);
UmbracoRouteValuesFactory factory = GetFactory(out _, out UmbracoRenderingDefaults renderingDefaults);
var routeVals = new RouteValueDictionary();
UmbracoRouteValues result = factory.Create(new DefaultHttpContext(), routeVals, request);

View File

@@ -112,7 +112,7 @@
<PackageReference Include="Microsoft.Owin.Testing" Version="4.1.1" />
<PackageReference Include="Microsoft.Web.Infrastructure" Version="1.0.0.0" />
<PackageReference Include="MiniProfiler" Version="4.2.1" />
<PackageReference Include="Moq" Version="4.14.6" />
<PackageReference Include="Moq" Version="4.15.2" />
<PackageReference Include="NPoco" Version="4.0.2" />
<PackageReference Include="NUnit" Version="3.12.0" />
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
@@ -307,7 +307,7 @@
<Service Include="{82A7F48D-3B50-4B1E-B82E-3ADA8210C358}" />
</ItemGroup>
<ItemGroup>
<Folder Include="IO" />
<Folder Include="IO\" />
</ItemGroup>
<!-- get NuGet packages directory -->
<PropertyGroup>

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
@@ -61,7 +61,7 @@ namespace Umbraco.Web.Common.AspNetCore
public Uri GetApplicationUrl()
{
//Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
// Fixme: This causes problems with site swap on azure because azure pre-warms a site by calling into `localhost` and when it does that
// it changes the URL to `localhost:80` which actually doesn't work for pinging itself, it only works internally in Azure. The ironic part
// about this is that this is here specifically for the slot swap scenario https://issues.umbraco.org/issue/U4-10626

View File

@@ -0,0 +1,7 @@
namespace Umbraco.Web.Common.Routing
{
public interface IRoutableDocumentFilter
{
bool IsDocumentRequest(string absPath);
}
}

View File

@@ -20,7 +20,7 @@ namespace Umbraco.Web.Common.Routing
/// <remarks>
/// There are various checks to determine if this is a front-end request such as checking if the request is part of any reserved paths or existing MVC routes.
/// </remarks>
public sealed class RoutableDocumentFilter
public sealed class RoutableDocumentFilter : IRoutableDocumentFilter
{
private readonly ConcurrentDictionary<string, bool> _routeChecks = new ConcurrentDictionary<string, bool>(StringComparer.OrdinalIgnoreCase);
private readonly GlobalSettings _globalSettings;

View File

@@ -16,6 +16,7 @@ namespace Umbraco.Web
public class UmbracoContext : DisposableObjectSlim, IDisposeOnRequestEnd, IUmbracoContext
{
private readonly IHostingEnvironment _hostingEnvironment;
private readonly UriUtility _uriUtility;
private readonly ICookieManager _cookieManager;
private readonly IRequestAccessor _requestAccessor;
private readonly Lazy<IPublishedSnapshot> _publishedSnapshot;
@@ -23,6 +24,8 @@ namespace Umbraco.Web
private bool? _previewing;
private readonly IBackOfficeSecurity _backofficeSecurity;
private readonly UmbracoRequestPaths _umbracoRequestPaths;
private Uri _originalRequestUrl;
private Uri _cleanedUmbracoUrl;
// initializes a new instance of the UmbracoContext class
// internal for unit tests
@@ -43,8 +46,8 @@ namespace Umbraco.Web
throw new ArgumentNullException(nameof(publishedSnapshotService));
}
VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
VariationContextAccessor = variationContextAccessor ?? throw new ArgumentNullException(nameof(variationContextAccessor));
_uriUtility = uriUtility;
_hostingEnvironment = hostingEnvironment;
_cookieManager = cookieManager;
_requestAccessor = requestAccessor;
@@ -56,15 +59,6 @@ namespace Umbraco.Web
// beware - we cannot expect a current user here, so detecting preview mode must be a lazy thing
_publishedSnapshot = new Lazy<IPublishedSnapshot>(() => publishedSnapshotService.CreatePublishedSnapshot(PreviewToken));
// set the urls...
// NOTE: The request will not be available during app startup so we can only set this to an absolute URL of localhost, this
// is a work around to being able to access the UmbracoContext during application startup and this will also ensure that people
// 'could' still generate URLs during startup BUT any domain driven URL generation will not work because it is NOT possible to get
// the current domain during application startup.
// see: http://issues.umbraco.org/issue/U4-1890
OriginalRequestUrl = _requestAccessor.GetRequestUrl() ?? new Uri("http://localhost");
CleanedUmbracoUrl = uriUtility.UriToUmbraco(OriginalRequestUrl);
}
/// <inheritdoc/>
@@ -79,10 +73,17 @@ namespace Umbraco.Web
internal Guid UmbracoRequestId { get; }
/// <inheritdoc/>
public Uri OriginalRequestUrl { get; }
// set the urls lazily, no need to allocate until they are needed...
// NOTE: The request will not be available during app startup so we can only set this to an absolute URL of localhost, this
// is a work around to being able to access the UmbracoContext during application startup and this will also ensure that people
// 'could' still generate URLs during startup BUT any domain driven URL generation will not work because it is NOT possible to get
// the current domain during application startup.
// see: http://issues.umbraco.org/issue/U4-1890
public Uri OriginalRequestUrl => _originalRequestUrl ?? (_originalRequestUrl = _requestAccessor.GetRequestUrl() ?? new Uri("http://localhost"));
/// <inheritdoc/>
public Uri CleanedUmbracoUrl { get; }
// set the urls lazily, no need to allocate until they are needed...
public Uri CleanedUmbracoUrl => _cleanedUmbracoUrl ?? (_cleanedUmbracoUrl = _uriUtility.UriToUmbraco(OriginalRequestUrl));
/// <inheritdoc/>
public IPublishedSnapshot PublishedSnapshot => _publishedSnapshot.Value;

View File

@@ -41,7 +41,7 @@ namespace Umbraco.Web.Website.DependencyInjection
builder.Services.AddSingleton<HijackedRouteEvaluator>();
builder.Services.AddSingleton<IUmbracoRouteValuesFactory, UmbracoRouteValuesFactory>();
builder.Services.AddSingleton<IUmbracoRenderingDefaults, UmbracoRenderingDefaults>();
builder.Services.AddSingleton<RoutableDocumentFilter>();
builder.Services.AddSingleton<IRoutableDocumentFilter, RoutableDocumentFilter>();
builder.AddDistributedCache();

View File

@@ -34,7 +34,7 @@ namespace Umbraco.Web.Website.Routing
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IRuntimeState _runtime;
private readonly IUmbracoRouteValuesFactory _routeValuesFactory;
private readonly RoutableDocumentFilter _routableDocumentFilter;
private readonly IRoutableDocumentFilter _routableDocumentFilter;
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoRouteValueTransformer"/> class.
@@ -47,16 +47,21 @@ namespace Umbraco.Web.Website.Routing
IHostingEnvironment hostingEnvironment,
IRuntimeState runtime,
IUmbracoRouteValuesFactory routeValuesFactory,
RoutableDocumentFilter routableDocumentFilter)
IRoutableDocumentFilter routableDocumentFilter)
{
_logger = logger;
_umbracoContextAccessor = umbracoContextAccessor;
_publishedRouter = publishedRouter;
if (globalSettings is null)
{
throw new System.ArgumentNullException(nameof(globalSettings));
}
_logger = logger ?? throw new System.ArgumentNullException(nameof(logger));
_umbracoContextAccessor = umbracoContextAccessor ?? throw new System.ArgumentNullException(nameof(umbracoContextAccessor));
_publishedRouter = publishedRouter ?? throw new System.ArgumentNullException(nameof(publishedRouter));
_globalSettings = globalSettings.Value;
_hostingEnvironment = hostingEnvironment;
_runtime = runtime;
_routeValuesFactory = routeValuesFactory;
_routableDocumentFilter = routableDocumentFilter;
_hostingEnvironment = hostingEnvironment ?? throw new System.ArgumentNullException(nameof(hostingEnvironment));
_runtime = runtime ?? throw new System.ArgumentNullException(nameof(runtime));
_routeValuesFactory = routeValuesFactory ?? throw new System.ArgumentNullException(nameof(routeValuesFactory));
_routableDocumentFilter = routableDocumentFilter ?? throw new System.ArgumentNullException(nameof(routableDocumentFilter));
}
/// <inheritdoc/>
@@ -113,9 +118,10 @@ namespace Umbraco.Web.Website.Routing
// an immutable object. The only way to make this better would be to have a RouteRequest
// as part of UmbracoContext but then it will require a PublishedRouter dependency so not sure that's worth it.
// Maybe could be a one-time Set method instead?
IPublishedRequest publishedRequest = umbracoContext.PublishedRequest = await _publishedRouter.RouteRequestAsync(requestBuilder, new RouteRequestOptions(RouteDirection.Inbound));
IPublishedRequest routedRequest = await _publishedRouter.RouteRequestAsync(requestBuilder, new RouteRequestOptions(RouteDirection.Inbound));
umbracoContext.PublishedRequest = routedRequest;
return publishedRequest;
return routedRequest;
}
}
}

View File

@@ -62,7 +62,6 @@ namespace Umbraco.Web
// 'could' still generate URLs during startup BUT any domain driven URL generation will not work because it is NOT possible to get
// the current domain during application startup.
// see: http://issues.umbraco.org/issue/U4-1890
//
OriginalRequestUrl = GetRequestFromContext()?.Url ?? new Uri("http://localhost");
CleanedUmbracoUrl = uriUtility.UriToUmbraco(OriginalRequestUrl);
}