cdbrelease/cdbfetch.js

50 lines
1.4 KiB
JavaScript

'use strict';
const needle = require('needle');
const mylog = require('./mylog');
const config = require('./config');
const delay = () => new Promise(r => setTimeout(r, 2000 + Math.random() * 2000));
const maxattempts = 10;
async function fetch(uri, meth, data, opts, ...rest) {
if(uri.startsWith('/'))
uri = config.root.trimEnd('/') + uri;
meth = meth || 'get';
opts = opts || {};
opts.headers = opts.headers || {};
opts.headers.Authorization = `Bearer ${config.token}`;
opts.headers.Referer = uri;
opts.open_timeout = config.timeout * 1000;
opts.read_timeout = config.timeout * 1000;
opts.response_timeout = config.timeout * 1000;
if(!opts.hasOwnProperty('follow_max'))
opts.follow_max = 10;
for(let attempt = 1; attempt <= maxattempts; attempt++)
try {
mylog(`# ${meth} ${uri}`);
const resp = await needle(meth, uri, data, opts, ...rest);
if(!/^[23]\d\d/.test(resp.statusCode.toString())) {
const failure = {
method: meth,
uri,
data,
statusCode: resp.statusCode,
statusMessage: resp.statusMessage,
body: resp.body
};
throw (Object.assign(new Error(JSON.stringify(failure)), failure));
}
return resp;
}
catch (err) {
if(attempt === maxattempts ||
err.statusCode && !/^(?:429|5\d\d)$/.test(err.statusCode.toString()) ||
!err.statusCode && !/remote end closed socket/i.test(err.message))
throw err;
await delay();
}
}
module.exports = fetch;