Files
tf_docs/server.js
T

80 lines
1.8 KiB
JavaScript

'use strict';
const http = require('http');
const PORT = Number(process.env.PORT) || 3000;
const VM_DOCS_BASE_URL = (process.env.VM_DOCS_BASE_URL || '').replace(/\/+$/, '');
const STAND_RE = /^[A-Za-z0-9._-]+$/;
function send(res, status, body, headers = {}) {
const data = Buffer.from(String(body));
res.writeHead(status, {
'Content-Type': 'text/plain; charset=utf-8',
'Content-Length': data.length,
...headers,
});
res.end(data);
}
function redirect(res, location) {
send(res, 302, '', { Location: location });
}
const server = http.createServer((req, res) => {
if (req.method !== 'GET' && req.method !== 'HEAD') {
send(res, 405, 'Method Not Allowed');
return;
}
let pathname;
try {
pathname = decodeURIComponent(req.url.split('?')[0]);
} catch (err) {
send(res, 400, 'Bad Request');
return;
}
if (pathname === '/health') {
send(res, 200, 'ok');
return;
}
if (pathname === '/') {
if (!VM_DOCS_BASE_URL) {
send(res, 500, 'VM_DOCS_BASE_URL is not configured');
return;
}
redirect(res, VM_DOCS_BASE_URL + '/');
return;
}
if (!VM_DOCS_BASE_URL) {
send(res, 500, 'VM_DOCS_BASE_URL is not configured');
return;
}
const segments = pathname.split('/').filter((s) => s !== '');
if (segments.some((s) => s === '..')) {
send(res, 400, 'Bad Request');
return;
}
const stand = segments[0];
if (!stand || !STAND_RE.test(stand)) {
send(res, 404, 'Not Found');
return;
}
redirect(res, VM_DOCS_BASE_URL + pathname);
});
if (require.main === module) {
server.listen(PORT, () => {
console.log(`redirect router listening on :${PORT}`);
console.log(`VM_DOCS_BASE_URL=${VM_DOCS_BASE_URL || '(not set)'}`);
});
}
module.exports = { server, send, redirect };