@@ -0,0 +1,72 @@
|
||||
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));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user