summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Halls <dahalls@gmail.com>2020-11-23 23:35:04 +0000
committerBeth Griggs <bgriggs@redhat.com>2020-12-15 20:15:27 +0000
commit71c3efe278e4110138bd8071f31b1cf60bd8501d (patch)
tree548a01f3d4f4529132f57e490773d6c31e5fcbe3
parent6cea3152fe5cb9d3238a47f422f43714a98e517b (diff)
downloadnode-new-71c3efe278e4110138bd8071f31b1cf60bd8501d.tar.gz
http2: check write not scheduled in scope destructor
Fixes: https://github.com/nodejs/node/issues/33156 PR-URL: https://github.com/nodejs/node/pull/36241 Backport-PR-URL: https://github.com/nodejs/node/pull/36372 Reviewed-By: Matteo Collina <matteo.collina@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
-rw-r--r--src/node_http2.cc3
-rw-r--r--test/parallel/test-http2-close-while-writing.js46
2 files changed, 48 insertions, 1 deletions
diff --git a/src/node_http2.cc b/src/node_http2.cc
index fc8385a39f..d3db319def 100644
--- a/src/node_http2.cc
+++ b/src/node_http2.cc
@@ -88,7 +88,8 @@ Http2Scope::Http2Scope(Http2Session* session) : session_(session) {
Http2Scope::~Http2Scope() {
if (!session_) return;
session_->set_in_scope(false);
- session_->MaybeScheduleWrite();
+ if (!session_->is_write_scheduled())
+ session_->MaybeScheduleWrite();
}
// The Http2Options object is used during the construction of Http2Session
diff --git a/test/parallel/test-http2-close-while-writing.js b/test/parallel/test-http2-close-while-writing.js
new file mode 100644
index 0000000000..d8537c31b0
--- /dev/null
+++ b/test/parallel/test-http2-close-while-writing.js
@@ -0,0 +1,46 @@
+'use strict';
+// https://github.com/nodejs/node/issues/33156
+const common = require('../common');
+const fixtures = require('../common/fixtures');
+
+if (!common.hasCrypto) {
+ common.skip('missing crypto');
+}
+
+const http2 = require('http2');
+
+const key = fixtures.readKey('agent8-key.pem', 'binary');
+const cert = fixtures.readKey('agent8-cert.pem', 'binary');
+const ca = fixtures.readKey('fake-startcom-root-cert.pem', 'binary');
+
+const server = http2.createSecureServer({
+ key,
+ cert,
+ maxSessionMemory: 1000
+});
+
+let client_stream;
+
+server.on('session', common.mustCall(function(session) {
+ session.on('stream', common.mustCall(function(stream) {
+ stream.resume();
+ stream.on('data', function() {
+ this.write(Buffer.alloc(1));
+ process.nextTick(() => client_stream.destroy());
+ });
+ }));
+}));
+
+server.listen(0, function() {
+ const client = http2.connect(`https://localhost:${server.address().port}`, {
+ ca,
+ maxSessionMemory: 1000
+ });
+ client_stream = client.request({ ':method': 'POST' });
+ client_stream.on('close', common.mustCall(() => {
+ client.close();
+ server.close();
+ }));
+ client_stream.resume();
+ client_stream.write(Buffer.alloc(64 * 1024));
+});