http2: avoid bind and properly clean up in compat
PR-URL: https://github.com/nodejs/node/pull/20374 Reviewed-By: Anatoli Papirovski <apapirovski@mac.com> Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Trivikram Kamat <trivikr.dev@gmail.com>
This commit is contained in:
parent
187e641736
commit
0d762af48e
@ -19,7 +19,6 @@ const {
|
|||||||
} = require('internal/errors').codes;
|
} = require('internal/errors').codes;
|
||||||
const { kSocket } = require('internal/http2/util');
|
const { kSocket } = require('internal/http2/util');
|
||||||
|
|
||||||
const kFinish = Symbol('finish');
|
|
||||||
const kBeginSend = Symbol('begin-send');
|
const kBeginSend = Symbol('begin-send');
|
||||||
const kState = Symbol('state');
|
const kState = Symbol('state');
|
||||||
const kStream = Symbol('stream');
|
const kStream = Symbol('stream');
|
||||||
@ -223,6 +222,27 @@ const proxySocketHandler = {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function onStreamCloseRequest() {
|
||||||
|
const req = this[kRequest];
|
||||||
|
|
||||||
|
if (req === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const state = req[kState];
|
||||||
|
state.closed = true;
|
||||||
|
|
||||||
|
req.push(null);
|
||||||
|
// if the user didn't interact with incoming data and didn't pipe it,
|
||||||
|
// dump it for compatibility with http1
|
||||||
|
if (!state.didRead && !req._readableState.resumeScheduled)
|
||||||
|
req.resume();
|
||||||
|
|
||||||
|
this[kProxySocket] = null;
|
||||||
|
this[kRequest] = undefined;
|
||||||
|
|
||||||
|
req.emit('close');
|
||||||
|
}
|
||||||
|
|
||||||
class Http2ServerRequest extends Readable {
|
class Http2ServerRequest extends Readable {
|
||||||
constructor(stream, headers, options, rawHeaders) {
|
constructor(stream, headers, options, rawHeaders) {
|
||||||
super(options);
|
super(options);
|
||||||
@ -246,7 +266,7 @@ class Http2ServerRequest extends Readable {
|
|||||||
stream.on('end', onStreamEnd);
|
stream.on('end', onStreamEnd);
|
||||||
stream.on('error', onStreamError);
|
stream.on('error', onStreamError);
|
||||||
stream.on('aborted', onStreamAbortedRequest);
|
stream.on('aborted', onStreamAbortedRequest);
|
||||||
stream.on('close', this[kFinish].bind(this));
|
stream.on('close', onStreamCloseRequest);
|
||||||
this.on('pause', onRequestPause);
|
this.on('pause', onRequestPause);
|
||||||
this.on('resume', onRequestResume);
|
this.on('resume', onRequestResume);
|
||||||
}
|
}
|
||||||
@ -349,24 +369,30 @@ class Http2ServerRequest extends Readable {
|
|||||||
return;
|
return;
|
||||||
this[kStream].setTimeout(msecs, callback);
|
this[kStream].setTimeout(msecs, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
[kFinish]() {
|
|
||||||
const state = this[kState];
|
|
||||||
if (state.closed)
|
|
||||||
return;
|
|
||||||
state.closed = true;
|
|
||||||
this.push(null);
|
|
||||||
this[kStream][kRequest] = undefined;
|
|
||||||
// if the user didn't interact with incoming data and didn't pipe it,
|
|
||||||
// dump it for compatibility with http1
|
|
||||||
if (!state.didRead && !this._readableState.resumeScheduled)
|
|
||||||
this.resume();
|
|
||||||
this.emit('close');
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function onStreamTrailersReady() {
|
function onStreamTrailersReady() {
|
||||||
this[kStream].sendTrailers(this[kTrailers]);
|
this.sendTrailers(this[kResponse][kTrailers]);
|
||||||
|
}
|
||||||
|
|
||||||
|
function onStreamCloseResponse() {
|
||||||
|
const res = this[kResponse];
|
||||||
|
|
||||||
|
if (res === undefined)
|
||||||
|
return;
|
||||||
|
|
||||||
|
const state = res[kState];
|
||||||
|
|
||||||
|
if (this.headRequest !== state.headRequest)
|
||||||
|
return;
|
||||||
|
|
||||||
|
state.closed = true;
|
||||||
|
|
||||||
|
this[kProxySocket] = null;
|
||||||
|
this[kResponse] = undefined;
|
||||||
|
|
||||||
|
res.emit('finish');
|
||||||
|
res.emit('close');
|
||||||
}
|
}
|
||||||
|
|
||||||
class Http2ServerResponse extends Stream {
|
class Http2ServerResponse extends Stream {
|
||||||
@ -387,8 +413,8 @@ class Http2ServerResponse extends Stream {
|
|||||||
this.writable = true;
|
this.writable = true;
|
||||||
stream.on('drain', onStreamDrain);
|
stream.on('drain', onStreamDrain);
|
||||||
stream.on('aborted', onStreamAbortedResponse);
|
stream.on('aborted', onStreamAbortedResponse);
|
||||||
stream.on('close', this[kFinish].bind(this));
|
stream.on('close', onStreamCloseResponse);
|
||||||
stream.on('wantTrailers', onStreamTrailersReady.bind(this));
|
stream.on('wantTrailers', onStreamTrailersReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
// User land modules such as finalhandler just check truthiness of this
|
// User land modules such as finalhandler just check truthiness of this
|
||||||
@ -619,7 +645,7 @@ class Http2ServerResponse extends Stream {
|
|||||||
this.writeHead(this[kState].statusCode);
|
this.writeHead(this[kState].statusCode);
|
||||||
|
|
||||||
if (isFinished)
|
if (isFinished)
|
||||||
this[kFinish]();
|
onStreamCloseResponse.call(stream);
|
||||||
else
|
else
|
||||||
stream.end();
|
stream.end();
|
||||||
|
|
||||||
@ -665,18 +691,6 @@ class Http2ServerResponse extends Stream {
|
|||||||
this[kStream].respond(headers, options);
|
this[kStream].respond(headers, options);
|
||||||
}
|
}
|
||||||
|
|
||||||
[kFinish]() {
|
|
||||||
const stream = this[kStream];
|
|
||||||
const state = this[kState];
|
|
||||||
if (state.closed || stream.headRequest !== state.headRequest)
|
|
||||||
return;
|
|
||||||
state.closed = true;
|
|
||||||
this[kProxySocket] = null;
|
|
||||||
stream[kResponse] = undefined;
|
|
||||||
this.emit('finish');
|
|
||||||
this.emit('close');
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO doesn't support callbacks
|
// TODO doesn't support callbacks
|
||||||
writeContinue() {
|
writeContinue() {
|
||||||
const stream = this[kStream];
|
const stream = this[kStream];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user