forked from svrjs/svrjs
Add secondary HTTP server and handlers for primary HTTP server
This commit is contained in:
parent
7b4612e8b0
commit
b758e11513
2 changed files with 230 additions and 4 deletions
64
src/handlers/noproxyHandler.js
Normal file
64
src/handlers/noproxyHandler.js
Normal 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;
|
||||||
|
};
|
170
src/index.js
170
src/index.js
|
@ -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
|
||||||
|
|
Reference in a new issue