68 lines
2.1 KiB
TypeScript
68 lines
2.1 KiB
TypeScript
import http from 'node:http';
|
|
|
|
import { configFromEnv } from './config.js';
|
|
import { AppserviceDaemon } from './server.js';
|
|
|
|
const cfg = configFromEnv();
|
|
const daemon = new AppserviceDaemon(cfg);
|
|
|
|
const MAX_BODY_BYTES = 1024 * 1024;
|
|
|
|
const server = http.createServer((req, res) => {
|
|
const chunks: Buffer[] = [];
|
|
let received = 0;
|
|
let rejected = false;
|
|
req.on('data', (chunk: Buffer) => {
|
|
received += chunk.length;
|
|
if (received > MAX_BODY_BYTES) {
|
|
rejected = true;
|
|
res.writeHead(413, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ errcode: 'M_TOO_LARGE', error: 'request body too large' }));
|
|
req.destroy();
|
|
return;
|
|
}
|
|
chunks.push(chunk);
|
|
});
|
|
req.on('end', () => {
|
|
if (rejected) return;
|
|
void (async () => {
|
|
const url = new URL(req.url ?? '/', 'http://localhost');
|
|
let body: unknown;
|
|
try {
|
|
const raw = Buffer.concat(chunks).toString();
|
|
body = raw ? JSON.parse(raw) : undefined;
|
|
} catch {
|
|
res.writeHead(400, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ errcode: 'M_NOT_JSON', error: 'invalid json' }));
|
|
return;
|
|
}
|
|
const result = await daemon.handle({
|
|
method: req.method ?? 'GET',
|
|
path: url.pathname,
|
|
searchParams: url.searchParams,
|
|
authorizationHeader: req.headers.authorization,
|
|
body,
|
|
});
|
|
res.writeHead(result.status, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify(result.body));
|
|
})().catch((error: unknown) => {
|
|
console.error('request failed:', error);
|
|
if (res.headersSent) {
|
|
res.destroy();
|
|
return;
|
|
}
|
|
res.writeHead(500, { 'Content-Type': 'application/json' });
|
|
res.end(JSON.stringify({ error: 'internal error' }));
|
|
});
|
|
});
|
|
});
|
|
|
|
server.listen(cfg.port, () => {
|
|
console.log(
|
|
`mosaic-as listening on :${cfg.port} (homeserver ${cfg.homeserverUrl}, domain ${cfg.domain})`,
|
|
);
|
|
if (cfg.bridgeTokens.length === 0) {
|
|
console.warn('WARNING: MOSAIC_AS_BRIDGE_TOKENS is empty — bridge API will deny all requests');
|
|
}
|
|
});
|