NodeJS HTTPs request returns Socket Hang up - javascript

const https = require("https");
const fs = require("fs");
const options = {
hostname: "en.wikipedia.org",
port: 443,
path: "/wiki/George_Washington",
method: "GET",
// ciphers: 'DES-CBC3-SHA'
};
const req = https.request(options, (res) => {
let responseBody = "";
console.log("Response started");
console.log(`Server Status: ${res.statusCode} `);
console.log(res.headers);
res.setEncoding("UTF-8");
res.once("data", (chunk) => {
console.log(chunk);
});
res.on("data", (chunk) => {
console.log(`--chunk-- ${chunk.length}`);
responseBody += chunk;
});
res.on("end", () => {
fs.writeFile("gw.html", responseBody, (err) => {
if (err) throw err;
console.log("Downloaded file");
});
});
});
req.on("error", (err) => {
console.log("Request problem", err);
});
returns
// Request problem { Error: socket hang up
// at createHangUpError (_http_client.js:330:15)
// at TLSSocket.socketOnEnd (_http_client.js:423:23)
// at TLSSocket.emit (events.js:165:20)
// at endReadableNT (_stream_readable.js:1101:12)
// at process._tickCallback (internal/process/next_tick.js:152:19) code: 'ECONNRESET' }

http.request() opens a new tunnel to the server. It returns a Writable stream which allows you to send data to the server, and the callback gets called with the stream that the server responds with. Now the error you encountered (ECONNRESET) basically means that the tunnel was closed. That usually happens when an error occured on a low level (very unlikely) or the tunnel timed out because no data was received. In your case the server only responded when you sent something to it, even if it was an empty package, so all you have to do is to end the stream, causing it to get flushed as an empty packet to the server, which causes it to respond:
req.end();
You might want to have a look at the request package which allows you to avoid dealing with such low-level things.

Related

WebSocket connection is taking long time and failed

I created a secure websocket using this,
const Socket = require("websocket").server
const https = require("tls")
const fs = require('fs');
//certificate information
const certificate = {
cert: fs.readFileSync("/home/WebRTC/ssl/webrtc.crt",'utf8'),
key: fs.readFileSync("/home/WebRTC/ssl/webrtc.key",'utf8')
};
const server = https.createServer(certificate,(req, res) => {})
server.listen(3000, () => {
console.log("Listening on port 3000...")
})
const webSocket = new Socket({ httpServer: server })
and created the web client using this,
const webSocket = new WebSocket("wss://ip:3000")
webSocket.onerror= (event) => {
alert("Connection error occured");
}
webSocket.onopen = (event) =>{
alert("Connection established");
}
webSocket.onmessage = (event) => {
alert("Message received");
}
Im using https. Created a self signed certificate
wss://ip:3000. here the IP is the certificate resolving IP. These files are hosted in a publicly accessible server
But when I put the request, it takes a lot of time and gives and error.
"WebSocket connection to 'wss://ip:3000/' failed: "
Please be kind enough to help

My JSON.parse in app.js doesnt function properly

app.js:
const express = require("express");
const https = require("https");
const app = express();
const port = 3000;
app.get("/",function(req,res){
const url ="https://maps.googleapis.com/maps/api/geocode/jsonaddress=1600+Amphitheatre+Parkway,+Mountain+View,+CA&key=YOUR_API_KEY;
console.log(response.statusCode);
response.on("data",function(data){
var jatin=JSON.parse(data);
console.log(jatin);
})
})
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
Error on Console
app.listen(3000,function(){ console.log("server started on port
3000"); })
server started on port 3000 200 undefined:26
"long_name"
SyntaxError: Unexpected end of JSON input
at JSON.parse ()
at IncomingMessage. (/home/jatin/Downloads/full_stack/Web-Development/maps/app.js:11:21)
at IncomingMessage.emit (events.js:189:13)
at IncomingMessage.Readable.read (_stream_readable.js:487:10)
at flow (_stream_readable.js:931:34)
at resume_ (_stream_readable.js:912:3)
at process._tickCallback (internal/process/next_tick.js:63:19) [nodemon] app crashed - waiting for file changes before starting
The output is visible when I run it on browser but on the console it throws an error.
For some reason JSON.parse() isn't working as expected.
I am trying to make a geocoding API call and in response, it gives me a JSON output...
which when I enter it as a URL on the browser the expected output is received
But when app.js is run on a node express server and when I hit my localhost:3000 I am getting the console error
Apparently the JSON.parse("data") is working but stops unexpectedly. Which leads to error.
You need to have your code to perform JSON.parse on end event instead, like this example form the documentation:
http.get('http://nodejs.org/dist/index.json', (res) => {
const { statusCode } = res;
const contentType = res.headers['content-type'];
let error;
if (statusCode !== 200) {
error = new Error('Request Failed.\n' +
`Status Code: ${statusCode}`);
} else if (!/^application\/json/.test(contentType)) {
error = new Error('Invalid content-type.\n' +
`Expected application/json but received ${contentType}`);
}
if (error) {
console.error(error.message);
// Consume response data to free up memory
res.resume();
return;
}
res.setEncoding('utf8');
let rawData = '';
res.on('data', (chunk) => { rawData += chunk; });
res.on('end', () => {
try {
const parsedData = JSON.parse(rawData);
console.log(parsedData);
} catch (e) {
console.error(e.message);
}
});
}).on('error', (e) => {
console.error(`Got error: ${e.message}`);
});
Notice that this is http.get, but it should be the same for https.get, so in your code the on('data') should be used to assemble the chunks before your perform JSON.parse() on it.
const express = require("express");
const https = require("https");
const app = express();
const port = 3000;
app.get("/", function(req, res) {
const url = "API_URL";
https.get(url, function(response) {
console.log(response.statusCode);
let body = "";
response.on("data", function(data) {
body += data;
});
response.on("end", function() {
console.log(JSON.parse(body));
});
});
res.end("End data response");
});
app.listen(port, () => console.log(`Example app listening on port ${port}!`));
basically .on('end', callback') and .on('data', callback') are event listener to data receive and request end events, and to be able to handle your requests response in node when using http(s).get you have to attache an event listener on data event which is invoked every time your request receives a chunk of the request response, and once the request ended by the service the event end will be invoked stating that there is no more data from the server requested hence the request ended.
as stated in the documentation:
The callback must take care to consume the response data for reasons
stated in http.ClientRequest section.

NextJS, Express, Error during WebSocket handshake: Unexpected response code: 200

The basic problem can be summarized as follows: When creating a Websocket server in Node using ws with the server option populated by an express server(as in this example), while using that same express server to handle the routing for NextJS (as in this example), the upgrade header seems to not be properly parsed.
Instead of the request being routed to the Websocket server, express sends back an HTTP 200 OK response.
I've searched high and low for an answer to this, it may be that I simply do not understand the problem. A possibly related question was brought up in an issue on NextJS's github. They recommend setting WebsocketPort and WebsocketProxyPort options in the local next.config.js, however I have tried this to no avail.
A minimal example of the relevant server code can be found below. You may find the full example here.
const express = require('express')
const next = require('next')
const SocketServer = require('ws').Server;
const port = parseInt(process.env.PORT, 10) || 3000
const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
setInterval(() => {
wss.clients.forEach((client) => {
client.send(new Date().toTimeString());
});
}, 1000);
}).catch(ex => {
console.error(ex.stack);
process.exit(1);
});
The expected result, of course, is a connection to the websocket server. Instead I receive the following error:
WebSocket connection to 'ws://localhost:3000/' failed: Error during WebSocket handshake: Unexpected response code: 200
Can anyone elucidate anything for me here?
Ok, after more digging I have solved the problem. Quite simply, the ws.Server object to which I was trying to feed the server = express() object is not strictly speaking an http server object. However, server.listen() returns such an http server object. On such an object we can listen for an 'upgrade' call, which we can pass to our ws.Server object's handleUpgrade() event listener, through which we can connect. I will be updating the examples that I linked in my question, but the relevant code is below:
app.prepare().then(() => {
const server = express()
server.all('*', (req, res) => {
return handle(req, res)
})
const wss = new SocketServer({ server });
wss.on('connection', function connection(ws, request) {
console.log('Client connected');
ws.on('close', () => console.log('Client disconnected'));
});
wss.on('error', function (error) {
console.log(error);
});
let srv = server.listen(port, err => {
if (err) throw err
console.log(`> Ready on http://localhost:${port}`)
})
srv.on('upgrade', function(req, socket, head) {
wss.handleUpgrade(req, socket, head, function connected(ws) {
wss.emit('connection', ws, req);
})
});

socket hang up in tls node.js

I want to convert below python code to Node.js
xmppSocket = socket.socket()
xmppSocket.connect((HOST, 5222))
xmppSocket = ssl.wrap_socket(xmppSocket)
xmppSocket.sendall("Dummy Text")
So I wrote below code do the same.
var tls = require('tls');
const options = {
host: HOST,
port: PORT
};
var socket = tls.connect(options, () => {
console.log('client connected',
socket.authorized ? 'authorized' : 'unauthorized');
}).setEncoding('utf8')
.on('data', (data) => {
console.log(data);
})
.on('end', () => {
console.log("End connection");
}).on('error', (error) => {
console.log("Error is:", error)
});
But this is returning me below error.
Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1092:19)
What exactly going wrong in this piece of code?
Why I'm getting this error?

Node js response.write(average size html) takes forever for page to load

This is a simple web scraper.
The HTTP request is sent by NodeJS and response to the client with HTML. The console show body.toString() immediately, but on the browser it loads forever, when I stop the server, it display the page.
I did the similar things in express, it just works, but for some reason, I am not allowed to use express. So I have to write in pure NodeJS.
I have also tried to do it without HTTP request, only left the function response.write and response.end in the if statement, it is fine when I put a few strings in response.write, but when I put minify HTML inside response.write, same situation happen, loading takes forever and display the page when I stop the server.
The following is my code, any help is appreciated, thanks in advance.
const url = require("url"),
http = require('http');
const port = 3000;
const requestHandler = (request, response) => {
if (request.url === "/") {
const options = {
"method": "GET",
"hostname": "something.com",
"port": null,
"path": "/",
"headers": {
"content-type": "multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW",
}
};
const req = http.request(options, function (res) {
let chunks = [];
res.on("data", function (chunk) {
chunks.push(chunk);
});
res.on("end", function () {
let body = Buffer.concat(chunks);
console.log(body.toString());
const html = body.toString();
response.write(html);
response.end();
});
});
req.write("");
req.end();
}
}
const server = http.createServer(requestHandler)
server.listen(port, (err) => {
if (err) {
return console.log('something bad happened', err)
}
console.log(`server is listening on ${port}`)
})

Categories