From 499171bbd8146224c72f98277b3c8ab20a69069f Mon Sep 17 00:00:00 2001 From: ofirbarak Date: Thu, 3 Feb 2022 18:25:38 +0200 Subject: [PATCH] http2: fix no response event on continue request When sending a continue request, server response with null, it does not fires the response event type Fixes: https://github.com/nodejs/node/issues/38258 PR-URL: https://github.com/nodejs/node/pull/41739 Refs: https://github.com/nodejs/node/pull/38561 Reviewed-By: Benjamin Gruenbaum Reviewed-By: Matteo Collina Reviewed-By: James M Snell --- lib/internal/http2/core.js | 3 +- .../test-http2-compat-expect-continue.js | 107 ++++++++++++------ 2 files changed, 75 insertions(+), 35 deletions(-) diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index c486676f72a2bd..0960bcc5e63e40 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -394,8 +394,7 @@ function onSessionHeaders(handle, id, cat, flags, headers, sensitiveHeaders) { } } else if (cat === NGHTTP2_HCAT_PUSH_RESPONSE) { event = 'push'; - // cat === NGHTTP2_HCAT_HEADERS: - } else if (!endOfStream && status !== undefined && status >= 200) { + } else if (status !== undefined && status >= 200) { event = 'response'; } else { event = endOfStream ? 'trailers' : 'headers'; diff --git a/test/parallel/test-http2-compat-expect-continue.js b/test/parallel/test-http2-compat-expect-continue.js index cb90e51f3bc9d7..d0decb1472a9e1 100644 --- a/test/parallel/test-http2-compat-expect-continue.js +++ b/test/parallel/test-http2-compat-expect-continue.js @@ -6,49 +6,90 @@ if (!common.hasCrypto) const assert = require('assert'); const http2 = require('http2'); -const testResBody = 'other stuff!\n'; +{ + const testResBody = 'other stuff!\n'; -// Checks the full 100-continue flow from client sending 'expect: 100-continue' -// through server receiving it, sending back :status 100, writing the rest of -// the request to finally the client receiving to. + // Checks the full 100-continue flow from client sending 'expect: 100-continue' + // through server receiving it, sending back :status 100, writing the rest of + // the request to finally the client receiving to. -const server = http2.createServer(); + const server = http2.createServer(); -let sentResponse = false; + let sentResponse = false; -server.on('request', common.mustCall((req, res) => { - res.end(testResBody); - sentResponse = true; -})); + server.on('request', common.mustCall((req, res) => { + res.end(testResBody); + sentResponse = true; + })); + + server.listen(0); + + server.on('listening', common.mustCall(() => { + let body = ''; -server.listen(0); + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request({ + ':method': 'POST', + 'expect': '100-continue' + }); -server.on('listening', common.mustCall(() => { - let body = ''; + let gotContinue = false; + req.on('continue', common.mustCall(() => { + gotContinue = true; + })); - const client = http2.connect(`http://localhost:${server.address().port}`); - const req = client.request({ - ':method': 'POST', - 'expect': '100-continue' - }); + req.on('response', common.mustCall((headers) => { + assert.strictEqual(gotContinue, true); + assert.strictEqual(sentResponse, true); + assert.strictEqual(headers[':status'], 200); + req.end(); + })); - let gotContinue = false; - req.on('continue', common.mustCall(() => { - gotContinue = true; + req.setEncoding('utf8'); + req.on('data', common.mustCall((chunk) => { body += chunk; })); + req.on('end', common.mustCall(() => { + assert.strictEqual(body, testResBody); + client.close(); + server.close(); + })); })); +} + +{ + // Checks the full 100-continue flow from client sending 'expect: 100-continue' + // through server receiving it and ending the request. + + const server = http2.createServer(); - req.on('response', common.mustCall((headers) => { - assert.strictEqual(gotContinue, true); - assert.strictEqual(sentResponse, true); - assert.strictEqual(headers[':status'], 200); - req.end(); + server.on('request', common.mustCall((req, res) => { + res.end(); })); - req.setEncoding('utf8'); - req.on('data', common.mustCall((chunk) => { body += chunk; })); - req.on('end', common.mustCall(() => { - assert.strictEqual(body, testResBody); - client.close(); - server.close(); + server.listen(0); + + server.on('listening', common.mustCall(() => { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request({ + ':path': '/', + 'expect': '100-continue' + }); + + let gotContinue = false; + req.on('continue', common.mustCall(() => { + gotContinue = true; + })); + + let gotResponse = false; + req.on('response', common.mustCall(() => { + gotResponse = true; + })); + + req.setEncoding('utf8'); + req.on('end', common.mustCall(() => { + assert.strictEqual(gotContinue, true); + assert.strictEqual(gotResponse, true); + client.close(); + server.close(); + })); })); -})); +}