nodejs/test/parallel/test-http2-session-graceful-close.js
Kushagra Pandey 2acc8bc6a9
http2: fix graceful session close
Fix issue where session.close() prematurely destroys the session
when response.end() was called with an empty payload while active
http2 streams still existed. This change ensures that sessions are
closed gracefully only after all http2 streams complete and clients
properly receive the GOAWAY frame as per the HTTP/2 spec.

Refs: https://nodejs.org/api/http2.html\#http2sessionclosecallback
PR-URL: https://github.com/nodejs/node/pull/57808
Fixes: https://github.com/nodejs/node/issues/57809
Refs: https://nodejs.org/api/http2.html%5C#http2sessionclosecallback
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Tim Perry <pimterry@gmail.com>
Reviewed-By: James M Snell <jasnell@gmail.com>
2025-04-19 16:36:03 +00:00

49 lines
1.2 KiB
JavaScript

'use strict';
const common = require('../common');
if (!common.hasCrypto)
common.skip('missing crypto');
const assert = require('assert');
const h2 = require('http2');
const server = h2.createServer();
let session;
server.on('session', common.mustCall(function(s) {
session = s;
session.on('close', common.mustCall(function() {
server.close();
}));
}));
server.listen(0, common.mustCall(function() {
const port = server.address().port;
const url = `http://localhost:${port}`;
const client = h2.connect(url, common.mustCall(function() {
const headers = {
':path': '/',
':method': 'GET',
':scheme': 'http',
':authority': `localhost:${port}`
};
const request = client.request(headers);
request.on('response', common.mustCall(function(headers) {
assert.strictEqual(headers[':status'], 200);
}, 1));
request.on('end', common.mustCall(function() {
client.close();
}));
request.end();
request.resume();
}));
client.on('goaway', common.mustCallAtLeast(1));
}));
server.once('request', common.mustCall(function(request, response) {
response.on('finish', common.mustCall(function() {
session.close();
}));
response.end();
}));