Skip to content

Commit d1b7825

Browse files
ronagBethGriggs
authored andcommitted
http2: avoid bind and properly clean up in compat
Backport-PR-URL: #22850 PR-URL: #20374 Reviewed-By: Anatoli Papirovski <[email protected]> Reviewed-By: James M Snell <[email protected]> Reviewed-By: Trivikram Kamat <[email protected]>
1 parent 4f00354 commit d1b7825

File tree

1 file changed

+46
-32
lines changed

1 file changed

+46
-32
lines changed

lib/internal/http2/compat.js

+46-32
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const constants = binding.constants;
77
const errors = require('internal/errors');
88
const { kSocket } = require('internal/http2/util');
99

10-
const kFinish = Symbol('finish');
1110
const kBeginSend = Symbol('begin-send');
1211
const kState = Symbol('state');
1312
const kStream = Symbol('stream');
@@ -211,6 +210,27 @@ const proxySocketHandler = {
211210
}
212211
};
213212

213+
function onStreamCloseRequest() {
214+
const req = this[kRequest];
215+
216+
if (req === undefined)
217+
return;
218+
219+
const state = req[kState];
220+
state.closed = true;
221+
222+
req.push(null);
223+
// if the user didn't interact with incoming data and didn't pipe it,
224+
// dump it for compatibility with http1
225+
if (!state.didRead && !req._readableState.resumeScheduled)
226+
req.resume();
227+
228+
this[kProxySocket] = null;
229+
this[kRequest] = undefined;
230+
231+
req.emit('close');
232+
}
233+
214234
class Http2ServerRequest extends Readable {
215235
constructor(stream, headers, options, rawHeaders) {
216236
super(options);
@@ -234,7 +254,7 @@ class Http2ServerRequest extends Readable {
234254
stream.on('end', onStreamEnd);
235255
stream.on('error', onStreamError);
236256
stream.on('aborted', onStreamAbortedRequest);
237-
stream.on('close', this[kFinish].bind(this));
257+
stream.on('close', onStreamCloseRequest);
238258
this.on('pause', onRequestPause);
239259
this.on('resume', onRequestResume);
240260
}
@@ -335,24 +355,30 @@ class Http2ServerRequest extends Readable {
335355
return;
336356
this[kStream].setTimeout(msecs, callback);
337357
}
338-
339-
[kFinish]() {
340-
const state = this[kState];
341-
if (state.closed)
342-
return;
343-
state.closed = true;
344-
this.push(null);
345-
this[kStream][kRequest] = undefined;
346-
// if the user didn't interact with incoming data and didn't pipe it,
347-
// dump it for compatibility with http1
348-
if (!state.didRead && !this._readableState.resumeScheduled)
349-
this.resume();
350-
this.emit('close');
351-
}
352358
}
353359

354360
function onStreamTrailersReady() {
355-
this[kStream].sendTrailers(this[kTrailers]);
361+
this.sendTrailers(this[kResponse][kTrailers]);
362+
}
363+
364+
function onStreamCloseResponse() {
365+
const res = this[kResponse];
366+
367+
if (res === undefined)
368+
return;
369+
370+
const state = res[kState];
371+
372+
if (this.headRequest !== state.headRequest)
373+
return;
374+
375+
state.closed = true;
376+
377+
this[kProxySocket] = null;
378+
this[kResponse] = undefined;
379+
380+
res.emit('finish');
381+
res.emit('close');
356382
}
357383

358384
class Http2ServerResponse extends Stream {
@@ -373,8 +399,8 @@ class Http2ServerResponse extends Stream {
373399
this.writable = true;
374400
stream.on('drain', onStreamDrain);
375401
stream.on('aborted', onStreamAbortedResponse);
376-
stream.on('close', this[kFinish].bind(this));
377-
stream.on('wantTrailers', onStreamTrailersReady.bind(this));
402+
stream.on('close', onStreamCloseResponse);
403+
stream.on('wantTrailers', onStreamTrailersReady);
378404
}
379405

380406
// User land modules such as finalhandler just check truthiness of this
@@ -605,7 +631,7 @@ class Http2ServerResponse extends Stream {
605631
this.writeHead(this[kState].statusCode);
606632

607633
if (isFinished)
608-
this[kFinish]();
634+
onStreamCloseResponse.call(stream);
609635
else
610636
stream.end();
611637
}
@@ -649,18 +675,6 @@ class Http2ServerResponse extends Stream {
649675
this[kStream].respond(headers, options);
650676
}
651677

652-
[kFinish]() {
653-
const stream = this[kStream];
654-
const state = this[kState];
655-
if (state.closed || stream.headRequest !== state.headRequest)
656-
return;
657-
state.closed = true;
658-
this[kProxySocket] = null;
659-
stream[kResponse] = undefined;
660-
this.emit('finish');
661-
this.emit('close');
662-
}
663-
664678
// TODO doesn't support callbacks
665679
writeContinue() {
666680
const stream = this[kStream];

0 commit comments

Comments
 (0)