1
0
Fork 0
forked from svrjs/svrjs

Add secondary HTTP server and handlers for primary HTTP server

This commit is contained in:
Dorian Niemiec 2024-08-25 17:04:49 +02:00
parent 7b4612e8b0
commit b758e11513
2 changed files with 230 additions and 4 deletions

View file

@ -0,0 +1,64 @@
const generateServerString = require("../utils/generateServerString");
const svrjsInfo = require("../../svrjs.json");
const { name } = svrjsInfo;
let serverconsole = {};
function noproxyHandler(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);
var reqip = socket.remoteAddress;
var reqport = socket.remotePort;
process.reqcounter++;
logFacilities.locmessage(
"Somebody connected to " +
(config.secure
? (typeof config.sport == "number" ? "port " : "socket ") + config.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"]);
logFacilities.errmessage("This server will never be a proxy.");
if (!socket.destroyed) socket.end("HTTP/1.1 501 Not Implemented\n\n");
}
module.exports = (serverconsoleO, middlewareO) => {
serverconsole = serverconsoleO;
return noproxyHandler;
};

View file

@ -493,15 +493,177 @@ const proxyHandler = require("./handlers/proxyHandler.js")(
middleware, middleware,
); );
const noproxyHandler = require("./handlers/noproxyHandler.js")(serverconsole);
const clientErrorHandler = require("./handlers/clientErrorHandler.js")( const clientErrorHandler = require("./handlers/clientErrorHandler.js")(
serverconsole, serverconsole,
); );
let server = {};
let server2 = {};
// Create secondary HTTP server
try {
server2 = http.createServer({
requireHostHeader: false,
});
} catch (err) {
server2 = http.createServer();
}
// Add handlers to secondary HTTP server
server2.on("request", requestHandler);
server2.on("checkExpectation", requestHandler);
server2.on("clientError", clientErrorHandler);
server2.on("connect", process.serverConfig.disableToHTTPSRedirect ? proxyHandler : noproxyHandler);
// Create HTTP server // Create HTTP server
const server = http if (process.serverConfig.enableHTTP2 == true) {
.createServer(requestHandler) if (process.serverConfig.secure) {
.on("connect", proxyHandler) server = http2.createSecureServer({
.on("clientError", clientErrorHandler); allowHTTP1: true,
requireHostHeader: false,
key: key,
cert: cert,
requestCert: configJSON.useClientCertificate,
rejectUnauthorized: configJSON.rejectUnauthorizedClientCertificates,
ciphers: configJSON.cipherSuite,
ecdhCurve: configJSON.ecdhCurve,
minVersion: configJSON.tlsMinVersion,
maxVersion: configJSON.tlsMaxVersion,
sigalgs: configJSON.signatureAlgorithms,
settings: configJSON.http2Settings,
});
} else {
server = http2.createServer({
allowHTTP1: true,
requireHostHeader: false,
settings: configJSON.http2Settings,
});
}
} else {
if (process.serverConfig.secure) {
server = https.createServer({
key: key,
cert: cert,
requireHostHeader: false,
requestCert: configJSON.useClientCertificate,
rejectUnauthorized: configJSON.rejectUnauthorizedClientCertificates,
ciphers: configJSON.cipherSuite,
ecdhCurve: configJSON.ecdhCurve,
minVersion: configJSON.tlsMinVersion,
maxVersion: configJSON.tlsMaxVersion,
sigalgs: configJSON.signatureAlgorithms,
});
} else {
try {
server = http.createServer({
requireHostHeader: false,
});
} catch (err) {
server = http.createServer();
}
}
}
// TODO: SNI
//if (secure) {
// try {
// sniCredentials.forEach(function (sniCredentialsSingle) {
// server.addContext(sniCredentialsSingle.name, {
// cert: sniCredentialsSingle.cert,
// key: sniCredentialsSingle.key
// });
// try {
// var snMatches = sniCredentialsSingle.name.match(/^([^:[]*|\[[^]]*\]?)((?::.*)?)$/);
// if (!snMatches[1][0].match(/^\.+$/)) snMatches[1][0] = snMatches[1][0].replace(/\.+$/, "");
// server._contexts[server._contexts.length - 1][0] = new RegExp("^" + snMatches[1].replace(/([.^$+?\-\\[\]{}])/g, "\\$1").replace(/\*/g, "[^.:]*") + ((snMatches[1][0] == "[" || snMatches[1].match(/^(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])\.(?:25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9]?[0-9])$/)) ? "" : "\.?") + snMatches[2].replace(/([.^$+?\-\\[\]{}])/g, "\\$1").replace(/\*/g, "[^.]*") + "$", "i");
// } catch (ex) {
// // Can't replace regex, ignoring...
// }
// });
// } catch (err) {
// // SNI error
// }
//}
// Add handlers to the server
server.on("request", requestHandler);
server.on("checkExpectation", requestHandler);
server.on("connect", proxyHandler);
server.on("clientError", clientErrorHandler);
if (process.serverConfig.secure) {
server.prependListener("connection", function (sock) {
sock.reallyDestroy = sock.destroy;
sock.destroy = function () {
sock.toDestroy = true;
};
});
server.prependListener("tlsClientError", function (err, sock) {
if (
err.code == "ERR_SSL_HTTP_REQUEST" ||
err.message.indexOf("http request") != -1
) {
sock._parent.destroy = sock._parent.reallyDestroy;
sock._readableState = sock._parent._readableState;
sock._writableState = sock._parent._writableState;
sock._parent.toDestroy = false;
sock.pipe = function (a, b, c) {
sock._parent.pipe(a, b, c);
};
sock.write = function (a, b, c) {
sock._parent.write(a, b, c);
};
sock.end = function (a, b, c) {
sock._parent.end(a, b, c);
};
sock.destroyed = sock._parent.destroyed;
sock.readable = sock._parent.readable;
sock.writable = sock._parent.writable;
sock.remoteAddress = sock._parent.remoteAddress;
sock.remotePort = sock._parent.remoteAddress;
sock.destroy = function (a, b, c) {
try {
sock._parent.destroy(a, b, c);
sock.destroyed = sock._parent.destroyed;
} catch (err) {
// Socket is probably already destroyed.
}
};
} else {
sock._parent.destroy = sock._parent.reallyDestroy;
try {
if (sock._parent.toDestroy) sock._parent.destroy();
} catch (err) {
// Socket is probably already destroyed.
}
}
});
server.prependListener("secureConnection", function (sock) {
sock._parent.destroy = sock._parent.reallyDestroy;
delete sock._parent.reallyDestroy;
});
// TODO: OCSP stapling
/*if (process.serverConfig.enableOCSPStapling && !ocsp._errored) {
server.on("OCSPRequest", function (cert, issuer, callback) {
ocsp.getOCSPURI(cert, function (err, uri) {
if (err) return callback(err);
var req = ocsp.request.generate(cert, issuer);
var options = {
url: uri,
ocsp: req.data
};
ocspCache.request(req.id, options, callback);
});
});
}*/
}
// TODO: close, open, stop, restart commands // TODO: close, open, stop, restart commands
// Base commands // Base commands