Files
typedserver/ts/servertools/classes.handlerproxy.ts

108 lines
3.3 KiB
TypeScript
Raw Normal View History

2024-02-20 17:30:46 +01:00
import * as plugins from '../plugins.js';
2023-03-30 15:15:48 +02:00
import { Handler } from './classes.handler.js';
2024-05-11 12:51:20 +02:00
import * as interfaces from '../../dist_ts_interfaces/index.js';
2023-03-30 15:15:48 +02:00
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.ICoreResponse;
2023-03-30 15:15:48 +02:00
try {
const smartRequest = plugins.smartrequest.SmartRequest.create()
.url(proxyRequestUrl);
// Execute request based on method
switch (req.method.toUpperCase()) {
case 'GET':
proxiedResponse = await smartRequest.get();
break;
case 'POST':
proxiedResponse = await smartRequest.post();
break;
case 'PUT':
proxiedResponse = await smartRequest.put();
break;
case 'DELETE':
proxiedResponse = await smartRequest.delete();
break;
case 'PATCH':
proxiedResponse = await smartRequest.patch();
break;
default:
// For other methods, default to GET
proxiedResponse = await smartRequest.get();
break;
}
2023-03-30 15:15:48 +02:00
} catch {
res.end('failed to fullfill request');
return;
}
const headers = proxiedResponse.headers;
for (const header of Object.keys(headers)) {
res.set(header, headers[header] as string);
2023-03-30 15:15:48 +02:00
}
// set additional headers
if (optionsArg && optionsArg.headers) {
for (const key of Object.keys(optionsArg.headers)) {
res.set(key, optionsArg.headers[key]);
}
}
// Get response body as buffer
let responseToSend: Buffer;
try {
const arrayBuffer = await proxiedResponse.arrayBuffer();
responseToSend = Buffer.from(arrayBuffer);
} catch {
// If we can't get arrayBuffer, try text
try {
const text = await proxiedResponse.text();
responseToSend = Buffer.from(text);
} catch {
// Provide a default empty buffer if body cannot be read
responseToSend = Buffer.from('');
}
2023-03-30 15:15:48 +02:00
}
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();
});
}
}