diff --git a/src/cdn/downloadWithCurl.ts b/src/cdn/downloadWithCurl.ts index 12dabd3..3caec12 100644 --- a/src/cdn/downloadWithCurl.ts +++ b/src/cdn/downloadWithCurl.ts @@ -4,19 +4,33 @@ import * as childProcess from 'child_process'; * Downloads a file using a curl child process, to allow for speed-limiting and timeout if download is too slow. * Takes as input the host domain name, the path and the file size */ -export default function downloadWithCurl({ host, path, tempFileName, size, resolve, reject }: {host: string, path: string, tempFileName: string, size: number, resolve: (downloadedFile: string) => void, reject: () => void}): void { - const url = `http://${host}${(path.substr(0, 1) === '/' ? '' : '/')}${path}`; +export default function downloadWithCurl({ host, path, tempFileName }: {host: string, path: string, tempFileName: string}): Promise { + return new Promise((resolve, reject) => { + const url = `http://${host}${(path.substr(0, 1) === '/' ? '' : '/')}${path}`; - const parameters: string[] = [ - //... - '--limit-rate', '30m', //maximum speed of 30 MB/s = 240 MBit/s - '--speed-limit', String(100 * 1024 * 1024), //abort if less than 100 MB in 15 seconds - '--speed-time', '15', - '--output', tempFileName, - url, - ]; + const parameters: string[] = [ + //... + '--silent', + '--limit-rate', '30m', //maximum speed of 30 MB/s = 240 MBit/s + '--speed-limit', String(100 * 1024 * 1024), //abort if less than 100 MB in 15 seconds + '--speed-time', '15', + '--output', tempFileName, + url, + ]; - const spawnedProcess = childProcess.spawn('curl', parameters); + const spawnedProcess = childProcess.spawn('curl', parameters); - resolve(tempFileName); + spawnedProcess.stderr.setEncoding('utf8'); + spawnedProcess.stderr.on('data', (error) => { + reject(`Error in process:\n> curl ${parameters.join(' ')}\n${error}`); + }); + + spawnedProcess.on('exit', (code) => { + if (code === 0) { + resolve(tempFileName); + } else { + reject(`Error in process:\n> curl ${parameters.join(' ')}\nNon-zero exit code ${code}.`); + } + }); + }); } diff --git a/src/cdn/downloadWrapper.ts b/src/cdn/downloadWrapper.ts index 270b29b..14393e5 100644 --- a/src/cdn/downloadWrapper.ts +++ b/src/cdn/downloadWrapper.ts @@ -23,10 +23,17 @@ export default async function downloadWrapper({ host, path, size, useCurl = fals //Download either via curl or natively with Node if (useCurl) { - const downloadResult = await new Promise((resolve, reject) => { - downloadWithCurl({ host, path, tempFileName, size, resolve, reject }); - }) as string; - return downloadResult; + //Try up to three times + for (let i = 0; i < 3; i += 3) { + try { + const downloadResult = await downloadWithCurl({ host, path, tempFileName }); + return downloadResult; + } catch { + //ignore error and try again + } + } + //Download failed, throw error + throw new Error('Could not download with curl'); } else { const downloadResult = await new Promise((resolve, reject) => { downloadUrlContents(host, path, tempFileName, resolve, reject);