Test localtunnel and retry if it failed

This commit is contained in:
Brandon Keepers 2017-06-11 01:06:53 -05:00
parent 76223a5029
commit 98887fb148
No known key found for this signature in database
GPG Key ID: F9533396D5FACBF6
2 changed files with 42 additions and 16 deletions

View File

@ -36,9 +36,13 @@ if (!program.privateKey) {
}
if (program.tunnel) {
const setupTunnel = require('../lib/tunnel');
try {
setupTunnel(program.tunnel, program.port);
const setupTunnel = require('../lib/tunnel');
setupTunnel(program.tunnel, program.port).then(tunnel => {
console.log('Listening on ' + tunnel.url);
}).catch(err => {
console.warn('Could not open tunnel: ', err.message);
});
} catch (err) {
console.warn('Run `npm install --save-dev localtunnel` to enable localtunnel.');
}

View File

@ -1,22 +1,44 @@
// eslint-disable-next-line import/no-extraneous-dependencies, import/no-unresolved
const localtunnel = require('localtunnel');
const https = require('https');
module.exports = function (subdomain, port) {
if(subdomain !== 'string') {
module.exports = function setupTunnel(subdomain, port, retries = 0) {
if(typeof subdomain !== 'string') {
subdomain = require('os').userInfo().username;
}
const tunnel = localtunnel(port, {subdomain}, (err, tunnel) => {
if (err) {
console.warn('Could not open tunnel: ', err.message);
} else {
console.log('Listening on ' + tunnel.url);
}
return new Promise((resolve, reject) => {
localtunnel(port, {subdomain}, (err, tunnel) => {
if (err) {
reject(err);
} else {
testTunnel(subdomain).then(() => resolve(tunnel)).catch(err => {
if(retries < 3) {
console.warn(`Failed to connect to localtunnel.me. Trying again (tries: ${retries + 1})`);
resolve(setupTunnel(subdomain, port, retries + 1));
} else {
reject('Failed to connect to localtunnel.me. Giving up.');
}
});
}
});
});
}
// When a tunnel is closed and then immediately reopened (e.g. restarting the
// server to reload changes), then localtunnel.me may connect but not pass
// requests through. This test that the tunnel returns 200 for /ping.
function testTunnel(subdomain) {
const options = {
host: `${subdomain}.localtunnel.me`,
port: 443,
path: '/ping',
method: 'GET'
};
return new Promise((resolve, reject) => {
https.request(options, function(res) {
res.statusCode == 200 ? resolve() : reject();
}).end();
});
tunnel.on('close', () => {
console.warn('Local tunnel closed');
});
return tunnel;
}