fix(ext/node): handle http2 server ending stream (#26235)

Closes #24845
This commit is contained in:
Toby Ealden 2024-10-15 19:05:10 +01:00 committed by GitHub
parent 3888806169
commit c5a7f98d82
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 14 additions and 8 deletions

View File

@ -488,14 +488,12 @@ pub async fn op_http2_client_get_response_body_chunk(
loop {
let result = poll_fn(|cx| poll_data_or_trailers(cx, &mut body)).await;
if let Err(err) = result {
let reason = err.reason();
if let Some(reason) = reason {
if reason == Reason::CANCEL {
return Ok((None, false, true));
match err.reason() {
Some(Reason::NO_ERROR) => return Ok((None, true, false)),
Some(Reason::CANCEL) => return Ok((None, false, true)),
_ => return Err(err.into()),
}
}
return Err(err.into());
}
match result.unwrap() {
DataOrTrailers::Data(data) => {
return Ok((Some(data.to_vec()), false, false));

View File

@ -882,6 +882,7 @@ export class ClientHttp2Stream extends Duplex {
trailersReady: false,
endAfterHeaders: false,
shutdownWritableCalled: false,
serverEndedCall: false,
};
this[kDenoResponse] = undefined;
this[kDenoRid] = undefined;
@ -1109,7 +1110,9 @@ export class ClientHttp2Stream extends Duplex {
}
debugHttp2(">>> chunk", chunk, finished, this[kDenoResponse].bodyRid);
if (chunk === null) {
if (finished || chunk === null) {
this[kState].serverEndedCall = true;
const trailerList = await op_http2_client_get_response_trailers(
this[kDenoResponse].bodyRid,
);
@ -1237,8 +1240,10 @@ export class ClientHttp2Stream extends Duplex {
this[kSession] = undefined;
session[kMaybeDestroy]();
if (callback) {
callback(err);
}
}
[kMaybeDestroy](code = constants.NGHTTP2_NO_ERROR) {
debugHttp2(
@ -1280,6 +1285,9 @@ function shutdownWritable(stream, callback, streamRid) {
if (state.flags & STREAM_FLAGS_HAS_TRAILERS) {
onStreamTrailers(stream);
callback();
} else if (state.serverEndedCall) {
debugHttp2(">>> stream finished");
callback();
} else {
op_http2_client_send_data(streamRid, new Uint8Array(), true)
.then(() => {