diff --git a/lib/http.js b/lib/http.js index 4c4234c..af199ad 100644 --- a/lib/http.js +++ b/lib/http.js @@ -943,6 +943,7 @@ Agent.prototype.request = function request(options, callback) { port: options.port, localAddress: options.localAddress }); + var self = this; endpoint.socket.on('error', function (error) { self._log.error('Socket error: ' + error.toString()); @@ -954,6 +955,10 @@ Agent.prototype.request = function request(options, callback) { request.emit('error', error); }); + endpoint.on('closed', function () { + delete self.endpoints[key]; + }); + this.endpoints[key] = endpoint; endpoint.pipe(endpoint.socket).pipe(endpoint); request._start(endpoint.createStream(), options); @@ -1011,6 +1016,9 @@ Agent.prototype.request = function request(options, callback) { self._log.info({ e: endpoint, server: options.host + ':' + options.port }, 'New outgoing HTTP/2 connection'); self.endpoints[key] = endpoint; + endpoint.on('closed', function () { + delete self.endpoints[key]; + }); self.emit(key, endpoint); } else { self.emit(key, undefined); diff --git a/lib/protocol/connection.js b/lib/protocol/connection.js index 2b86b7f..87f825f 100644 --- a/lib/protocol/connection.js +++ b/lib/protocol/connection.js @@ -574,6 +574,7 @@ Connection.prototype.close = function close(error) { }); this.push(null); this._closed = true; + this.emit('closed'); }; Connection.prototype._receiveGoaway = function _receiveGoaway(frame) { @@ -583,6 +584,7 @@ Connection.prototype._receiveGoaway = function _receiveGoaway(frame) { if (frame.error !== 'NO_ERROR') { this.emit('peerError', frame.error); } + this.emit('closed'); }; // Flow control diff --git a/lib/protocol/endpoint.js b/lib/protocol/endpoint.js index a218db0..e462e20 100644 --- a/lib/protocol/endpoint.js +++ b/lib/protocol/endpoint.js @@ -233,8 +233,8 @@ Endpoint.prototype._initializeErrorHandling = function _initializeErrorHandling( this._compressor.on('error', this._error.bind(this, 'compressor')); this._decompressor.on('error', this._error.bind(this, 'decompressor')); this._connection.on('error', this._error.bind(this, 'connection')); - this._connection.on('peerError', this.emit.bind(this, 'peerError')); + this._connection.on('closed', this.emit.bind(this, 'closed')); }; Endpoint.prototype._error = function _error(component, error) { diff --git a/test/connection.js b/test/connection.js index 2c68857..b330ddd 100644 --- a/test/connection.js +++ b/test/connection.js @@ -232,6 +232,12 @@ describe('connection.js', function() { c.close(); }); + it('should emit an event', function(done) { + c.on('closed', function () { + done(); + }); + c.close(); + }); }); }); }); diff --git a/test/endpoint.js b/test/endpoint.js index bdd2569..318dce2 100644 --- a/test/endpoint.js +++ b/test/endpoint.js @@ -26,6 +26,17 @@ describe('endpoint.js', function() { }); }); }); + describe('connection closing', function() { + describe('closing the endpoint connection', function() { + it('should emit an event', function(done) { + var c = new Endpoint(util.log.child({ role: 'client' }), 'CLIENT', settings); + c.on('closed', function () { + done(); + }); + c.close(); + }); + }); + }); describe('bunyan serializer', function() { describe('`e`', function() { var format = endpoint.serializers.e;