goldilocks.js/lib/tunnel-server-manager.js

62 lines
2.2 KiB
JavaScript

'use strict';
module.exports.create = function (deps, config) {
if (!config.tunnelServer || !Array.isArray(config.tunnelServer.servernames) || !config.tunnelServer.secret) {
return {
isAdminDomain: function () { return false; }
, isClientDomain: function () { return false; }
};
}
var tunnelOpts = Object.assign({}, config.tunnelServer);
// This function should not be called because connections to the admin domains
// should already be decrypted, and connections to non-client domains should never
// be given to us in the first place.
tunnelOpts.httpsTunnel = function (servername, conn) {
console.error('tunnel server received encrypted connection to', servername);
conn.end();
};
tunnelOpts.httpsInvalid = tunnelOpts.httpsTunnel;
// This function should not be called because ACME challenges should be handled
// before admin domain connections are given to us, and the only non-encrypted
// client connections that should be given to us are ACME challenges.
tunnelOpts.handleHttp = function (servername, conn) {
console.error('tunnel server received un-encrypted connection to', servername);
conn.end([
'HTTP/1.1 404 Not Found'
, 'Date: ' + (new Date()).toUTCString()
, 'Connection: close'
, 'Content-Type: text/html'
, 'Content-Length: 9'
, ''
, 'Not Found'
].join('\r\n'));
};
tunnelOpts.handleInsecureHttp = tunnelOpts.handleHttp;
var tunnelServer = require('stunneld').create(tunnelOpts);
var httpServer = require('http').createServer(function (req, res) {
// status code 426 = Upgrade Required
res.statusCode = 426;
res.setHeader('Content-Type', 'application/json');
res.end(JSON.stringify({error: {
message: 'Only websockets accepted for tunnel server'
}}));
});
var wsServer = new (require('ws').Server)({ server: httpServer });
wsServer.on('connection', tunnelServer.ws);
return {
isAdminDomain: function (domain) {
return config.tunnelServer.servernames.indexOf(domain) !== -1;
}
, handleAdminConn: function (conn) {
httpServer.emit('connection', conn);
}
, isClientDomain: tunnelServer.isClientDomain
, handleClientConn: tunnelServer.tcp
};
};