Error: getaddrinfo ENOTFOUND when sending https request Node.js and API - javascript

I am developing a dashboard, I need to conect to a API and catch a Auth Token and afther that send info by using a HTTPS protocol. I use a Nodejs, and when I run my code I have the next error on the pm2 monit:
Error: getaddrinfo ENOTFOUND my.url.net/path
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:67:26) {
errno: -3008,
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'my.url.net/path'
}
Also here is my code where I made the request (Node.js):
const path = require('path');
require('dotenv').config({path: path.join('path','.env')});
const https = require('https');
const database = require('./sql');
const fs = require ('fs');
const user = process.env.USER;
const pwd = PWD;
const host = 'https://my.url.net/extencio';
const host_1 = 'my.url.net/extention';
async function getLoginToken(pForce){
if (login_token.Health && !pForce) { return login_token }
//Creates the POST request
const options = {
protocol: 'https:',
hostname: host_1,
path: '/api/auth/token',
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
};
//Body of the POST request, contains the user and password
const post_data = JSON.stringify({username: user, password: pwd});
.
Here is the rest of the code:
return new Promise((resolve, reject) => {
const req = new https.request(options, (response) => {
response.setEncoding('utf8');
response.on('data', function(chunk){
const output = JSON.parse(chunk);
if(output.token){
login_token.Health = true;
login_token.Token = output.token;
resolve(login_token)
}
else{
login_token.Health = false;
login_token.Token = '';
resolve(login_token);
}
});
});
req.write(post_data);
req.end();
req.on('error', function(err) {
console.log(err);
login_token.Health = false;
login_token.Token = '';
resolve(login_token)
});
});
}

Remove protocol, and use domain names only for the host. For instance:
Wrong:
const host = 'https://my.url.net/extencio'
const path = '/api/auth/token'
Correct:
const host = 'my.url.net'
const path = '/extencio/api/auth/token'
See documentation for the http.request options.

It seems that is trying to getaddrinfo of the full url, instead of just the hostname. I would put hostname in option as only "my.url.net" and update path with the rest of the url.

#Eric0607 the error stackoverflow.com/questions/65810720/… you've provided is not showing anymore, I might've been too late to reply.
but in case you got "an invalid local cert SSL error", here is a fix I found that works for it.
disable SSL check in your code, not recommended but it would work temporarily, turn it on after you're done or it can be risky.

Related

NodeJS Error when sending POST request using http.request or Axios

I'm trying to send some data in NodeJS from one localhost server to another, but I'm getting a nasty error. On the server that receives the request it appears the request goes through because I'm getting an object logged to the terminal there, except its properties are null (they're supposed to be set to the properties in the req body, or null).
I get the error even if I try with Axios, which tells me that it’s not an issue with http.request or Axios. If anyone could help me understand what's going on I'd appreciate it.
Error:
events.js:377
throw er; // Unhandled 'error' event
^
Error: write EPROTO 8669511168:error:1408F10B:SSL routines:ssl3_get_record:wrong version number:../deps/openssl/openssl/ssl/record/ssl3_record.c:332:
at WriteWrap.onWriteComplete [as oncomplete] (internal/stream_base_commons.js:94:16)
Emitted 'error' event on ClientRequest instance
{
errno: -100,
code: 'EPROTO',
syscall: 'write'
}
The project sending the request looks like this:
Resources file
const http = require('http');
const options = {
host: 'localhost',
port: 3000,
path: '/create',
method: 'POST',
header: {
'Content-Type':'application/json'
}
}
const body = {
inquiryTotal: ‘20.00’
}
const stringifiedBody = JSON.stringify(body)
module.exports.Inquiries = {
create: () => {
req = http.request(options, (res) => {
console.log(res);
});
req.write(stringifiedBody); // this is an object that's already stringified to JSON
req.end();
/*axios.post('localhost:3000/v1/orders/create', {
orderTotal: '21.00'
}).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})*/
}
}
Server sending request:
const resource = require('./lib/resource');
// create server code
resource.Inquiries.create;
Assuming you are correctly setup your API endpoint, you can try this (added some comments inside the code):
const axios = require("axios").default;
const body = {
inquiryTotal: "20.00" // Use single-qupte ('') or double-quote ("") here and don't use back-quote (``)
};
module.exports.Inquiries = {
create: () => {
axios
.post("http://localhost:3000/v1/orders/create", body) // Add http:// in the beginning of your url
.then((res) => {
console.log(res);
})
.catch((err) => {
console.log(err);
});
}
};

Downloading a lot of images with NodeJS

I got a large list of URLs (8000+) I want to download the images from.
I created a script that will download the files, as long as I'm setting the limit to about a 100.
If I try to download more I'm getting errors like
(node:6740) UnhandledPromiseRejectionWarning: Error: read ECONNRESET
(node:3808) UnhandledPromiseRejectionWarning: Error: connect ETIMEDOUT
(node:7052) UnhandledPromiseRejectionWarning: Error: Client network socket disconnected before secure TLS connection was established
This is the code that reads my CSV with URL's:
const fotoDownload = require('./async-foto');
const csv = require('csv-parser');
const fs = require('fs');
const results = [];
fs.createReadStream('\\\\hk-nas02\\import\\Partij\\Files\\partij.csv')
.pipe(csv( { separator: ';'}))
.on('data', (data) => results.push(data))
.on('end', () => {
console.log(results.length)
let NoPartijen = results.length;
for(i = 0;i < 50; i++){
//console.log(results[i]);
itemno = i
path = '..\\files\\images\\'+results[i]['partij.VPARTIJNR']+'_'+results[i]['partij.PARTIJNR']+'_H.jpg';
console.log(path)
fotoDownload.fotoDownload(results[i]['partij.EXFOTOURL'], path, itemno)
}
console.log('Test');
});
and calls the following code to download:
const util = require('util')
const fs = require('fs')
const axios = require("axios").default;
module.exports = {
fotoDownload: async (url, path, itemno) => {
try {
const response = await axios({
method: "GET",
url: url,
responseType: "stream",})
await response.data.pipe(fs.createWriteStream(path));
console.log('Start foto download' + itemno);
return;
} catch (err) {
throw new Error(err)
}
}
}
I'm assuming I need the chop the data into chunks or something, but I'm a bit lost here. Can someone put me in the right direction?
You need to set a timeout for downloading the images & add connection keep-alive
something like this
axios.defaults.timeout = 30000; //or whateve your desired timeout
axios.defaults.httpsAgent = new https.Agent({ keepAlive: true });
module.exports = {
fotoDownload: async (url, path, itemno) => {
try {
const response = await axios({
method: "GET",
url: url,
responseType: "stream",})
await response.data.pipe(fs.createWriteStream(path));
console.log('Start foto download' + itemno);
return;
} catch (err) {
throw new Error(err)
}
}
}
Note: make sure u have https installed
run npm i http or npm i https

Error by Node JS request to external service with required p12 certificat

There is a service which provides a XML under a certain URL (for example: https://myxml). The organisation from that service send me a p12 certificate with the password.
In the Browser it works correct.
On my local machine I'm running a Node JS server. I want to send a request from my node server and get the response from the service.
I'm pretty new to certificates.
This is the error I get after trying to get the request from the service
error:0906D06C:PEM routines:PEM_read_bio:no start line
This is the implementation in the node server
const request = require('request');
const fs = require('fs');
const path = require('path');
const certFile = path.resolve(__dirname, 'folder/cert.p12');
var options = {
url: 'https://myxml',
cert: fs.readFileSync(certFile),
passphrase: 'xyz'
}
request.get(options);
request('https://myxml', function(error, response, body){
console.log("error: ", error);
console.log("statusCode: ", response && response.statusCode);
console.log("body: ", body);
})
Try reading the file in as binary and using it directly
var p12 = fs.readFileSync('file.p12', 'binary');
var p12Asn1 = forge.asn1.fromDer(p12, false);
var p12Parsed = forge.pkcs12.pkcs12FromAsn1(p12Asn1, false, 'password');
also add agentOptions in request like
request({
method: 'GET',
url: 'https://myxml',
rejectUnauthorized: false,
strictSSL: false,
agentOptions: {
//pfx: pfx,
pfx: require('fs').readFileSync('string_path_to_the_p12_key_file.p12'),
passphrase: 'redacted_password'
}
}

https request basic authentication node.js

I am really getting crazy looking for this over the web and stackoverflow.
Other posts about this topic talk of http request, not httpS.
I'm coding server side with node.js and I need to make an https request to another website to login
If I use postman tool in chrome trying with https://user:pass#webstudenti.unica.it/esse3/auth/Logon.do everything works fine and I log in.
If I use request library in node I can't login and I get a page with a custom error message about an error in my getting/sending data.
Maybe I am wrong setting the options to pass to request.
var request = require('request');
var cheerio = require('cheerio');
var user = 'xxx';
var pass = 'yyy';
var options = {
url : 'https://webstudenti.unica.it',
path : '/esse3/auth/Logon.do',
method : 'GET',
port: 443,
authorization : {
username: user,
password: pass
}
}
request( options, function(err, res, html){
if(err){
console.log(err)
return
}
console.log(html)
var $ = cheerio.load(html)
var c = $('head title').text();
console.log(c);
})
http://jsfiddle.net/985bs0sc/1/
You're not setting your http auth options correctly (namely authorization should instead be auth). It should look like:
var options = {
url: 'https://webstudenti.unica.it',
path: '/esse3/auth/Logon.do',
method: 'GET',
port: 443,
auth: {
user: user,
pass: pass
}
}
http/https should make no difference in the authentication. Most likely your user/pass needs to be base64 encoded. Try
var user = new Buffer('xxx').toString('base64');
var pass = new Buffer('yyy').toString('base64');
See: https://security.stackexchange.com/questions/29916/why-does-http-basic-authentication-encode-the-username-and-password-with-base64
Don't use npm package request because it is deprecated, use Node native https instead
const https = require('https')
var options = {
host: 'test.example.com',
port: 443,
path: '/api/service/'+servicename,
// authentication headers
headers: {
'Authorization': 'Basic ' + new Buffer(username + ':' + passw).toString('base64')
}
};
//this is the call
request = https.get(options, function(res){
console.log(`statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error(error)
})
req.end()
With the updated version, I am able to make https call with basic auth.
var request = require('request');
request.get('https://localhost:15672/api/vhosts', {
'auth': {
'user': 'guest',
'pass': 'guest',
'sendImmediately': false
}
},function(error, response, body){
if(error){
console.log(error)
console.log("failed to get vhosts");
res.status(500).send('health check failed');
}
else{
res.status(200).send('rabbit mq is running');
}
})
Use Node.js' URL module to build your URL object. The httpsAgent module is required if you are calling servers w self-signed certificates.
const https = require('https');
const httpsAgent = new https.Agent({
rejectUnauthorized: false,
});
// Allow SELF_SIGNED_CERT, aka set rejectUnauthorized: false
let options = {
agent: httpsAgent
}
let address = "10.10.10.1";
let path = "/api/v1/foo";
let url = new URL(`https://${address}${path}`);
url.username = "joe";
url.password = "password123";
url.agent = httpsAgent
let apiCall = new Promise(function (resolve, reject) {
var data = '';
https.get(url, options, res => {
res.on('data', function (chunk){ data += chunk })
res.on('end', function () {
resolve(data);
})
}).on('error', function (e) {
reject(e);
});
});
try {
let result = await apiCall;
} catch (e) {
console.error(e);
} finally {
console.log('We do cleanup here');
}

Implementing a simple proxy server using node.js

I'm trying to create a simple node.js proxy server for experimental purposes and I came up with this simple script:
var url = require("url");
var http = require("http");
var https = require("https");
http.createServer(function (request, response) {
var path = url.parse(request.url).path;
if (!path.indexOf("/resource/")) {
var protocol;
path = path.slice(10);
var location = url.parse(path);
switch (location.protocol) {
case "http:":
protocol = http;
break;
case "https:":
protocol = https;
break;
default:
response.writeHead(400);
response.end();
return;
}
var options = {
host: location.host,
hostname: location.hostname,
port: +location.port,
method: request.method,
path: location.path,
headers: request.headers,
auth: location.auth
};
var clientRequest = protocol.request(options, function (clientResponse) {
response.writeHead(clientResponse.statusCode, clientResponse.headers);
clientResponse.on("data", response.write);
clientResponse.on("end", function () {
response.addTrailers(clientResponse.trailers);
response.end();
});
});
request.on("data", clientRequest.write);
request.on("end", clientRequest.end);
} else {
response.writeHead(404);
response.end();
}
}).listen(8484);
I don't know where I'm going wrong but it gives me the following error when I try to load any page:
http.js:645
this._implicitHeader();
^
TypeError: Object #<IncomingMessage> has no method '_implicitHeader'
at IncomingMessage.<anonymous> (http.js:645:10)
at IncomingMessage.emit (events.js:64:17)
at HTTPParser.onMessageComplete (http.js:137:23)
at Socket.ondata (http.js:1410:22)
at TCP.onread (net.js:374:27)
I wonder what could the problem be. Debugging in node.js is so much more difficult than in Rhino. Any help will be greatly appreciated.
As I mentioned in the comments, your primary problem is that your .write and .end calls are not bound properly to a context, so they will just flip out and throw errors all over.
With that fixed, requests give a 404 because the headers property will pull in the host header of the original request, localhost:8484. Following your example, that will get send to jquery.com's server, and it will 404. You need to remove the host header before proxying.
Add this before calling protocol.request.
delete options.headers.host;

Categories

Resources