Skip to content
This repository was archived by the owner on Jul 6, 2018. It is now read-only.

Commit b545d63

Browse files
committed
Additional test cases
1 parent a6d74b4 commit b545d63

7 files changed

+233
-6
lines changed

lib/internal/http2/core.js

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -876,6 +876,8 @@ function onStreamClosed(code) {
876876

877877
function onStreamError(error) {
878878
const session = this.session;
879+
if (session === undefined)
880+
process.emit('error', error);
879881
if (!session.emit('streamError', error, this))
880882
session.emit('error', error, this);
881883
}
@@ -1117,6 +1119,8 @@ class ServerHttp2Stream extends Http2Stream {
11171119
}
11181120

11191121
pushStream(headers, options, callback) {
1122+
if (this.session === undefined || this.session._state.destroyed)
1123+
throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
11201124
_unrefActive(this);
11211125
const session = this.session;
11221126
const state = session._state;
@@ -1170,6 +1174,8 @@ class ServerHttp2Stream extends Http2Stream {
11701174
}
11711175

11721176
respond(headers, options) {
1177+
if (this.session === undefined || this.session._state.destroyed)
1178+
throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
11731179
_unrefActive(this);
11741180
const state = this._state;
11751181

@@ -1226,14 +1232,11 @@ class ServerHttp2Stream extends Http2Stream {
12261232
// a 1xx informational code and it MUST be sent before the request/response
12271233
// headers are sent, or an error will be thrown.
12281234
additionalHeaders(headers) {
1229-
if (this.id === undefined) {
1230-
this.once('connect', () => this.additionalHeaders(headers));
1231-
return;
1232-
}
1235+
if (this.session === undefined || this.session._state.destroyed)
1236+
throw new errors.Error('ERR_HTTP2_INVALID_SESSION');
12331237

1234-
if (this._state.headersSent) {
1238+
if (this._state.headersSent)
12351239
throw new errors.Error('ERR_HTTP2_HEADERS_AFTER_RESPOND');
1236-
}
12371240

12381241
assertIsObject(headers, 'headers');
12391242
headers = Object.assign(Object.create(null), headers);
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const h2 = require('http2');
6+
7+
const server = h2.createServer();
8+
9+
// we use the lower-level API here
10+
server.on('stream', common.mustCall(onStream));
11+
12+
function onStream(stream, headers, flags) {
13+
stream.session.destroy();
14+
assert.throws(() => stream.additionalHeaders({}),
15+
common.expectsError({
16+
code: 'ERR_HTTP2_INVALID_SESSION',
17+
message: /^The session has been destroyed$/
18+
}));
19+
}
20+
21+
server.listen(0);
22+
23+
server.on('listening', common.mustCall(() => {
24+
25+
const client = h2.connect(`http://localhost:${server.address().port}`);
26+
27+
const req = client.request({ ':path': '/' });
28+
29+
req.on('response', common.mustNotCall());
30+
req.resume();
31+
req.on('end', common.mustCall(() => {
32+
server.close();
33+
client.destroy();
34+
}));
35+
req.end();
36+
37+
}));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const h2 = require('http2');
6+
7+
const server = h2.createServer();
8+
9+
// we use the lower-level API here
10+
server.on('stream', common.mustCall(onStream));
11+
12+
function onStream(stream, headers, flags) {
13+
stream.session.destroy();
14+
assert.throws(() => stream.pushStream({}, common.mustNotCall()),
15+
common.expectsError({
16+
code: 'ERR_HTTP2_INVALID_SESSION',
17+
message: /^The session has been destroyed$/
18+
}));
19+
}
20+
21+
server.listen(0);
22+
23+
server.on('listening', common.mustCall(() => {
24+
25+
const client = h2.connect(`http://localhost:${server.address().port}`);
26+
27+
const req = client.request({ ':path': '/' });
28+
29+
req.on('response', common.mustNotCall());
30+
req.resume();
31+
req.on('end', common.mustCall(() => {
32+
server.close();
33+
client.destroy();
34+
}));
35+
req.end();
36+
37+
}));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const h2 = require('http2');
6+
7+
const server = h2.createServer();
8+
9+
// we use the lower-level API here
10+
server.on('stream', common.mustCall(onStream));
11+
12+
function onStream(stream, headers, flags) {
13+
stream.session.destroy();
14+
assert.throws(() => stream.respond({}),
15+
common.expectsError({
16+
code: 'ERR_HTTP2_INVALID_SESSION',
17+
message: /^The session has been destroyed$/
18+
}));
19+
}
20+
21+
server.listen(0);
22+
23+
server.on('listening', common.mustCall(() => {
24+
25+
const client = h2.connect(`http://localhost:${server.address().port}`);
26+
27+
const req = client.request({ ':path': '/' });
28+
29+
req.on('response', common.mustNotCall());
30+
req.resume();
31+
req.on('end', common.mustCall(() => {
32+
server.close();
33+
client.destroy();
34+
}));
35+
req.end();
36+
37+
}));
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const h2 = require('http2');
6+
7+
const server = h2.createServer();
8+
9+
// we use the lower-level API here
10+
server.on('stream', common.mustCall(onStream));
11+
12+
function onStream(stream, headers, flags) {
13+
stream.session.destroy();
14+
assert.throws(() => stream.write('data'),
15+
common.expectsError({
16+
type: Error,
17+
message: /^write after end$/
18+
}));
19+
}
20+
21+
server.listen(0);
22+
23+
server.on('listening', common.mustCall(() => {
24+
25+
const client = h2.connect(`http://localhost:${server.address().port}`);
26+
27+
const req = client.request({ ':path': '/' });
28+
29+
req.on('response', common.mustNotCall());
30+
req.resume();
31+
req.on('end', common.mustCall(() => {
32+
server.close();
33+
client.destroy();
34+
}));
35+
req.end();
36+
37+
}));
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const assert = require('assert');
5+
const h2 = require('http2');
6+
7+
const server = h2.createServer();
8+
9+
// we use the lower-level API here
10+
server.on('stream', common.mustCall(onStream));
11+
12+
function onStream(stream, headers, flags) {
13+
stream.rstWithCancel();
14+
stream.additionalHeaders({
15+
':status': 123,
16+
abc: 123
17+
});
18+
setImmediate(() => {
19+
stream.respond({':status': 200});
20+
stream.end('data');
21+
});
22+
}
23+
24+
server.listen(0);
25+
26+
server.on('listening', common.mustCall(() => {
27+
28+
const client = h2.connect(`http://localhost:${server.address().port}`);
29+
30+
const req = client.request({ ':path': '/' });
31+
32+
req.on('headers', common.mustNotCall());
33+
34+
req.on('streamClosed', common.mustCall((code) => {
35+
assert.strictEqual(h2.constants.NGHTTP2_CANCEL, code);
36+
server.close();
37+
client.destroy();
38+
}));
39+
40+
req.on('response', common.mustNotCall());
41+
42+
}));
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
const h2 = require('http2');
5+
6+
const server = h2.createServer();
7+
8+
// we use the lower-level API here
9+
server.on('stream', common.mustCall(onStream));
10+
11+
function onStream(stream, headers, flags) {
12+
stream.session.shutdown({graceful: true}, common.mustCall(() => {
13+
stream.session.destroy();
14+
}));
15+
stream.respond({});
16+
stream.end('data');
17+
}
18+
19+
server.listen(0);
20+
21+
server.on('listening', common.mustCall(() => {
22+
23+
const client = h2.connect(`http://localhost:${server.address().port}`);
24+
25+
const req = client.request({ ':path': '/' });
26+
27+
req.on('response', common.mustNotCall());
28+
req.resume();
29+
req.on('end', common.mustCall(() => {
30+
server.close();
31+
}));
32+
req.end();
33+
34+
}));

0 commit comments

Comments
 (0)