refactor(battle-node): distinct WS auth status codes + named handler delegate

This commit is contained in:
gamer147
2026-06-01 11:45:50 -04:00
parent a364f539ad
commit 2588388d9d
2 changed files with 20 additions and 8 deletions

View File

@@ -51,11 +51,19 @@ public static class BattleNodeExtensions
public static IApplicationBuilder UseBattleNode(this IApplicationBuilder app)
{
app.UseWebSockets();
app.Map("/socket.io", branch => branch.Run(async ctx =>
{
var handler = ctx.RequestServices.GetRequiredService<BattleNodeWebSocketHandler>();
await handler.HandleAsync(ctx);
}));
app.Map("/socket.io", branch => branch.Run(HandleSocketIoAsync));
return app;
}
/// <summary>
/// Terminal handler for <c>/socket.io/*</c> — resolves the singleton
/// <see cref="BattleNodeWebSocketHandler"/> from DI and hands the request over.
/// Extracted from the inline lambda in <see cref="UseBattleNode"/> so stack traces
/// show a real method name during WS connect failures.
/// </summary>
private static async Task HandleSocketIoAsync(Microsoft.AspNetCore.Http.HttpContext ctx)
{
var handler = ctx.RequestServices.GetRequiredService<BattleNodeWebSocketHandler>();
await handler.HandleAsync(ctx);
}
}

View File

@@ -47,6 +47,10 @@ public sealed class BattleNodeWebSocketHandler
/// </summary>
public async Task HandleAsync(HttpContext ctx)
{
// Status code mapping: 400 protocol violations (not WS, missing creds);
// 401 credential validation failures (decrypt, viewer mismatch); 404 unknown
// BattleId. Log messages carry the diagnostic detail; the wire code gives the
// client class of failure.
if (!ctx.WebSockets.IsWebSocketRequest)
{
ctx.Response.StatusCode = StatusCodes.Status400BadRequest;
@@ -75,7 +79,7 @@ public sealed class BattleNodeWebSocketHandler
catch (Exception ex)
{
_log.LogWarning(ex, "viewerId failed to decrypt (encryptedLen={Len})", encryptedViewerId.Length);
ctx.Response.StatusCode = StatusCodes.Status400BadRequest;
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}
@@ -86,7 +90,7 @@ public sealed class BattleNodeWebSocketHandler
"WS upgrade for unknown BattleId={Bid} (decrypted viewerId={Vid}). " +
"Bridge may not have minted this battle, or it was already consumed/expired.",
battleId, viewerId);
ctx.Response.StatusCode = StatusCodes.Status400BadRequest;
ctx.Response.StatusCode = StatusCodes.Status404NotFound;
return;
}
if (pending.ViewerId != viewerId)
@@ -94,7 +98,7 @@ public sealed class BattleNodeWebSocketHandler
_log.LogWarning(
"WS upgrade viewer-id mismatch on BattleId={Bid}: bridge expected={Expected}, decrypted={Got}.",
battleId, pending.ViewerId, viewerId);
ctx.Response.StatusCode = StatusCodes.Status400BadRequest;
ctx.Response.StatusCode = StatusCodes.Status401Unauthorized;
return;
}