Get http status code in node.js - javascript

So, i'm trying to get the http status code of an URL that i pass to the funcion. so far i've used the request module but the problem is that request fetches all the content of the given URL and if the content is a big amount of data it's slow, but i just need to get the status code to make an if statement.
request(audioURL, function (error, response) {
if (!error && response.statusCode == 200) {
queue.push({
title: videoTitle,
user: message.author.username,
mention: message.author.mention(),
url: audioURL
});
bot.reply(message, "\"" + videoTitle + "\" has been added to the queue.")
}
else {
bot.reply(message, "Sorry, I couldn't get the audio track for that video. HTTP status code: " + response.statusCode);
}
});
This is what i got so far.audioURL is a basic string with a link to a media file

http.request can take an options Object as its first parameter. Use something like this:
const options = {
method: 'HEAD',
host: 'example.com',
};
const req = http.request(options, (res) => {
console.log(JSON.stringify(res.headers));
});
req.end();
The problem is that you'll want to turn your audioURL into its components, to pass as parameters of options. I'm using the HEAD method, that fetches only the headers of your request.

Related

Firebase http function finishing before http request library returns data

I have an HTTP triggered Firebase function, which uses the request library https://github.com/request/request to make an HTTP post to another API. The logs show the POST request is returning the correct data but the Firebase function is finishing before the Async POST returns the data.
How do I make the overall function wait for the POST request?
const functions = require('firebase-functions');
var requestDependency = require('request');
exports.XXXXXXXXXX = functions.https.onRequest((request, response) => {
var answer = 'testo';
var jsonResponse = null;
var jsonData = 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
let url = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //or production
requestDependency.post({
headers: {
'content-type': 'XXXXXXXXXXXXXXXXXXXX' ,
'Accept': 'XXXXXXXXXXXXXXXXXXXX',
'XXXXXXXXXX-Access-Token': 'XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX'
},
url: url,
body: jsonData
}, function(error, response, body) {
if (error) {
console.log('errrrrrrrror1')
} else {
jsonResponse = body;
console.log(jsonResponse); <-----Shows correct data returned
console.log('Done.');
answer = jsonResponse;
console.log('TEST: ' + answer)
}
});
console.log("Performing search");
response.send(cardName+" "+jsonResponse); <---jsonResponse not populated
});
According to the documentation, HTTP functions are terminated when a response is sent to the client. This means your call to response.send() is effectively terminating the function.
The problem is that the call to post() is asynchronous and returns immediately while the HTTP request continues in the background. Function execution continues right after the post. This means your sent response is almost certainly going to get executed before the HTTP request finishes.
If you want to wait for the HTTP request to finish, put your response to the client inside the callback that handles the response from the HTTP request.
function(error, response, body) {
if (error) {
console.log('errrrrrrrror1')
// send an error response here
} else {
jsonResponse = body;
console.log(jsonResponse); <-----Shows correct data returned
console.log('Done.');
answer = jsonResponse;
console.log('TEST: ' + answer)
// send an success response here
}
});
Also watch this video series to get a better grasp on how Cloud Functions works: https://www.youtube.com/watch?v=7IkUgCLr5oA&index=2&list=PLl-K7zZEsYLkPZHe41m4jfAxUi0JjLgSM

Spotify API Error Code 400 - No Search Query

I am trying to use the Spotify API search function to recieve album data. This my request:
request.post(authOptions, function(error, response, body) {
if (!error && response.statusCode === 200) {
// use the access token to access the Spotify Web API
var token = body.access_token;
var options = {
url: 'https://api.spotify.com/v1/search',
data: {
q: 'currents',
type: 'album',
},
headers: {
'Authorization': 'Bearer ' + token
},
json: true
};
request.get(options, function(error, response, body) {
console.log(body);
});
}
});
However, when this code executes I continually get an Error Code 400 - "no search query" response. Can anyone help spot why this my query options are not being properly read?
Thanks.
Solved: The request library requires a querystring object called qs in the options object. Changing "data" to "qs" fixed it.

How do I send a file with node.js request module?

I am trying to use an API to update a list on another server using node.js. For my last step, I need to send a POST that contains a csv file. In the API, they list under FormData that I need a Key called file and a Value of Binary Upload, then the body of the request should be made of listname: name and file: FileUpload.
function addList(token, path, callback) {
//Define FormData and fs
var FormData = require('form-data');
var fs = require('fs');
//Define request headers.
headers = {
'X-Gatekeeper-SessionToken': token,
'Accept': 'application/json',
'Content-Type': 'multipart/form-data'
};
//Build request.
options = {
method: 'POST',
uri: '{URL given by API}',
json: true,
headers: headers
};
//Make http request.
req(
options,
function (error, response, body) {
//Error handling.
if (error) { callback(new Error('Something bad happened')); }
json = JSON.parse(JSON.stringify(response));
callback.call(json);
}
);
//Attempt to create form and send through request
var form = new FormData();
form.append('listname', 'TEST LIST');
form.append('file', fs.createReadStream(path, { encoding: 'binary' }));
form.pipe(req);};
I am a veteran of front end javascript for html and css, but this is my first adventure with backend node.js. The error I keep getting is: TypeError: dest.on is not a function
From what I can tell, this has to do with the way I used form.pipe(req) but I can't find documentation telling me the appropriate usage. If you don't have a direct answer, a finger pointing toward the right documentation would be appreciated.
The issue is you're not passing the request instance into your pipe call, you're passing the request module itself. Take a reference to the return value of your req(...) call and pass this instead i.e.
//Make http request.
const reqInst = req(
options,
function (error, response, body) {
//Error handling.
if (error) { callback(new Error('Something bad happened')); }
json = JSON.parse(JSON.stringify(response));
callback.call(json);
}
);
//Attempt to create form and send through request
var form = new FormData();
...
form.pipe(reqInst);
This line:
.pipe(fileinclude)
Should be this:
.pipe(fileinclude())
from
why am i getting this error? dest.on is not a function - using gulp-file-include

Receving POST request from Node JS server on Arduino

Im trying to send a post request to an arduino with Node JS and the Request package:
var body = {
d:"5",
l:"6",
TOTAL_VOLUME: "75",
meterId: "9"
};
var options = {
url: 'http://'+'192.168.1.102'+'/configData',
timeout: 7000,
headers: {
'Content-type' : 'application/json',
'Content-length': JSON.stringify(body).length
},
json:true,
body: JSON.stringify(body)
};
request.post(options, function (error, response, body) {
//console.log(error);
//console.log(response);
console.log(body);
if (!error && response.statusCode == 200) {
console.log("Changed configuration succesfully. ");
// Request to enpoint to save changes in database
var options = {
url: 'http://'+'8.8.8.8:4000'+'/meter/'+meter.id+'/',
method: 'PUT',
timeout: 10000,
body: {
'tank_diameter': tank_diameter,
'tank_length':tank_length,
'tank_capacity': tank_capacity
}
};
/*request(options, function (error, response, body) {
if (!error && response.statusCode == 200) {
}
});*/
}
done();
}).on('error', function(err) {
console.log(err);
done();
});
The above code is how I send the data, However Im not able to get the data on the arduino.
This is the code on arduino:
server.on("/configData", HTTP_POST, [](){ // configData Seteo de Valores desde POST
StaticJsonBuffer<200> configBuffer;
JsonObject& configJson= configBuffer.parseObject(server.arg("plain"));
String l = configJson["l"];
String d = configJson["d"];
String meterId2 = configJson["meterId"];
String volumenTotal = configJson["TOTAL_VOLUME"];
LENGTH = l.toFloat();
HEIGHT = d.toFloat();
meterId = meterId2.toInt();
TOTAL_VOLUME = volumenTotal.toFloat();
// GUARDAR EN LA EEPROM
int EEadr = 0;
EEPROM.write(EEadr, HEIGHT);
EEPROM.commit();
EEadr = 10;
EEPROM.write(EEadr, LENGTH);
EEPROM.commit();
EEadr = 20;
EEPROM.write(EEadr, TOTAL_VOLUME);
EEPROM.commit();
EEadr = 30;
EEPROM.write(EEadr, meterId);
EEPROM.commit();
//SHOW ON SERIAL MONITOR
Serial.println("l= "+l);
Serial.println("d= "+d);
Serial.println("meterId2= "+meterId2);
Serial.println("TOTAL_VOLUME= "+volumenTotal);
server.send ( 200, "text/json", "{success:true}" );
});
The weird thing is that if I use curl like this:
curl -H "Content-type: application/json" -X POST -d "{l:\"55\", r:\"10\", meterId: \"2\"}" http://192.168.1.2
The arduino does receive the data correctly, so the problem is most likely on my Node JS request. Can anyone tell me what Im I doing wrong here?
UPDATE:
Ive checked the requests with wireshark, and it results that the curl request (the one that is working) is being sent as Line based text data. Can anyone tell me how can I send it the same way using Node JS and request?
In these type of situations you can check your request structure with applications like wireshark.
In this problem if you can see that you attach your hole json as a single string, because when you set json flag of request in request library it convert your body into json for you so now you have something like:
var options = {
body: JSON.stringfy(JSON.stringfy(body))
};
so you can correct your application by simply set following options:
var options = {
url: 'http://'+'www.goole.com'+'/configData',
timeout: 7000,
json:true,
body: body
};

401 unauthorized except through browser

I've been trying to do an HTML GET request, using a URL that works in the browser but somehow results in a 401 Unauthorized error when I run my code. The problem is that I did provide authentication; the URL is of the form
http://username:password#url?param=value
It succeeds in Firefox and Chrome (I also went through Incognito mode to avoid cookies), as well as Google's Postman app, but despite trying several other HTTP GET request methods they all return unauthorized error. I've run it through REST API and XMLHttpRequest, as well as command line.
Any ideas on what could be causing this? Or, even better, if someone's had a similar problem and has a solution?
(Note: I'm pretty new to this whole thing, not sure if I was clear/detailed enough. I'll do my best to elaborate if anyone needs.)
Edit: Here's some idea of the original code I was running:
var func = function() {
var options = {
baseUrl: SERVER,
uri: '/device.cgi',
qs: {
param1: value1,
param2: value2
}
};
request(options, function(err, response, body) {
if (err) console.log(err);
else console.log(body);
});
};
I also ran
function httpGet(theUrl)
{
var xmlHttp = new XMLHttpRequest();
xmlHttp.open( "GET", theUrl, false ); // false for synchronous request
xmlHttp.send( null );
return xmlHttp.responseText;
}
from this question and got the same Unauthorized result.
And because apparently the device I'm using is fine with POST as well,
var func = function () {
var formData = {
form: {
param1: value1,
param2: value2
}
};
request.post(SERVER + 'device.cgi', formData, function (err, response, body) {
if (err) {
console.log(err);
}
else console.log(body);
}).auth(userID, userPass);
};
still with exactly the same result.
http://username:password#url?param=value
The browser is taking that URL, and creates the Basic HTTP Authorization header for you.
Node.js does not do that for you, and thus you must set the Authorization header yourself in code.
var http = require('http');
var options = {
host: 'www.tempuri.org',
path: '/helloworld/',
headers: {
'Authorization': 'Basic QWxhZGRpbjpPcGVuU2VzYW1l'
}
};
http.request(options, function(response) {
var body = '';
response.on('data',function(c) {
body+= c;
})
response.on('end',function() {
console.log(body)
})
}).end();
The following links discuss basic auth, how the browser encodes the data in the URL, and how you could implement it yourself in Node.js:
Basic access authentication (Wikipedia)
Can you pass user/pass for HTTP Basic Authentication in URL parameters? (serverfault)
Basic HTTP authentication in Node.js using the request module (Hay Kranen)

Categories