http2: use 'close' event instead of 'streamClosed'
PR-URL: https://github.com/nodejs/node/pull/17328 Fixes: https://github.com/nodejs/node/issues/15303 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: Sebastiaan Deckers <sebdeckers83@gmail.com>
This commit is contained in:
parent
df33d8d0b3
commit
1b99542ea4
@ -633,7 +633,7 @@ All [`Http2Stream`][] instances are destroyed either when:
|
|||||||
When an `Http2Stream` instance is destroyed, an attempt will be made to send an
|
When an `Http2Stream` instance is destroyed, an attempt will be made to send an
|
||||||
`RST_STREAM` frame will be sent to the connected peer.
|
`RST_STREAM` frame will be sent to the connected peer.
|
||||||
|
|
||||||
Once the `Http2Stream` instance is destroyed, the `'streamClosed'` event will
|
When the `Http2Stream` instance is destroyed, the `'close'` event will
|
||||||
be emitted. Because `Http2Stream` is an instance of `stream.Duplex`, the
|
be emitted. Because `Http2Stream` is an instance of `stream.Duplex`, the
|
||||||
`'end'` event will also be emitted if the stream data is currently flowing.
|
`'end'` event will also be emitted if the stream data is currently flowing.
|
||||||
The `'error'` event may also be emitted if `http2stream.destroy()` was called
|
The `'error'` event may also be emitted if `http2stream.destroy()` was called
|
||||||
@ -655,6 +655,18 @@ abnormally aborted in mid-communication.
|
|||||||
*Note*: The `'aborted'` event will only be emitted if the `Http2Stream`
|
*Note*: The `'aborted'` event will only be emitted if the `Http2Stream`
|
||||||
writable side has not been ended.
|
writable side has not been ended.
|
||||||
|
|
||||||
|
#### Event: 'close'
|
||||||
|
<!-- YAML
|
||||||
|
added: v8.4.0
|
||||||
|
-->
|
||||||
|
|
||||||
|
The `'close'` event is emitted when the `Http2Stream` is destroyed. Once
|
||||||
|
this event is emitted, the `Http2Stream` instance is no longer usable.
|
||||||
|
|
||||||
|
The listener callback is passed a single argument specifying the HTTP/2 error
|
||||||
|
code specified when closing the stream. If the code is any value other than
|
||||||
|
`NGHTTP2_NO_ERROR` (`0`), an `'error'` event will also be emitted.
|
||||||
|
|
||||||
#### Event: 'error'
|
#### Event: 'error'
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v8.4.0
|
added: v8.4.0
|
||||||
@ -674,18 +686,6 @@ argument identifying the frame type, and an integer argument identifying the
|
|||||||
error code. The `Http2Stream` instance will be destroyed immediately after the
|
error code. The `Http2Stream` instance will be destroyed immediately after the
|
||||||
`'frameError'` event is emitted.
|
`'frameError'` event is emitted.
|
||||||
|
|
||||||
#### Event: 'streamClosed'
|
|
||||||
<!-- YAML
|
|
||||||
added: v8.4.0
|
|
||||||
-->
|
|
||||||
|
|
||||||
The `'streamClosed'` event is emitted when the `Http2Stream` is destroyed. Once
|
|
||||||
this event is emitted, the `Http2Stream` instance is no longer usable.
|
|
||||||
|
|
||||||
The listener callback is passed a single argument specifying the HTTP/2 error
|
|
||||||
code specified when closing the stream. If the code is any value other than
|
|
||||||
`NGHTTP2_NO_ERROR` (`0`), an `'error'` event will also be emitted.
|
|
||||||
|
|
||||||
#### Event: 'timeout'
|
#### Event: 'timeout'
|
||||||
<!-- YAML
|
<!-- YAML
|
||||||
added: v8.4.0
|
added: v8.4.0
|
||||||
|
@ -250,7 +250,7 @@ class Http2ServerRequest extends Readable {
|
|||||||
stream.on('close', onStreamClosedRequest);
|
stream.on('close', onStreamClosedRequest);
|
||||||
stream.on('aborted', onStreamAbortedRequest);
|
stream.on('aborted', onStreamAbortedRequest);
|
||||||
const onfinish = this[kFinish].bind(this);
|
const onfinish = this[kFinish].bind(this);
|
||||||
stream.on('streamClosed', onfinish);
|
stream.on('close', onfinish);
|
||||||
stream.on('finish', onfinish);
|
stream.on('finish', onfinish);
|
||||||
this.on('pause', onRequestPause);
|
this.on('pause', onRequestPause);
|
||||||
this.on('resume', onRequestResume);
|
this.on('resume', onRequestResume);
|
||||||
@ -383,7 +383,7 @@ class Http2ServerResponse extends Stream {
|
|||||||
stream.on('close', onStreamClosedResponse);
|
stream.on('close', onStreamClosedResponse);
|
||||||
stream.on('aborted', onStreamAbortedResponse);
|
stream.on('aborted', onStreamAbortedResponse);
|
||||||
const onfinish = this[kFinish].bind(this);
|
const onfinish = this[kFinish].bind(this);
|
||||||
stream.on('streamClosed', onfinish);
|
stream.on('close', onfinish);
|
||||||
stream.on('finish', onfinish);
|
stream.on('finish', onfinish);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -226,10 +226,8 @@ function onStreamTrailers() {
|
|||||||
return headersList;
|
return headersList;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called when the stream is closed. The streamClosed event is emitted on the
|
// Called when the stream is closed. The close event is emitted on the
|
||||||
// Http2Stream instance. Note that this event is distinctly different than the
|
// Http2Stream instance
|
||||||
// require('stream') interface 'close' event which deals with the state of the
|
|
||||||
// Readable and Writable sides of the Duplex.
|
|
||||||
function onStreamClose(code) {
|
function onStreamClose(code) {
|
||||||
const stream = this[kOwner];
|
const stream = this[kOwner];
|
||||||
stream[kUpdateTimer]();
|
stream[kUpdateTimer]();
|
||||||
@ -1485,7 +1483,7 @@ function continueStreamDestroy(err, callback) {
|
|||||||
abort(this);
|
abort(this);
|
||||||
this.push(null); // Close the readable side
|
this.push(null); // Close the readable side
|
||||||
this.end(); // Close the writable side
|
this.end(); // Close the writable side
|
||||||
process.nextTick(emit, this, 'streamClosed', code);
|
process.nextTick(emit, this, 'close', code);
|
||||||
}
|
}
|
||||||
|
|
||||||
function finishStreamDestroy() {
|
function finishStreamDestroy() {
|
||||||
|
@ -13,7 +13,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
|
|
||||||
const req = client.request();
|
const req = client.request();
|
||||||
req.on('streamClosed', common.mustCall());
|
req.on('close', common.mustCall());
|
||||||
|
|
||||||
client.on('error', common.expectsError({
|
client.on('error', common.expectsError({
|
||||||
code: 'ERR_HTTP2_ERROR',
|
code: 'ERR_HTTP2_ERROR',
|
||||||
|
@ -27,7 +27,7 @@ server.on('listening', common.mustCall(() => {
|
|||||||
// second call doesn't do anything
|
// second call doesn't do anything
|
||||||
assert.doesNotThrow(() => req.rstStream(8));
|
assert.doesNotThrow(() => req.rstStream(8));
|
||||||
|
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(req.destroyed, true);
|
assert.strictEqual(req.destroyed, true);
|
||||||
assert.strictEqual(code, 0);
|
assert.strictEqual(code, 0);
|
||||||
server.close();
|
server.close();
|
||||||
|
@ -41,7 +41,7 @@ server.on('listening', common.mustCall(() => {
|
|||||||
})(err);
|
})(err);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(req.rstCode, NGHTTP2_INTERNAL_ERROR);
|
assert.strictEqual(req.rstCode, NGHTTP2_INTERNAL_ERROR);
|
||||||
assert.strictEqual(code, NGHTTP2_INTERNAL_ERROR);
|
assert.strictEqual(code, NGHTTP2_INTERNAL_ERROR);
|
||||||
server.close();
|
server.close();
|
||||||
|
@ -30,7 +30,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
type: Error,
|
type: Error,
|
||||||
message: 'Stream closed with error code 1'
|
message: 'Stream closed with error code 1'
|
||||||
}));
|
}));
|
||||||
req.on('streamClosed', common.mustCall(maybeClose));
|
req.on('close', common.mustCall(maybeClose));
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 0; i <= count; i += 1)
|
for (let i = 0; i <= count; i += 1)
|
||||||
|
@ -183,10 +183,10 @@ const {
|
|||||||
|
|
||||||
|
|
||||||
{
|
{
|
||||||
// Should be able to call .end with cb from stream 'streamClosed'
|
// Should be able to call .end with cb from stream 'close'
|
||||||
const server = createServer(mustCall((request, response) => {
|
const server = createServer(mustCall((request, response) => {
|
||||||
response.writeHead(HTTP_STATUS_OK, { foo: 'bar' });
|
response.writeHead(HTTP_STATUS_OK, { foo: 'bar' });
|
||||||
response.stream.on('streamClosed', mustCall(() => {
|
response.stream.on('close', mustCall(() => {
|
||||||
response.end(mustCall());
|
response.end(mustCall());
|
||||||
}));
|
}));
|
||||||
}));
|
}));
|
||||||
|
@ -63,8 +63,8 @@ server.on('request', common.mustCall(function(request, response) {
|
|||||||
assert.strictEqual(request.socket.connecting, false);
|
assert.strictEqual(request.socket.connecting, false);
|
||||||
|
|
||||||
// socket events are bound and emitted on Http2Stream
|
// socket events are bound and emitted on Http2Stream
|
||||||
request.socket.on('streamClosed', common.mustCall());
|
request.socket.on('close', common.mustCall());
|
||||||
request.socket.once('streamClosed', common.mustCall());
|
request.socket.once('close', common.mustCall());
|
||||||
request.socket.on('testEvent', common.mustCall());
|
request.socket.on('testEvent', common.mustCall());
|
||||||
request.socket.emit('testEvent');
|
request.socket.emit('testEvent');
|
||||||
}));
|
}));
|
||||||
|
@ -42,7 +42,7 @@ server.on('stream', common.mustCall((stream, headers, flags, rawHeaders) => {
|
|||||||
server.listen(0, common.mustCall(() => {
|
server.listen(0, common.mustCall(() => {
|
||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
const req = client.request(src);
|
const req = client.request(src);
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
server.close();
|
server.close();
|
||||||
client.destroy();
|
client.destroy();
|
||||||
}));
|
}));
|
||||||
|
@ -54,7 +54,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
const req = client.request(src);
|
const req = client.request(src);
|
||||||
req.on('response', common.mustCall(checkHeaders));
|
req.on('response', common.mustCall(checkHeaders));
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
server.close();
|
server.close();
|
||||||
client.destroy();
|
client.destroy();
|
||||||
}));
|
}));
|
||||||
|
@ -34,7 +34,7 @@ server.on('stream', common.mustCall((stream) => {
|
|||||||
pushedStream.respond({ ':status': 200 });
|
pushedStream.respond({ ':status': 200 });
|
||||||
pushedStream.on('aborted', common.mustCall());
|
pushedStream.on('aborted', common.mustCall());
|
||||||
pushedStream.on('error', common.mustNotCall());
|
pushedStream.on('error', common.mustNotCall());
|
||||||
pushedStream.on('streamClosed',
|
pushedStream.on('close',
|
||||||
common.mustCall((code) => assert.strictEqual(code, 8)));
|
common.mustCall((code) => assert.strictEqual(code, 8)));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@ -67,12 +67,12 @@ server.on('listening', common.mustCall(() => {
|
|||||||
client.on('stream', common.mustCall((stream) => {
|
client.on('stream', common.mustCall((stream) => {
|
||||||
stream.resume();
|
stream.resume();
|
||||||
stream.on('end', common.mustCall());
|
stream.on('end', common.mustCall());
|
||||||
stream.on('streamClosed', common.mustCall(maybeClose));
|
stream.on('close', common.mustCall(maybeClose));
|
||||||
}));
|
}));
|
||||||
|
|
||||||
req.on('response', common.mustCall());
|
req.on('response', common.mustCall());
|
||||||
|
|
||||||
req.resume();
|
req.resume();
|
||||||
req.on('end', common.mustCall());
|
req.on('end', common.mustCall());
|
||||||
req.on('streamClosed', common.mustCall(maybeClose));
|
req.on('close', common.mustCall(maybeClose));
|
||||||
}));
|
}));
|
||||||
|
@ -117,7 +117,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
const req = client.request();
|
const req = client.request();
|
||||||
|
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
@ -144,7 +144,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
const req = client.request();
|
const req = client.request();
|
||||||
|
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
@ -71,7 +71,7 @@ server.listen(0, () => {
|
|||||||
req.on('end', common.mustCall(() => {
|
req.on('end', common.mustCall(() => {
|
||||||
assert.strictEqual(check, data.toString('utf8', 8, 11));
|
assert.strictEqual(check, data.toString('utf8', 8, 11));
|
||||||
}));
|
}));
|
||||||
req.on('streamClosed', common.mustCall(maybeClose));
|
req.on('close', common.mustCall(maybeClose));
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ server.listen(0, () => {
|
|||||||
req.on('end', common.mustCall(() => {
|
req.on('end', common.mustCall(() => {
|
||||||
assert.strictEqual(check, data.toString('utf8', 8, 28));
|
assert.strictEqual(check, data.toString('utf8', 8, 28));
|
||||||
}));
|
}));
|
||||||
req.on('streamClosed', common.mustCall(maybeClose));
|
req.on('close', common.mustCall(maybeClose));
|
||||||
req.end();
|
req.end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,7 +13,7 @@ const server = http2.createServer();
|
|||||||
const status = [204, 205, 304];
|
const status = [204, 205, 304];
|
||||||
|
|
||||||
server.on('stream', common.mustCall((stream) => {
|
server.on('stream', common.mustCall((stream) => {
|
||||||
stream.on('streamClosed', common.mustCall(() => {
|
stream.on('close', common.mustCall(() => {
|
||||||
assert.strictEqual(stream.destroyed, true);
|
assert.strictEqual(stream.destroyed, true);
|
||||||
}));
|
}));
|
||||||
stream.respond({ ':status': status.shift() });
|
stream.respond({ ':status': status.shift() });
|
||||||
|
@ -67,7 +67,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
}));
|
}));
|
||||||
req.resume();
|
req.resume();
|
||||||
req.on('end', common.mustCall());
|
req.on('end', common.mustCall());
|
||||||
req.on('streamClosed', common.mustCall(maybeClose));
|
req.on('close', common.mustCall(maybeClose));
|
||||||
}
|
}
|
||||||
|
|
||||||
doTest(str, 'location', str);
|
doTest(str, 'location', str);
|
||||||
|
@ -35,7 +35,7 @@ server.on('listening', common.mustCall(() => {
|
|||||||
|
|
||||||
req.on('headers', common.mustNotCall());
|
req.on('headers', common.mustNotCall());
|
||||||
|
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(h2.constants.NGHTTP2_NO_ERROR, code);
|
assert.strictEqual(h2.constants.NGHTTP2_NO_ERROR, code);
|
||||||
server.close();
|
server.close();
|
||||||
client.destroy();
|
client.destroy();
|
||||||
|
@ -43,7 +43,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
':method': 'POST',
|
':method': 'POST',
|
||||||
rstmethod: test[0]
|
rstmethod: test[0]
|
||||||
});
|
});
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(code, test[1]);
|
assert.strictEqual(code, test[1]);
|
||||||
countdown.dec();
|
countdown.dec();
|
||||||
}));
|
}));
|
||||||
|
@ -49,7 +49,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const req = client.request();
|
const req = client.request();
|
||||||
req.resume();
|
req.resume();
|
||||||
req.on('end', common.mustCall());
|
req.on('end', common.mustCall());
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
@ -21,7 +21,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||||
const req = client.request();
|
const req = client.request();
|
||||||
req.resume();
|
req.resume();
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
@ -11,7 +11,7 @@ let req;
|
|||||||
const server = http2.createServer();
|
const server = http2.createServer();
|
||||||
server.on('stream', common.mustCall((stream) => {
|
server.on('stream', common.mustCall((stream) => {
|
||||||
stream.on('error', common.mustCall(() => {
|
stream.on('error', common.mustCall(() => {
|
||||||
stream.on('streamClosed', common.mustCall((code) => {
|
stream.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(code, 2);
|
assert.strictEqual(code, 2);
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
|
@ -22,7 +22,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
type: Error,
|
type: Error,
|
||||||
message: 'Stream closed with error code 11'
|
message: 'Stream closed with error code 11'
|
||||||
}));
|
}));
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(code, NGHTTP2_ENHANCE_YOUR_CALM);
|
assert.strictEqual(code, NGHTTP2_ENHANCE_YOUR_CALM);
|
||||||
server.close();
|
server.close();
|
||||||
client.destroy();
|
client.destroy();
|
||||||
|
@ -25,7 +25,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
type: Error,
|
type: Error,
|
||||||
message: 'Stream closed with error code 11'
|
message: 'Stream closed with error code 11'
|
||||||
}));
|
}));
|
||||||
req.on('streamClosed', common.mustCall((code) => {
|
req.on('close', common.mustCall((code) => {
|
||||||
assert.strictEqual(code, NGHTTP2_ENHANCE_YOUR_CALM);
|
assert.strictEqual(code, NGHTTP2_ENHANCE_YOUR_CALM);
|
||||||
server.close();
|
server.close();
|
||||||
client.destroy();
|
client.destroy();
|
||||||
|
@ -30,7 +30,7 @@ server.listen(0, common.mustCall(() => {
|
|||||||
req.setEncoding('utf8');
|
req.setEncoding('utf8');
|
||||||
req.on('data', (chunk) => actual += chunk);
|
req.on('data', (chunk) => actual += chunk);
|
||||||
req.on('end', common.mustCall(() => assert.strictEqual(actual, 'abcxyz')));
|
req.on('end', common.mustCall(() => assert.strictEqual(actual, 'abcxyz')));
|
||||||
req.on('streamClosed', common.mustCall(() => {
|
req.on('close', common.mustCall(() => {
|
||||||
client.destroy();
|
client.destroy();
|
||||||
server.close();
|
server.close();
|
||||||
}));
|
}));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user