Files
myAi/web/Middleware/SiteModeMiddleware.cs
T
claude aa79b422e4
Build and Push Docker Images / build (push) Successful in 31s
Changes
2026-05-20 14:25:07 +03:00

73 lines
2.1 KiB
C#

using Microsoft.Extensions.Options;
using Web.Settings;
namespace Web.Middleware;
public sealed class SiteModeMiddleware(RequestDelegate next, IOptions<SiteSettings> options)
{
private static readonly string[] StaticAssetPrefixes =
[
"/css/",
"/js/",
"/img/",
"/logo/",
"/fonts/"
];
public async Task InvokeAsync(HttpContext context)
{
var mode = ResolveMode(options.Value.Mode);
if (mode == SiteModes.Normal)
{
await next(context);
return;
}
var path = context.Request.Path.Value ?? "/";
var statusPath = GetStatusPath(mode);
if (IsAllowedPath(path, statusPath))
{
if (mode == SiteModes.Unavailable &&
path.Equals("/site-unavailable.html", StringComparison.OrdinalIgnoreCase))
{
context.Response.StatusCode = StatusCodes.Status503ServiceUnavailable;
context.Response.Headers.RetryAfter = "3600";
}
await next(context);
return;
}
context.Response.Redirect(statusPath);
}
private static string ResolveMode(string? configuredMode)
{
if (string.Equals(configuredMode, SiteModes.UnderConstruction, StringComparison.OrdinalIgnoreCase))
return SiteModes.UnderConstruction;
if (string.Equals(configuredMode, SiteModes.Unavailable, StringComparison.OrdinalIgnoreCase))
return SiteModes.Unavailable;
return SiteModes.Normal;
}
private static string GetStatusPath(string mode) =>
mode == SiteModes.UnderConstruction
? "/under-construction.html"
: "/site-unavailable.html";
private static bool IsAllowedPath(string path, string statusPath)
{
if (path.Equals(statusPath, StringComparison.OrdinalIgnoreCase))
return true;
if (path.Equals("/favicon.ico", StringComparison.OrdinalIgnoreCase))
return true;
return StaticAssetPrefixes.Any(prefix =>
path.StartsWith(prefix, StringComparison.OrdinalIgnoreCase));
}
}