service-core/core/client.mjs

84 lines
2.4 KiB
JavaScript
Raw Normal View History

2020-09-07 00:47:53 +00:00
import http from 'http'
import https from 'https'
import fs from 'fs'
2020-09-12 20:31:36 +00:00
import url from 'url'
2020-09-07 00:47:53 +00:00
2020-09-12 20:31:36 +00:00
export function request(path, filePath = null, redirects, returnText = false) {
let newRedirects = redirects + 1
if (!path || !path.startsWith('http')) {
return Promise.reject(new Error('URL was empty or missing http in front'))
}
let parsed = new url.URL(path)
2020-09-07 00:47:53 +00:00
let h
if (parsed.protocol === 'https:') {
h = https
} else {
h = http
}
return new Promise(function(resolve, reject) {
if (!path) {
return reject(new Error('Request path was empty'))
}
let req = h.request({
path: parsed.pathname + parsed.search,
port: parsed.port,
method: 'GET',
headers: {
'User-Agent': 'TheThing/service-core',
Accept: 'application/vnd.github.v3+json'
},
2020-09-12 20:31:36 +00:00
timeout: returnText ? 5000 : 60000,
2020-09-07 00:47:53 +00:00
hostname: parsed.hostname
}, function(res) {
let output = ''
if (filePath) {
let file = fs.createWriteStream(filePath)
res.pipe(file)
} else {
res.on('data', function(chunk) {
output += chunk
})
}
res.on('end', function() {
if (res.statusCode >= 300 && res.statusCode < 400) {
2020-09-12 20:31:36 +00:00
if (newRedirects > 5) {
2020-09-07 00:47:53 +00:00
return reject(new Error(`Too many redirects (last one was ${res.headers.location})`))
}
2020-09-12 20:31:36 +00:00
if (!res.headers.location) {
return reject(new Error('Redirect returned no path in location header'))
}
if (res.headers.location.startsWith('http')) {
return resolve(request(res.headers.location, filePath, newRedirects, returnText))
} else {
return resolve(request(url.resolve(path, res.headers.location), filePath, newRedirects, returnText))
}
2020-09-07 00:47:53 +00:00
} else if (res.statusCode >= 400) {
2020-09-12 20:31:36 +00:00
return reject(new Error(`HTTP Error ${res.statusCode}: ${output}`))
2020-09-07 00:47:53 +00:00
}
resolve({
statusCode: res.statusCode,
status: res.statusCode,
statusMessage: res.statusMessage,
headers: res.headers,
body: output
})
})
req.on('error', reject)
2020-09-12 20:31:36 +00:00
req.on('timeout', function(err) {
reject(err)
})
2020-09-07 00:47:53 +00:00
})
req.end()
}).then(function(res) {
2020-09-12 20:31:36 +00:00
if (!filePath && !returnText) {
2020-09-07 00:47:53 +00:00
try {
res.body = JSON.parse(res.body)
} catch(e) {
throw new Error(res.body)
}
}
return res
})
}