From 24515e41a324e4891c75be30e4068962cbe64d4f Mon Sep 17 00:00:00 2001 From: C-3PO Date: Fri, 5 Oct 2018 18:50:32 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Finish=20curl=20download=20implemen?= =?UTF-8?q?tation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/cdn/downloadWithCurl.ts | 38 +++++++++++++++++++++++++------------ src/cdn/downloadWrapper.ts | 15 +++++++++++---- 2 files changed, 37 insertions(+), 16 deletions(-) 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);