http: emit close as the last event in the client

Emit close event after all other events in the client, e.g.
error will be emitted before close.

PR-URL: https://github.com/nodejs/node/pull/15588
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
Reviewed-By: Luigi Pinca <luigipinca@gmail.com>
This commit is contained in:
Robert Nagy 2017-09-24 20:27:44 +02:00 committed by Matteo Collina
parent df5dc2da39
commit 5d99a9bf65
2 changed files with 31 additions and 1 deletions

View File

@ -346,7 +346,6 @@ function socketCloseListener() {
// NOTE: It's important to get parser here, because it could be freed by
// the `socketOnData`.
var parser = socket.parser;
req.emit('close');
if (req.res && req.res.readable) {
// Socket closed before we emitted 'end' below.
req.res.emit('aborted');
@ -362,6 +361,7 @@ function socketCloseListener() {
req.socket._hadError = true;
req.emit('error', createHangUpError());
}
req.emit('close');
// Too bad. That output wasn't getting written.
// This is pretty terrible that it doesn't raise an error.

View File

@ -0,0 +1,30 @@
'use strict';
const common = require('../common');
// This test ensures that the `'close'` event is emitted after the `'error'`
// event when a request is made and the socket is closed before we started to
// receive a response.
const assert = require('assert');
const http = require('http');
const server = http.createServer(common.mustNotCall());
server.listen(0, common.mustCall(() => {
const req = http.get({ port: server.address().port }, common.mustNotCall());
let errorEmitted = false;
req.on('error', (err) => {
errorEmitted = true;
assert.strictEqual(err.constructor, Error);
assert.strictEqual(err.message, 'socket hang up');
assert.strictEqual(err.code, 'ECONNRESET');
});
req.on('close', common.mustCall(() => {
assert.strictEqual(errorEmitted, true);
server.close();
}));
req.destroy();
}));