How to use https module with uri? - node.js

I am trying to use native https module in nodejs.
The code sample below works fine with request-promise-native library
var apiver = '2017-09-01';
var resource = 'https://management.azure.com/';
const rp = require('request-promise-native');
var options = {
uri: `${process.env["MSI_ENDPOINT"]}/?resource=${resource}&api-version=${apiver}`,
headers: {
'Secret': process.env["MSI_SECRET"]
}
};
return rp(options);
Here the uri = "http://127.0.0.1:41437/MSI/token//?resource=https://management.azure.com/&api-version=2017-09-01"
But if I try to do the same thing using https module it throws error
return new Promise( (resolve,reject) => {
var apiver = '2017-09-01';
var resource = 'https://management.azure.com/';
var options = {
"method": "GET",
"hostname": "localhost",
"port": 41437,
"protocol": "https:",
"path": `/MSI/token/?resource=${resource}&api-version=${apiver}`,
headers: {
'Secret': process.env["MSI_SECRET"]
}
};
var req = https.request(options, function (res) {
var body = '';
res.setEncoding('utf8');
res.on('data', function (chunk) {
body += chunk;
});
res.on('end', function () {
if (res.statusCode == 200) {
resolve(body);
} else {
reject({'error':null,'res':res});
}
});
});
req.on('error', function (e) {
reject({'error':e,'res':null});
});
req.end();
});
Following error is thrown
{
hostname: 'localhost',
port: 41437,
protocol: 'https:',
path: '/MSI/token/?resource=https://management.azure.com/&api-version=2017-09-01',
headers: { Secret: '41A1BDD07D4B42159F71353FCCE2F0EB' } }
2018-10-05T11:36:12.395 [Info] { error: {
Error: connect EACCES 127.0.0.1:41437
at Object.exports._errnoException (util.js:1020:11)
at exports._exceptionWithHostPort (util.js:1043:20)
at TCPConnectWrap.afterConnect [as oncomplete] (net.js:1086:14)
code: 'EACCES',
errno: 'EACCES',
syscall: 'connect',
address: '127.0.0.1',
port: 41437
},
res: null
}
Is it not possible to do this request with native https module?

Related

sending http request with proxy ip in node.js

I am trying to send an http get request from a different ip, such as hardcoding the proxy ip to use.
I have a working http get request in node.js:
const https = require('https')
//get access token
let accessToken = await spotifyAuth.getAccessToken();
//create data
const data = JSON.stringify({
offset: 0,
})
//create options data obj
const options = {
hostname: 'api.spotify.com',
path: '/v1/artists/1XqqyIQYMonHgllb1uysL3/albums',
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken,
},
}
const req = https.request(options, res => {
console.log(`proxyiprequest() statusCode: ${res.statusCode}`)
res.on('data', d => {
process.stdout.write(d)
})
})
req.on('error', error => {
console.error('proxyiprequest() err=', error)
})
req.write(data)
req.end()
So I'm trying to add an https proxy ip address/port combo I found from here like so:
//create options data obj
const options = {
host: "220.135.165.38",
port: 8080,
hostname: 'api.spotify.com',
path: '/v1/artists/1XqqyIQYMonHgllb1uysL3/albums',
method: 'GET',
headers: {
'Authorization': 'Bearer ' + accessToken,
},
}
Would this method work? If I run the request it errors out like:
proxyiprequest() err= { Error: write EPROTO 18:error:1B:SSL routines:ssl3_get_record:wrong version number:../ssl/record/ssl3_record.c:331:
at WriteWrap.afterWrite [as oncomplete] (net.js:789:14) errno: 'EPROTO', code: 'EPROTO', syscall: 'write' }

nodejs equivalent of https curl -k request

I was following the guide here https://www.elastic.co/guide/en/cloud-on-k8s/current/k8s-deploy-elasticsearch.html for accessing elasticsearch via a curl request and was wondering how I can translate this curl -u "elastic:somepassword" -k "https://quickstart-es-http:9200" to nodejs.
I have this setup but I'm unable to connect:
https.get(
"https://quickstart-es-http:9200",
{ headers: { authorization: "Basic elastic:" + process.env.ES_SECRET } },
(innerRes) => {
let data = "";
innerRes.on("error", (err) => {
console.error("erro>>", err);
});
innerRes.on("data", (chunk) => {
data += chunk;
});
innerRes.on("end", () => {
console.log("data", data);
res.send(data);
});
innerRes.on("close", () => {
console.log("data", data);
res.send(data);
});
}
);
the error message I'm getting is:
Error: connect ECONNREFUSED 10.28.9.116:9200
at TCPConnectWrap.afterConnect [as oncomplete] (node:net:1133:16)
Emitted 'error' event on ClientRequest instance at:
at TLSSocket.socketErrorListener (node:_http_client:447:9)
at TLSSocket.emit (node:events:365:28)
at emitErrorNT (node:internal/streams/destroy:193:8)
at emitErrorCloseNT (node:internal/streams/destroy:158:3)
at processTicksAndRejections (node:internal/process/task_queues:83:21) {
errno: -111,
code: 'ECONNREFUSED',
syscall: 'connect',
address: '10.28.9.116',
port: 9200
}
Thank you!
You can set rejectUnauthorized to false. See more here https://nodejs.org/api/https.html#https_https_request_url_options_callback
const https = require('https');
const options = {
hostname: 'encrypted.google.com',
port: 443,
path: '/',
method: 'GET',
rejectUnauthorized: false
};
const req = https.request(options, (res) => {
console.log('statusCode:', res.statusCode);
console.log('headers:', res.headers);
res.on('data', (d) => {
process.stdout.write(d);
});
});
req.on('error', (e) => {
console.error(e);
});
req.end();

ENOTFOUND when making API call from Azure Functions NodeJS

I am trying to make an API call using Azure Functions. But I am getting below error.
{
"errno": "ENOTFOUND",
"code": "ENOTFOUND",
"syscall": "getaddrinfo",
"hostname": "https://jsonplaceholder.typicode.com",
"host": "https://jsonplaceholder.typicode.com",
"port": "80"
}
My Code
var http = require('http');
module.exports = function (context) {
context.log('JavaScript HTTP trigger function processed a request.');
var options = {
host: 'https://jsonplaceholder.typicode.com',
port: '80',
path: '/users',
method: 'GET'
};
// Set up the request
var req = http.request(options, (res) => {
var body = "";
res.on("data", (chunk) => {
body += chunk;
});
res.on("end", () => {
context.res = body;
context.done();
});
}).on("error", (error) => {
context.log('error');
context.res = {
status: 500,
body: error
};
context.done();
});
req.end();
};
How could I solve this?
You made a few common mistakes:
You are using http module for https URL.
Change host value to jsonplaceholder.typicode.com
For https protocol port should be 443
Change options as below:
For http:
var options = {
host: 'jsonplaceholder.typicode.com',
port: '80',
path: '/users',
method: 'GET'
};
For https:
Use https module to make request and options object should be like this
var options = {
host: 'jsonplaceholder.typicode.com',
port: '443',
path: '/users',
method: 'GET'
};
Demo:https://repl.it/repls/RepentantGoldenrodPriority

Getting error on hitting Google Vision Api

const options = {
hostname: 'https://vision.googleapis.com/v1/images:annotate?key=<some key>',
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
const req = http.request(options, (res : any) => {
res.on('data', (chunk : any) => {
console.log(`BODY: ${chunk}`);
});
});
req.on('error', (e) => {
console.log(e)
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(JSON.stringify(body))
req.end()
I am trying to use one of the google vision feature i.e. Text Detection. But when ever I am hitting that api I am getting this error. I double checked the url and other data.
{ Error: getaddrinfo ENOTFOUND https://vision.googleapis.com/v1/images:annotate?key=<> https://vision.googleapis.
com/v1/images:annotate?key=<key>:80
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:56:26)
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname:
'https://vision.googleapis.com/v1/images:annotate?key=<key>',
host:
'https://vision.googleapis.com/v1/images:annotate?key=<key>',
port: 80 }
This code should work, there are only a couple of changes necessary, for example we'll use the https module rather than the http module.
const https = require('https');
const options = {
hostname: 'vision.googleapis.com',
path: '/v1/images:annotate?key=' + API_KEY,
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
let data = "";
const req = https.request(options, (res: any) => {
res.on('data', (chunk: any) => {
data += chunk;
});
res.on('end', (chunk) => {
console.log(`BODY: ${data}`);
});
});
req.on('error', (e) => {
console.log(e)
console.error(`problem with request: ${e.message}`);
});
// Write data to request body
req.write(JSON.stringify(body))
req.end()
Try modifying the request to:
const options = {
method: 'POST',
headers: {
'Content-Type' : 'application/json'
}
};
const req = http.request(`https://vision.googleapis.com/v1/images:annotate?key=<some key>`, options, (res : any) => {
res.on('data', (chunk : any) => {
console.log(`BODY: ${chunk}`);
});
});
because https://vision.googleapis.com/v1/images:annotate?key=<some key> is a full URL, not a valid hostname.

How nodejs app to request to my another https server?

Below is nodejs app to request to my another https server
var https = require('https');
jsonObject = JSON.stringify({"arg1":"4","arg2":"True"});
// prepare the header
var postheaders = {
'Content-Type' : 'application/json',
'Content-Length' : Buffer.byteLength(jsonObject, 'utf8')
};
// the post options
var optionspost = {
host : 'https://www.example.com/',
path : '/my/path/?arg1=4&arg2=True',
method : 'POST',
headers : postheaders
};
var reqPost = https.request(optionspost, function(res) {
console.log("statusCode: ", res.statusCode);
res.on('data', function(d) {
console.info('POST result:\n');
process.stdout.write(d);
console.info('\n\nPOST completed');
});
});
reqPost.write(jsonObject);
reqPost.end();
reqPost.on('error', function(e) {
console.error(e);
});
I always got below errors anybody can say where i went wrong
{ [Error: getaddrinfo ENOTFOUND https://www.example.com/]
code: 'ENOTFOUND',
errno: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'https://www.example.com/' }
// the post options
var optionspost = {
host : 'www.example.com',
path : '/my/path/?arg1=4&arg2=True',
method : 'POST',
headers : postheader
}
The host attribute needs to be a fully qualified domain name. Remove the https:// and the trailing slash and it should work.

Resources