https handshake fails from JavaScript client to Node.js/socket.io server - javascript

I'm able to handshake from a JavaScript client (NOT browser or Node.js based) to a Node.js server that uses socket.io using http but not https. For https, the server code includes
var app = express();
var https = require("https");
var fs = require("fs");
var options = {
key: fs.readFileSync("server.key"),
cert: fs.readFileSync("server.cert")
};
var server = https.createServer(options, app);
var socketio = require("socket.io");
var io = socketio.listen(server);
server.listen(443);
and the client code includes
var xhr = new XMLHttpRequest();
xhr.open("GET", "https://localhost:443/socket.io/1/");
xhr.onreadystatechange = function(){
if(xhr.readyState !== 4){
return;
}
callback({status: xhr.status,
header: xhr.getAllResponseHeaders(),
body: xhr.responseText
});
};
xhr.send();
The client is run after the server has started but the handshake fails with the values
readyState: 4
status: 0
header:
body:
Does the client need to include some security info or do something else for the handshake to work with https and get a session ID?

Related

synchronizing http response with socket connection

I am using a http server with a socket connection , when http request hits, socket connection sends message to different client which performs a http request after this http response the client replies to the message and and response of initial http request is send.
My problem is first http request sometimes get response successfuly and sometimes not, I think there is a sync problem, how to solve it.
code for creating socket and httpserver -
const app = require('express')()
bodyParser = require('body-parser')
app.use(bodyParser.json())
const net = require('net');
var client;
var res1,currentReq;
//----------------------------------------------------------------------------
// http requests listener
//----------------------------------------------------------------------------
app.listen(8001, () => console.log('Http server listening on port 8001'));
//----------------------------------------------------------------------------
// http requests handling
//----------------------------------------------------------------------------
app.post('/makeCall', (req, res) => {
console.log('sd' + req.body)
res1 = res;
currentReq='makeCall';
console.log('{"route":"/api/makeCall","data":{"product_id":"' + req.body.product_id + '","destination":"' + req.body.destination + '"}}');
client.write('{"route":"/api/makeCall","data":{"product_id":"' + req.body.product_id + '","destination":"' + req.body.destination + '"}}');
});
//----------------------------------------------------------------------------
// Establishing tcp connection for incoming requests
//----------------------------------------------------------------------------
var server = net.createServer(function(connection) {
console.log ('client has connected successfully!');
client = connection;
client.on('data',function(data){
switch(currentReq)
{
case 'makeCall' :
console.log('send make call response');
res1.end(data);
break;
}
console.log(data.toString());
//res1.end(data);
});
connection.pipe(connection);
});
//----------------------------------------------------------------------------
// listener for tcp connections
//----------------------------------------------------------------------------
server.listen(8000, function() {
console.log('server for localhost is listening on port 8000');
console.log('server bound address is: ' + server.address ());
});
code for client to which socket connects -
tcpClient.on('connect',function(){
logger.info("[%s] , Connected to the server at %s:%s",__file,CONFIG.tcp_server_host,CONFIG.tcp_server_port);
logger.info("[%s] , TCP client info %s",__file,tcpClient.address().address);
});
// Handle data event
tcpClient.on('data',function(data){
logger.info('[%s] , Data recevied',__file);
// Convert the Buffer to JSON object
var reqInfo;
reqInfo = JSON.parse(data.toString());
if(reqInfo!=null){
switch(reqInfo.route){
case '/api/makeCall':;
var product_id = reqInfo.data.product_id;
var destination = reqInfo.data.destination;
var test = {};
var source;
var myJSONObject = {'product_id':product_id};
MongoClient.connect(url, function(err, db) {
var dbo = db.db("mapping");
dbo.collection("mapping").findOne({"id":product_id},function(err,result)
{
if(err)
{
throw err;
}
JSON.stringify(result);
sourceDB = result.source;
// Set the options for HTTPS request
options.method = "POST";
options.url = "url";
options.json = true;
options.auth = {
user: '123',
password: '123'
};
options.body = {"Source": sourceDB,"Destination": destination} ;
logger.info('[%s] , HTTPS request options : %o',__file,options);
request(options,function(error,res1,body){
tcpClient.write('Sending data to Falcon');
});
});
});

Unable to send a http POST request to ASP.NET web api Controller using javascript

There is a node.js server and I'm going to call my web api controller when a client connected with node.js server using a websocket. Im' using socket.io to connect client with node.js server, then node.js server sends a xhr POST request to web api controller. but getting the response as,
"{"Message":"No HTTP resource was found that matches the request URI 'http://localhost:4928/api/Player'.","MessageDetail":"No action was found on the controller 'Player' that matches the request."}"
Web API Method
public class PlayerController : ApiController
{
public IEnumerable<string> Get()
{
return new string[] { "value1", "value2" };
}
public string Post(string value)
{
return value;
}
}
Node.js
var app = require('express')();
var http = require('http').Server(app);
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var xhr = new XMLHttpRequest();
var querystring = require('querystring');
var io = require('socket.io')(http);
io.on('connection', function (socket) {
console.log('A user connected ' + socket.handshake.address);
PostRequest(socket.handshake.address);
//Whenever someone disconnects this piece of code executed
socket.on('disconnect', function () {
console.log('A user disconnected ' + socket.handshake.address);
});
});
function PostRequest(data) {
var url = "http://localhost:4928/api/Player";
var params = "value=" + data;/* querystring.stringify({ "value": data })*/
xhr.open('POST', url, true);
xhr.onreadystatechange = function () {//Call a function when the state changes.
if (xhr.readyState == 4 && xhr.status == 200) {
console.log(xhr.responseText);
}
console.log(xhr.responseText);
}
xhr.send(querystring.stringify({ value: "sss" }));
}
http.listen(3000, function () {
console.log('listening on *:3000');
});
Anyway this is working when I'm call the get method sending a xhr get request
You need to inform Web API to look for the value parameter in the Request body since you're not sending data via query string. Try modifying your Post action signature:
public string Post([FromBody]string value)
{
...
}

Ajax response not coming through from node.js

My Ajax request is not receiving proper response! It always enters readyState '4' with response status '0' ??
Client Code:
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function(){
if(xhttp.readyState == 4 && xhttp.status == 200){
document.getElementById("lastNameLabel").innerHTML = "response recieved!";
const responseJSON = JSON.parse(xhttp.responseText);
if(responseJSON.emailTaken == "false"){
window.location = server+"/client/home.html";
}
}
};
xhttp.open("POST", server+"/signUp", true);
xhttp.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
xhttp.send("email="+email);
server Code (Node.js + Express):
app.post('/signUp', (req, res) => {
res.end("it worked!!");
});
I Know my Server is processing the request since I see the url call, but the response never reaches the html client!!. I'm Super Stuck!
Putting #jaromanda-x's suggestion as an answer, you need to enable CORS in your server.
This is how it's done:
var cors = require('cors');
app.use(cors());
For more info, refer this express doc about it.
You have to have your NodeJS server reply with an HTTP response message that includes a status code and reason phrase such as
res.status(200).send({ status: 'ok' });

Displaying Data on Website from Node.js (Without Frameworks)

I have a Node.js webserver and I am fetching data from a mysql Server. The fetched Data needs to be displayed now in the frontend as HTML. I am not allowed to use any 3rd Party node.js/JavaScript framework's.
I'm new to Webserver development and i'm having a hard time figuring out how to "transport" the Backend Data to the Frontend.
I have 2 Ideas in my mind but dont know what's the right way to approach this problem...
Send Data via JSON to Client and process it with JavaScript. (Possible? and if yes how?)
Before sending the HTTP response, parse the HTML and insert the data. (Complicated without using Frameworks and too costly ?)
What would be the right way to solve this problem ?
Any Help would be appreciated. Thank's.
Solved it like this:
app.js
var http = require('http');
var url = require('url');
var server = http.createServer(function(req, res) {
var q = url.parse(req.url, true);
if(q.filename == "command"){
res.writeHead(200, {'Content-Type':'application/json'});
return res.end(some_json);
}
}
index.html
<script>
xmlhttp = new XMLHttpRequest();
xmlhttp.open("POST","http://localhost:8000/command", true);
xmlhttp.onreadystatechange=function(){
if (xmlhttp.readyState==4 && xmlhttp.status==200){
//Process Data
var jsonObj = JSON.parse(xmlhttp.responseText);
document.getElementById("test").innerHTML = jsonObj;
}
}
xmlhttp.send();
</script>
<div id="test"></div>
Something like this?
const http = require('http');
const util = require('util');
const hostname = '127.0.0.1';
const port = 3000;
const server = http.createServer((req, res) => {
mysql.query("select * from table").then(rows => {
res.statusCode = 200;
res.setHeader('Content-Type', 'text/html');
res.end(`<html><head></head><body>${util.inspect(rows)}</body></html>`);
})
});
server.listen(port, hostname, () => {
console.log(`Server running at http://${hostname}:${port}/`);
});

How do you send a post via XMLhttprequest to my own Node server in vanilla javascript?

I am trying to send data to node via a XMLhttprequest. The data looks like this (/q/zmw:95632.1.99999.json). My connection to Node is correct, however, I was getting an empty object so I set the headers to Content-Type application/json and then stringified the data. However Node gives me a Unexpected token " error. I presume it is because of the string, however, if I don't stringify the data then it errors out because of the "/" in the data. How do i properly send the data using pure Javascript. I want to stay away from axios and jquery because I want to become more proficient in vanilla javascript. I will make the final call to the api in node by assembling the url prefix and suffix.
Here is my code:
function getCityForecast(e){
//User selects option data from an early JSONP request.
var id = document.getElementById('cities');
var getValue = id.options[id.selectedIndex].value;
//Assembles the suffix for http request that I will do in Node.
var suffix = getValue + ".json";
var string = JSON.stringify(suffix);
console.log(suffix);
var xhr = new XMLHttpRequest();
xhr.open("POST", "http://localhost:3000/", true);
xhr.setRequestHeader("Content-Type", "application/json;charset=UTF-8");
xhr.send(string);
}
Node.js code:
var express = require('express');
var app = express();
var bodyParser = require('body-parser');
var path = require('path');
var request = require('request');
var http = require('http');
// ****************** Middle Ware *******************
app.use(bodyParser.urlencoded({ extended: true }));
app.use(bodyParser.json());
app.use(express.static(__dirname + '/public'));
app.post('/', function(req, res){
console.log('working');
console.log(req.body);
});
app.listen(3000, function() { console.log('listening')});
I figured it out my mistake and this was my problem. I was trying to send a string instead of an object. So it wasn't proper JSON like this:
var string = JSON.stringify(suffix);
To remedy the situation I added:
var newObj = JSON.stringify({link : suffix});
This allowed my post to be successful because I was now sending an object hence the word Javascript Object Notation.
This is working for me, at the moment. The REST API I'm hitting requires a token. Yours might not, or it might be looking for some other custom header. Read the API's documentation. Note, you might need a polyfill/shim for cross browser-ness (promises). I'm doing GET, but this works for POST, too. You may need to pass an object. If you're passing credentials to get a token, don't forget window.btoa. Call it like:
httpReq('GET', device.address, path, device.token).then(function(data) {
//console.log(data);
updateInstrument(deviceId,path,data);
}, function(status) {
console.log(status);
});
function httpReq(method, host, path, token) {
if(method === "DELETE" || method === "GET"|| method === "POST" || method === "PUT" ){
var address = 'https://' + host + path;
return new Promise(function(resolve, reject) {
var xhr = new XMLHttpRequest();
xhr.open(method, address, true);
xhr.setRequestHeader("Accept", "application/json");
xhr.setRequestHeader ("X-auth-token", token);
//xhr.setRequestHeader ("Content-Type", "application/x-www-form-urlencoded");
xhr.onload = function() {
var status = xhr.status;
if (status == 200 || status == 201 || status == 202) {
resolve(xhr.response);
}
// this is where we catch 404s and alert what guage or resource failed to respond
else {
reject(status);
}
};
xhr.send();
});
} else {
console.log('invalid method');
}
};

Categories