50 lines
1.4 KiB
JavaScript
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;
|