Skip to content

Commit

Permalink
http2: add http2stream.endAfterHeaders property
Browse files Browse the repository at this point in the history
Indicates is the END_STREAM flag was set on the received HEADERS frame

PR-URL: #22843
Fixes: #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>
  • Loading branch information
jasnell authored and addaleax committed Sep 17, 2018
1 parent eee5adf commit efe0bbc
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 1 deletion.
11 changes: 11 additions & 0 deletions doc/api/http2.md
Original file line number Diff line number Diff line change
Expand Up @@ -958,6 +958,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: v9.4.0
Expand Down
9 changes: 8 additions & 1 deletion lib/internal/http2/core.js
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,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;
Expand Down Expand Up @@ -1548,7 +1550,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);
Expand Down Expand Up @@ -1594,6 +1597,10 @@ class Http2Stream extends Duplex {
return `Http2Stream ${util.format(obj)}`;
}

get endAfterHeaders() {
return this[kState].endAfterHeaders;
}

get sentHeaders() {
return this[kSentHeaders];
}
Expand Down
50 changes: 50 additions & 0 deletions test/parallel/test-http2-endafterheaders.js
Original file line number Diff line number Diff line change
@@ -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();
}));
}
}));

0 comments on commit efe0bbc

Please sign in to comment.