|
|
|
@ -116,26 +116,30 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
-----END CERTIFICATE-----
|
|
|
|
|
`,
|
|
|
|
|
},
|
|
|
|
|
async (req, res) => {
|
|
|
|
|
async (originRequest, originResponse) => {
|
|
|
|
|
/**
|
|
|
|
|
* endRequest function
|
|
|
|
|
* can be used to prematurely end a request
|
|
|
|
|
*/
|
|
|
|
|
const endRequest = (
|
|
|
|
|
const endOriginReqRes = (
|
|
|
|
|
statusArg: number = 404,
|
|
|
|
|
messageArg: string = 'This route is not available on this server.',
|
|
|
|
|
headers: plugins.http.OutgoingHttpHeaders = {}
|
|
|
|
|
) => {
|
|
|
|
|
res.writeHead(statusArg, messageArg);
|
|
|
|
|
res.end(messageArg);
|
|
|
|
|
originResponse.writeHead(statusArg, messageArg);
|
|
|
|
|
originResponse.end(messageArg);
|
|
|
|
|
if (originRequest.socket !== originResponse.socket) {
|
|
|
|
|
console.log('hey, something is strange.')
|
|
|
|
|
}
|
|
|
|
|
originResponse.destroy();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
console.log(`got request: ${req.headers.host}${plugins.url.parse(req.url).path}`);
|
|
|
|
|
const destinationConfig = this.router.routeReq(req);
|
|
|
|
|
console.log(`got request: ${originRequest.headers.host}${plugins.url.parse(originRequest.url).path}`);
|
|
|
|
|
const destinationConfig = this.router.routeReq(originRequest);
|
|
|
|
|
|
|
|
|
|
if (!destinationConfig) {
|
|
|
|
|
console.log(`${req.headers.host} can't be routed properly. Terminating request.`);
|
|
|
|
|
endRequest();
|
|
|
|
|
console.log(`${originRequest.headers.host} can't be routed properly. Terminating request.`);
|
|
|
|
|
endOriginReqRes();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -144,14 +148,14 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
const authInfo = destinationConfig.authentication;
|
|
|
|
|
switch (authInfo.type) {
|
|
|
|
|
case 'Basic':
|
|
|
|
|
const authHeader = req.headers.authorization;
|
|
|
|
|
const authHeader = originRequest.headers.authorization;
|
|
|
|
|
if (authHeader) {
|
|
|
|
|
if (!authHeader.includes('Basic ')) {
|
|
|
|
|
return endRequest(401, 'Authentication required', {
|
|
|
|
|
return endOriginReqRes(401, 'Authentication required', {
|
|
|
|
|
'WWW-Authenticate': 'Basic realm="Access to the staging site", charset="UTF-8"',
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
const authStringBase64 = req.headers.authorization.replace('Basic ', '');
|
|
|
|
|
const authStringBase64 = originRequest.headers.authorization.replace('Basic ', '');
|
|
|
|
|
const authString: string = plugins.smartstring.base64.decode(authStringBase64);
|
|
|
|
|
const userPassArray = authString.split(':');
|
|
|
|
|
const user = userPassArray[0];
|
|
|
|
@ -159,12 +163,12 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
if (user === authInfo.user && pass === authInfo.pass) {
|
|
|
|
|
console.log('request successfully authenticated');
|
|
|
|
|
} else {
|
|
|
|
|
return endRequest(403, 'Forbidden: Wrong credentials');
|
|
|
|
|
return endOriginReqRes(403, 'Forbidden: Wrong credentials');
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
return endRequest(
|
|
|
|
|
return endOriginReqRes(
|
|
|
|
|
403,
|
|
|
|
|
'Forbidden: unsupported authentication method configured. Please report to the admin.'
|
|
|
|
|
);
|
|
|
|
@ -173,62 +177,66 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
|
|
|
|
|
let destinationUrl: string;
|
|
|
|
|
if (destinationConfig) {
|
|
|
|
|
destinationUrl = `http://${destinationConfig.destinationIp}:${destinationConfig.destinationPort}${req.url}`;
|
|
|
|
|
destinationUrl = `http://${destinationConfig.destinationIp}:${destinationConfig.destinationPort}${originRequest.url}`;
|
|
|
|
|
} else {
|
|
|
|
|
return endRequest();
|
|
|
|
|
return endOriginReqRes();
|
|
|
|
|
}
|
|
|
|
|
console.log(destinationUrl);
|
|
|
|
|
const response = await plugins.smartrequest.request(
|
|
|
|
|
const proxyResponse = await plugins.smartrequest.request(
|
|
|
|
|
destinationUrl,
|
|
|
|
|
{
|
|
|
|
|
method: req.method,
|
|
|
|
|
headers: req.headers,
|
|
|
|
|
method: originRequest.method,
|
|
|
|
|
headers: originRequest.headers,
|
|
|
|
|
keepAlive: true,
|
|
|
|
|
},
|
|
|
|
|
true, // lets make this streaming
|
|
|
|
|
(request) => {
|
|
|
|
|
req.on('data', (data) => {
|
|
|
|
|
request.write(data);
|
|
|
|
|
(proxyRequest) => {
|
|
|
|
|
originRequest.on('data', (data) => {
|
|
|
|
|
proxyRequest.write(data);
|
|
|
|
|
});
|
|
|
|
|
req.on('end', (data) => {
|
|
|
|
|
request.end();
|
|
|
|
|
originRequest.on('end', (data) => {
|
|
|
|
|
proxyRequest.end();
|
|
|
|
|
});
|
|
|
|
|
req.on('error', () => {
|
|
|
|
|
request.end();
|
|
|
|
|
originRequest.on('error', () => {
|
|
|
|
|
proxyRequest.end();
|
|
|
|
|
});
|
|
|
|
|
req.on('close', () => {
|
|
|
|
|
request.end();
|
|
|
|
|
originRequest.on('close', () => {
|
|
|
|
|
proxyRequest.end();
|
|
|
|
|
});
|
|
|
|
|
req.on('timeout', () => {
|
|
|
|
|
request.end();
|
|
|
|
|
request.destroy();
|
|
|
|
|
originRequest.on('timeout', () => {
|
|
|
|
|
proxyRequest.end();
|
|
|
|
|
originRequest.destroy();
|
|
|
|
|
});
|
|
|
|
|
proxyRequest.on('error', () => {
|
|
|
|
|
endOriginReqRes();
|
|
|
|
|
})
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
res.statusCode = response.statusCode;
|
|
|
|
|
console.log(response.statusCode);
|
|
|
|
|
originResponse.statusCode = proxyResponse.statusCode;
|
|
|
|
|
console.log(proxyResponse.statusCode);
|
|
|
|
|
for (const defaultHeader of Object.keys(this.defaultHeaders)) {
|
|
|
|
|
res.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]);
|
|
|
|
|
originResponse.setHeader(defaultHeader, this.defaultHeaders[defaultHeader]);
|
|
|
|
|
}
|
|
|
|
|
for (const header of Object.keys(response.headers)) {
|
|
|
|
|
res.setHeader(header, response.headers[header]);
|
|
|
|
|
for (const header of Object.keys(proxyResponse.headers)) {
|
|
|
|
|
originResponse.setHeader(header, proxyResponse.headers[header]);
|
|
|
|
|
}
|
|
|
|
|
response.on('data', (data) => {
|
|
|
|
|
res.write(data);
|
|
|
|
|
proxyResponse.on('data', (data) => {
|
|
|
|
|
originResponse.write(data);
|
|
|
|
|
});
|
|
|
|
|
response.on('end', () => {
|
|
|
|
|
res.end();
|
|
|
|
|
proxyResponse.on('end', () => {
|
|
|
|
|
originResponse.end();
|
|
|
|
|
});
|
|
|
|
|
response.on('error', () => {
|
|
|
|
|
res.end();
|
|
|
|
|
proxyResponse.on('error', () => {
|
|
|
|
|
originResponse.destroy();
|
|
|
|
|
});
|
|
|
|
|
response.on('close', () => {
|
|
|
|
|
res.end();
|
|
|
|
|
proxyResponse.on('close', () => {
|
|
|
|
|
originResponse.end();
|
|
|
|
|
});
|
|
|
|
|
response.on('timeout', () => {
|
|
|
|
|
res.end();
|
|
|
|
|
res.destroy();
|
|
|
|
|
proxyResponse.on('timeout', () => {
|
|
|
|
|
originResponse.end();
|
|
|
|
|
originResponse.destroy()
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
@ -259,9 +267,7 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
|
|
|
|
|
// handle closing
|
|
|
|
|
const cleanUp = () => {
|
|
|
|
|
ws.close();
|
|
|
|
|
ws.terminate();
|
|
|
|
|
wsc.close();
|
|
|
|
|
wsc.terminate();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
@ -273,27 +279,18 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
cleanUp();
|
|
|
|
|
});
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
});
|
|
|
|
|
this.httpsServer.keepAliveTimeout = 61000;
|
|
|
|
|
this.httpsServer.headersTimeout = 65000;
|
|
|
|
|
|
|
|
|
|
this.httpsServer.on('connection', (connection: plugins.net.Socket) => {
|
|
|
|
|
connection.setTimeout(60000);
|
|
|
|
|
this.socketMap.add(connection);
|
|
|
|
|
console.log(`added connection. now ${this.socketMap.getArray().length} sockets connected.`);
|
|
|
|
|
const destroyConnection = () => {
|
|
|
|
|
}
|
|
|
|
|
const cleanupConnection = () => {
|
|
|
|
|
if (this.socketMap.checkForObject(connection)) {
|
|
|
|
|
this.socketMap.remove(connection);
|
|
|
|
|
console.log(`removed connection. ${this.socketMap.getArray().length} sockets remaining.`);
|
|
|
|
|
connection.end();
|
|
|
|
|
connection.destroy();
|
|
|
|
|
console.log(`socket successfully destroyed.`);
|
|
|
|
|
/* plugins.smartdelay.delayFor(10000).then(() => {
|
|
|
|
|
connection.removeAllListeners();
|
|
|
|
|
}) */
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
connection.on('close', () => {
|
|
|
|
@ -307,7 +304,7 @@ JNj2Dr5H0XoLFFnvuvzcRbhlJ9J67JzR+7g=
|
|
|
|
|
});
|
|
|
|
|
connection.on('timeout', () => {
|
|
|
|
|
cleanupConnection();
|
|
|
|
|
});
|
|
|
|
|
})
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
this.httpsServer.listen(this.options.port);
|
|
|
|
|