diff --git a/lib/http.js b/lib/http.js index 4efc5fe6..648537bb 100644 --- a/lib/http.js +++ b/lib/http.js @@ -396,6 +396,36 @@ exports.IncomingRequest = IncomingRequest; exports.OutgoingResponse = OutgoingResponse; exports.ServerResponse = OutgoingResponse; // for API compatibility +// Forward events `event` on `source` to all listeners on `target`. +// +// Note: The calling context is `source`. +function forwardEvent(event, source, target) { + function forward() { + var listeners = target.listeners(event); + + var n = listeners.length; + + // Special case for `error` event with no listeners. + if (n === 0 && event === 'error') { + var args = [event]; + args.push.apply(args, arguments); + + target.emit.apply(target, args); + return; + } + + for (var i = 0; i < n; ++i) { + listeners[i].apply(source, arguments); + } + } + + source.on(event, forward); + + // A reference to the function is necessary to be able to stop + // forwarding. + return forward; +} + // Server class // ------------ @@ -430,6 +460,9 @@ function Server(options) { } }); this._server.on('request', this.emit.bind(this, 'request')); + + forwardEvent('error', this._server, this); + forwardEvent('listening', this._server, this); } // HTTP2 over plain TCP diff --git a/test/http.js b/test/http.js index d5c64c6f..96d43f16 100644 --- a/test/http.js +++ b/test/http.js @@ -38,6 +38,36 @@ describe('http.js', function() { }).to.throw(Error); }); }); + describe('method `listen()`', function () { + it('should emit `listening` event', function (done) { + var server = http2.createServer(serverOptions); + + server.on('listening', function () { + server.close(); + + done(); + }) + + server.listen(0); + }); + it('should emit `error` on failure', function (done) { + var server = http2.createServer(serverOptions); + + // This TCP server is used to explicitly take a port to make + // server.listen() fails. + var net = require('net').createServer(); + + server.on('error', function () { + net.close() + + done(); + }); + + net.listen(0, function () { + server.listen(this.address().port); + }); + }); + }); describe('property `timeout`', function() { it('should be a proxy for the backing HTTPS server\'s `timeout` property', function() { var server = new http2.Server(serverOptions);