mirror of
https://github.com/morluto/rea.git
synced 2026-11-15 11:13:21 +00:00
76 lines
2.7 KiB
TypeScript
76 lines
2.7 KiB
TypeScript
import { readFile, writeFile } from "node:fs/promises";
|
|
import { z } from "zod";
|
|
import { readStableArtifact } from "../../artifacts/readStableArtifact.js";
|
|
import { webNetworkCaptureBudgetsSchema } from "../../domain/webNetworkCapture.js";
|
|
import { captureBudgets, withCaptureBudgets } from "./CaptureBudgets.js";
|
|
import { CaptureFormatError } from "./CaptureFormatError.js";
|
|
|
|
const requestSchema = z.strictObject({
|
|
snapshot_path: z.string(),
|
|
reply_path: z.string(),
|
|
sensitive_values: z.array(z.string().min(1)),
|
|
budgets: webNetworkCaptureBudgetsSchema,
|
|
});
|
|
|
|
/** Parse untrusted captures in an owned heap and return one complete bounded reply. */
|
|
const main = async (): Promise<void> => {
|
|
const format = z.enum(["har", "saz", "qlog"]).parse(process.argv[3]);
|
|
const request = requestSchema.parse(
|
|
JSON.parse(await readFile(process.argv[2] ?? "", "utf8")),
|
|
);
|
|
await withCaptureBudgets(request.budgets, async () => {
|
|
let reply: unknown;
|
|
try {
|
|
let value;
|
|
if (format !== "saz") {
|
|
const { decodeCaptureText } = await import("./CaptureJson.js");
|
|
const decoder =
|
|
format === "har"
|
|
? (await import("./HarCapture.js")).decodeHarCapture
|
|
: (await import("./QlogCapture.js")).decodeQlogCapture;
|
|
const snapshot = await readStableArtifact(
|
|
request.snapshot_path,
|
|
captureBudgets().inputBytes,
|
|
);
|
|
value = decoder(
|
|
decodeCaptureText(snapshot.bytes, format === "har" ? "HAR" : "qlog"),
|
|
request.sensitive_values,
|
|
);
|
|
} else {
|
|
const { decodeSazCapture } = await import("./SazCapture.js");
|
|
value = await decodeSazCapture(
|
|
request.snapshot_path,
|
|
request.sensitive_values,
|
|
);
|
|
}
|
|
reply = { ok: true, value };
|
|
} catch (cause: unknown) {
|
|
reply =
|
|
cause instanceof CaptureFormatError
|
|
? {
|
|
ok: false,
|
|
reason: cause.replyReason,
|
|
message: cause.message,
|
|
pointer: cause.pointer,
|
|
}
|
|
: {
|
|
ok: false,
|
|
reason: "decoder",
|
|
message: `Capture decoder failed unexpectedly (${cause instanceof Error ? cause.name : "unknown exception"}).`,
|
|
pointer: "",
|
|
};
|
|
}
|
|
let text = JSON.stringify(reply);
|
|
if (Buffer.byteLength(text) > captureBudgets().outputBytes)
|
|
text = JSON.stringify({
|
|
ok: false,
|
|
reason: "limit",
|
|
message:
|
|
"Capture reply exceeds max_reply_bytes; raise that per-call allowance and retry after cleanup.",
|
|
pointer: "",
|
|
});
|
|
await writeFile(request.reply_path, text, { flag: "wx", mode: 0o600 });
|
|
});
|
|
};
|
|
await main();
|