Learning and Implementing Gateways with Node.js
I am learning about gateways and working on their implementation using Node.js. One specific feature I am focusing on is rate limiting, which I intend to implement myself. This rate limiter utilizes IP addresses to keep track of the number of requests.
To ensure the functionality is correctly implemented, I need to conduct thorough testing. In particular, I am looking for a way to make multiple requests with different IP addresses to test the rate limiting locally.
Consider a simple (not accurate to what I intend to implement) rate limiter.
const cash = {};
const limit = 50;
const rateLimiter = async (req, res, next) => {
if (!cash[req.ip]) cash[req.ip] = { count: 0, time: [] };
if (cash[req.ip].count >= limit) {
if (Date.now() - cash[req.ip].time[0] < 60000) {
return res.send("Limit reached");
} else {
for (const t of cash[req.ip].time) {
if (Date.now() - t > 60000) break;
cash[req.ip].time.shift(); // Remove the oldest entry
cash[req.ip].count--;
}
}
}
cash[req.ip].count++;
cash[req.ip].time.push(Date.now());
next();
};
Manipulating IP Address in Axios or Node-Fetch for Custom Requests
I want to run a script where I need to make custom requests to a server using Axios or Node-Fetch. I want to perform some experiments and need to manipulate the IP address that is being sent in the request object.
Here is a simplified version of my current code using Axios:
const axios = require("axios");
const http = require("http");
function getRandomPrivateIP() {
const octet3 = Math.floor(Math.random() * 256);
const octet4 = Math.floor(Math.random() * 256);
return `192.168.${octet3}.${octet4}`;
}
function createAxiosInstanceWithIP(ipAddress) {
const agent = new http.Agent({
localAddress: ipAddress,
});
return axios.create({ httpAgent: agent, httpsAgent: agent });
}
const url = "http://localhost:8080/gateway";
const numberOfRequests = 1000;
for (let i = 0; i < numberOfRequests; i++) {
const customIPAddress = getRandomPrivateIP(); // Invoke the function
const axiosInstance = createAxiosInstanceWithIP(customIPAddress);
axiosInstance
.get(url)
.then((response) => {
// Handle the response
console.log(`Request ${i + 1} successful`);
})
.catch((error) => {
// Handle errors
console.error(`Request ${i + 1} failed: ${error.message}`);
});
}
Above code throws error:
Request 1000 failed: bind EINVAL 192.168.72.253
Is there a way to manipulate the IP address in the request object to have more control over the experiment I am trying to perform? I have explored Apache server and other dedicated VPS for benchmarking, but I would like to customize the IP address for my requests within the script.
Furthermore, if there are instances where I may be making mistakes or need to approach situations with a different mindset, let me know.
I found the solution, it is as follows
The
localAddressoption in thehttp.Agentis used for binding the socket to a local interface's IP address, but it does not affect the outgoing IP address in the HTTP request. To achieve what I wanted, we need to use a custom DNS resolver to resolve the host to a specific IP.Here is an updated version of the code:
This code includes a custom DNS resolver function in the
lookupoption of thehttp.Agent, which resolves the hostname to the specified IP address.