@cocalc/hub
Version:
CoCalc: Backend webserver component
92 lines • 3.33 kB
JavaScript
;
// Websocket support
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const lru_cache_1 = __importDefault(require("lru-cache"));
const http_proxy_1 = require("http-proxy");
const version_1 = require("./version");
const target_1 = require("./target");
const logger_1 = __importDefault(require("../logger"));
const util_1 = require("./util");
const winston = (0, logger_1.default)("proxy: handle-upgrade");
function init({ projectControl, isPersonal }, proxy_regexp) {
const cache = new lru_cache_1.default({
max: 5000,
maxAge: 1000 * 60 * 3,
});
const re = new RegExp(proxy_regexp);
async function handleProxyUpgradeRequest(req, socket, head) {
const dbg = (m) => {
winston.silly(`${req.url}: ${m}`);
};
dbg("got upgrade request");
if (!isPersonal && (0, version_1.versionCheckFails)(req)) {
dbg("version check failed");
return;
}
if (!req.url.match(re)) {
dbg(`nothing to do; req.url="${req.url}" doesn't need to be proxied`);
return;
}
const url = (0, util_1.stripBasePath)(req.url);
dbg("calling getTarget");
const { host, port, internal_url } = await (0, target_1.getTarget)({
url,
isPersonal,
projectControl,
});
dbg(`got ${host}, ${port}`);
const target = `ws://${host}:${port}`;
if (internal_url != null) {
req.url = internal_url;
}
if (cache.has(target)) {
dbg("using cache");
const proxy = cache.get(target);
proxy?.ws(req, socket, head);
return;
}
dbg(`target = ${target}`);
dbg("not using cache");
const proxy = (0, http_proxy_1.createProxyServer)({
ws: true,
target,
timeout: 3000,
});
cache.set(target, proxy);
// taken from https://github.com/http-party/node-http-proxy/issues/1401
proxy.on("proxyRes", function (proxyRes) {
//console.log(
// "Raw [target] response",
// JSON.stringify(proxyRes.headers, true, 2)
//);
proxyRes.headers["x-reverse-proxy"] = "custom-proxy";
proxyRes.headers["cache-control"] = "no-cache, no-store";
//console.log(
// "Updated [proxied] response",
// JSON.stringify(proxyRes.headers, true, 2)
//);
});
proxy.on("error", (err) => {
winston.debug(`websocket proxy error, so clearing cache -- ${err}`);
cache.del(target);
});
proxy.on("close", () => {
dbg("websocket proxy close, so removing from cache");
cache.del(target);
});
proxy.ws(req, socket, head);
}
return async (req, socket, head) => {
try {
await handleProxyUpgradeRequest(req, socket, head);
}
catch (err) {
winston.debug(`error upgrading to websocket url=${req.url} -- ${err}`);
}
};
}
exports.default = init;
//# sourceMappingURL=handle-upgrade.js.map