UNPKG

openclaw

Version:

Multi-channel AI gateway with extensible messaging integrations

86 lines (85 loc) 3.02 kB
import { t as FsSafeError, w as root } from "./fs-safe-B6pvPGnf.js"; import { n as detectMime } from "./mime-CVpcq9ju.js"; import { i as resolveCanvasHttpPathToLocalPath, r as resolveCanvasDocumentsDir } from "./documents-CbIJFnxI.js"; import path from "node:path"; //#region src/canvas/serve.runtime.ts async function readRootFile(root, relativePath) { try { const opened = await root.open(relativePath); try { return { data: await opened.handle.readFile(), realPath: opened.realPath }; } finally { await opened.handle.close().catch(() => {}); } } catch (error) { if (error instanceof FsSafeError) return null; throw error; } } async function resolveDocumentSandbox(root, relativePath) { const documentId = relativePath.split(path.sep)[0]; if (!documentId) return; const opened = await readRootFile(root, path.join(documentId, "manifest.json")); if (!opened) return; try { return JSON.parse(opened.data.toString("utf8")).cspSandbox === "scripts" ? "scripts" : void 0; } catch { return; } } /** Serves one managed Canvas document request. */ async function handleCanvasDocumentHttpRequest(req, res) { const localPath = resolveCanvasHttpPathToLocalPath(req.url ?? ""); if (!localPath) return false; if (req.method !== "GET" && req.method !== "HEAD") { res.statusCode = 405; res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end("Method Not Allowed"); return true; } try { const documentsDir = resolveCanvasDocumentsDir(); const relativePath = path.relative(documentsDir, localPath); const root$1 = await root(documentsDir); const opened = await readRootFile(root$1, relativePath); if (!opened) { res.statusCode = 404; res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end("not found"); return true; } const lowerPath = opened.realPath.toLowerCase(); const mime = lowerPath.endsWith(".html") || lowerPath.endsWith(".htm") ? "text/html" : await detectMime({ filePath: opened.realPath }) ?? "application/octet-stream"; res.setHeader("Cache-Control", "no-store"); if (mime === "text/html") { const body = opened.data.toString("utf8"); res.setHeader("Content-Type", "text/html; charset=utf-8"); res.setHeader("Content-Length", String(Buffer.byteLength(body))); if (await resolveDocumentSandbox(root$1, relativePath) === "scripts") res.setHeader("Content-Security-Policy", "sandbox allow-scripts"); if (req.method === "HEAD") { res.end(); return true; } res.end(body); return true; } res.setHeader("Content-Type", mime); res.setHeader("Content-Length", String(opened.data.byteLength)); if (req.method === "HEAD") { res.end(); return true; } res.end(opened.data); return true; } catch (error) { res.statusCode = error instanceof FsSafeError ? 404 : 500; res.setHeader("Content-Type", "text/plain; charset=utf-8"); res.end(error instanceof FsSafeError ? "not found" : "error"); return true; } } //#endregion export { handleCanvasDocumentHttpRequest };