mirror of
https://github.com/nodejs/node.git
synced 2024-11-21 10:59:27 +00:00
93c4efeb25
A detailed analysis of the cause of this bug is in my linked comment on the corresponding issue. The primary fix is the new setImmediate call in Http2Stream#_destroy, which prevents a re-entrant call into Http2Session::SendPendingData when sending trailers after the Http2Session has been shut down, allowing the trailer data to be flushed properly before the socket is closed. As a result of this change, writes can be initiated later in the lifetime of the Http2Session. So, when a JSStreamSocket is used as the underlying socket reference for an Http2Session, it needs to be able to accept write calls after it is closed. In addition, now that outgoing data can be flushed differently after a session is closed, in two tests clients receive errors that they previously did not receive. I believe the new errors are more correct, so I changed the tests to match. Fixes: https://github.com/nodejs/node/issues/42713 Refs: https://github.com/nodejs/node/issues/42713#issuecomment-1756140062 PR-URL: https://github.com/nodejs/node/pull/50202 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
56 lines
1.5 KiB
JavaScript
56 lines
1.5 KiB
JavaScript
'use strict';
|
|
|
|
const common = require('../common');
|
|
if (!common.hasCrypto)
|
|
common.skip('missing crypto');
|
|
|
|
const assert = require('assert');
|
|
const { createServer, constants, connect } = require('http2');
|
|
|
|
const server = createServer();
|
|
|
|
server.on('stream', (stream, headers) => {
|
|
stream.respond(undefined, { waitForTrailers: true });
|
|
|
|
stream.on('data', common.mustNotCall());
|
|
|
|
stream.on('wantTrailers', common.mustCall(() => {
|
|
// Trigger a frame error by sending a trailer that is too large
|
|
stream.sendTrailers({ 'test-trailer': 'X'.repeat(64 * 1024) });
|
|
}));
|
|
|
|
stream.on('frameError', common.mustCall((frameType, errorCode) => {
|
|
assert.strictEqual(errorCode, constants.NGHTTP2_FRAME_SIZE_ERROR);
|
|
}));
|
|
|
|
stream.on('error', common.expectsError({
|
|
code: 'ERR_HTTP2_STREAM_ERROR',
|
|
}));
|
|
|
|
stream.on('close', common.mustCall());
|
|
|
|
stream.end();
|
|
});
|
|
|
|
server.listen(0, () => {
|
|
const clientSession = connect(`http://localhost:${server.address().port}`);
|
|
|
|
clientSession.on('frameError', common.mustNotCall());
|
|
clientSession.on('close', common.mustCall(() => {
|
|
server.close();
|
|
}));
|
|
|
|
const clientStream = clientSession.request();
|
|
|
|
clientStream.on('close', common.mustCall());
|
|
clientStream.on('error', common.expectsError({
|
|
code: 'ERR_HTTP2_STREAM_ERROR',
|
|
name: 'Error',
|
|
message: 'Stream closed with error code NGHTTP2_FRAME_SIZE_ERROR'
|
|
}));
|
|
// This event mustn't be called once the frame size error is from the server
|
|
clientStream.on('frameError', common.mustNotCall());
|
|
|
|
clientStream.end();
|
|
});
|