fix(battle-node): read WS credentials from headers; skip Steam auth on WS upgrades
Two issues caught in the real-client smoke: 1) BestHTTP's SocketOptions.AdditionalQueryParams puts BattleId and viewerId on HTTP request HEADERS for WebSocket-only transport (NOT on the URL query string as the in-battle/transport.md spec says). Real clients therefore send them as headers; our handler was reading from query and rejecting every connect with "Unknown battle/viewer pair: <bid>/<garbage>". Fix: header-first, query- fallback (so the integration test still works against TestServer). 2) The Steam auth handler was running on every WS upgrade and throwing NotSupportedException on Request.Body.Seek (Kestrel's HttpRequestStream doesn't support Seek, and a WS upgrade is GET with Content-Length: 0 anyway). It flooded logs and added no value — the battle node has its own per-connection credentials. Skip auth when IsWebSocketRequest is true. Spec correction for in-battle/transport.md to follow. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -35,6 +35,15 @@ public class SteamSessionAuthenticationHandler : AuthenticationHandler<SteamAuth
|
||||
protected async override Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
string path = Request.Path;
|
||||
// WebSocket upgrades carry no body — Request.Body.Seek throws NotSupportedException
|
||||
// on Kestrel's HttpRequestStream. The battle node has its own per-connection auth
|
||||
// (encrypted viewerId query/header validated against the matched battle id), so the
|
||||
// Steam handler has nothing to do here. Returning NoResult lets the request proceed
|
||||
// unauthenticated to the WS endpoint.
|
||||
if (Context.WebSockets.IsWebSocketRequest)
|
||||
{
|
||||
return AuthenticateResult.NoResult();
|
||||
}
|
||||
byte[] requestBytes;
|
||||
try
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user