



















@@ -7,7 +7,7 @@ import {
77symlinkSync,
88writeFileSync,
99} from "node:fs";
10-import { createServer as createNetServer } from "node:net";
10+import { createConnection as createNetConnection, createServer as createNetServer } from "node:net";
1111import { tmpdir } from "node:os";
1212import { join, win32 } from "node:path";
1313import { setTimeout as delay } from "node:timers/promises";
@@ -685,6 +685,36 @@ describe("scripts/openclaw-cross-os-release-checks", () => {
685685}
686686});
687687688+it("closes static release artifact sockets left by aborted clients", async () => {
689+const dir = mkdtempSync(join(tmpdir(), "openclaw-cross-os-static-server-close-"));
690+const filePath = join(dir, "openclaw-2026.4.14.tgz");
691+const logPath = join(dir, "server.log");
692+let server: Awaited<ReturnType<typeof startStaticFileServer>> | undefined;
693+694+try {
695+writeFileSync(filePath, Buffer.alloc(1024 * 1024, "x"));
696+server = await startStaticFileServer({ filePath, logPath });
697+const url = new URL(server.url);
698+const socket = createNetConnection(Number(url.port), url.hostname);
699+await new Promise<void>((resolve, reject) => {
700+socket.once("connect", resolve);
701+socket.once("error", reject);
702+});
703+socket.write(`GET ${url.pathname} HTTP/1.1\r\nHost: ${url.host}\r\n\r\n`);
704+await Promise.race([
705+server.close(),
706+delay(1_000).then(() => Promise.reject(new Error("close timed out"))),
707+]);
708+await Promise.race([
709+new Promise<void>((resolve) => socket.once("close", resolve)),
710+delay(1_000).then(() => Promise.reject(new Error("socket close timed out"))),
711+]);
712+} finally {
713+await server?.close().catch(() => {});
714+rmSync(dir, { recursive: true, force: true });
715+}
716+});
717+688718it("does not preload static release artifacts before serving them", () => {
689719const source = readFileSync("scripts/openclaw-cross-os-release-checks.ts", "utf8");
690720const serverSource = source.slice(
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。