Http2 Server are allowed to early respond without fully consuming client input stream, but must respond with an error code of NO_ERROR when sending RST_STREAM. Nginx treat any other error code as fatal if not done so Commit change error code from CANCEL to NO_ERROR, when the server is early responding to the client https://github.com/hyperium/h2/issues/633 https://trac.nginx.org/nginx/ticket/2376
This commit is contained in:
committed by
GitHub
parent
756384f4cd
commit
b0f54d80f2
@@ -1461,9 +1461,21 @@ fn drop_stream_ref(inner: &Mutex<Inner>, key: store::Key) {
|
||||
|
||||
fn maybe_cancel(stream: &mut store::Ptr, actions: &mut Actions, counts: &mut Counts) {
|
||||
if stream.is_canceled_interest() {
|
||||
// Server is allowed to early respond without fully consuming the client input stream
|
||||
// But per the RFC, must send a RST_STREAM(NO_ERROR) in such cases. https://www.rfc-editor.org/rfc/rfc7540#section-8.1
|
||||
// Some other http2 implementation may interpret other error code as fatal if not respected (i.e: nginx https://trac.nginx.org/nginx/ticket/2376)
|
||||
let reason = if counts.peer().is_server()
|
||||
&& stream.state.is_send_closed()
|
||||
&& stream.state.is_recv_streaming()
|
||||
{
|
||||
Reason::NO_ERROR
|
||||
} else {
|
||||
Reason::CANCEL
|
||||
};
|
||||
|
||||
actions
|
||||
.send
|
||||
.schedule_implicit_reset(stream, Reason::CANCEL, counts, &mut actions.task);
|
||||
.schedule_implicit_reset(stream, reason, counts, &mut actions.task);
|
||||
actions.recv.enqueue_reset_expiration(stream, counts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -566,7 +566,9 @@ async fn sends_reset_cancel_when_req_body_is_dropped() {
|
||||
client
|
||||
.recv_frame(frames::headers(1).response(200).eos())
|
||||
.await;
|
||||
client.recv_frame(frames::reset(1).cancel()).await;
|
||||
client
|
||||
.recv_frame(frames::reset(1).reason(Reason::NO_ERROR))
|
||||
.await;
|
||||
};
|
||||
|
||||
let srv = async move {
|
||||
|
||||
Reference in New Issue
Block a user