phorge/support/aphlict/server/aphlict_server.js
Joshua Spence 2b12f61602 Don't exit from the Aphlict Server prematurely
Summary: By calling `process.exit(1)` we are forcing the Node.js process to exit prematurely. Specifically, the process is terminated before the error is written to the log file. This can be verified by inspecting the value of `debug._logs[0]._writableState.writing` immediately before the process is terminated.

Test Plan: Ran `./bin/aphlict debug` without the `ws` module being installed. Verified that `<<< UNCAUGHT EXCEPTION! >>>` was echoed to the console as well as the log file. Also verified that the exit status was non-zero.

Reviewers: #blessed_reviewers, epriestley

Reviewed By: #blessed_reviewers, epriestley

Subscribers: Korvin, epriestley

Differential Revision: https://secure.phabricator.com/D11426
2015-01-20 06:36:51 +11:00

124 lines
3.1 KiB
JavaScript

var JX = require('./lib/javelin').JX;
var http = require('http');
var https = require('https');
var util = require('util');
var fs = require('fs');
JX.require('lib/AphlictListenerList', __dirname);
JX.require('lib/AphlictLog', __dirname);
function parse_command_line_arguments(argv) {
var config = {
'client-port': 22280,
'admin-port': 22281,
'client-host': '0.0.0.0',
'admin-host': '127.0.0.1',
log: '/var/log/aphlict.log',
'ssl-key': null,
'ssl-cert': null,
test: false
};
for (var ii = 2; ii < argv.length; ii++) {
var arg = argv[ii];
var matches = arg.match(/^--([^=]+)=(.*)$/);
if (!matches) {
throw new Error("Unknown argument '" + arg + "'!");
}
if (!(matches[1] in config)) {
throw new Error("Unknown argument '" + matches[1] + "'!");
}
config[matches[1]] = matches[2];
}
config['client-port'] = parseInt(config['client-port'], 10);
config['admin-port'] = parseInt(config['admin-port'], 10);
return config;
}
var debug = new JX.AphlictLog()
.addConsole(console);
var config = parse_command_line_arguments(process.argv);
process.on('uncaughtException', function(err) {
var context = null;
if (err.code == 'EACCES' && err.path == config.log) {
context = util.format(
'Unable to open logfile ("%s"). Check that permissions are set ' +
'correctly.',
err.path);
}
var message = [
'\n<<< UNCAUGHT EXCEPTION! >>>',
];
if (context) {
message.push(context);
}
message.push(err.stack);
debug.log(message.join('\n\n'));
});
try {
require('ws');
} catch (ex) {
throw new Error(
'You need to install the Node.js "ws" module for websocket support. ' +
'See "Notifications User Guide: Setup and Configuration" in the ' +
'documentation for instructions. ' + ex.toString());
}
var ssl_config = {
enabled: (config['ssl-key'] || config['ssl-cert'])
};
// Load the SSL certificates (if any were provided) now, so that runs with
// `--test` will see any errors.
if (ssl_config.enabled) {
ssl_config.key = fs.readFileSync(config['ssl-key']);
ssl_config.cert = fs.readFileSync(config['ssl-cert']);
}
// Add the logfile so we'll fail if we can't write to it.
if (config.log) {
debug.addLog(config.log);
}
// If we're just doing a configuration test, exit here before starting any
// servers.
if (config.test) {
debug.log('Configuration test OK.');
process.exit(0);
}
JX.require('lib/AphlictAdminServer', __dirname);
JX.require('lib/AphlictClientServer', __dirname);
var server;
if (ssl_config.enabled) {
server = https.createServer({
key: ssl_config.key,
cert: ssl_config.cert
}, function(req, res) {
res.writeHead(501);
res.end('HTTP/501 Use Websockets\n');
});
} else {
server = http.createServer(function() {});
}
var client_server = new JX.AphlictClientServer(server);
var admin_server = new JX.AphlictAdminServer();
client_server.setLogger(debug);
admin_server.setLogger(debug);
admin_server.setClientServer(client_server);
client_server.listen(config['client-port'], config['client-host']);
admin_server.listen(config['admin-port'], config['admin-host']);
debug.log('Started Server (PID %d)', process.pid);