mirror of
https://github.com/leonvanzyl/autocoder.git
synced 2026-03-17 02:43:09 +00:00
fix: accept WebSocket before validation to prevent opaque 403 errors
All WebSocket endpoints now call websocket.accept() before any validation checks. Previously, closing the connection before accepting caused Starlette to return an opaque HTTP 403 instead of a meaningful error message. Changes: - Server: Accept WebSocket first, then send JSON error + close with 4xxx code if validation fails (expand, spec, assistant, terminal, main project WS) - Server: ConnectionManager.connect() no longer calls accept() to avoid double-accept - UI: Gate expand button and keyboard shortcut on hasSpec - UI: Skip WebSocket reconnection on application error codes (4000-4999) - UI: Update keyboard shortcuts help text Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -225,9 +225,7 @@ async def terminal_websocket(websocket: WebSocket, project_name: str, terminal_i
|
|||||||
await websocket.accept()
|
await websocket.accept()
|
||||||
|
|
||||||
# Validate project name
|
# Validate project name
|
||||||
try:
|
if not validate_project_name(project_name):
|
||||||
project_name = validate_project_name(project_name)
|
|
||||||
except Exception:
|
|
||||||
await websocket.send_json({"type": "error", "message": "Invalid project name"})
|
await websocket.send_json({"type": "error", "message": "Invalid project name"})
|
||||||
await websocket.close(
|
await websocket.close(
|
||||||
code=TerminalCloseCode.INVALID_PROJECT_NAME, reason="Invalid project name"
|
code=TerminalCloseCode.INVALID_PROJECT_NAME, reason="Invalid project name"
|
||||||
|
|||||||
@@ -728,9 +728,7 @@ async def project_websocket(websocket: WebSocket, project_name: str):
|
|||||||
# Always accept WebSocket first to avoid opaque 403 errors
|
# Always accept WebSocket first to avoid opaque 403 errors
|
||||||
await websocket.accept()
|
await websocket.accept()
|
||||||
|
|
||||||
try:
|
if not validate_project_name(project_name):
|
||||||
project_name = validate_project_name(project_name)
|
|
||||||
except Exception:
|
|
||||||
await websocket.send_json({"type": "error", "content": "Invalid project name"})
|
await websocket.send_json({"type": "error", "content": "Invalid project name"})
|
||||||
await websocket.close(code=4000, reason="Invalid project name")
|
await websocket.close(code=4000, reason="Invalid project name")
|
||||||
return
|
return
|
||||||
@@ -885,8 +883,7 @@ async def project_websocket(websocket: WebSocket, project_name: str):
|
|||||||
break
|
break
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
logger.warning(f"Invalid JSON from WebSocket: {data[:100] if data else 'empty'}")
|
logger.warning(f"Invalid JSON from WebSocket: {data[:100] if data else 'empty'}")
|
||||||
except Exception as e:
|
except Exception:
|
||||||
logger.warning(f"WebSocket error: {e}")
|
|
||||||
break
|
break
|
||||||
|
|
||||||
finally:
|
finally:
|
||||||
|
|||||||
Reference in New Issue
Block a user