Files
UHD_Media_Tool/apps/server/src/sandbox/worker.ts
T

34 lines
1.4 KiB
TypeScript

// 沙箱子进程入口:先加载任务表,再撤销全部权限,然后从 stdin 读一条 {job, input},把 {ok, result | error} 写到 stdout。
// 开发 / 测试由 deno run 直接跑本文件;编译二进制以 `<自身> --role sandbox` 拉起(main.ts 在加载其余模块前分派)。
import { prepareJobs, SANDBOX_JOBS } from "./jobs.ts";
const PERMISSIONS = ["read", "write", "net", "env", "run", "ffi", "sys"] as const;
async function writeAll(bytes: Uint8Array) {
let off = 0;
while (off < bytes.length) off += await Deno.stdout.write(bytes.subarray(off));
}
export async function sandboxWorkerMain(): Promise<void> {
await prepareJobs();
for (const name of PERMISSIONS) {
try {
Deno.permissions.revokeSync({ name } as Deno.PermissionDescriptor);
} catch {
// 运行时不认识的权限名:跳过
}
}
let out: unknown;
try {
const req = JSON.parse(await new Response(Deno.stdin.readable).text()) as { job: string; input: unknown };
const fn = (SANDBOX_JOBS as Record<string, (i: unknown) => unknown>)[req.job];
if (!fn) throw new Error(`没有这个沙箱任务:${req.job}`);
out = { ok: true, result: await fn(req.input) };
} catch (e) {
out = { ok: false, error: `${(e as Error).name}: ${(e as Error).message}`.slice(0, 2000) };
}
await writeAll(new TextEncoder().encode(`${JSON.stringify(out)}\n`));
}
if (import.meta.main) await sandboxWorkerMain();