UNPKG

@grace-js/grace

Version:

An opinionated API framework

93 lines 3.26 kB
import { Server } from "node:http"; import { IP_HEADERS } from "../../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; } export class NodeAdapter { listen(grace, port) { this.server = new 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 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(); } } //# sourceMappingURL=adapter.js.map