Reputation: 51
I need to make a Node js proxy server which depending on the content in the body will redirect to one server or another.
Example: I send a request to the server 127.0.0.1:8080 with the data {"tag": "server_1"}. This server will read the data and if the tag is "server_1" then it sends the request to the server 127.0.0.1:8081 otherwise the request goes to the 127.0.0.1:8082.
I started to make a proxy but I cannot modify the hostname, the port and the protocol according to the received data.
Here is my code:
const http = require('http');
const https = require('https');
const proxyHostname = '0.0.0.0';
const proxyPort = 8080;
const primaryServerProtocol = "http";
const primaryServerHostname = "127.0.0.1";
const primaryServerPort = 8081;
const secondaryServerProtocol = "https";
const secondaryServerHostname = "127.0.0.1";
const secondaryServerPort = 8082;
const proxyServer = http.createServer((clientRequest, clientResponse) => {
const serverRequestOptions = {
hostname: primaryServerHostname,
port: primaryServerPort,
path: clientRequest.url,
method: clientRequest.method,
headers: clientRequest.headers,
rejectUnauthorized: false
}
/***********************
let data = [];
clientRequest.on('data', function (chunk) {
data.push(chunk);
});
clientRequest.on('end', function () {
data = Buffer.concat(data).toString();
if (data.includes("server_2")) {
// Set options...
}
});
***********************/
const proxy = https.request(serverRequestOptions, (serverResponse) => {
clientResponse.writeHead(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(clientResponse, {
end: true
});
});
clientRequest.pipe(proxy, {
end: true
});
});
proxyServer.listen(proxyPort, proxyHostname, () => {
console.log(`Server running at http://${proxyHostname}:${proxyPort}`);
});
I also tried with http-proxy but I have a preference for the vanilla solution but I don't really understand how the pipes work for my case.
const http = require('http');
const httpProxy = require('http-proxy');
const proxyHostname = '0.0.0.0';
const proxyPort = 8080;
const primaryServerProtocol = "http:";
const primaryServerHostname = "127.0.0.1";
const primaryServerPort = 8081;
const secondaryServerProtocol = "https:";
const secondaryServerHostname = "127.0.0.1";
const secondaryServerPort = 8082;
const options = {
target: {
protocol: primaryServerProtocol,
host: primaryServerHostname,
port: primaryServerPort,
},
secure: false
};
const proxy = httpProxy.createProxyServer();
const proxyServer = http.createServer((req, res) => {
proxy.web(req, res, options);
});
/***********************
proxy.on('proxyReq', (proxyReq, req) => {
let data = '';
req.on('data', chunk => {
data += chunk;
});
req.on('end', () => {
if (data.includes("server_2")) {
// Set options...
}
});
});
***********************/
proxyServer.listen(proxyPort, proxyHostname, () => {
console.log(`Server running at http://${proxyHostname}:${proxyPort}`);
});
This code works but sends to the correct server with a delay request ... Do you have an idea or a solution?
Upvotes: 3
Views: 1652
Reputation: 51
I post my solution for those who might be interested :
const http = require('http');
const https = require('https');
const proxyHostname = '0.0.0.0';
const proxyPort = 8080;
const primaryServerHostname = "127.0.0.1";
const primaryServerPort = 8081;
const secondaryServerHostname = "127.0.0.1";
const secondaryServerPort = 8082;
const proxyServer = http.createServer((clientRequest, clientResponse) => {
const serverRequestOptions = {
path: clientRequest.url,
method: clientRequest.method,
headers: clientRequest.headers,
rejectUnauthorized: false
}
let requestBody = [];
clientRequest.on('data', (chunk) => {
requestBody.push(chunk);
});
clientRequest.on('end', () => {
requestBody = Buffer.concat(requestBody).toString();
if (requestBody.includes("server_2")) {
serverRequestOptions.hostname = secondaryServerHostname;
serverRequestOptions.port = secondaryServerPort;
} else {
serverRequestOptions.hostname = primaryServerHostname;
serverRequestOptions.port = primaryServerPort;
}
const proxy = https.request(serverRequestOptions, (serverResponse) => {
clientResponse.writeHead(serverResponse.statusCode, serverResponse.headers);
serverResponse.pipe(clientResponse);
});
proxy.on('error', (err) => {
console.error(err);
clientResponse.statusCode = 500;
clientResponse.end(err.message);
});
proxy.write(requestBody);
proxy.end();
});
clientRequest.on('error', (err) => {
console.error(err);
clientResponse.statusCode = 400;
clientResponse.end(err.message);
});
clientResponse.on('error', (err) => {
console.error(err);
clientResponse.end(err.message);
});
});
proxyServer.listen(proxyPort, proxyHostname, () => {
console.log(`Server running at http://${proxyHostname}:${proxyPort}`);
});
Upvotes: 2