From a4cda5e6b508557fde039fe2ac4e39dab82fa4f9 Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 22:34:10 +0800 Subject: [PATCH 1/7] split code --- postinstall.js | 50 +++++++++++++++++++++++++------------------------- 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/postinstall.js b/postinstall.js index fbbb644..ae4bb60 100644 --- a/postinstall.js +++ b/postinstall.js @@ -42,12 +42,35 @@ function retry(err) { if (err) { console.warn('ngrok - install failed, retrying'); return setTimeout(function() { - install(retry); + install(retry); }, 500); } process.exit(0); } +function extract(cb) { + console.log('ngrok - unpacking binary') + new Zip(localFile).extract({path: localPath}) + .once('error', error) + .once('extract', function() { + var suffix = os.platform() === 'win32' ? '.exe' : ''; + if (suffix === '.exe') + fs.writeFileSync(localPath + 'ngrok.cmd', 'ngrok.exe'); + fs.unlinkSync(localFile); + var target = localPath + 'ngrok' + suffix; + fs.chmodSync(target, 0755); + if (!fs.existsSync(target) || fs.statSync(target).size <= 0) + return error(new Error('corrupted file ' + target)); + console.log('ngrok - binary unpacked to ' + target); + cb(null); + }); + + function error(e) { + console.warn('ngrok - error unpacking binary', e); + cb(e); + } +} + function install(cb) { console.log('ngrok - downloading binary ' + cdnFile); request @@ -55,33 +78,10 @@ function install(cb) { .pipe(fs.createWriteStream(localFile)) .on('finish', function() { console.log('ngrok - binary downloaded to ' + localFile); - extract(); + extract(cb); }) .on('error', function(e) { console.warn('ngrok - error downloading binary', e); cb(e); }); - - function extract() { - console.log('ngrok - unpacking binary') - new Zip(localFile).extract({path: localPath}) - .once('error', error) - .once('extract', function() { - var suffix = os.platform() === 'win32' ? '.exe' : ''; - if (suffix === '.exe') - fs.writeFileSync(localPath + 'ngrok.cmd', 'ngrok.exe'); - fs.unlinkSync(localFile); - var target = localPath + 'ngrok' + suffix; - fs.chmodSync(target, 0755); - if (!fs.existsSync(target) || fs.statSync(target).size <= 0) - return error(new Error('corrupted file ' + target)); - console.log('ngrok - binary unpacked to ' + target); - cb(null); - }); - } - - function error(e) { - console.warn('ngrok - error unpacking binary', e); - cb(e); - } } \ No newline at end of file From d79dd38bab5b555a123474c25e53eea20c30a7d5 Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 22:55:10 +0800 Subject: [PATCH 2/7] Add show download progress --- postinstall.js | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/postinstall.js b/postinstall.js index ae4bb60..5d5fc3e 100644 --- a/postinstall.js +++ b/postinstall.js @@ -1,5 +1,6 @@ var os = require('os'); var fs = require('fs'); +var readline = require('readline'); var Zip = require('decompress-zip'); var request = require('request'); @@ -73,11 +74,36 @@ function extract(cb) { function install(cb) { console.log('ngrok - downloading binary ' + cdnFile); + var total = 0; + var downloaded = 0; + var shouldClearLine = false; + + var showProgress = function () { + if (shouldClearLine) { + readline.clearLine(process.stdout); + readline.cursorTo(process.stdout, 0); + } + + var progress = downloaded + (total ? ('/' + total) : ''); + process.stdout.write('ngrok - downloading progress: ' + progress); + shouldClearLine= true; + } + + var outputStream = fs.createWriteStream(localFile); + request .get(cdnFile) - .pipe(fs.createWriteStream(localFile)) - .on('finish', function() { - console.log('ngrok - binary downloaded to ' + localFile); + .on('response', function (res) { + total = res.headers['content-length']; + total > 0 && showProgress(); + }) + .on('data', function (data) { + downloaded += data.length; + showProgress(); + outputStream.write(data); + }) + .on('complete', function () { + console.log('\nngrok - binary downloaded to ' + localFile); extract(cb); }) .on('error', function(e) { From 371c0f120240179c3b23b4838bcad2e8a60339e9 Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 23:12:49 +0800 Subject: [PATCH 3/7] Reuse downloaded local file --- postinstall.js | 40 ++++++++++++++++++++++++---------------- 1 file changed, 24 insertions(+), 16 deletions(-) diff --git a/postinstall.js b/postinstall.js index 5d5fc3e..3a11923 100644 --- a/postinstall.js +++ b/postinstall.js @@ -29,24 +29,33 @@ if (!cdnFile) { var localPath = __dirname + '/bin/'; var localFile = localPath + 'ngrok.zip'; -var attempts = 0; -var maxAttempts = 3; -install(retry); +install(); -function retry(err) { - attempts++; - if (err && attempts === maxAttempts) { - console.error('ngrok - install failed', err); - return process.exit(1); +function install () { + if (fs.existsSync(localFile) && fs.statSync(localFile).size) { + extract(retry) + } else { + download(retry); } - if (err) { - console.warn('ngrok - install failed, retrying'); - return setTimeout(function() { - install(retry); - }, 500); + + var attempts = 0; + var maxAttempts = 3; + + function retry(err) { + attempts++; + if (err && attempts === maxAttempts) { + console.error('ngrok - install failed', err); + return process.exit(1); + } + if (err) { + console.warn('ngrok - install failed, retrying'); + return setTimeout(function() { + download(retry); + }, 500); + } + process.exit(0); } - process.exit(0); } function extract(cb) { @@ -57,7 +66,6 @@ function extract(cb) { var suffix = os.platform() === 'win32' ? '.exe' : ''; if (suffix === '.exe') fs.writeFileSync(localPath + 'ngrok.cmd', 'ngrok.exe'); - fs.unlinkSync(localFile); var target = localPath + 'ngrok' + suffix; fs.chmodSync(target, 0755); if (!fs.existsSync(target) || fs.statSync(target).size <= 0) @@ -72,7 +80,7 @@ function extract(cb) { } } -function install(cb) { +function download(cb) { console.log('ngrok - downloading binary ' + cdnFile); var total = 0; var downloaded = 0; From c17bbbed54629f086ba2071a7e116f006f76264b Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 23:34:37 +0800 Subject: [PATCH 4/7] try to download to home dir and bin dir as a fallback --- postinstall.js | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/postinstall.js b/postinstall.js index 3a11923..aab5212 100644 --- a/postinstall.js +++ b/postinstall.js @@ -1,5 +1,6 @@ var os = require('os'); var fs = require('fs'); +var path = require('path'); var readline = require('readline'); var Zip = require('decompress-zip'); var request = require('request'); @@ -27,8 +28,16 @@ if (!cdnFile) { process.exit(1); } -var localPath = __dirname + '/bin/'; -var localFile = localPath + 'ngrok.zip'; +var binPath = path.join(__dirname, 'bin'); +var localPath; +try { + localPath = path.join(os.homedir(), '.ngrok'); + fs.existsSync(localPath) || fs.mkdirSync(localPath); +} catch (err) { + localPath = binPath; +} + +var localFile = path.join(localPath, 'ngrok.zip'); install(); @@ -60,13 +69,13 @@ function install () { function extract(cb) { console.log('ngrok - unpacking binary') - new Zip(localFile).extract({path: localPath}) + new Zip(localFile).extract({path: binPath}) .once('error', error) .once('extract', function() { var suffix = os.platform() === 'win32' ? '.exe' : ''; if (suffix === '.exe') - fs.writeFileSync(localPath + 'ngrok.cmd', 'ngrok.exe'); - var target = localPath + 'ngrok' + suffix; + fs.writeFileSync(path.join(binPath, 'ngrok.cmd'), 'ngrok.exe'); + var target = path.join(binPath, 'ngrok' + suffix); fs.chmodSync(target, 0755); if (!fs.existsSync(target) || fs.statSync(target).size <= 0) return error(new Error('corrupted file ' + target)); From 3c4670b31a44f031abcbf06f30b68fea21b83e6e Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 23:45:20 +0800 Subject: [PATCH 5/7] download to temp dir and copy to local dir when success --- postinstall.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/postinstall.js b/postinstall.js index aab5212..a0c5007 100644 --- a/postinstall.js +++ b/postinstall.js @@ -105,8 +105,8 @@ function download(cb) { process.stdout.write('ngrok - downloading progress: ' + progress); shouldClearLine= true; } - - var outputStream = fs.createWriteStream(localFile); + var tempFile = path.join(os.tmpdir(), 'ngrok.zip'); + var outputStream = fs.createWriteStream(tempFile); request .get(cdnFile) @@ -121,7 +121,10 @@ function download(cb) { }) .on('complete', function () { console.log('\nngrok - binary downloaded to ' + localFile); - extract(cb); + var readStream = fs.createReadStream(tempFile); + readStream + .pipe(fs.createWriteStream(localFile)) + .on('finish', () => extract(cb)); }) .on('error', function(e) { console.warn('ngrok - error downloading binary', e); From cb4d0c4ec7029cbcfa7ce0facffb86403dd786c0 Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 23:51:56 +0800 Subject: [PATCH 6/7] check cdn file in `install` --- postinstall.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/postinstall.js b/postinstall.js index a0c5007..9efb04f 100644 --- a/postinstall.js +++ b/postinstall.js @@ -23,11 +23,6 @@ var cdnFiles = { var arch = process.env.NGROK_ARCH || (os.platform() + os.arch()); var cdnFile = cdnFiles[arch]; -if (!cdnFile) { - console.error('ngrok - platform ' + arch + ' is not supported.'); - process.exit(1); -} - var binPath = path.join(__dirname, 'bin'); var localPath; try { @@ -44,6 +39,9 @@ install(); function install () { if (fs.existsSync(localFile) && fs.statSync(localFile).size) { extract(retry) + } else if (!cdnFile) { + console.error('ngrok - platform ' + arch + ' is not supported.'); + process.exit(1); } else { download(retry); } From 06d1cc06bd98a87b7c682e4354512cc5c7a4cd51 Mon Sep 17 00:00:00 2001 From: gaoqiankun Date: Sat, 8 Jul 2017 23:57:41 +0800 Subject: [PATCH 7/7] use base64 encode of cdn file name as local file name --- postinstall.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/postinstall.js b/postinstall.js index 9efb04f..3f3547c 100644 --- a/postinstall.js +++ b/postinstall.js @@ -31,8 +31,8 @@ try { } catch (err) { localPath = binPath; } - -var localFile = path.join(localPath, 'ngrok.zip'); +var localFileName = new Buffer(cdnFile).toString('base64'); +var localFile = path.join(localPath, localFileName + '.zip'); install();