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}`);
|
2025-08-17 08:14:08 +00:00
|
|
|
let proxiedResponse: plugins.smartrequest.ICoreResponse;
|
2023-03-30 15:15:48 +02:00
|
|
|
try {
|
2025-08-17 08:14:08 +00:00
|
|
|
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;
|
|
|
|
}
|
2025-08-17 08:14:08 +00:00
|
|
|
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]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2025-08-17 08:14:08 +00:00
|
|
|
// Get response body as buffer
|
2025-03-16 12:02:49 +00:00
|
|
|
let responseToSend: Buffer;
|
2025-08-17 08:14:08 +00:00
|
|
|
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('');
|
2025-03-16 12:02:49 +00:00
|
|
|
}
|
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();
|
|
|
|
});
|
|
|
|
}
|
2025-03-16 11:53:57 +00:00
|
|
|
}
|