Recover failed conversion workers and validate Nitro downloads correctly
This commit is contained in:
1 parent
a78d8256e0
commit
7880d5d5df
5 files changed
+91
-8
No files matched your search
@@ -1,5 +1,10 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { validatePngBytes, validateSwfBytes } from "./download";
|
||||
import { createNitroBundle } from "../../swf/nitro-builder";
|
||||
import {
|
||||
validateNitroBytes,
|
||||
validatePngBytes,
|
||||
validateSwfBytes,
|
||||
} from "./download";
|
||||
|
||||
describe("import/core/download validators", () => {
|
||||
it("accepts FWS/CWS/ZWS swf magic", () => {
|
||||
@@ -22,3 +27,14 @@ describe("import/core/download validators", () => {
|
||||
expect(validatePngBytes(Buffer.from([1, 2, 3, 4, 5, 6, 7, 8]))).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
it("validates nitro bundles separately from PNG files", () => {
|
||||
const png = Buffer.from([137, 80, 78, 71, 13, 10, 26, 10]);
|
||||
const bundle = createNitroBundle({ name: "chair" }, png, "chair");
|
||||
expect(validateNitroBytes(bundle)).toBe(true);
|
||||
expect(validatePngBytes(bundle)).toBe(false);
|
||||
expect(validateNitroBytes(png)).toBe(false);
|
||||
expect(validateNitroBytes(Buffer.from("<html>Access denied</html>"))).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
@@ -1,4 +1,5 @@
|
||||
import { promises as fs } from "node:fs";
|
||||
import { parseNitroBundle } from "../../swf/nitro-builder";
|
||||
|
||||
import { browserHeaders } from "./browser-headers";
|
||||
|
||||
@@ -18,6 +19,20 @@ export function validatePngBytes(buffer: Buffer): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
export function validateNitroBytes(buffer: Buffer): boolean {
|
||||
try {
|
||||
const bundle = parseNitroBundle(buffer);
|
||||
return (
|
||||
!!bundle.json &&
|
||||
typeof bundle.json === "object" &&
|
||||
!Array.isArray(bundle.json) &&
|
||||
validatePngBytes(bundle.png)
|
||||
);
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
export async function tryDownloadCandidates(
|
||||
urls: string[],
|
||||
destPath: string,
|
||||
@@ -33,7 +48,7 @@ export async function tryDownloadCandidates(
|
||||
export async function downloadFile(
|
||||
url: string,
|
||||
destPath: string,
|
||||
options?: { maxRetries?: number; validate?: "swf" | "png" },
|
||||
options?: { maxRetries?: number; validate?: "swf" | "png" | "nitro" },
|
||||
): Promise<{ ok: boolean; size: number }> {
|
||||
const maxRetries = options?.maxRetries ?? 3;
|
||||
const baseDelay = 1000;
|
||||
@@ -79,6 +94,8 @@ export async function downloadFile(
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (options?.validate === "nitro" && !validateNitroBytes(buffer))
|
||||
return { ok: false, size: 0 };
|
||||
await fs.writeFile(/*turbopackIgnore: true*/ destPath, buffer);
|
||||
return { ok: true, size: buffer.length };
|
||||
} catch (err) {
|
||||
|
||||
Reference in new issue
Block a user