import * as plugins from '../plugins.js'; import { Handler } from './classes.handler.js'; import * as interfaces from '../../dist_ts_interfaces/index.js'; export class HandlerProxy extends Handler { /** * The constuctor of HandlerProxy * @param remoteMountPointArg */ constructor( remoteMountPointArg: string, optionsArg?: { responseModifier?: interfaces.TResponseModifier; headers?: { [key: string]: string }; } ) { super('ALL', async (req, res) => { const relativeRequestPath = req.path.slice(req.route.path.length - 1); const proxyRequestUrl = remoteMountPointArg + relativeRequestPath; console.log(`proxy ${req.path} to ${proxyRequestUrl}`); let proxiedResponse: plugins.smartrequest.IExtendedIncomingMessage; try { proxiedResponse = await plugins.smartrequest.request(proxyRequestUrl, { method: req.method, autoJsonParse: false, }); } catch { res.end('failed to fullfill request'); return; } for (const header of Object.keys(proxiedResponse.headers)) { res.set(header, proxiedResponse.headers[header] as string); } // set additional headers if (optionsArg && optionsArg.headers) { for (const key of Object.keys(optionsArg.headers)) { res.set(key, optionsArg.headers[key]); } } // Ensure body exists and convert it to Buffer consistently let responseToSend: Buffer; if (proxiedResponse.body !== undefined && proxiedResponse.body !== null) { if (Buffer.isBuffer(proxiedResponse.body)) { responseToSend = proxiedResponse.body; } else if (typeof proxiedResponse.body === 'string') { responseToSend = Buffer.from(proxiedResponse.body); } else { // Handle other types (like objects) by JSON stringifying them responseToSend = Buffer.from(JSON.stringify(proxiedResponse.body)); } } else { // Provide a default empty buffer if body is undefined/null responseToSend = Buffer.from(''); } if (optionsArg && optionsArg.responseModifier) { const modifiedResponse = await optionsArg.responseModifier({ headers: res.getHeaders(), path: req.path, responseContent: responseToSend, }); // headers for (const key of Object.keys(res.getHeaders())) { if (!modifiedResponse.headers[key]) { res.removeHeader(key); } } for (const key of Object.keys(modifiedResponse.headers)) { res.setHeader(key, modifiedResponse.headers[key]); } // responseContent responseToSend = modifiedResponse.responseContent; } res.status(200); res.write(responseToSend); res.end(); }); } }