diff --git a/lib/internal/http2/compat.js b/lib/internal/http2/compat.js index 2437009486668c..a02d3b0c5844fa 100644 --- a/lib/internal/http2/compat.js +++ b/lib/internal/http2/compat.js @@ -706,7 +706,7 @@ class Http2ServerResponse extends Stream { writeHead(statusCode, statusMessage, headers) { const state = this[kState]; - if (state.closed || this.stream.destroyed) + if (state.closed || this.stream.destroyed || this.stream.closed) return this; if (this[kStream].headersSent) throw new ERR_HTTP2_HEADERS_SENT(); diff --git a/test/parallel/test-http2-compat-write-head-after-close.js b/test/parallel/test-http2-compat-write-head-after-close.js new file mode 100644 index 00000000000000..541973f5dbc5c6 --- /dev/null +++ b/test/parallel/test-http2-compat-write-head-after-close.js @@ -0,0 +1,23 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) { common.skip('missing crypto'); }; +const h2 = require('http2'); + +const server = h2.createServer((req, res) => { + const stream = req.stream; + stream.close(); + res.writeHead(200, { 'content-type': 'text/plain' }); +}); + +server.listen(0, common.mustCall(() => { + const port = server.address().port; + const client = h2.connect(`http://localhost:${port}`); + const req = client.request({ ':path': '/' }); + req.on('response', common.mustNotCall('head after close should not be sent')); + req.on('end', common.mustCall(() => { + client.close(); + server.close(); + })); + req.end(); +}));