Skip to content

Instantly share code, notes, and snippets.

@cobysy
Created October 7, 2018 21:36
Show Gist options
  • Save cobysy/d2756bed099d7a8a1b9dd5d279701f17 to your computer and use it in GitHub Desktop.
Save cobysy/d2756bed099d7a8a1b9dd5d279701f17 to your computer and use it in GitHub Desktop.
serve with https
#!/usr/bin/env node
// You need self-signed certs at first
// $ openssl req -nodes -new -x509 -keyout server.key -out server.cert
// Native
const https = require('https');
const fs = require('fs');
const {promisify} = require('util');
const dns = require('dns');
const os = require('os');
// Packages
// $ yarn add boxen chalk serve-handler
const chalk = require('chalk');
const handler = require('serve-handler');
const boxen = require('boxen');
// Utilities
const lookup = promisify(dns.lookup);
const warning = (message) => chalk`{yellow WARNING:} ${message}`;
const info = (message) => chalk`{magenta INFO:} ${message}`;
const error = (message) => chalk`{red ERROR:} ${message}`;
const registerShutdown = (fn) => {
let run = false;
const wrapper = () => {
if (!run) {
run = true;
fn();
}
};
process.on('SIGINT', wrapper);
process.on('SIGTERM', wrapper);
process.on('exit', wrapper);
};
const startEndpoint = () => {
const server = https.createServer({
key: fs.readFileSync('./server.key'),
cert: fs.readFileSync('./server.cert')
}, (request, response) => handler(request, response));
const {isTTY} = process.stdout;
server.on('error', (err) => {
console.error(error(`Failed to serve: ${err.stack}`));
process.exit(1);
});
server.listen(443, async () => {
const details = server.address();
registerShutdown(() => server.close());
let localAddress = null;
let networkAddress = null;
const address = details.address === '::' ? 'localhost' : details.address;
localAddress = `https://${address}:${details.port}`;
try {
const {address: ip} = await lookup(os.hostname());
networkAddress = `https://${ip}:${details.port}`;
} catch (err) {
console.error(error(`DNS lookup failed: ${err.message}`));
}
if (isTTY && process.env.NODE_ENV !== 'production') {
let message = chalk.green('Serving!');
if (localAddress) {
const prefix = networkAddress ? '- ' : '';
const space = networkAddress ? ' ' : ' ';
message += `\n\n${chalk.bold(`${prefix}Local:`)}${space}${localAddress}`;
}
if (networkAddress) {
message += `\n${chalk.bold('- On Your Network:')} ${networkAddress}`;
}
console.log(boxen(message, {
padding: 1,
borderColor: 'green',
margin: 1
}));
} else {
const suffix = localAddress ? ` at ${localAddress}` : '';
console.log(info(`Accepting connections${suffix}`));
}
});
};
(async () => {
startEndpoint();
registerShutdown(() => {
console.log(`\n${info('Gracefully shutting down. Please wait...')}`);
process.on('SIGINT', () => {
console.log(`\n${warning('Force-closing all open sockets...')}`);
process.exit(0);
});
});
})();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment