Node.js Error: Max redirects exceeded - node.js

how I can ignore pages with cycle redirects?
I use this code to fetching pages:
var libxml = require("libxmljs"),
http = require('follow-redirects').http,
url = require("url");
var request = http.request( { "host": host, "path": URL, "port": 80 }, function( response ) {
var str = '';
response.on( 'data', function( chunk ) {
str += chunk;
});
response.on( 'end', function() {
callback( str, response.statusCode );
}).on( 'error', function ( err ) {
console.log( err );
});
}).end();
It will not go to 'error' block, and I've got an exception:
events.js:85
throw er; // Unhandled 'error' event
^
Error: Max redirects exceeded.
at ClientRequest.cb (/var/parsing/node_modules/follow-redirects/create.js:55:19)
at ClientRequest.g (events.js:199:16)
at ClientRequest.emit (events.js:107:17)
at HTTPParser.parserOnIncomingClient [as onIncoming] (_http_client.js:426:21)
at HTTPParser.parserOnHeadersComplete (_http_common.js:111:23)
at Socket.socketOnData (_http_client.js:317:20)
at Socket.emit (events.js:107:17)
at readableAddChunk (_stream_readable.js:163:16)
at Socket.Readable.push (_stream_readable.js:126:10)
at TCP.onread (net.js:538:20)

The error is being thrown by the request object, not the response object, so you need to add an (additional) error listener to request;
var request = http.request(...).on('error', function(err) {
...
}).end();

Looking at the docs for the package you are using (https://www.npmjs.com/package/follow-redirects), it looks like it just has a maxRedirects option. Directly from the linked page:
require('follow-redirects').maxRedirects = 10; // Has global affect (be careful!)
https.request({
host: 'bitly.com',
path: '/UHfDGO',
maxRedirects: 3 // per request setting
}, function (res) {/* ... */});

Related

NodeJS - Error (response 408) when downloading a pdf with node-downloader-helper

I want to download pdf with nodeJS, so I created a function with node-downloader-helper module (see below). This function is called multiples time to download a list of pdf.
function downloadPDF(url, dirname, index) {
const options = {
method: "GET", // Request Method Verb
headers: {}, // Custom HTTP Header ex: Authorization, User-Agent
fileName: `document${index}.pdf`, // Custom filename when saved
forceResume: false, // If the server does not return the "accept-ranges" header, can be force if it does support it
removeOnStop: true, // remove the file when is stopped (default:true)
removeOnFail: true, // remove the file when fail (default:true)
httpRequestOptions: {}, // Override the http request options
httpsRequestOptions: {
timeout: 10000, // Timeout in milliseconds
}, // Override the https request options, ex: to add SSL Certs
timeout: 10000, // Timeout in ms, 0 to disable (default:0)
};
const dl = new DownloaderHelper(encodeURI(url), dirname, options);
dl.on('end', () => console.log('Download Completed'));
dl.on('error', (err) => console.log('Download Failed', err));
dl.start().catch(err => console.error(err));
}
When I run my program I get this error : (and sometimes with server completely crash). I think it’s about a timeout error but I tried different methods but none worked.
Error: Response status was 408
at ClientRequest.<anonymous> (/home/ubuntu/CPE-Colle/node_modules/node-downloader-helper/dist/index.js:1:7055)
at Object.onceWrapper (node:events:642:26)
at ClientRequest.emit (node:events:527:28)
at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:631:27)
at HTTPParser.parserOnHeadersComplete (node:_http_common:117:17)
at TLSSocket.socketOnData (node:_http_client:494:22)
at TLSSocket.emit (node:events:527:28)
at addChunk (node:internal/streams/readable:324:12)
at readableAddChunk (node:internal/streams/readable:297:9)
at Readable.push (node:internal/streams/readable:234:10) {
status: 408,
body: ''
}
I think found the solution, my puppeteer browser that was fetching pdf links wasn't closing so after a while my server crashed.

How to get places from google maps by location with node js? And then integrate to dialogflow?

I want to do an application in react-native front-end with Dialogflow and nodejs back-end which when I ask for restaurants from Sydney, for example, to return places.
What i do:
i try to get places from https://maps.googleapis.com
here is my request:
if (result.action === 'find-a-place') {
console.log("am intrat in if")
let place_type = responses[0].queryResult.parameters.fields['placesType'].stringValue;
console.log(" places-type e : " + place_type)
const city = responses[0].queryResult.parameters.fields['location'].listValue.values[0].structValue.fields['city'].stringValue; // city is a required param
//res.send(city)
console.log("city: " + city + " and place type is " + place_type)
//let date = '';
getPlaces(place_type, city)
.then((output) => {
res.send(output)
})
}
and here is the function:
function getPlaces(place_type, city) {
// Create the path for the HTTP request to get the weather
let path_google = '/maps/api/place/textsearch/xml?query='+place_type+'+in+'+city+'&key='+process.env.YOUR_API_KEY
console.log('API Request: ' + host_google + path_google);
//Make the HTTP request to get the weather
http.get({ host: host_google, path: path_google }, (res) => {
let body = ''; // var to store the response chunks
res.on('data', (d) => { body += d; }); // store each response chunk
res.on('end', () => {
// After all the data has been received parse the JSON for desired data
let response = JSON.parse(body);
console.log("json ul complet: " + response)
});
res.on('error', (error) => {
console.log(`Error calling the weather API: ${error}`)
reject();
});
});
}
END THE ERROR:
city: Sydney and place type is: restaurant
API Request: https://maps.googleapis.com/maps/api/place/textsearch/xml?query=restaurant+in+Sydney&key=AIzaSyB5pzEDTvHZpJh2puV8X6hu6BQqt7D7NSs
Input is TypeError: Cannot read property 'then' of undefined
events.js:187
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND https://maps.googleapis.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26)
API Request: https://maps.googleapis.com/maps/api/place/textsearch/xml?query=restaurant+in+Sydney&key=AIzaSyB5pzEDTvHZpJh2puV8X6hu6BQqt7D7NSs
Input is TypeError: Cannot read property 'then' of undefined
events.js:187
throw er; // Unhandled 'error' event
^
Error: getaddrinfo ENOTFOUND https://maps.googleapis.com
at GetAddrInfoReqWrap.onlookup [as oncomplete] (dns.js:60:26)
Emitted 'error' event on ClientRequest instance at:
at Socket.socketErrorListener (_http_client.js:406:9)
at Socket.emit (events.js:210:5)
at emitErrorNT (internal/streams/destroy.js:92:8)
at emitErrorAndCloseNT (internal/streams/destroy.js:60:3)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
errno: 'ENOTFOUND',
code: 'ENOTFOUND',
syscall: 'getaddrinfo',
hostname: 'https://maps.googleapis.com'
}
Please help.

Howo to get IPP endpoint

I'm using the ipp npm module to send a print job from a google cloud function. I believe I have set up the printer correctly but I don't know how I'm supposed to know the exact uri for sending the print job.
The printer model is Brother MFC-L3770CDW
Here is how my settings look in the web view for the printer configuration.
And here is the function code.:
var ipp = require('ipp');
var PDFDocument = require('pdfkit');
var doc = new PDFDocument;
doc.text("Hello World");
var buffers = [];
doc.on('data', buffers.push.bind(buffers));
doc.on('end', function () {
var printer = ipp.Printer("https://10.0.0.55:443");
var file = {
"operation-attributes-tag":{
"requesting-user-name": "User",
"job-name": "Print Job",
"document-format": "application/pdf"
},
data: Buffer.concat(buffers)
};
printer.execute("Print-Job", file, function (err, res) {
if(err) {
console.log(err);
}
else{
console.log("Printed: "+res.statusCode);
}
});
console.log('executing');
});
doc.end();
console.log('finished executing');
I have tried various uris such as
https://10.0.0.55:631
https://10.0.0.55:443
https://10.0.0.55:631/ipp
https://10.0.0.55:631/ipp/printer
Sometimes I get an error like:
"Error: socket hang up
at TLSSocket.onHangUp (_tls_wrap.js:1148:19)
at Object.onceWrapper (events.js:313:30)
at emitNone (events.js:111:20)
at TLSSocket.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
at _combinedTickCallback (internal/process/next_tick.js:139:11)
at process._tickCallback (internal/process/next_tick.js:181:9)
code: 'ECONNRESET',
path: null,
host: '10.0.0.55',
port: '631',
localAddress: undefined }"

Error: socket hang up in Http Request made in Node JS using request-promise causing for loop to restart

I am trying to make an Http Request using request-promise inside a for loop. But it seems if a Http Request takes long, request-promise closes the connection.
This behavior is ok but what I am not able to grasp is the for loop starts from 0 again after the error is printed.
Below is the code
const rp = require('request-promise');
async function stepIterator(processingSteps, documentId) {
var finalResult = null;
for (var step = 0, len = processingSteps.length; step < len; step++) {
if (step === 0 || step === 1 || step == 2 || step == 3) {
try {
console.log('Calling step ', step);
let url = 'http://internal-server:8080/process';
let collection = getCollection(documentId);
let splitText = getSPlit(documentId);
let outputFormat = 'xmi';
let documentObject = await callServer(url, collection, splitText, outputFormat);
finalResult = documentObject;
} catch (error) {
console.log("Error");
}
}
}
return finalResult;
}
async function callServer(url, collection, splitText, outputFormat) {
var options = {
method: 'POST',
uri: url,
headers: {
'Content-Type': 'multipart/form-data',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive '
},
formData: {
collection: collection,
text: splitText,
output: outputFormat
}
};
return rp(options)
}
The complete error trace is as follows
{ RequestError: Error: socket hang up
at new RequestError (D:\New_Projects\new-data-access-layer\node_modules\request-promise-core\lib\errors.js:14:15)
at Request.plumbing.callback (D:\New_Projects\new-data-access-layer\node_modules\request-promise-core\lib\plumbing.js:87:29)
at Request.RP$callback [as _callback] (D:\New_Projects\new-data-access-layer\node_modules\request-promise-core\lib\plumbing.js:46:31)
at self.callback (D:\New_Projects\new-data-access-layer\node_modules\request\request.js:185:22)
at Request.emit (events.js:182:13)
at Request.onRequestError (D:\New_Projects\new-data-access-layer\node_modules\request\request.js:881:8)
at ClientRequest.emit (events.js:182:13)
at Socket.socketOnEnd (_http_client.js:425:9)
at Socket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19) name: 'RequestError', message: 'Error: socket hang up', cause:
{ Error: socket hang up
at createHangUpError (_http_client.js:322:15)
at Socket.socketOnEnd (_http_client.js:425:23)
at Socket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19) code: 'ECONNRESET' }, error: { Error: socket hang up
at createHangUpError (_http_client.js:322:15)
at Socket.socketOnEnd (_http_client.js:425:23)
at Socket.emit (events.js:187:15)
at endReadableNT (_stream_readable.js:1094:12)
at process._tickCallback (internal/process/next_tick.js:63:19) code: 'ECONNRESET' }, options: { method: 'POST',
uri: 'http://internal-server:8080/process',
json: true,
headers: { Connection: 'keep-alive ' },
body:
{ docSplitId: [Array],
_id: 5c579d84812acb17ec74ac39,
contentType: 'application/pdf',
location:
'C:\\Users\\newuser\\AppData\\Local\\Temp\\2\\report.pdf',
docModelVersion: '1',
visualMetaDataId: null,
categoryId: '5c52a72f6df294140c0535bc',
deductedInfo: null,
status: 'New',
isDeleted: false,
metadata: [Object],
detailedStatus: [Array] },
callback: [Function: RP$callback],
transform: undefined,
simple: true,
resolveWithFullResponse: false,
transform2xxOnly: false }, response: undefined }
Obviously the socket is hanging! Don't bother with http, it is a little complex. Use node unirest and it closes the data stream.
var unirest = require('unirest');
var req = unirest('POST', 'localhost:3200/store/artifact/metamodel')
.attach('file', '/home/arsene/DB.ecore')
.field('description', 'We are trying to save the metamodel')
.field('project', '6256d72a81c4b80ccfc1768b')
.end(function (res) {
if (res.error) throw new Error(res.error);
console.log(res.raw_body);
});
Hope this helps!

If I disable NODE_TLS_REJECT_UNAUTHORIZED, my request is still denied

I am disabling Node from rejecting self signed certificates and making a request.
const { USER, PW } = process.env;
const b64 = new Buffer(`${VP_API_USER}:${VP_API_PW}`).toString("base64");
const Authorization = `Basic ${b64}`;
const doFind = async url => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
const results = await fetch(url, { headers: { Authorization } })
.then(r => (r.ok ? r.json() : Promise.reject(r)))
.catch(err => {
return Promise.reject(err);
});
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
return results;
};
I am still being rejected.
{ FetchError: request to https://<url>:55544/contracts failed, reason: connect ECONNREFUSED <url>:55544
at ClientRequest.<anonymous> (/Users/mjhamm75/Developer/sedd-monorepo/node_modules/node-fetch/index.js:133:11)
at emitOne (events.js:116:13)
at ClientRequest.emit (events.js:211:7)
at TLSSocket.socketErrorListener (_http_client.js:387:9)
at emitOne (events.js:116:13)
at TLSSocket.emit (events.js:211:7)
at emitErrorNT (internal/streams/destroy.js:64:8)
at _combinedTickCallback (internal/process/next_tick.js:138:11)
at process._tickCallback (internal/process/next_tick.js:180:9)
name: 'FetchError',
message: 'request to https://<url>:55544/contracts failed, reason: connect ECONNREFUSED <url>:55544',
type: 'system',
errno: 'ECONNREFUSED',
code: 'ECONNREFUSED' }
What am I doing wrong?
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
line should go inside the callback (your then or catch before the return. because a promise gets resolved in the callback, but your line
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
is written outside of it, even though it appears after the statement, it runs immediately without waiting for the callback. so, your tls is effectively never disabled.
I hope this helps:)
Previous answer looks incorrect - await postpones execution of next line until promise will be resolved.
According to the documentation the NODE_TLS_REJECT_UNAUTHORIZED value should be string '0' to disable TLS validation.
This is how I would approach it, if I had to reset the env var afterwards.
Using .finally() the statement will execute regardless of the outcome of the fetch.
const doFind = async url => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 0;
const results = await fetch(url, { headers: { Authorization } })
.then(r => (r.ok ? r.json() : Promise.reject(r)))
.catch(err => {
return Promise.reject(err);
})
.finally(() => {
process.env.NODE_TLS_REJECT_UNAUTHORIZED = 1;
});
return results;
};

Resources