Page MenuHomeSealhub

proxy.ts
No OneTemporary

proxy.ts

import express from "express";
import type { Server } from "node:http";
import type { Request, Response, Express } from "express";
import { createProxyMiddleware, responseInterceptor } from "http-proxy-middleware";
import { HTMLRewriter } from "html-rewriter-wasm";
import type TheApp from "./app.js";
import { htmlUnescape } from "escape-goat";
import { promisify } from "util";
import { PROXY_TARGET } from "src/back/config.js";
const encoder = new TextEncoder();
const decoder = new TextDecoder();
export default class Proxy {
express_app: Express;
server: Server;
constructor(public app: TheApp) {}
async start() {
this.express_app = express();
console.log("Starting proxy...");
const { items: rules } = await this.app.collections.rules
.suList()
.format({ code: "original" })
.filter({ active: true })
.fetch();
const code = rules
.map((rule) => `{${htmlUnescape(rule.get("code") || "")}}`)
.join("\n");
console.log("The code to run is");
console.log(code);
const proxyMiddleware = createProxyMiddleware<Request, Response>({
target: PROXY_TARGET,
changeOrigin: true,
selfHandleResponse: true,
on: {
// eslint-disable-next-line @typescript-eslint/no-misused-promises
proxyRes: responseInterceptor(async (responseBuffer, proxyRes, req) => {
if (!proxyRes.headers["content-type"]?.includes("html")) {
// only rewrite html
return responseBuffer;
}
const response = responseBuffer.toString("utf8"); // convert buffer to string
let output = "";
const rewriter = new HTMLRewriter((outputChunk) => {
output += decoder.decode(outputChunk);
});
try {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const url = req.url; // to make it available in eval
eval(code);
await this.app.collections.logs.suCreate({
content: "success",
timestamp: new Date().getTime(),
url: req.url,
});
} catch (e) {
const message = e instanceof Error ? e.message : "";
await this.app.collections.logs.suCreate({
content: message,
timestamp: new Date().getTime(),
url: req.url,
});
rewriter.free();
return responseBuffer;
}
try {
await rewriter.write(encoder.encode(response));
await rewriter.end();
} catch (e) {
console.error(e);
return responseBuffer;
} finally {
rewriter.free(); // Remember to free memory
}
return output;
}),
},
});
this.express_app.use("/", proxyMiddleware);
const port = 3000;
this.server = this.express_app.listen(port);
console.log(
`Proxy started. Target URL is ${PROXY_TARGET}. Listening on :${port}`
);
}
stop() {
console.log("Stopping proxy...");
// eslint-disable-next-line @typescript-eslint/no-unsafe-call, @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions
return promisify(this.server.close.bind(this.server)).bind(
this.server
)() as Promise<void>;
}
}
let instance: Proxy;
export function getProxy(app: TheApp): Proxy {
if (!instance) {
instance = new Proxy(app);
}
return instance;
}

File Metadata

Mime Type
text/x-java
Expires
Tue, Feb 25, 03:57 (1 d, 9 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
610439
Default Alt Text
proxy.ts (3 KB)

Event Timeline