feat: add HTTP server adapter and request-mapping tests

This commit is contained in:
Codex
2026-02-18 12:37:46 +00:00
parent fedab9f7bd
commit 78d72cc4a9
2 changed files with 110 additions and 0 deletions

79
src/server.js Normal file
View File

@@ -0,0 +1,79 @@
"use strict";
const http = require("node:http");
const { buildApp } = require("./app");
const { config } = require("./config");
function readBody(req) {
return new Promise((resolve, reject) => {
let data = "";
req.setEncoding("utf8");
req.on("data", (chunk) => {
data += chunk;
if (data.length > 2_000_000) {
reject(new Error("payload_too_large"));
}
});
req.on("end", () => resolve(data));
req.on("error", reject);
});
}
function normalizeHeaders(rawHeaders) {
return Object.fromEntries(
Object.entries(rawHeaders || {}).map(([k, v]) => [
String(k).toLowerCase(),
Array.isArray(v) ? v.join(",") : (v || ""),
]),
);
}
function mapToAppRequest({ req, rawBody }) {
const url = new URL(req.url, "http://localhost");
return {
method: req.method || "GET",
path: url.pathname,
headers: normalizeHeaders(req.headers),
rawBody,
};
}
function createHttpServer({ app }) {
return http.createServer(async (req, res) => {
try {
const rawBody = await readBody(req);
const response = app.handleRequest(mapToAppRequest({ req, rawBody }));
res.statusCode = response.status;
for (const [key, value] of Object.entries(response.headers || {})) {
res.setHeader(key, value);
}
res.end(response.body || "");
} catch (error) {
res.statusCode = 500;
res.setHeader("content-type", "application/json; charset=utf-8");
res.end(JSON.stringify({ error: error.message || "internal_error" }));
}
});
}
function start() {
const app = buildApp({ config });
const server = createHttpServer({ app });
server.listen(config.port, () => {
// eslint-disable-next-line no-console
console.log(`xartaudio server listening on :${config.port}`);
});
}
if (require.main === module) {
start();
}
module.exports = {
mapToAppRequest,
normalizeHeaders,
createHttpServer,
start,
};