Unable to parse InputStreamResource response in nodejs - node.js

How to read InputStreamResource in nodejs?
Our REST API returns response as InputStreamResource. We need to convert this response as xlsx file or json format. Please help
Below is the code:
var options = {
host: 'xxxxxxxxxxxxxxxxx',
port: xxxxx,
path: '/eeeeee/axxxxxxx?code=' + req.query.code,
method: 'GET',
headers:{
'user_id': req.headers.user_id,
'access_token': req.headers.access_token
}
};
var req = https.request(options, function (res) {
var decoder = new StringDecoder('utf8');
res.on('data', function(chunk) {
console.log(chunk)
var textChunk = decoder.write(chunk);
console.log(textChunk)
});
});
req.end();
req.on('error', function(e) {
console.error(e);
});
Response is getting this way ...
enter image description here

var req = https.request(options, function (res) {
var resData = ''
res.setEncoding('binary')
res.on('data', function(chunk){
resData += chunk
})
res.on('end', function(){
// fs.writeFile('message1.xlsx', resData, 'binary', function(err){
// if (err) throw err
// console.log('File saved.')
// })
var new_wb = XLSX.read(resData, {type:'binary'});
console.log('File saved.');
})
});

Related

Azure Function ignoring https.request

I have an azure function with this line of code.
var myReq = https.request(options, function(res) {
context.log('STATUS: ' + res.statusCode);
context.log('HEADERS: ' + JSON.stringify(res.headers));
body += res.statusCode
res.on('data', function (chunk) {
context.log('BODY: ' + chunk);
});
});
myReq.on('error', function(e) {
context.log('problem with request: ' + e.message);
});
myReq.write(postData);
myReq.end();
But my code seems to just skip this part of code, with no errors. I am new to Azure and node.js so I might have missed some basic parts in setting this up.
Any ideas?
Edit:
Here is my full code
const https = require('https');
const querystring = require('querystring');
module.exports = async function (context, req) {
if (req.query.accessCode || (req.body && req.body.accessCode)) {
context.log('JavaScript HTTP trigger function processed a request.');
var options = {
host: 'httpbin.org',
port: 80,
path: '/post',
method: 'POST'
};
var postData = querystring.stringify({
client_id : '1234',
client_secret: 'xyz',
code: req.query.accessCode
});
var body = "";
var myReq = https.request(options, function(res) {
context.log('STATUS: ' + res.statusCode);
context.log('HEADERS: ' + JSON.stringify(res.headers));
body += res.statusCode
res.on('data', function (chunk) {
context.log('BODY: ' + chunk);
});
});
myReq.on('error', function(e) {
context.log('problem with request: ' + e.message);
});
myReq.write(postData);
myReq.end();
context.log("help");
context.res = {
status: 200,
body: "Hello " + (body)
};
} else {
context.res = {
status: 400,
body: "Please pass a name on the query string or in the request body"
};
}
};
Ideally it should work. You can also try using request module like below
const request = require('request');
request('http://www.google.com', function (error, response, body) {
console.error('error:', error); // Print the error if one occurred
console.log('statusCode:', response && response.statusCode); // Print the response status code if a response was received
console.log('body:', body); // Print the HTML for the Google homepage.
});
Try and see if it helps.
Solved by doing await properly. Used this as guide.
var https = require('https');
var util = require('util');
const querystring = require('querystring');
var request = require('request')
module.exports = async function (context, req) {
context.log('JavaScript HTTP trigger function processed a request.');
/*if (req.query.name || (req.body && req.body.name)) {*/
var getOptions = {
contentType: 'application/json',
headers: {
'Authorization': <bearer_token>
},
};
var postData = {
"key": "value"
};
var postOptions = {
method: 'post',
body: postData,
json: true,
url: <post_url>,
headers: {
'Authorization': <bearer_token>
},
};
try{
var httpPost = await HttpPostFunction(context, postOptions);
var httpGet = await HttpGetFunction(context, <get_url>, getOptions);
return {
res: httpPost
};
}catch(err){
//handle errr
console.log(err);
};
};
async function HttpPostFunction(context, options) {
context.log("Starting HTTP Post Call");
return new Promise((resolve, reject) => {
var data = '';
request(options, function (err, res, body) {
if (err) {
console.error('error posting json: ', err)
reject(err)
}
var headers = res.headers;
var statusCode = res.statusCode;
//context.log('headers: ', headers);
//context.log('statusCode: ', statusCode);
//context.log('body: ', body);
resolve(body);
})
});
};
async function HttpGetFunction(context, url, options) {
context.log("Starting HTTP Get Call");
return new Promise((resolve, reject) => {
var data = '';
https.get(url, options, (resp) => {
// 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', () => {
resolve(JSON.parse(data));
});
}).on("error", (err) => {
console.log("Error: " + err.message);
reject(err.message);
});
});
};

Stream application/json POST request

I have working code to buffer a .json file and then POST that data to a server.
fs.readFile(filePath, 'utf-8', function (err, buf) {
if(err){
reject(err);
}
else{
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
'Content-Length': buf.length
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
console.log('data from SC:', data);
//call fn on data and if it passes we are good
resolve();
});
});
// write data to request body
req.write(buf);
req.end();
}
});
what I would like to do instead is to avoid buffering it, and just use fs.createReadStream, something like so:
fs.createReadStream(filePath, 'utf-8', function (err, strm) {
if(err){
reject(err);
}
else{
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
// 'Content-Length': buf.length
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
console.log('data from SC:', data);
//call fn on data and if it passes we are good
resolve();
});
});
// write data to request body
req.write(strm);
req.end();
}
});
but that doesn't quite work? Is it possible to do this?
This seems to work, but not sure if it's 100% correct
const strm = fs.createReadStream(filePath);
const req = http.request({
method: 'POST',
host: 'localhost',
path: '/event',
port: '4031',
headers: {
'Content-Type': 'application/json',
}
});
req.on('error', reject);
var data = '';
req.on('response', function (res) {
res.setEncoding('utf8');
res.on('data', function ($data) {
data += $data
});
res.on('end', function () {
data = JSON.parse(data);
resolve();
});
});
// write data to request body
strm.pipe(req);

Using Q library for HTTP api response testing in nodejs

how to use Q to make it wait until previous response has come from the server.
What I am looking to do here is compare the response from test server and production server for the same request.
I get the responses back from both the servers, but unable to compare them since the assert statement is executed before the response comes back.
Any one know what I am doing wrong. heres the code.
var Q = require('q');
var path='';
var prodResponse = '';
var tstReponse = '';
Q.fcall(readFile())
.then(secondFunction())
.then(thirdFunction())
.then(function(){
console.log("prodResponse: "+prodResponse);
console.log("tstResponse: "+tstResponse);
assert.strictEqual(prodResponse, tstResponse)
})
.catch(function(){
console.log('error occurred');
})
.done();
function readFile(){
fs.readFile('hostname.json', function (err, data) {
if (err) return console.error(err);
path = JSON.parse(data);
return JSON.parse(data);
});
}
function secondFunction(){
var prodOptions = {
hostname: 'somehostname.com',
port: 80,
path: "/path?"+path.path,
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
auth : ''
};
return http.request(prodOptions, function(res) {
console.log('Prod');
res.setEncoding('utf8');
res.on('data', function (chunk) {
prodResponse = chunk;
return chunk;
});
res.on('end', function() {
console.log('No more data in response.');
})
}).on('error', function(e) {
console.log('problem with request: ' + e.message);
}).end();
}
function thirdFunction(){
// same a second, only difference is the response http.
}
There is multiple errors in your code
Q.fcall(readFile())
Your q variable is q and not Q. So this line will crash because Q is undefined (javascript is case sensitive).
Then, readFile doesn't return any promise (in fact, it returns nothing). So the q library can't use anything to wait the end of any asynchronous work. The then callbacks will be fired immediatly.
You can use Q.ninvoke to make your readFile function return a promise, and you can use Q.defer to create and return a promise from your secondFunction:
var Q = require('q');
var path='';
var prodResponse = [];
var tstReponse = '';
readFile()
.then(secondFunction())
.then(thirdFunction())
.then(function(){
console.log("prodResponse: "+prodResponse);
console.log("tstResponse: "+tstResponse);
assert.strictEqual(prodResponse, tstResponse)
})
.catch(function(){
console.log('error occurred');
})
.done();
function readFile(){
return Q.ninvoke(fs, 'readFile', 'hostname.json').then(function (data) {
path = JSON.parse(data);
return path;
}, function (err) {
console.error(err);
});
}
function secondFunction(){
var prodOptions = {
hostname: 'somehostname.com',
port: 80,
path: "/path?"+path.path,
method: 'POST',
headers: {
'Content-Type': 'application/json;charset=UTF-8'
},
auth : ''
};
var defer = Q.defer();
var chunks = [];
http.request(prodOptions, function(res) {
console.log('Prod');
res.setEncoding('utf8');
res.on('data', function (chunk) {
chunks.push(chunk);
});
res.on('end', function() {
console.log('No more data in response.');
prodResponse = chunks.join('');
defer.resolve(prodResponse);
})
}).on('error', function(e) {
console.log('problem with request: ' + e.message);
defer.reject(e);
}).end();
return defer.promise;
}
function thirdFunction(){
// same a second, only difference is the response http.
}

Invoking Web Service(Soap) through nodejs Status Code error 415

I am trying to invoke WCF WebService (SOAP Request) via nodejs. I am getting 415(unsupported media type) http status error code. Any idea what I am missing?
var http = require('http');
var options = {
host:'localhost',
port:'34563',
path:'/Service1.svc',
connection:'keep-alive',
accept:'*/*',
method:'POST',
header: {
'Content-Type':'text/xml;charset="UTF-8"',
'Content-Length':data.length,
'Accept':'*/*',
'SOAPAction':'http://tempuri.org/IService1/GetData'
}
};
var req=http.request(options, function(res) {
console.log(res.statusCode);
res.on('data', function(data) {
console.log(data);
});
res.on('end', function() {
});
res.on('error', function(error) {
console.log('1'+error);
});
});
var data='<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">'+
'<s:Body>'+
'<GetData xmlns="http://tempuri.org/">'+
'<value>12</value>'+
'</GetData>'+
'</s:Body>' +
'</s:Envelope>';
req.write(data);
req.end();
damn... Its silly mistake,
it supposed to be headers, 's' missed.
var options = {
host:'localhost',
port:'34563',
path:'/Service1.svc',
connection:'keep-alive',
accept:'*/*',
method:'POST',
headers: {
'Content-Type':'text/xml;charset="UTF-8"',
'Content-Length':data.length,
'Accept':'*/*',
'SOAPAction':'http://tempuri.org/IService1/GetData'
}
};
var req=http.request(options, function(res) {
console.log(res.statusCode);
var body = '';
res.on('data', function(data) {
body += data;
});
res.on('end', function() {
console.log(body);
});
res.on('error', function(error) {
console.log(error);
});
});

socket hang up node 0.8.17

I am getting a "socket hang up" error while doing a post request. I am not able to resolve it.
sparqlQ = getSPARQLPrefix() + query_string;
console.log(sparqlQ)
var options = {
host: process.env['SESAME_HOST'],
port: process.env['SESAME_PORT'],
method: 'POST',
path:
'/openrdf-sesame/repositories/myReo?update=' +
encodeURIComponent(sparqlQ) +
'&content-type=application/sparql-results+json',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Accept': 'application/sparql-results+json',
},
};
var req = http.request(options, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('error', function (error) {
console.log(error)
});
res.on('end', function () {
console.log(data)
req.end();
callback(null);
});
}).on('error', function(e) {
console.alert("Error getting sesame response [%s]", e.message);
req.end();
callback(e.message);
return
});
What am I doing wrong? Please help!
Two things to mention here.
You are not calling req.end() on your http request.
refer this documentation on the http module of node.js.
With http.request() one must always call req.end() to signify that
you're done with the request - even if there is no data being written
to the request body.
on the req.error event you are calling console.alert which i think should be console.log
Here is a sample code
http = require("http");
var options = {
host: "localhost",
port: 80,
method: 'POST'
};
var req = http.request(options, function(res) {
var data = "";
res.on('data', function (chunk) {
data += chunk;
});
res.on('error', function (error) { });
res.on('end', function () {
console.log(data)
req.end();
console.log(null);
});
}).on('error', function(e) {
console.log("Error getting sesame response [%s]", e.message);
req.end();
console.log(e.message);
return
});
req.end();

Resources