Fix canvas transfer timeouts and move images out of snapshots

This commit is contained in:
2026-11-06 21:51:13 +08:00
parent af844131ed
commit 570cd53fc3
21 changed files with 460 additions and 48 deletions
+10 -1
View File
@@ -20,10 +20,16 @@ const upstream = createServer(async (req, res) => {
if (req.url.includes("/canvas")) assert.equal(req.headers.accept, "application/vnd.foundry.canvas+json;version=2");
if (req.url.startsWith("/projects/endoleap/workspaces/space/assets")) {
if (req.headers.authorization !== "Bearer test-only-session") { res.statusCode = 401; res.end(JSON.stringify({error:"invalid_session"})); return; }
if (req.method === "GET") { res.setHeader("Content-Type", req.url.endsWith("/bad") ? "image/svg+xml" : "image/png"); res.end(Buffer.from([137,80,78,71,13,10,26,10])); return; }
if (req.method === "GET") { res.setHeader("X-Asset-Variant", new URL(req.url,"http://mock").searchParams.get("variant") === "preview" ? "preview" : "original"); res.setHeader("Content-Type", req.url.endsWith("/bad") ? "image/svg+xml" : "image/png"); res.end(Buffer.from([137,80,78,71,13,10,26,10])); return; }
let bytes = Buffer.alloc(0); for await (const chunk of req) bytes = Buffer.concat([bytes, chunk]);
res.end(JSON.stringify({type:req.headers["content-type"],bytes:bytes.length,key:req.headers["idempotency-key"],multipart:bytes.includes(Buffer.from('name="image"'))})); return;
}
if (canonical.endsWith("/materials/slow-body-board/canvas")) {
res.setHeader("ETag", '\"210\"');
res.write('{"version":210,"document":');
await new Promise((resolve) => setTimeout(resolve, 15200));
res.end('{"schema_version":2,"nodes":[],"edges":[],"viewport":{"x":0,"y":0,"zoom":1}}}'); return;
}
if (canonical.endsWith("/materials/stream-board/canvas")) {
assert.equal(req.headers.authorization, "Bearer test-only-session");
res.setHeader("ETag", '\"1\"'); res.setHeader("X-Canvas-Schema-Version", "2");
@@ -190,11 +196,14 @@ try {
const response = await fetch(v2Base + "/" + path, { method: "POST", headers: { Cookie: session, Origin: host, "Content-Type": "application/json", "Idempotency-Key": idem, "If-Match": '\"7\"' }, body: "{}" });
assert.equal(response.status, 200, path); const echo = await response.json(); assert.equal(echo.key, idem); assert.equal(echo.version, '\"7\"'); assert.equal(echo.accept, "application/vnd.foundry.canvas+json;version=2");
}
const preview = await fetch(host + "/api/foundry/workspaces/space/assets/image?variant=preview", { headers: { Cookie: session } });assert.equal(preview.status,200);assert.equal(preview.headers.get("x-asset-variant"),"preview");await preview.arrayBuffer();
const directoryResponse = await (await fetch(host + "/api/foundry/workspaces/space/materials?kind=board&sort=modified&include_subgraphs=true&limit=100&offset=100", { headers: { Cookie: session } })).json();
const directoryQuery = new URL(directoryResponse.url, "http://mock").searchParams;
assert.equal(directoryQuery.get("include_subgraphs"), "true"); assert.equal(directoryQuery.get("offset"), "100");
const events = await (await fetch(v2Base + "/ai/runs/run-1?after_seq=12&limit=100&status=active&include_descendants=true&cursor=cursor&secret=drop", { headers: { Cookie: session } })).json();
const query = new URL(events.url, "http://mock").searchParams; assert.equal(query.get("after_seq"), "12"); assert.equal(query.get("include_descendants"), "true"); assert.equal(query.get("cursor"), "cursor"); assert.equal(query.get("secret"), null);
const slowSnapshot = await fetch(host + "/api/foundry/workspaces/space/materials/slow-body-board/canvas", { headers: { Cookie: session } });
assert.ok(slowSnapshot.headers.get("x-canvas-trace-id")); assert.equal((await slowSnapshot.json()).version, 210, "A valid body can finish after the old 15-second total deadline");
const asset = await fetch(host + "/api/foundry/workspaces/space/assets/image-1", { headers: { Cookie: session } });
assert.equal(asset.status, 200); assert.equal(asset.headers.get("content-type"), "image/png"); assert.equal(asset.headers.get("x-content-type-options"), "nosniff"); assert.ok(asset.headers.get("set-cookie")?.includes("HttpOnly")); assert.equal((await asset.arrayBuffer()).byteLength, 8);
assert.equal((await fetch(host + "/api/foundry/workspaces/space/assets/image-1")).status, 401);