diff --git a/src/handlers/proxyHandler.js b/src/handlers/proxyHandler.js new file mode 100644 index 0000000..d0e0420 --- /dev/null +++ b/src/handlers/proxyHandler.js @@ -0,0 +1,75 @@ +let serverconsole = {}; +let middleware = []; + +function proxyHandler(req, socket, head) { + let reqIdInt = Math.floor(Math.random() * 16777216); + if (reqIdInt == 16777216) reqIdInt = 0; + const reqId = + "0".repeat(6 - reqIdInt.toString(16).length) + reqIdInt.toString(16); + + // SVR.JS log facilities + const logFacilities = { + climessage: (msg) => serverconsole.climessage(msg, reqId), + reqmessage: (msg) => serverconsole.reqmessage(msg, reqId), + resmessage: (msg) => serverconsole.resmessage(msg, reqId), + errmessage: (msg) => serverconsole.errmessage(msg, reqId), + locerrmessage: (msg) => serverconsole.locerrmessage(msg, reqId), + locwarnmessage: (msg) => serverconsole.locwarnmessage(msg, reqId), + locmessage: (msg) => serverconsole.locmessage(msg, reqId), + }; + + socket.on("close", (hasError) => { + if (!hasError) serverconsole.locmessage("Client disconnected."); + else serverconsole.locmessage("Client disconnected due to error."); + }); + socket.on("error", () => {}); + + // SVR.JS configuration object (modified) + const config = Object.assign(process.serverConfig); + + config.generateServerString = () => { + return generateServerString(config.exposeServerVersion); + }; + + var reqip = socket.remoteAddress; + var reqport = socket.remotePort; + process.reqcounter++; + logFacilities.locmessage("Somebody connected to " + (config.secure ? ((typeof config.sport == "number" ? "port " : "socket ") + sport) : ((typeof config.port == "number" ? "port " : "socket ") + config.port)) + "..."); + logFacilities.reqmessage("Client " + ((!reqip || reqip == "") ? "[unknown client]" : (reqip + ((reqport && reqport !== 0) && reqport != "" ? ":" + reqport : ""))) + " wants to proxy " + req.url + " through this server"); + if (req.headers["user-agent"] != undefined) logFacilities.reqmessage("Client uses " + req.headers["user-agent"]); + + let index = 0; + + // Call the next middleware function + const next = () => { + let currentMiddleware = middleware[index++]; + while (currentMiddleware && !currentMiddleware.proxy) { + currentMiddleware = middleware[index++]; + } + if (currentMiddleware) { + try { + currentMiddleware.proxy(req, socket, head, logFacilities, config, next); + } catch (err) { + logFacilities.errmessage( + "There was an error while processing the request!", + ); + logFacilities.errmessage("Stack:"); + logFacilities.errmessage(err.stack); + socket.end("HTTP/1.1 500 Internal Server Error\n\n"); + } + } else { + logFacilities.errmessage("SVR.JS doesn't support proxy without proxy mod."); + if (!socket.destroyed) socket.end("HTTP/1.1 501 Not Implemented\n\n"); + } + }; + + // Handle middleware + next(); +} + +module.exports = (serverconsoleO, middlewareO) => { + serverconsole = serverconsoleO; + middleware = middlewareO; + return proxyHandler; +}; + \ No newline at end of file diff --git a/src/handlers/requestHandler.js b/src/handlers/requestHandler.js index 11311fd..c39f6e8 100644 --- a/src/handlers/requestHandler.js +++ b/src/handlers/requestHandler.js @@ -710,7 +710,7 @@ function requestHandler(req, res) { // Call the next middleware function const next = () => { let currentMiddleware = middleware[index++]; - while (req.isProxy && currentMiddleware && !currentMiddleware.proxySafe) { + while (req.isProxy && currentMiddleware && currentMiddleware.proxySafe !== false && !(currentMiddleware.proxySafe || currentMiddleware.proxy)) { currentMiddleware = middleware[index++]; } if (currentMiddleware) { diff --git a/src/index.js b/src/index.js index 5b8424a..e6a9fd6 100644 --- a/src/index.js +++ b/src/index.js @@ -303,6 +303,11 @@ const requestHandler = require("./handlers/requestHandler.js")( middleware, ); +const proxyHandler = require("./handlers/proxyHandler.js")( + serverconsole, + middleware, +); + const clientErrorHandler = require("./handlers/clientErrorHandler.js")( serverconsole, ); @@ -310,6 +315,7 @@ const clientErrorHandler = require("./handlers/clientErrorHandler.js")( // Create HTTP server http .createServer(requestHandler) + .on("connect", proxyHandler) .on("clientError", clientErrorHandler) .listen(3000);