Files
whistle/lib/https/server-agent.js
T
2015-07-14 10:07:58 +08:00

115 lines
2.1 KiB
JavaScript

var tls = require('tls');
var Q = require('q');
var cert = require('./cert');
var MAX_SERVERS = 256;
var MAX_PORT = 60000;
var curPort = 50000;
var domain = require('domain');
function ServerAgent() {
this._cache = {};
this._serverCount = 0;
}
var proto = ServerAgent.prototype;
proto.createServer = function createServer(hostname, secureConnectionListener, callback) {
var self = this;
var cache = self._cache;
var promise = cache[hostname];
var defer;
if (!promise) {
defer = Q.defer();
cache[hostname] = promise = defer.promise;
}
promise.done(callback);
if (!defer) {
return ;
}
var certs = cert.getCert(hostname);
self.freeServer();
self._getServer({
key: certs[0],
cert: certs[1]
}, secureConnectionListener,
defer.resolve.bind(defer), hostname);
self._serverCount++;
return self;
};
proto._getServer = function getServer(options, secureConnectionListener, callback, hostname) {
var self = this;
var cache = self._cache;
if (curPort > MAX_PORT) {
curPort = MIN_PORT = 40000;
}
var d = domain.create();
function destroy() {
self._destroy(hostname);
d.dispose();
}
d.on('error', destroy)
.on('close', destroy);
d.run(function() {
var server = tls.createServer(options, secureConnectionListener);
server.on('error', function () {
self._getServer(options, secureConnectionListener, callback, hostname);
});
var port = curPort++;
server.listen(port, 'localhost', function() {
callback(port);
});
});
};
proto.freeServer = function() {
if (this._serverCount < MAX_SERVERS) {
return;
}
var cache = this._cache;
for (var i in cache) {
var server = cache[i];
if (!server.connections) {
delete cache[i];
server.close();
if (--this._serverCount < MAX_SERVERS) {
return;
}
}
}
};
proto._destroy = function _destroy(hostname) {
var cache = this._cache;
var server = cache[hostname];
if (server) {
delete cache[hostname];
server.close();
}
};
proto.destroy = function destroy() {
var cache = this._cache;
this._cache = {};
for (var i in cache) {
var server = cache[i];
delete cache[i];
server.close();
}
};
module.exports = ServerAgent;