refactor(battle-node): distinct WS auth status codes + named handler delegate
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user