Skip to content

Commit 0605719

Browse files
committed
http2: compat ERR_STREAM_ALREADY_FINISHED
Make http/2 compat end() match Writable and http/1.
1 parent 605d7c4 commit 0605719

File tree

2 files changed

+36
-12
lines changed

2 files changed

+36
-12
lines changed

lib/internal/http2/compat.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ const {
3131
ERR_HTTP2_STATUS_INVALID,
3232
ERR_INVALID_ARG_VALUE,
3333
ERR_INVALID_CALLBACK,
34-
ERR_INVALID_HTTP_TOKEN
34+
ERR_INVALID_HTTP_TOKEN,
35+
ERR_STREAM_ALREADY_FINISHED
3536
},
3637
hideStackFrames
3738
} = require('internal/errors');
@@ -652,11 +653,6 @@ class Http2ServerResponse extends Stream {
652653
const stream = this[kStream];
653654
const state = this[kState];
654655

655-
if ((state.closed || state.ending) &&
656-
state.headRequest === stream.headRequest) {
657-
return this;
658-
}
659-
660656
if (typeof chunk === 'function') {
661657
cb = chunk;
662658
chunk = null;
@@ -665,6 +661,22 @@ class Http2ServerResponse extends Stream {
665661
encoding = 'utf8';
666662
}
667663

664+
if (this.writableEnded) {
665+
if (typeof cb === 'function') {
666+
if (!this.finished) {
667+
this.on('finish', cb);
668+
} else {
669+
cb(new ERR_STREAM_ALREADY_FINISHED('end'));
670+
}
671+
}
672+
return this;
673+
}
674+
675+
if ((state.closed || state.ending) &&
676+
state.headRequest === stream.headRequest) {
677+
return this;
678+
}
679+
668680
if (chunk !== null && chunk !== undefined)
669681
this.write(chunk, encoding);
670682

test/parallel/test-http2-compat-serverresponse-end.js

+18-6
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
const {
44
mustCall,
55
mustNotCall,
6+
expectsError,
67
hasCrypto,
78
platformTimeout,
89
skip
@@ -25,16 +26,22 @@ const {
2526
// but callback will only be called once
2627
const server = createServer(mustCall((request, response) => {
2728
response.end('end', 'utf8', mustCall(() => {
28-
response.end(mustNotCall());
29+
response.end(mustCall());
2930
process.nextTick(() => {
30-
response.end(mustNotCall());
31+
response.end(expectsError({
32+
code: 'ERR_STREAM_ALREADY_FINISHED'
33+
}));
3134
server.close();
3235
});
3336
}));
3437
response.on('finish', mustCall(() => {
35-
response.end(mustNotCall());
38+
response.end(expectsError({
39+
code: 'ERR_STREAM_ALREADY_FINISHED'
40+
}));
41+
}));
42+
response.end(expectsError({
43+
code: 'ERR_STREAM_ALREADY_FINISHED'
3644
}));
37-
response.end(mustNotCall());
3845
}));
3946
server.listen(0, mustCall(() => {
4047
let data = '';
@@ -292,7 +299,10 @@ const {
292299
}));
293300
response.end('data', mustCall(() => {
294301
strictEqual(finished, false);
295-
response.end('data', mustNotCall());
302+
strictEqual(response.end('data', expectsError({
303+
code: 'ERR_STREAM_ALREADY_FINISHED'
304+
})), response);
305+
strictEqual(response.end(), response);
296306
}));
297307
}));
298308
server.listen(0, mustCall(() => {
@@ -326,7 +336,9 @@ const {
326336
// Should be able to respond to HEAD with just .end
327337
const server = createServer(mustCall((request, response) => {
328338
response.end('data', mustCall());
329-
response.end(mustNotCall());
339+
strictEqual(response.end('data', expectsError({
340+
code: 'ERR_STREAM_ALREADY_FINISHED'
341+
})), response);
330342
}));
331343
server.listen(0, mustCall(() => {
332344
const { port } = server.address();

0 commit comments

Comments
 (0)