openclaw
Version:
Multi-channel AI gateway with extensible messaging integrations
75 lines (74 loc) • 3.63 kB
JavaScript
import { m as waitForHttpRequestRejection } from "./http-body-D3IMwTJJ.js";
import { D as tryBeginGatewayRootWorkAdmission } from "./gateway-work-admission-R1IpuDim.js";
import { o as isProtectedPluginRoutePathFromContext, s as resolvePluginRoutePathContext, t as findMatchingPluginHttpRoutes } from "./route-match-BkI3BCZw.js";
//#region src/gateway/server/http-work-admission.ts
async function runWithGatewayBoundaryWorkAdmission(origin, reject, run) {
const admission = tryBeginGatewayRootWorkAdmission(origin);
if (!admission) {
reject();
return true;
}
try {
return await admission.run(async () => await run());
} finally {
admission.release();
}
}
/** Runs one HTTP user-work route under the same root fence as Gateway RPCs. */
async function runWithGatewayHttpWorkAdmission(res, run) {
return await runWithGatewayBoundaryWorkAdmission("http:request", () => {
res.statusCode = 503;
res.setHeader("Content-Type", "application/json; charset=utf-8");
res.setHeader("Cache-Control", "no-store");
res.setHeader("Retry-After", "1");
res.end(JSON.stringify({ error: {
message: "Gateway is temporarily unavailable while suspending or restarting",
type: "service_unavailable",
code: "gateway_unavailable"
} }));
}, async () => {
try {
return await run();
} finally {
await waitForHttpRequestRejection(res.req);
}
});
}
function writeGatewayUpgradeServiceUnavailable(socket, body) {
socket.write(`HTTP/1.1 503 Service Unavailable\r
Connection: close\r
Content-Type: text/plain; charset=utf-8\r
Content-Length: ${Buffer.byteLength(body, "utf8")}\r\n\r
` + body);
}
/** Holds upgrade admission until one plugin handler owns or declines the socket. */
async function runWithGatewayUpgradeWorkAdmission(socket, run) {
return await runWithGatewayBoundaryWorkAdmission("http:upgrade", () => {
writeGatewayUpgradeServiceUnavailable(socket, "Gateway websocket admission closed");
socket.destroy();
}, run);
}
//#endregion
//#region src/gateway/server/plugins-http/route-auth.ts
/**
* Gateway-auth decisions for plugin HTTP routes.
*/
function matchedPluginRoutesRequireGatewayAuth(routes) {
return routes.some((route) => route.auth === "gateway");
}
/** Returns true when a plugin path must pass gateway auth before routing. */
function shouldEnforceGatewayAuthForPluginPath(registry, pathnameOrContext) {
const pathContext = typeof pathnameOrContext === "string" ? resolvePluginRoutePathContext(pathnameOrContext) : pathnameOrContext;
if (pathContext.malformedEncoding || pathContext.decodePassLimitReached) return true;
if (isProtectedPluginRoutePathFromContext(pathContext)) return true;
return matchedPluginRoutesRequireGatewayAuth(findMatchingPluginHttpRoutes(registry, pathContext));
}
/** Returns true only when an existing route owns authentication entirely inside its plugin. */
function isPluginAuthenticatedRoutePath(registry, pathnameOrContext) {
const pathContext = typeof pathnameOrContext === "string" ? resolvePluginRoutePathContext(pathnameOrContext) : pathnameOrContext;
if (pathContext.malformedEncoding || pathContext.decodePassLimitReached || isProtectedPluginRoutePathFromContext(pathContext)) return false;
const matchedRoutes = findMatchingPluginHttpRoutes(registry, pathContext);
return matchedRoutes.length > 0 && matchedRoutes.every((route) => route.auth === "plugin");
}
//#endregion
export { runWithGatewayUpgradeWorkAdmission as a, runWithGatewayHttpWorkAdmission as i, matchedPluginRoutesRequireGatewayAuth as n, writeGatewayUpgradeServiceUnavailable as o, shouldEnforceGatewayAuthForPluginPath as r, isPluginAuthenticatedRoutePath as t };