V13: Eaglery route domains for virtual page controllers (#16635)
* Do domain routing eagerly * Cleanup * Fix comment
This commit is contained in:
@@ -8,7 +8,9 @@ using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Cms.Web.Common.Controllers;
|
||||
using Umbraco.Cms.Web.Common.Routing;
|
||||
using Umbraco.Cms.Web.Website.Controllers;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
@@ -37,6 +39,8 @@ internal class EagerMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly EndpointDataSource _endpointDataSource;
|
||||
private readonly UmbracoRequestPaths _umbracoRequestPaths;
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IPublishedRouter _publishedRouter;
|
||||
private GlobalSettings _globalSettings;
|
||||
private readonly Lazy<Endpoint> _installEndpoint;
|
||||
private readonly Lazy<Endpoint> _renderEndpoint;
|
||||
@@ -45,11 +49,15 @@ internal class EagerMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
||||
IRuntimeState runtimeState,
|
||||
EndpointDataSource endpointDataSource,
|
||||
UmbracoRequestPaths umbracoRequestPaths,
|
||||
IOptionsMonitor<GlobalSettings> globalSettings)
|
||||
IOptionsMonitor<GlobalSettings> globalSettings,
|
||||
IUmbracoContextAccessor umbracoContextAccessor,
|
||||
IPublishedRouter publishedRouter)
|
||||
{
|
||||
_runtimeState = runtimeState;
|
||||
_endpointDataSource = endpointDataSource;
|
||||
_umbracoRequestPaths = umbracoRequestPaths;
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_publishedRouter = publishedRouter;
|
||||
_globalSettings = globalSettings.CurrentValue;
|
||||
globalSettings.OnChange(settings => _globalSettings = settings);
|
||||
_installEndpoint = new Lazy<Endpoint>(GetInstallEndpoint);
|
||||
@@ -112,11 +120,22 @@ internal class EagerMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
||||
ControllerActionDescriptor? controllerDescriptor = routeEndpoint.Metadata.GetMetadata<ControllerActionDescriptor>();
|
||||
TypeInfo? controllerTypeInfo = controllerDescriptor?.ControllerTypeInfo;
|
||||
if (controllerTypeInfo is not null &&
|
||||
(controllerTypeInfo.IsType<RenderController>() || controllerTypeInfo.IsType<SurfaceController>()))
|
||||
(controllerTypeInfo.IsType<RenderController>()
|
||||
|| controllerTypeInfo.IsType<SurfaceController>()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// If it's an UmbracoPageController we need to do some domain routing.
|
||||
// We need to do this in oder to handle cultures for our Dictionary.
|
||||
// This is because UmbracoPublishedContentCultureProvider is ued to set the Thread.CurrentThread.CurrentUICulture
|
||||
// The CultureProvider is run before the actual routing, this means that our UmbracoVirtualPageFilterAttribute is hit AFTER the culture is set.
|
||||
// Meaning we have to route the domain part already now, this is not pretty, but it beats having to look for content we know doesn't exist.
|
||||
if (controllerTypeInfo is not null && controllerTypeInfo.IsType<UmbracoPageController>())
|
||||
{
|
||||
await RouteVirtualRequestAsync(httpContext);
|
||||
}
|
||||
|
||||
if (routeEndpoint.Order < lowestOrder)
|
||||
{
|
||||
// We have to ensure that the route is valid for the current request method.
|
||||
@@ -153,6 +172,22 @@ internal class EagerMatcherPolicy : MatcherPolicy, IEndpointSelectorPolicy
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RouteVirtualRequestAsync(HttpContext context)
|
||||
{
|
||||
if (_umbracoContextAccessor.TryGetUmbracoContext(out IUmbracoContext? umbracoContext) is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
IPublishedRequestBuilder requestBuilder =
|
||||
await _publishedRouter.CreateRequestAsync(umbracoContext.CleanedUmbracoUrl);
|
||||
_publishedRouter.RouteDomain(requestBuilder);
|
||||
// This is just a temporary RouteValues object just for culture which will be overwritten later
|
||||
// so we can just use a dummy action descriptor.
|
||||
var umbracoRouteValues = new UmbracoRouteValues(requestBuilder.Build(), new ControllerActionDescriptor());
|
||||
context.Features.Set(umbracoRouteValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the first endpoint candidate with the specified endpoint, invalidating all other candidates,
|
||||
/// guaranteeing that the specified endpoint will be hit.
|
||||
|
||||
Reference in New Issue
Block a user