nodejs - know from which ip address the server makes the get - node.js

Sorry, I'm quite new to network programming and nodejs. I'm using nodes in a server with some clients in a local network.
Sometimes I have to ask data to clients via get request:
// somewhere inside server.js
function askDataToClient(ip) {
var options = {
host: String(ip),
port: 80,
path: '/client/read',
auth: 'username:password'
};
var request = http.get(options, function(htres){
var body = "";
htres.on('data', function(data) {
body += data;
});
htres.on('end', function() {
body = JSON.parse(body);
res.json(body);
res.end();
})
htres.on('error', function(e) {
// ...
});
});
}
I'd like to know the server ip used for calling this get request.
I know of this answer but it gives me all the various network active on the server machine:
lo0 127.0.0.1
en1 192.168.3.60
bridge0 192.168.2.1
If I'm querying the client 192.168.3.36 I know it is the second ip, 192.168.3.60 because they are on the same network.. but How to know it programmatically?

You should be able to use htres.socket.address().address to get the IP.

Check out request.connection.remoteAddress property available for the HTTP Request object. This indicates the address of the remote host performing the request.

Related

public ip npm package not working in Digital Ocean server

I have used the public-ip npm package to get the public IP address of the user, it is giving the same public IP address as in http://whatismyipaddress.com, but when using it in a Digital Ocean server it is giving me the Digital Ocean IP address instead of user's public IP address.
I have tried it on nodejs.
const publicIp = require('public-ip');
const ip = await publicIp.v4(); //to save ip in user
I want the public IP address of the user instead of getting the Digital Ocean IP address.
Just query https://api.ipify.org/
// web
let xhr = new XMLHttpRequest();
xhr.open('GET', 'https://api.ipify.org');
xhr.send();
xhr.onload = function() {
if (xhr.status != 200) {
console.log(`Error ${xhr.status}: ${xhr.statusText}`); // e.g. 404: Not Found
} else { // show the result
console.log(xhr.response)
}
};
// nodejs
const https = require('https');
https.get('https://api.ipify.org', (resp) => {
let data = '';
// A chunk of data has been recieved.
resp.on('data', (chunk) => {
data += chunk;
});
// The whole response has been received. Print out the result.
resp.on('end', () => {
console.log(JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: " + err.message);
});
This function publicIp.v4() and public-ip module will help you get (detect) your public IP of server or computer that application's running on (not IP of user). And Digital Ocean returns value of its public IP is right.
In your case, you need to retrieve user's IP from user's request, it can be call remote client IP address. It's better for you to check this question Express.js: how to get remote client address
Hope it can help.

socket.cork is not a function when trying to initiate request through socks proxy (TOR)

_http_outgoing.js:797
socket.cork();
^
TypeError: socket.cork is not a function
at ClientRequest._flushOutput (_http_outgoing.js:797:10)
at ClientRequest._flush (_http_outgoing.js:776:16)
....
Getting above error when trying to http.get() or request() using SOCKS proxy agent previously created with "proxysocket" library.
I am trying to create working agent to use it socket.io, or ws or http to make connections via SOCKS proxy. I tries "proxysocket" library and its agent gives me error above.
let agent = proxysocket.createAgent("127.0.0.1", 9050);
request("http://www.google.com", {agent: agent}, (err, res, body) => {
if (err){
console.log("Http request error: " + err);
} else{
console.log("Http request connection success!");
console.log('statusCode:', response && response.statusCode);
console.log(body)
}
});
Ok, here is the solution. I tried tons of proxy agents, and the only working one is "socks5-http-client".
Other agents were giving all kinds of errors when using SOCKS5 protocol.
const http = require("http");
const Agent = require("socks5-http-client/lib/Agent"); // Constructor
let agent = new Agent({
socksHost: 'localhost', // Defaults to 'localhost'.
socksPort: 9050 // Defaults to 1080.
});
http.get({
hostname: "www.google.com", // Can be also onion address if used behind TOR
port: 80,
agent: agent,
method: 'GET'
}, (res)=>{
console.log("Connected");
res.pipe(process.stdout);
//Process res
}).on('error', (err) => {
console.error(`Got error: ${err.message}`);
});
Such agent can be passed into any kinds of libraries that use http.Agent such as socket.io, ws, etc.

Node https request options within response callback

I'm making an https request with the node https module wherein I set the localAddress option. Each local IP in the list is mapped to a different public IP.
I'm simply trying to print the public IP as reported by a server on the internet beside the corresponding local IP. The problem is I'm not sure how to get the request options in the response callback:
var https = require('https');
var localIps = [
'192.168.88.135',
'192.168.88.136',
'192.168.88.137',
'192.168.88.138',
'192.168.88.139',
];
for(index in localIps) {
var localIp = localIps[index];
var options = {
localAddress: localIp,
host: 'mypublicserver.com',
path: '/whats-my-ip.php'
};
https.get(options, function(res) {
res.on('data', function(d) {
console.log(
// XXX localIp is always printing the last IP from localIps
'Local Network IP: ' + localIp +
' Public Outbound IP: ' + d);
});
}).on('error', function(e) {
console.error(e);
});
}
It's printing something like this (which is wrong)
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.132
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.131
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.130
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.133
Local Network IP: 192.168.88.139 Public Outbound IP: 88.88.888.134
So how do I get the correct options object inside the response callback?
Apparently res is an http.IncomingMessage instance, but I'm failing to find how to get the associated request object from it.
The problem is that the for loop will finish iterating over localIps before any of the responses comes back. So when the first response comes back the localIp variable is set to last ip of the localIps array.
The easiest you can do is to enclose the code in closure or also called IIFE -> Immediately invoked function expression
var https = require('https');
var localIps = [
'192.168.88.135',
'192.168.88.136',
'192.168.88.137',
'192.168.88.138',
'192.168.88.139',
];
for(index in localIps) {
var localIp = localIps[index];
var options = {
localAddress: localIp,
host: 'mypublicserver.com',
path: '/whats-my-ip.php'
};
(function(opts){
https.get(opts, function(res) {
res.on('data', function(d) {
console.log(
// XXX localIp is always printing the last IP from localIps
'Local Network IP: ' + opts.localAddress +
' Public Outbound IP: ' + d);
});
}).on('error', function(e) {
console.error(e);
});
})(options);
}
To find more https://www.google.cz/search?q=javascript+for+loop+closure

Is it possible to pass network errors to client

I have created a http server which is creating proxy to send requests to target system.
function sendErrorResponse(client_req,client_res){
var options = {
:
};
var proxy = http.request(options, function (res) {
res.pipe(client_res, {
end: true
});
});
client_req.pipe(proxy, {
end: true
});
}
or using http-proxy npm package
function sendErrorResponse(client_req,client_res){
proxy.web(client_req, client_res, { target: 'http://localhost:7777' });
}
Now when client request to my server, I proxy some of the requests to other server and send to client whtever I get from the target server. I want that if target server gives some error (DNS resolution, network errors etc.) I can send same to the client instead of responding client with 500 with some error message.
How can I do that?

how to get external ip of the server from node.js

I'm using now.js and there's this line that refers to localhost. In order for someone to access the server outside I need to modify localhost to be the current external ip of my computer(my ip is dynamic). Is there any way to detect the current external ip from the script?
window.now = nowInitialize("//localhost:8081", {});
You could ask an external service like this one (which is nice because it returns it without formatting).
To use it, you could use Node's built in http module:
require('http').request({
hostname: 'fugal.org',
path: '/ip.cgi',
agent: false
}, function(res) {
if(res.statusCode != 200) {
throw new Error('non-OK status: ' + res.statusCode);
}
res.setEncoding('utf-8');
var ipAddress = '';
res.on('data', function(chunk) { ipAddress += chunk; });
res.on('end', function() {
// ipAddress contains the external IP address
});
}).on('error', function(err) {
throw err;
});
Keep in mind that external services can go down or change — this has happened once already, invalidating this answer. I've updated it, but this could happen again…

Resources