mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-07 23:01:24 +00:00
chore: Enable "curly" rule to avoid single-statement if confusion/errors.
This commit is contained in:
@@ -44,7 +44,9 @@ async function resolveA2uiRoot(): Promise<string | null> {
|
||||
}
|
||||
|
||||
async function resolveA2uiRootReal(): Promise<string | null> {
|
||||
if (cachedA2uiRootReal !== undefined) return cachedA2uiRootReal;
|
||||
if (cachedA2uiRootReal !== undefined) {
|
||||
return cachedA2uiRootReal;
|
||||
}
|
||||
if (!resolvingA2uiRoot) {
|
||||
resolvingA2uiRoot = (async () => {
|
||||
const root = await resolveA2uiRoot();
|
||||
@@ -64,7 +66,9 @@ function normalizeUrlPath(rawPath: string): string {
|
||||
async function resolveA2uiFilePath(rootReal: string, urlPath: string) {
|
||||
const normalized = normalizeUrlPath(urlPath);
|
||||
const rel = normalized.replace(/^\/+/, "");
|
||||
if (rel.split("/").some((p) => p === "..")) return null;
|
||||
if (rel.split("/").some((p) => p === "..")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
let candidate = path.join(rootReal, rel);
|
||||
if (normalized.endsWith("/")) {
|
||||
@@ -83,9 +87,13 @@ async function resolveA2uiFilePath(rootReal: string, urlPath: string) {
|
||||
const rootPrefix = rootReal.endsWith(path.sep) ? rootReal : `${rootReal}${path.sep}`;
|
||||
try {
|
||||
const lstat = await fs.lstat(candidate);
|
||||
if (lstat.isSymbolicLink()) return null;
|
||||
if (lstat.isSymbolicLink()) {
|
||||
return null;
|
||||
}
|
||||
const real = await fs.realpath(candidate);
|
||||
if (!real.startsWith(rootPrefix)) return null;
|
||||
if (!real.startsWith(rootPrefix)) {
|
||||
return null;
|
||||
}
|
||||
return real;
|
||||
} catch {
|
||||
return null;
|
||||
@@ -156,12 +164,16 @@ export async function handleA2uiHttpRequest(
|
||||
res: ServerResponse,
|
||||
): Promise<boolean> {
|
||||
const urlRaw = req.url;
|
||||
if (!urlRaw) return false;
|
||||
if (!urlRaw) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const url = new URL(urlRaw, "http://localhost");
|
||||
const basePath =
|
||||
url.pathname === A2UI_PATH || url.pathname.startsWith(`${A2UI_PATH}/`) ? A2UI_PATH : undefined;
|
||||
if (!basePath) return false;
|
||||
if (!basePath) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (req.method !== "GET" && req.method !== "HEAD") {
|
||||
res.statusCode = 405;
|
||||
|
||||
@@ -84,14 +84,18 @@ describe("canvas host", () => {
|
||||
|
||||
const server = createServer((req, res) => {
|
||||
void (async () => {
|
||||
if (await handler.handleHttpRequest(req, res)) return;
|
||||
if (await handler.handleHttpRequest(req, res)) {
|
||||
return;
|
||||
}
|
||||
res.statusCode = 404;
|
||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
res.end("Not Found");
|
||||
})();
|
||||
});
|
||||
server.on("upgrade", (req, socket, head) => {
|
||||
if (handler.handleUpgrade(req, socket, head)) return;
|
||||
if (handler.handleUpgrade(req, socket, head)) {
|
||||
return;
|
||||
}
|
||||
socket.destroy();
|
||||
});
|
||||
|
||||
|
||||
@@ -159,13 +159,17 @@ function normalizeUrlPath(rawPath: string): string {
|
||||
async function resolveFilePath(rootReal: string, urlPath: string) {
|
||||
const normalized = normalizeUrlPath(urlPath);
|
||||
const rel = normalized.replace(/^\/+/, "");
|
||||
if (rel.split("/").some((p) => p === "..")) return null;
|
||||
if (rel.split("/").some((p) => p === "..")) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const tryOpen = async (relative: string) => {
|
||||
try {
|
||||
return await openFileWithinRoot({ rootDir: rootReal, relativePath: relative });
|
||||
} catch (err) {
|
||||
if (err instanceof SafeOpenError) return null;
|
||||
if (err instanceof SafeOpenError) {
|
||||
return null;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
};
|
||||
@@ -177,7 +181,9 @@ async function resolveFilePath(rootReal: string, urlPath: string) {
|
||||
const candidate = path.join(rootReal, rel);
|
||||
try {
|
||||
const st = await fs.lstat(candidate);
|
||||
if (st.isSymbolicLink()) return null;
|
||||
if (st.isSymbolicLink()) {
|
||||
return null;
|
||||
}
|
||||
if (st.isDirectory()) {
|
||||
return await tryOpen(path.posix.join(rel, "index.html"));
|
||||
}
|
||||
@@ -189,17 +195,27 @@ async function resolveFilePath(rootReal: string, urlPath: string) {
|
||||
}
|
||||
|
||||
function isDisabledByEnv() {
|
||||
if (isTruthyEnvValue(process.env.OPENCLAW_SKIP_CANVAS_HOST)) return true;
|
||||
if (isTruthyEnvValue(process.env.OPENCLAW_SKIP_CANVAS_HOST)) return true;
|
||||
if (process.env.NODE_ENV === "test") return true;
|
||||
if (process.env.VITEST) return true;
|
||||
if (isTruthyEnvValue(process.env.OPENCLAW_SKIP_CANVAS_HOST)) {
|
||||
return true;
|
||||
}
|
||||
if (isTruthyEnvValue(process.env.OPENCLAW_SKIP_CANVAS_HOST)) {
|
||||
return true;
|
||||
}
|
||||
if (process.env.NODE_ENV === "test") {
|
||||
return true;
|
||||
}
|
||||
if (process.env.VITEST) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function normalizeBasePath(rawPath: string | undefined) {
|
||||
const trimmed = (rawPath ?? CANVAS_HOST_PATH).trim();
|
||||
const normalized = normalizeUrlPath(trimmed || CANVAS_HOST_PATH);
|
||||
if (normalized === "/") return "/";
|
||||
if (normalized === "/") {
|
||||
return "/";
|
||||
}
|
||||
return normalized.replace(/\/+$/, "");
|
||||
}
|
||||
|
||||
@@ -260,7 +276,9 @@ export async function createCanvasHostHandler(
|
||||
|
||||
let debounce: NodeJS.Timeout | null = null;
|
||||
const broadcastReload = () => {
|
||||
if (!liveReload) return;
|
||||
if (!liveReload) {
|
||||
return;
|
||||
}
|
||||
for (const ws of sockets) {
|
||||
try {
|
||||
ws.send("reload");
|
||||
@@ -270,7 +288,9 @@ export async function createCanvasHostHandler(
|
||||
}
|
||||
};
|
||||
const scheduleReload = () => {
|
||||
if (debounce) clearTimeout(debounce);
|
||||
if (debounce) {
|
||||
clearTimeout(debounce);
|
||||
}
|
||||
debounce = setTimeout(() => {
|
||||
debounce = null;
|
||||
broadcastReload();
|
||||
@@ -292,7 +312,9 @@ export async function createCanvasHostHandler(
|
||||
: null;
|
||||
watcher?.on("all", () => scheduleReload());
|
||||
watcher?.on("error", (err) => {
|
||||
if (watcherClosed) return;
|
||||
if (watcherClosed) {
|
||||
return;
|
||||
}
|
||||
watcherClosed = true;
|
||||
opts.runtime.error(
|
||||
`canvasHost watcher error: ${String(err)} (live reload disabled; consider canvasHost.liveReload=false or a smaller canvasHost.root)`,
|
||||
@@ -301,9 +323,13 @@ export async function createCanvasHostHandler(
|
||||
});
|
||||
|
||||
const handleUpgrade = (req: IncomingMessage, socket: Duplex, head: Buffer) => {
|
||||
if (!wss) return false;
|
||||
if (!wss) {
|
||||
return false;
|
||||
}
|
||||
const url = new URL(req.url ?? "/", "http://localhost");
|
||||
if (url.pathname !== CANVAS_WS_PATH) return false;
|
||||
if (url.pathname !== CANVAS_WS_PATH) {
|
||||
return false;
|
||||
}
|
||||
wss.handleUpgrade(req, socket as Socket, head, (ws) => {
|
||||
wss.emit("connection", ws, req);
|
||||
});
|
||||
@@ -312,7 +338,9 @@ export async function createCanvasHostHandler(
|
||||
|
||||
const handleHttpRequest = async (req: IncomingMessage, res: ServerResponse) => {
|
||||
const urlRaw = req.url;
|
||||
if (!urlRaw) return false;
|
||||
if (!urlRaw) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const url = new URL(urlRaw, "http://localhost");
|
||||
@@ -325,7 +353,9 @@ export async function createCanvasHostHandler(
|
||||
|
||||
let urlPath = url.pathname;
|
||||
if (basePath !== "/") {
|
||||
if (urlPath !== basePath && !urlPath.startsWith(`${basePath}/`)) return false;
|
||||
if (urlPath !== basePath && !urlPath.startsWith(`${basePath}/`)) {
|
||||
return false;
|
||||
}
|
||||
urlPath = urlPath === basePath ? "/" : urlPath.slice(basePath.length) || "/";
|
||||
}
|
||||
|
||||
@@ -392,7 +422,9 @@ export async function createCanvasHostHandler(
|
||||
handleHttpRequest,
|
||||
handleUpgrade,
|
||||
close: async () => {
|
||||
if (debounce) clearTimeout(debounce);
|
||||
if (debounce) {
|
||||
clearTimeout(debounce);
|
||||
}
|
||||
watcherClosed = true;
|
||||
await watcher?.close().catch(() => {});
|
||||
if (wss) {
|
||||
@@ -420,10 +452,16 @@ export async function startCanvasHost(opts: CanvasHostServerOpts): Promise<Canva
|
||||
|
||||
const bindHost = opts.listenHost?.trim() || "0.0.0.0";
|
||||
const server: Server = http.createServer((req, res) => {
|
||||
if (String(req.headers.upgrade ?? "").toLowerCase() === "websocket") return;
|
||||
if (String(req.headers.upgrade ?? "").toLowerCase() === "websocket") {
|
||||
return;
|
||||
}
|
||||
void (async () => {
|
||||
if (await handleA2uiHttpRequest(req, res)) return;
|
||||
if (await handler.handleHttpRequest(req, res)) return;
|
||||
if (await handleA2uiHttpRequest(req, res)) {
|
||||
return;
|
||||
}
|
||||
if (await handler.handleHttpRequest(req, res)) {
|
||||
return;
|
||||
}
|
||||
res.statusCode = 404;
|
||||
res.setHeader("Content-Type", "text/plain; charset=utf-8");
|
||||
res.end("Not Found");
|
||||
@@ -435,7 +473,9 @@ export async function startCanvasHost(opts: CanvasHostServerOpts): Promise<Canva
|
||||
});
|
||||
});
|
||||
server.on("upgrade", (req, socket, head) => {
|
||||
if (handler.handleUpgrade(req, socket, head)) return;
|
||||
if (handler.handleUpgrade(req, socket, head)) {
|
||||
return;
|
||||
}
|
||||
socket.destroy();
|
||||
});
|
||||
|
||||
@@ -465,7 +505,9 @@ export async function startCanvasHost(opts: CanvasHostServerOpts): Promise<Canva
|
||||
port: boundPort,
|
||||
rootDir: handler.rootDir,
|
||||
close: async () => {
|
||||
if (ownsHandler) await handler.close();
|
||||
if (ownsHandler) {
|
||||
await handler.close();
|
||||
}
|
||||
await new Promise<void>((resolve, reject) =>
|
||||
server.close((err) => (err ? reject(err) : resolve())),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user