73 lines
2.3 KiB
TypeScript
73 lines
2.3 KiB
TypeScript
import { createServer, type IncomingMessage } from 'node:http';
|
|
import { Readable } from 'node:stream';
|
|
import { logger } from './logger';
|
|
import { handleRequest } from './router';
|
|
|
|
const PORT = parseInt(process.env['PORT'] ?? '4005', 10);
|
|
const COLLECTOR_URL = process.env['COLLECTOR_URL'] ?? 'http://localhost:4001';
|
|
const QUERY_API_URL = process.env['QUERY_API_URL'] ?? 'http://localhost:4003';
|
|
const ADMIN_URL = process.env['ADMIN_URL'] ?? 'http://localhost:3023';
|
|
|
|
async function readBody(req: IncomingMessage): Promise<Buffer> {
|
|
const chunks: Buffer[] = [];
|
|
for await (const chunk of req) {
|
|
chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk as Uint8Array));
|
|
}
|
|
return Buffer.concat(chunks);
|
|
}
|
|
|
|
const server = createServer(async (req, res) => {
|
|
try {
|
|
const bodyBuf = ['GET', 'HEAD', 'OPTIONS'].includes(req.method ?? '')
|
|
? Buffer.alloc(0)
|
|
: await readBody(req);
|
|
|
|
const host = req.headers['host'] ?? 'localhost';
|
|
const url = new URL(req.url ?? '/', `http://${host}`);
|
|
|
|
if (url.pathname === '/health') {
|
|
res.statusCode = 200;
|
|
res.setHeader('Content-Type', 'application/json');
|
|
res.end(JSON.stringify({ status: 'ok', service: 'analytics-website-backend' }));
|
|
return;
|
|
}
|
|
|
|
const headers = new Headers();
|
|
for (const [key, value] of Object.entries(req.headers)) {
|
|
if (value) headers.set(key, Array.isArray(value) ? value.join(', ') : value);
|
|
}
|
|
|
|
const webRequest = new Request(url, {
|
|
method: req.method ?? 'GET',
|
|
headers,
|
|
body: bodyBuf.length > 0 ? bodyBuf : undefined,
|
|
});
|
|
|
|
const response = await handleRequest(webRequest, url, {
|
|
collectorUrl: COLLECTOR_URL,
|
|
queryApiUrl: QUERY_API_URL,
|
|
adminUrl: ADMIN_URL,
|
|
});
|
|
|
|
res.statusCode = response.status;
|
|
response.headers.forEach((value, key) => res.setHeader(key, value));
|
|
|
|
if (!response.body) {
|
|
res.end();
|
|
return;
|
|
}
|
|
|
|
Readable.fromWeb(response.body as ReadableStream<Uint8Array>).pipe(res);
|
|
} catch (err) {
|
|
logger.error({ err }, 'Unhandled request error');
|
|
res.statusCode = 500;
|
|
res.end(JSON.stringify({ error: 'Internal server error' }));
|
|
}
|
|
});
|
|
|
|
server.listen(PORT, () => {
|
|
logger.info(
|
|
{ port: PORT, collector: COLLECTOR_URL, queryApi: QUERY_API_URL, admin: ADMIN_URL },
|
|
'Analytics website backend listening',
|
|
);
|
|
});
|