UNPKG

openhim-core

Version:

The OpenHIM core application that provides logging and routing of http requests

266 lines (238 loc) 7.24 kB
var Channel, Channels, Q, adaptSocketRequest, authorisation, config, datastore, http, logger, net, newKey, startListening, stopTCPServers, tcpServers, tls, tlsAuthentication; http = require('http'); net = require('net'); tls = require('tls'); config = require("./config/config"); config.tcpAdapter = config.get('tcpAdapter'); logger = require("winston"); Channels = require('./model/channels'); Channel = Channels.Channel; Q = require("q"); tlsAuthentication = require("./middleware/tlsAuthentication"); authorisation = require("./middleware/authorisation"); tcpServers = []; newKey = 0; datastore = {}; process.on('message', function(msg) { if (msg.type === 'start-tcp-channel') { logger.debug("Recieved message to start tcp channel: " + msg.channelID); return exports.startupTCPServer(msg.channelID, function() {}); } else if (msg.type === 'stop-tcp-channel') { logger.debug("Recieved message to stop tcp channel: " + msg.channelID); return exports.stopServerForChannel(msg.channelID, function() {}); } }); exports.popTransaction = function(key) { var res; res = datastore["" + key]; delete datastore["" + key]; return res; }; startListening = function(channel, tcpServer, host, port, callback) { tcpServer.listen(port, host, function() { tcpServers.push({ channelID: channel._id, server: tcpServer }); return callback(null); }); return tcpServer.on('error', function(err) { return logger.error(err + ' Host: ' + host + ' Port: ' + port); }); }; exports.notifyMasterToStartTCPServer = function(channelID, callback) { logger.debug("Sending message to master to start tcp channel: " + channelID); return process.send({ type: 'start-tcp-channel', channelID: channelID }); }; exports.startupTCPServer = function(channelID, callback) { var existingServer, handler, i, len; for (i = 0, len = tcpServers.length; i < len; i++) { existingServer = tcpServers[i]; if (existingServer.channelID.equals(channelID)) { return callback(null); } } handler = function(sock) { return Channel.findById(channelID, function(err, channel) { if (err) { return logger.error(err); } sock.on('data', function(data) { return adaptSocketRequest(channel, sock, "" + data); }); return sock.on('error', function(err) { return logger.error(err); }); }); }; return Channel.findById(channelID, function(err, channel) { var host, port, tcpServer; host = channel.tcpHost || '0.0.0.0'; port = channel.tcpPort; if (!port) { return callback("Channel " + channel.name + " (" + channel._id + "): TCP port not defined"); } if (channel.type === 'tls') { return tlsAuthentication.getServerOptions(true, function(err, options) { var tcpServer; if (err) { return callback(err); } tcpServer = tls.createServer(options, handler); return startListening(channel, tcpServer, host, port, function(err) { if (err) { return callback(err); } else { logger.info("Channel " + channel.name + " (" + channel._id + "): TLS server listening on port " + port); return callback(null); } }); }); } else if (channel.type === 'tcp') { tcpServer = net.createServer(handler); return startListening(channel, tcpServer, host, port, function(err) { if (err) { return callback(err); } else { logger.info("Channel " + channel.name + " (" + channel._id + "): TCP server listening on port " + port); return callback(null); } }); } else { return callback("Cannot handle " + channel.type + " channels"); } }); }; exports.startupServers = function(callback) { return Channel.find({ $or: [ { type: 'tcp' }, { type: 'tls' } ] }, function(err, channels) { var channel, fn, i, len, promises; if (err) { return callback(err); } promises = []; fn = function(channel) { var defer; if (Channels.isChannelEnabled(channel)) { defer = Q.defer(); exports.startupTCPServer(channel._id, function(err) { if (err) { return callback(err); } return defer.resolve(); }); return promises.push(defer.promise); } }; for (i = 0, len = channels.length; i < len; i++) { channel = channels[i]; fn(channel); } return (Q.all(promises)).then(function() { return callback(null); }); }); }; adaptSocketRequest = function(channel, sock, socketData) { var options, req; options = { hostname: config.tcpAdapter.httpReceiver.host, port: config.tcpAdapter.httpReceiver.httpPort, path: '/', method: 'POST' }; req = http.request(options, function(res) { var response; response = ''; res.on('data', function(data) { return response += data; }); return res.on('end', function() { if (sock.writable) { return sock.write(response); } }); }); req.on("error", function(err) { return logger.error(err); }); datastore["" + newKey] = {}; datastore["" + newKey].data = socketData; datastore["" + newKey].channel = channel; req.write("" + newKey); newKey++; if (newKey === Number.MAX_VALUE) { newKey = 0; } return req.end(); }; stopTCPServers = function(servers, callback) { var fn, i, len, promises, server; promises = []; fn = function(server) { var defer; defer = Q.defer(); server.server.close(function(err) { if (err) { logger.error("Could not close tcp server: " + err); return defer.reject(err); } else { logger.info("Channel " + server.channelID + ": Stopped TCP/TLS server"); return defer.resolve(); } }); return promises.push(defer.promise); }; for (i = 0, len = servers.length; i < len; i++) { server = servers[i]; fn(server); } return (Q.all(promises)).then(function() { return callback(); }); }; exports.stopServers = function(callback) { return stopTCPServers(tcpServers, function() { tcpServers = []; return callback(); }); }; exports.notifyMasterToStopTCPServer = function(channelID, callback) { logger.debug("Sending message to master to stop tcp channel: " + channelID); return process.send({ type: 'stop-tcp-channel', channelID: channelID }); }; exports.stopServerForChannel = function(channelID, callback) { var i, len, notStoppedTcpServers, server, serverDetails; server = null; notStoppedTcpServers = []; for (i = 0, len = tcpServers.length; i < len; i++) { serverDetails = tcpServers[i]; if (serverDetails.channelID.equals(channelID)) { server = serverDetails; } else { notStoppedTcpServers.push(serverDetails); } } if (!server) { return callback("Server for channel " + channelID + " not running"); } tcpServers = notStoppedTcpServers; return stopTCPServers([server], callback); }; if (process.env.NODE_ENV === "test") { exports.tcpServers = tcpServers; } //# sourceMappingURL=tcpAdapter.js.map