Disable trailing slash redirect for webpanel

Fixes #1761
This commit is contained in:
Jordan Dominion
2024-01-20 18:21:46 -05:00
parent 9e7d306594
commit 4d73cf2bb7
3 changed files with 44 additions and 2 deletions
@@ -30,6 +30,11 @@ namespace Tgstation.Server.Host.Controllers
/// </summary>
public const string ControlPanelRoute = "/app";
/// <summary>
/// The route to the control panel channel .json.
/// </summary>
public const string ChannelJsonRoute = "channel.json";
/// <summary>
/// Header for forcing channel.json to be fetched.
/// </summary>
@@ -70,7 +75,7 @@ namespace Tgstation.Server.Host.Controllers
/// Returns the <see cref="ControlPanelConfiguration.Channel"/>.
/// </summary>
/// <returns>A <see cref="JsonResult"/> with the <see cref="ControlPanelConfiguration.Channel"/>.</returns>
[Route("channel.json")]
[Route(ChannelJsonRoute)]
[HttpGet]
public IActionResult GetChannelJson()
{
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Hosting;
@@ -61,6 +62,27 @@ namespace Tgstation.Server.Host.Controllers
/// </summary>
readonly ControlPanelConfiguration controlPanelConfiguration;
/// <summary>
/// Gets a <see cref="Tuple{T1, T2}"/> giving the <see cref="ControlPanelController"/> and action names for a given <paramref name="actionExpression"/>.
/// </summary>
/// <param name="actionExpression">An expression invoking the action on <see cref="ControlPanelController"/>.</param>
/// <returns>A <see cref="Tuple{T1, T2}"/> containing the controller and action names.</returns>
static Tuple<string, string?> GetControlPanelActionLink(Expression<Func<ControlPanelController, IActionResult>> actionExpression)
{
var memberSelectorExpression = (MethodCallExpression)actionExpression.Body;
var method = memberSelectorExpression.Method;
var controllerName = typeof(ControlPanelController).Name;
const string ControllerSuffix = nameof(Controller);
if (controllerName.EndsWith(ControllerSuffix, StringComparison.Ordinal))
controllerName = controllerName.Substring(0, controllerName.Length - ControllerSuffix.Length);
var actionName = method.Name;
return Tuple.Create<string, string?>(controllerName, actionName);
}
/// <summary>
/// Initializes a new instance of the <see cref="RootController"/> class.
/// </summary>
@@ -136,5 +158,19 @@ namespace Tgstation.Server.Host.Controllers
return (IActionResult?)this.TryServeFile(hostEnvironment, logger, $"{logoFileName}.svg") ?? NotFound();
}
/// <summary>
/// Workaround for the webpanel always expecting a trailing slash.
/// </summary>
/// <returns>A <see cref="RedirectResult"/> to the <see cref="ControlPanelController.GetChannelJson"/>.</returns>
[HttpGet(ControlPanelController.ChannelJsonRoute)]
public RedirectToActionResult WebpanelChannelRedirect()
{
var actionTuple = GetControlPanelActionLink(controller => controller.GetChannelJson());
return RedirectToActionPermanent(
actionTuple.Item2,
actionTuple.Item1);
}
}
}
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Frozen;
using System.Collections.Generic;
using System.Globalization;
@@ -524,6 +524,7 @@ namespace Tgstation.Server.Host.Core
RequestPath = ControlPanelController.ControlPanelRoute,
EnableDefaultFiles = true,
EnableDirectoryBrowsing = false,
RedirectToAppendTrailingSlash = false,
});
}
else