This commit is contained in:
Daniel J. Summers 2023-07-04 23:33:36 -04:00
parent 805b04d127
commit e39ee05314
4 changed files with 112 additions and 1 deletions

1
.gitignore vendored
View File

@ -378,7 +378,6 @@ FodyWeavers.xsd
# VS Code files for those working on multiple tools # VS Code files for those working on multiple tools
.vscode/* .vscode/*
!.vscode/settings.json
!.vscode/tasks.json !.vscode/tasks.json
!.vscode/launch.json !.vscode/launch.json
!.vscode/extensions.json !.vscode/extensions.json

View File

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net7.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Abstractions" Version="2.2.0" />
<PackageReference Include="Microsoft.AspNetCore.Http.Extensions" Version="2.2.0" />
</ItemGroup>
</Project>

View File

@ -0,0 +1,41 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
namespace BitBadger.AspNetCore.CanonicalDomains;
public class CanonicalDomainMiddleware
{
/// <summary>
/// The domains which should be redirected
/// </summary>
internal static readonly IDictionary<string, string> CanonicalDomains = new Dictionary<string, string>();
/// <summary>
/// The next middleware in the pipeline to be executed
/// </summary>
private readonly RequestDelegate _next;
/// <summary>
/// Constructor
/// </summary>
/// <param name="next">The next middleware in the pipeline to be exectued</param>
public CanonicalDomainMiddleware(RequestDelegate next)
{
_next = next;
}
public async Task InvokeAsync(HttpContext ctx)
{
var host = ctx.Request.Host.Host;
if (CanonicalDomains.ContainsKey(host))
{
UriBuilder uri = new(ctx.Request.GetDisplayUrl());
uri.Host = CanonicalDomains[host];
ctx.Response.Redirect(uri.Uri.ToString ());
}
else
{
await _next.Invoke(ctx);
}
}
}

View File

@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace BitBadger.AspNetCore.CanonicalDomains;
/// <summary>
/// Extensions on the <see cref="IApplicationBuilder" /> interface
/// </summary>
public static class IApplicationBuilderExtensions
{
/// <summary>
/// Initialize and use the canonical domain middleware
/// </summary>
public static IApplicationBuilder UseCanonicalDomains(this IApplicationBuilder app)
{
void warnForMissingConfig() {
var logger = (ILogger<CanonicalDomainMiddleware>?)app.ApplicationServices
.GetService(typeof(ILogger<CanonicalDomainMiddleware>));
if (logger is not null)
{
logger.LogWarning("No canonical domain configuration was found; no domains will be redirected");
}
}
var config = (IConfiguration)app.ApplicationServices.GetService(typeof(IConfiguration))!;
var section = config.GetSection("CanonicalDomains");
if (section is not null)
{
foreach (var item in section.GetChildren())
{
var nonCanonical = item["From"];
var canonical = item["To"];
if (nonCanonical is not null && canonical is not null)
{
CanonicalDomainMiddleware.CanonicalDomains.Add(nonCanonical, canonical);
}
}
if (CanonicalDomainMiddleware.CanonicalDomains.Count > 0)
{
app.UseMiddleware<CanonicalDomainMiddleware> ();
}
else
{
warnForMissingConfig();
}
}
else
{
warnForMissingConfig();
}
return app;
}
}