mirror of
https://github.com/nodejs/node.git
synced 2026-10-14 10:26:26 -04:00
http2: fix FileHandle leak in respondWithFile
Ensure that the file handle is closed if header validation fails in respondWithFile. This prevents ERR_INVALID_STATE errors where a FileHandle object is closed during garbage collection. PR-URL: https://github.com/nodejs/node/pull/61707 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Tim Perry <pimterry@gmail.com>
This commit is contained in:
1 parent
286828be01
commit
f0be1c00da
2 files changed
+55
No files matched your search
@@ -2680,6 +2680,8 @@ function processRespondWithFD(self, fd, headers, offset = 0, length = -1,
|
||||
try {
|
||||
headersList = buildNgHeaderString(headers, assertValidPseudoHeaderResponse);
|
||||
} catch (err) {
|
||||
if (self.ownsFd)
|
||||
tryClose(fd);
|
||||
self.destroy(err);
|
||||
return;
|
||||
}
|
||||
@@ -2693,6 +2695,8 @@ function processRespondWithFD(self, fd, headers, offset = 0, length = -1,
|
||||
const ret = self[kHandle].respond(headersList, streamOptions);
|
||||
|
||||
if (ret < 0) {
|
||||
if (self.ownsFd)
|
||||
tryClose(fd);
|
||||
self.destroy(new NghttpError(ret));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,51 @@
|
||||
'use strict';
|
||||
const common = require('../common');
|
||||
if (!common.hasCrypto)
|
||||
common.skip('missing crypto');
|
||||
const fixtures = require('../common/fixtures');
|
||||
const assert = require('assert');
|
||||
const http2 = require('http2');
|
||||
const fs = require('fs');
|
||||
|
||||
const fname = fixtures.path('elipses.txt');
|
||||
|
||||
const server = http2.createServer();
|
||||
|
||||
server.on('stream', common.mustCall((stream) => {
|
||||
const originalClose = fs.close;
|
||||
let fdClosed = false;
|
||||
|
||||
fs.close = common.mustCall(function(fd, cb) {
|
||||
fdClosed = true;
|
||||
return originalClose.apply(this, arguments);
|
||||
});
|
||||
|
||||
const headers = {
|
||||
':method': 'GET',
|
||||
'content-type': 'text/plain'
|
||||
};
|
||||
|
||||
stream.respondWithFile(fname, headers);
|
||||
|
||||
stream.on('error', common.mustCall((err) => {
|
||||
assert.strictEqual(err.code, 'ERR_HTTP2_INVALID_PSEUDOHEADER');
|
||||
}));
|
||||
|
||||
stream.on('close', common.mustCall(() => {
|
||||
fs.close = originalClose;
|
||||
assert.strictEqual(fdClosed, true);
|
||||
}));
|
||||
}));
|
||||
|
||||
server.listen(0, common.mustCall(() => {
|
||||
const client = http2.connect(`http://localhost:${server.address().port}`);
|
||||
const req = client.request();
|
||||
|
||||
req.on('close', common.mustCall(() => {
|
||||
client.close();
|
||||
server.close();
|
||||
}));
|
||||
|
||||
req.on('error', common.mustCall());
|
||||
req.end();
|
||||
}));
|
||||
Reference in new issue
Block a user