From 25a8fa43c3829e2fef4a06f5f810b6731e881756 Mon Sep 17 00:00:00 2001 From: huchenxi Date: Thu, 23 Apr 2026 00:28:32 +0800 Subject: [PATCH 1/2] fix(hub): raise Socket.IO maxHttpBufferSize for file downloads Socket.IO Engine defaults maxHttpBufferSize to 1MB. File downloads go through WebSocket RPC (CLI reads file -> base64 -> Socket.IO ack), so any file >750KB (after base64 inflation) silently drops the response, causing the frontend download spinner to hang indefinitely. Raise the default to 100MB and expose it via the HAPI_SOCKET_MAX_BUFFER_SIZE env var so operators can tune it. --- hub/src/socket/server.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/hub/src/socket/server.ts b/hub/src/socket/server.ts index 19086a95b4..5e612fe3ff 100644 --- a/hub/src/socket/server.ts +++ b/hub/src/socket/server.ts @@ -20,6 +20,7 @@ const jwtPayloadSchema = z.object({ const DEFAULT_IDLE_TIMEOUT_MS = 15 * 60_000 const DEFAULT_MAX_TERMINALS = 4 +const DEFAULT_MAX_HTTP_BUFFER_SIZE = 100 * 1024 * 1024 function resolveEnvNumber(name: string, fallback: number): number { const raw = process.env[name] @@ -63,6 +64,7 @@ export function createSocketServer(deps: SocketServerDeps): { const engine = new Engine({ path: '/socket.io/', cors: corsOptions, + maxHttpBufferSize: resolveEnvNumber('HAPI_SOCKET_MAX_BUFFER_SIZE', DEFAULT_MAX_HTTP_BUFFER_SIZE), allowRequest: async (req) => { const origin = req.headers.get('origin') if (!origin || allowAllOrigins || corsOrigins.includes(origin)) { From a42367b1aef80bad47823c08e1be0852ec04bafe Mon Sep 17 00:00:00 2001 From: huchenxi Date: Mon, 27 Apr 2026 14:50:36 +0800 Subject: [PATCH 2/2] fix: tighten default maxHttpBufferSize and cap env override Address review feedback: - Lower default from 100MB to ~68MB (ceil(50MB * 4/3)) to just cover base64 inflation of the 50MB product file cap. - Add a max parameter to resolveEnvNumber so the env override cannot exceed the default, preventing unauthenticated frame budget abuse. --- hub/src/socket/server.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/hub/src/socket/server.ts b/hub/src/socket/server.ts index 5e612fe3ff..385a8aacdc 100644 --- a/hub/src/socket/server.ts +++ b/hub/src/socket/server.ts @@ -20,15 +20,15 @@ const jwtPayloadSchema = z.object({ const DEFAULT_IDLE_TIMEOUT_MS = 15 * 60_000 const DEFAULT_MAX_TERMINALS = 4 -const DEFAULT_MAX_HTTP_BUFFER_SIZE = 100 * 1024 * 1024 +const DEFAULT_MAX_HTTP_BUFFER_SIZE = Math.ceil((50 * 1024 * 1024 * 4) / 3) -function resolveEnvNumber(name: string, fallback: number): number { +function resolveEnvNumber(name: string, fallback: number, max = fallback): number { const raw = process.env[name] if (!raw) { return fallback } const parsed = Number.parseInt(raw, 10) - return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback + return Number.isFinite(parsed) && parsed > 0 ? Math.min(parsed, max) : fallback } export type SocketServerDeps = {