2025-02-05 23:07:07 +00:00

104 lines
2.8 KiB
JavaScript

import path from "node:path"
import fs from "node:fs"
import HyperExpress from "hyper-express"
import LiveDirectory from "live-directory"
const { WebSocket: WSClient } = require("ws")
const http = require("http")
// CONFIGURATION CONSTANTS
const publicPath = path.resolve(process.cwd(), "public")
const TARGET_HTTP = "http://localhost:9000"
const TARGET_WS = "ws://localhost:8080"
const LISTENT_PORT = 9999
async function main() {
if (!fs.existsSync(publicPath)) {
console.log("Public path does not exist, creating...")
fs.mkdirSync(publicPath)
}
const app = new HyperExpress.Server()
const liveDirectory = new LiveDirectory(publicPath)
app.any("/*", async (req, res) => {
if (req.url.startsWith("/api")) {
return handleApiProxyRequest(req, res)
}
return handleStaticFileRequest(liveDirectory, req, res)
})
await app.listen(LISTENT_PORT)
console.log(`LISTENING on port ${LISTENT_PORT}`)
}
async function handleStaticFileRequest(liveDirectory, req, res) {
let file = liveDirectory.get(req.path)
if (file === undefined) {
file = liveDirectory.get("index.html")
}
if (file === undefined) {
return res.status(404).json({ error: "Not found" })
}
const fileParts = file.path.split(".")
const extension = fileParts[fileParts.length - 1]
// Retrieve the file content and serve it depending on the type of content available for this file
const content = file.content
if (content instanceof Buffer) {
// Set appropriate mime-type and serve file content Buffer as response body (This means that the file content was cached in memory)
return res.type(extension).send(content)
} else {
// Set the type and stream the content as the response body (This means that the file content was NOT cached in memory)
return res.type(extension).stream(content)
}
}
async function handleApiProxyRequest(request, response) {
try {
const targetURL = new URL(request.url, TARGET_HTTP)
const headers = { ...request.headers, host: targetURL.host }
// Configurar la solicitud al servidor de destino
const proxyReq = http.request({
hostname: targetURL.hostname,
port: targetURL.port || 80,
path: targetURL.pathname + targetURL.search,
method: request.method,
headers,
})
// Manejar la respuesta del servidor de destino
proxyReq.on("response", (proxyRes) => {
response.status(proxyRes.statusCode)
// Copiar headers
Object.entries(proxyRes.headers).forEach(([key, val]) => {
response.header(key, val)
})
// Pipe de la respuesta
proxyRes.pipe(response.stream)
})
// Manejar errores
proxyReq.on("error", (error) => {
response.status(500).send(`Proxy error: ${error.message}`)
})
// Pipe del cuerpo de la solicitud
request.stream().pipe(proxyReq)
} catch (error) {
console.error(error)
response.status(500).send("Internal Server Error")
}
}
main()