Files
BetterDesk/web-nodejs/middleware/goApiProxy.js
T
UNITRONIX 1508c739b2 fix(api): Go :21114 default API and Node :21121 compat proxy (#160)
RustDesk clients could not log in after v3 when handlers moved to Go but
nothing listened on :21121 (API_ENABLED off) or Go bound the wrong port.
Go serves /api/login on 21114; the console proxies legacy :21121 URLs to
Go. Installers repair .env/systemd, Docker publishes both ports, and
firewall rules allow 21114 and 21121 on full installs.

Also includes betterdesk-support-agent (Fyne desktop helper) and
docs/important/ operator notes (API ports, update flow, agent roadmap).
2026-06-03 02:16:24 +02:00

89 lines
2.7 KiB
JavaScript

/**
* Backward compatibility: WAN :21121 → Go :21114.
* Default API is Go :21114 (direct). Node only forwards legacy client URLs after wanSecurity.
*/
const http = require('http');
const https = require('https');
const { URL } = require('url');
const config = require('../config/config');
const HOP_BY_HOP = new Set([
'connection', 'keep-alive', 'proxy-authenticate', 'proxy-authorization',
'te', 'trailers', 'transfer-encoding', 'upgrade', 'host'
]);
function getGoApiOrigin() {
const raw = config.betterdeskApiUrl || config.hbbsApiUrl || 'http://127.0.0.1:21114/api';
const u = new URL(raw.endsWith('/') ? raw : `${raw}/`);
return `${u.protocol}//${u.host}`;
}
/**
* Express middleware: forward request to Go HTTP API (same path + query).
*/
function goApiProxy(req, res) {
let target;
try {
target = new URL(req.originalUrl || req.url, getGoApiOrigin());
} catch (err) {
console.error('[rustdesk-api-proxy] invalid target URL:', err.message);
return res.status(502).json({ error: 'Bad Gateway' });
}
const headers = { ...req.headers };
for (const h of HOP_BY_HOP) {
delete headers[h];
}
const clientIp = req.headers['x-forwarded-for']?.split(',')[0]?.trim()
|| req.headers['x-real-ip']
|| req.ip
|| req.socket?.remoteAddress;
if (clientIp) {
headers['x-forwarded-for'] = req.headers['x-forwarded-for']
? `${req.headers['x-forwarded-for']}, ${clientIp}`
: clientIp;
headers['x-real-ip'] = clientIp;
}
headers.host = target.host;
const isTls = target.protocol === 'https:';
const port = target.port || (isTls ? 443 : 80);
const transport = isTls ? https : http;
const opts = {
hostname: target.hostname,
port,
path: `${target.pathname}${target.search}`,
method: req.method,
headers,
timeout: 15000,
rejectUnauthorized: !config.allowSelfSignedCerts
};
const proxyReq = transport.request(opts, (proxyRes) => {
const outHeaders = { ...proxyRes.headers };
delete outHeaders['transfer-encoding'];
res.writeHead(proxyRes.statusCode, outHeaders);
proxyRes.pipe(res);
});
proxyReq.on('timeout', () => {
proxyReq.destroy();
if (!res.headersSent) {
res.status(504).json({ error: 'Gateway Timeout' });
}
});
proxyReq.on('error', (err) => {
console.error(`[rustdesk-api-proxy] ${req.method} ${req.path}${target.origin}: ${err.message}`);
if (!res.headersSent) {
res.status(502).json({ error: 'Bad Gateway' });
}
});
req.pipe(proxyReq);
}
module.exports = { goApiProxy, getGoApiOrigin };