@@ -12,6 +12,7 @@ import {
|
12 | 12 | rpc, |
13 | 13 | waitForHttpBodyDeltas, |
14 | 14 | } from "./sandbox-exec-server.test-helpers.js"; |
| 15 | +import { SANDBOX_HTTP_STREAM_LINE_MAX_CHARS } from "./sandbox-exec-server/http.js"; |
15 | 16 | |
16 | 17 | afterEach(async () => { |
17 | 18 | vi.unstubAllEnvs(); |
@@ -212,4 +213,53 @@ describe("OpenClaw Codex sandbox exec-server HTTP", () => {
|
212 | 213 | { timeout: 5_000 }, |
213 | 214 | ); |
214 | 215 | }); |
| 216 | + |
| 217 | +it("rejects streaming HTTP helpers that never terminate a stdout line", async () => { |
| 218 | +const finalizeExec = vi.fn(async () => undefined); |
| 219 | +const sandbox = createSandboxContext({ |
| 220 | +buildExecSpec: async () => ({ |
| 221 | +argv: [ |
| 222 | +process.execPath, |
| 223 | +"-e", |
| 224 | +[ |
| 225 | +`process.stdout.write("x".repeat(${SANDBOX_HTTP_STREAM_LINE_MAX_CHARS + 1}));`, |
| 226 | +"setInterval(() => {}, 1000);", |
| 227 | +].join(""), |
| 228 | +], |
| 229 | +env: testExecEnv(), |
| 230 | +finalizeToken: "stream-line-token", |
| 231 | +stdinMode: "pipe-closed", |
| 232 | +}), |
| 233 | + finalizeExec, |
| 234 | +}); |
| 235 | +const client = createClient(); |
| 236 | +await ensureCodexSandboxExecServerEnvironment({ |
| 237 | +client: client as never, |
| 238 | + sandbox, |
| 239 | +}); |
| 240 | +const socket = await openSocket(execServerUrlFromClient(client)); |
| 241 | +await rpc(socket, "initialize", { clientName: "test" }); |
| 242 | +socket.send(JSON.stringify({ method: "initialized" })); |
| 243 | + |
| 244 | +await expect( |
| 245 | +rpc(socket, "http/request", { |
| 246 | +requestId: "http-stream-long-line", |
| 247 | +method: "GET", |
| 248 | +url: "https://example.test/sse", |
| 249 | +streamResponse: true, |
| 250 | +}), |
| 251 | +).rejects.toThrow("unterminated stdout line"); |
| 252 | + |
| 253 | +await vi.waitFor( |
| 254 | +() => |
| 255 | +expect(finalizeExec).toHaveBeenCalledWith( |
| 256 | +expect.objectContaining({ |
| 257 | +status: "failed", |
| 258 | +token: "stream-line-token", |
| 259 | +}), |
| 260 | +), |
| 261 | +{ timeout: 5_000 }, |
| 262 | +); |
| 263 | +socket.close(); |
| 264 | +}); |
215 | 265 | }); |