Socket hang up on http.request to a Node.js MongoDb server - node.js

In my local pc I've set up a Node.js proxy server who makes request to a node.js RESTful MongoDb server, one is at port 8080 and the proxy at port 3000.
I can see in the RESTful server log that all the queries are sent back correctly to the proxy, but the proxy hang up throwing this error:
events.js:72
throw er; // Unhandled 'error' event
^
Error: socket hang up
at createHangUpError (http.js:1472:15)
at Socket.socketOnEnd [as onend] (http.js:1568:23)
at Socket.g (events.js:180:16)
at Socket.EventEmitter.emit (events.js:117:20)
at _stream_readable.js:920:16
at process._tickCallback (node.js:415:13)
this is how I built my proxy request :
var proxy = function(req, res, next) {
try {
var options = mapRequest(req);
var dbReq = http.request(options, function(dbRes) {
var data = "";
res.headers = dbRes.headers;
dbRes.setEncoding('utf8');
dbRes.on('data', function(chunk) {
data = data + chunk;
});
dbRes.on('end', function() {
res.header('Content-Type', 'application/json');
res.statusCode = dbRes.statusCode;
res.httpVersion = dbRes.httpVersion;
res.trailers = dbRes.trailers;
res.send(data);
res.end();
});
});
dbReq.end(JSON.stringify(req.body));
} catch (error) {
console.log('ERROR: ', error.stack);
res.json(error);
res.end();
}
};
and these are the options sent to the MongoDB server:
{
"hostname":"127.0.0.1",
"path":"//databases/db1/collections/documents?apiKey=134557676&l=5&sk=0",
"method":"GET",
"port":"8080",
"headers":{
"host":"127.0.0.1",
"connection":"keep-alive",
"accept":"application/json, text/plain ",
"x-xsrf-token":"VPDlgN2iMWU2IXPIPH0aiwS5",
"user-agent":"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_2) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/33.0.1750.152 Safari/537.36",
"dnt":"1",
"referer":"http://localhost:3000/documents",
"accept-encoding":"gzip,deflate,sdch",
"accept-language":"it-IT,it;q=0.8,en-US;q=0.6,en;q=0.4",
"cookie":"XSRF-TOKEN=VPDlgN2iMWU2IXPIPH0aiwS5; connect.sess=s%3Aj%3A%7B%22passport%22%3A%7B%22user%22%3A%225298bfa9e4b070e1c60fd84f%22%7D%2C%22_csrf%22%3A%22VPDlgN2iMWU2IXPIPH0aiwS5%22%7D.wc85bNSpJIl7KnCHOUXiG5V2e7SI9XR9EctByTtqhu4"
}
}

I found a solution replacing http.request() withhttp.get(), apparently the socked hang up because the socket did not sent the connection end event within the timeout period.
A similar issue here: NodeJS - What does "socket hang up" actually mean?

Related

telnet using node js

1.I have tried using node js to connect telnet. I am trying to control the Epson projector using node js and telnet from my computer.
2.I am running the js code in cmd by: "node filelocation\test.js"
The code i used:
const telnet = require('telnet-client');
const server = new telnet();
// display server response
server.on("data", function(data){
console.log(''+data);
});
// login when connected
server.on("connect", function(){
server.write("%1POWR 1\r\n");
});
// connect to server
server.connect({
host: "192.168.2.170",
port: 4352
});
I am running the js code in cmd by: "node filelocation\test.js"
The error i get is :
TypeError: server.write is not a function
at Telnet.<anonymous> (C:\Users\USER\Desktop\TEST\telnet2.js:11:12)
at Telnet.emit (events.js:314:20)
at Socket.<anonymous> (C:\Users\USER\node_modules\telnet-client\lib\index.js:70:16)
at Object.onceWrapper (events.js:420:28)
at Socket.emit (events.js:326:22)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1132:10)
I used this code and it worked for me. Thanks all for the support.
var net = require('net');
var client = new net.Socket();
client.connect(4352, 'x.x.x.x', function() {
console.log('Connected');
client.write('%1POWR 0\r\n');
});
client.on('data', function(data) {
console.log('Received: ' + data);
client.destroy(); // kill client after server's response
});
client.on('close', function() {
console.log('Connection closed');
});
I checked this package and there are no write() function available to use. Instead use exec(). Also change on('connect') like below to catch the errors.
server.on("connect", function(err, param){
server.exec("%1POWR 1\r\n");
});

How can I read the raw HTTP response in a subpath with node?

I am trying to get a malformed HTTP response using node. Since the response is malformed, I cannot use request normally (it would give the HPE_INVALID_CONSTANT error)
From this answer https://stackoverflow.com/a/23543522/1748450 I can get the raw HTTP response using the net module like so:
var net = require('net');
var host = '192.168.1.1',
port = 80,
socket = net.connect(port, host, function() {
var request = "GET / HTTP/1.1\r\nHost: " + host + "\r\n\r\n",
rawResponse = "";
// send http request:
socket.end(request);
// assume utf-8 encoding:
socket.setEncoding('utf-8');
// collect raw http message:
socket.on('data', function(chunk) {
rawResponse += chunk;
});
socket.on('end', function(){
console.log(rawResponse);
});
});
However, this only works with getting the response from the host's root page (192.168.1.1). The page I'm trying to get the response from is actually 192.168.1.1/admin/landingpage.fwd.
If I try to edit host to that URL then I get this error:
events.js:187
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND 192.168.1.1/admin/landingpage.fwd
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26)
Emitted 'error' event on Socket instance at:
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: '192.168.1.1/admin/landingpage.fwd'
}
Is this possible to fetch this using the net module in the above example?
If not possible, what other way can I use to get the raw HTTP response from that URL?
You can just put the path in your http request as in:
var request = "GET /admin/landingpage.fwd HTTP/1.1\r\nHost: " + host + "\r\n\r\n",?
That's where the path goes in an http request.

Node HTTP Server EADDRINUSE

I'm currently writing an mocha test for my project.
The test should cover the output of an ajax request and therefore I created a simple HTTP-Server with node.
This is the current code:
const http = require('http');
const server = http.createServer(function(req, res) {
res.write('test');
});
const port = 5555;
process.on('uncaughtException', function(err) {
console.log("Unhandled Exception, shutting down Server ...")
server.close();
console.log("Server closed!");
console.log(err);
process.exit(1);
});
process.on('SIGTERM', function() {
console.log("Termination called, shutting down Server ...");
server.close();
console.log("Server closed!");
process.exit(1);
});
server.listen('success', function(req, res) {
res.writeHead(200, {
"Content-Type": "application/json"
});
res.write(JSON.stringify({
success: true,
message: "Form success!"
}));
res.close();
});
server.listen('fail', function(req, res) {
res.writeHead(200, {
"Content-Type": "application/json"
});
res.write(JSON.stringify({
success: false,
message: "Form fail!"
}));
res.close();
});
server.listen(port);
console.log("Server running on Port: " + port);
Now for some reason it always throws me an EADDRINUSE error even when the port isn't used. I killed all node/nodejs processes (there weren't any), searched for the program which is using the port (lsof -i tcp:5555) which didn't send any back and even restarted the machine without any difference.
This is the output of the Terminal:
Server running on Port: 5555
Unhandled Exception, shutting down Server ...
Server closed!
{ Error: listen EADDRINUSE success
at Object.exports._errnoException (util.js:1022:11)
at exports._exceptionWithHostPort (util.js:1045:20)
at Server._listen2 (net.js:1249:19)
at listen (net.js:1298:10)
at Server.listen (net.js:1382:7)
at Object.<anonymous> (/home/dominik/Documents/workspace/jelly/test/test-server.js:23:8)
at Module._compile (module.js:571:32)
at Object.Module._extensions..js (module.js:580:10)
at Module.load (module.js:488:32)
at tryModuleLoad (module.js:447:12)
code: 'EADDRINUSE',
errno: 'EADDRINUSE',
syscall: 'listen',
address: 'success',
port: -1 }
npm ERR! Test failed. See above for more details.
I tried to search for solutions already of course, but all I find is kill the server with the same commands. Thanks in advance
You are not using the http module correctly. With the statement server.listen('success',...) you are starting a UNIX socket server on the socket "success" which makes no sense.
Below is an example where the http server returns different responses based in the requested url. I recommend reading this tutorial.
const http = require('http');
const server = http.createServer(function (req, res) {
res.writeHead(200, {
'Content-Type': 'application/json',
});
var responseBody = {};
if (req.url === '/success') {
responseBody = {
success: true,
message: "Form success!"
};
}
if (req.url === '/fail') {
responseBody = {
success: false,
message: "Form fail!"
};
}
res.write(JSON.stringify(responseBody));
res.end();
});
const port = 5555;
process.on('uncaughtException', function (err) {
console.log("Unhandled Exception, shutting down Server ...")
server.close();
console.log("Server closed!");
console.log(err);
process.exit(1);
});
process.on('SIGTERM', function () {
console.log("Termination called, shutting down Server ...");
server.close();
console.log("Server closed!");
process.exit(1);
});
server.listen(port, function () {
console.log("Server running on Port: " + port);
});
Test:
curl http://localhost:5555/success
curl http://localhost:5555/fail

http request to a different app in a different port

I have 2 nodejs apps one running in port 8000 that only returns "hello"
and another app running on port 3000 that makes a simple http request to the first app
var http = require('http');
var r = http.get({
host: 'localhost',
path: '/',
port: '8000'
},
function(response) {
var body = '';
response.on('data', function(d) {
body += d;
});
response.on('end', function() {
console.log(body);
});
});
the console log returns
events.js:141
throw er; // Unhandled 'error' event
^
Error: connect ECONNREFUSED 127.0.0.1:8000
at Object.exports._errnoException (util.js:874:11)
at exports._exceptionWithHostPort (util.js:897:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1063:14)
What´s the problem here?
the first app is running correctly in http://localhost:8000/ but for some reason
when the second app makes a request to the first app I get the error I posted above. thanks for your help.
Seems like first app (on port 8000) is not reachable or not started at the moment, when second app sends request.

How can I use an https proxy with node.js https/request Client?

I need to send my client HTTPS requests through an intranet proxy to a server.
I use both https and request+global-tunnel and neither solutions seem to work.
The similar code with 'http' works. Is there other settings I missed?
The code failed with an error:
REQUEST:
problem with request: tunneling socket could not be established, cause=socket hang up
HTTPS:
events.js:72
throw er; // Unhandled 'error' event
^
Error: socket hang up
at SecurePair.error (tls.js:1011:23)
at EncryptedStream.CryptoStream._done (tls.js:703:22)
at CleartextStream.read [as _read] (tls.js:499:24)
The code is the simple https test.
var http = require("https");
var options = {
host: "proxy.myplace.com",
port: 912,
path: "https://www.google.com",
headers: {
Host: "www.google.com"
}
};
http.get(options, function(res) {
console.log(res);
res.pipe(process.stdout);
});
You probably want to establish a TLS encrypted connection between your node app and target destination through a proxy.
In order to do this you need to send a CONNECT request with the target destination host name and port. The proxy will create a TCP connection to the target host and then simply forwards packs between you and the target destination.
I highly recommend using the request client. This package simplifies the process and handling of making HTTP/S requests.
Example code using request client:
var request = require('request');
request({
url: 'https://www.google.com',
proxy: 'http://97.77.104.22:3128'
}, function (error, response, body) {
if (error) {
console.log(error);
} else {
console.log(response);
}
});
Example code using no external dependencies:
var http = require('http'),
tls = require('tls');
var req = http.request({
host: '97.77.104.22',
port: 3128,
method: 'CONNECT',
path: 'twitter.com:443'
});
req.on('connect', function (res, socket, head) {
var tlsConnection = tls.connect({
host: 'twitter.com',
socket: socket
}, function () {
tlsConnection.write('GET / HTTP/1.1\r\nHost: twitter.com\r\n\r\n');
});
tlsConnection.on('data', function (data) {
console.log(data.toString());
});
});
req.end();

Resources