diff options
author | James M Snell <jasnell@gmail.com> | 2018-09-13 19:31:48 +0300 |
---|---|---|
committer | Beth Griggs <Bethany.Griggs@uk.ibm.com> | 2018-10-17 02:07:24 +0300 |
commit | 2de17ead8979c6f55a25fdd0725f9952ae031d15 (patch) | |
tree | 4629218d036429017f7d2137067305948a4a2710 | |
parent | bae7c608e253d880c6241d787e45cd58b555d3b4 (diff) |
http2: add http2stream.endAfterHeaders property
Indicates is the END_STREAM flag was set on the received HEADERS frame
Backport-PR-URL: https://github.com/nodejs/node/pull/22850
PR-URL: https://github.com/nodejs/node/pull/22843
Fixes: https://github.com/nodejs/node/issues/22497
Reviewed-By: Matteo Collina <matteo.collina@gmail.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
Reviewed-By: Colin Ihrig <cjihrig@gmail.com>
-rw-r--r-- | doc/api/http2.md | 11 | ||||
-rw-r--r-- | lib/internal/http2/core.js | 9 | ||||
-rw-r--r-- | test/parallel/test-http2-endafterheaders.js | 50 |
3 files changed, 69 insertions, 1 deletions
diff --git a/doc/api/http2.md b/doc/api/http2.md index 81d1c8fa8e0..26ab8a461e0 100644 --- a/doc/api/http2.md +++ b/doc/api/http2.md @@ -952,6 +952,17 @@ added: v8.4.0 Set to `true` if the `Http2Stream` instance has been destroyed and is no longer usable. +#### http2stream.endAfterHeaders +<!-- YAML +added: REPLACEME +--> + +* {boolean} + +Set the `true` if the `END_STREAM` flag was set in the request or response +HEADERS frame received, indicating that no additional data should be received +and the readable side of the `Http2Stream` will be closed. + #### http2stream.pending <!-- YAML added: v8.11.2 diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js index 575e4152c94..a582fad9f4c 100644 --- a/lib/internal/http2/core.js +++ b/lib/internal/http2/core.js @@ -219,6 +219,8 @@ function onSessionHeaders(handle, id, cat, flags, headers) { } else { stream = new ClientHttp2Stream(session, handle, id, opts); } + if (endOfStream) + stream[kState].endAfterHeaders = true; process.nextTick(emit, session, 'stream', stream, obj, flags, headers); } else { let event; @@ -1557,7 +1559,8 @@ class Http2Stream extends Duplex { flags: STREAM_FLAGS_PENDING, rstCode: NGHTTP2_NO_ERROR, writeQueueSize: 0, - trailersReady: false + trailersReady: false, + endAfterHeaders: false }; this.on('pause', streamOnPause); @@ -1602,6 +1605,10 @@ class Http2Stream extends Duplex { return `Http2Stream ${util.format(obj)}`; } + get endAfterHeaders() { + return this[kState].endAfterHeaders; + } + get sentHeaders() { return this[kSentHeaders]; } diff --git a/test/parallel/test-http2-endafterheaders.js b/test/parallel/test-http2-endafterheaders.js new file mode 100644 index 00000000000..429ffc31884 --- /dev/null +++ b/test/parallel/test-http2-endafterheaders.js @@ -0,0 +1,50 @@ +'use strict'; + +const common = require('../common'); +if (!common.hasCrypto) + common.skip('missing crypto'); +const assert = require('assert'); +const http2 = require('http2'); +const Countdown = require('../common/countdown'); + +const server = http2.createServer(); +server.on('stream', common.mustCall((stream, headers) => { + const check = headers[':method'] === 'GET' ? true : false; + assert.strictEqual(stream.endAfterHeaders, check); + stream.on('data', common.mustNotCall()); + stream.on('end', common.mustCall()); + stream.respond(); + stream.end('ok'); +}, 2)); + +const countdown = new Countdown(2, () => server.close()); + +server.listen(0, common.mustCall(() => { + { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request(); + + req.resume(); + req.on('response', common.mustCall(() => { + assert.strictEqual(req.endAfterHeaders, false); + })); + req.on('end', common.mustCall(() => { + client.close(); + countdown.dec(); + })); + } + { + const client = http2.connect(`http://localhost:${server.address().port}`); + const req = client.request({ ':method': 'POST' }); + + req.resume(); + req.end(); + req.on('response', common.mustCall(() => { + assert.strictEqual(req.endAfterHeaders, false); + })); + req.on('end', common.mustCall(() => { + client.close(); + countdown.dec(); + })); + } +})); |