import {
Application,
type NextFunction,
type Request,
type Response,
} from "express";
import getLogger from "@cocalc/hub/logger";
import base_path from "@cocalc/backend/base-path";
import initRequest from "./handle-request";
import initUpgrade from "./handle-upgrade";
const logger = getLogger("proxy");
import type { Server } from "node:http";
import type { ProjectControlFunction } from "@cocalc/server/projects/control";
interface Options {
app: Application;
httpServer: Server;
projectControl: ProjectControlFunction;
isPersonal: boolean;
proxyConat: boolean;
}
const UUID_PATTERN =
"[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{4}-[a-fA-F0-9]{12}";
const UUID_REGEX = new RegExp(`^${UUID_PATTERN}$`);
function uuidMiddleware(
req: Request<{ project_id: string }>,
_res: Response,
next: NextFunction,
) {
if (UUID_REGEX.test(req.params.project_id)) {
return next();
}
return next("route");
}
export default function initProxy(opts: Options) {
const prefix = base_path.length <= 1 ? "" : base_path;
const routePath = `${prefix}/:project_id/{*splat}`;
logger.info("creating proxy server with route pattern", routePath);
const handleProxy = initRequest(opts);
const proxy_regexp = `^${prefix}\/${UUID_PATTERN}\/.*`;
const handleUpgrade = initUpgrade(opts, proxy_regexp);
opts.app.all(routePath, uuidMiddleware, handleProxy);
opts.httpServer.on("upgrade", handleUpgrade);
}