@grace-js/grace
Version:
An opinionated API framework
97 lines • 3.43 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.NodeAdapter = void 0;
const node_http_1 = require("node:http");
const headers_js_1 = require("../../utils/headers.js");
async function createRequestFromIncomingMessage(req, verbose) {
return new Promise((resolve, reject) => {
const requestHeaders = new Headers();
let body = [];
Object.entries(req.headers).forEach(([key, value]) => {
if (typeof value === 'string') {
requestHeaders.append(key, value);
}
if (Array.isArray(value)) {
value.forEach((v) => {
requestHeaders.append(key, v);
});
}
});
if (req.socket.remoteAddress) {
requestHeaders.append('Grace-Client-IP', req.socket.remoteAddress);
}
if (verbose) {
console.log('Incoming request', req.url, req.method, requestHeaders);
}
if (req.method !== 'GET' && req.method !== 'HEAD') {
req.on('data', (chunk) => {
body.push(chunk);
if (verbose) {
console.log('Chunk', chunk);
}
}).on('end', async () => {
body = Buffer.concat(body);
if (verbose) {
console.log('Body', body);
}
resolve(new Request('https://a.aa' + (req.url.startsWith('/') ? req.url : ('/' + req.url)), {
method: req.method,
headers: requestHeaders,
body: body
}));
});
}
else {
resolve(new Request('https://a.aa' + (req.url.startsWith('/') ? req.url : ('/' + req.url)), {
method: req.method,
headers: requestHeaders,
body: undefined
}));
}
});
}
function convertWebHeadersToNodeHeaders(headers) {
const result = {};
headers.forEach((value, key) => {
result[key] = value;
});
return result;
}
class NodeAdapter {
listen(grace, port) {
this.server = new node_http_1.Server(async (req, res) => {
const request = await createRequestFromIncomingMessage(req, grace.verbose);
const response = await grace.fetch(request);
res.writeHead(response.status, convertWebHeadersToNodeHeaders(response.headers));
const reader = response.body?.getReader();
const chunks = [];
while (reader) {
const { done, value } = await reader.read();
if (done) {
break;
}
chunks.push(value);
}
const combined = new Uint8Array(chunks.reduce((acc, val) => acc.concat(Array.from(val)), []));
res.end(combined);
});
this.server.listen(port);
}
getRequestIp(request) {
for (const header of headers_js_1.IP_HEADERS) {
if (request.headers.has(header)) {
const h = request.headers.get(header);
if (h.includes(',')) {
return h.split(',')[0];
}
return h;
}
}
return null;
}
close() {
this.server?.close();
}
}
exports.NodeAdapter = NodeAdapter;
//# sourceMappingURL=adapter.js.map