Send WINDOW_UPDATE for ignored DATA bytes when manual flow control is enabled
Since we do not call on_data_chunk_recv_callback for ignored DATA chunk, if nghttp2_option_set_no_auto_connection_window_update is used, application may not have a chance to send connection WINDOW_UPDATE. To fix this, we accumulate those received bytes, and if it exceeds certain number, we automatically send connection-level WINDOW_UPDATE.
This commit is contained in:
parent
ed38dbf67a
commit
6da044cbb5
|
@ -3889,6 +3889,10 @@ static int session_update_recv_connection_window_size
|
|||
session->recv_window_size);
|
||||
if(rv == 0) {
|
||||
session->recv_window_size = 0;
|
||||
/* recv_ign_window_size keeps track of ignored DATA bytes
|
||||
before any connection-level WINDOW_UPDATE therefore, we can
|
||||
reset it here. */
|
||||
session->recv_ign_window_size = 0;
|
||||
} else {
|
||||
return rv;
|
||||
}
|
||||
|
@ -5027,12 +5031,30 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
|
|||
readlen, iframe->payloadleft));
|
||||
|
||||
if(readlen > 0) {
|
||||
session->recv_ign_window_size += readlen;
|
||||
|
||||
/* Update connection-level flow control window for ignored
|
||||
DATA frame too */
|
||||
rv = session_update_recv_connection_window_size(session, readlen);
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
if((session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE) &&
|
||||
nghttp2_should_send_window_update
|
||||
(session->local_window_size, session->recv_ign_window_size)) {
|
||||
|
||||
rv = nghttp2_session_add_window_update
|
||||
(session, NGHTTP2_FLAG_NONE, 0, session->recv_ign_window_size);
|
||||
|
||||
if(nghttp2_is_fatal(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
session->recv_window_size -= session->recv_ign_window_size;
|
||||
session->recv_ign_window_size = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(iframe->payloadleft) {
|
||||
|
|
|
@ -200,6 +200,15 @@ struct nghttp2_session {
|
|||
WINDOW_UPDATE. This could be negative after submitting negative
|
||||
value to WINDOW_UPDATE. */
|
||||
int32_t recv_window_size;
|
||||
/* The number of bytes in ignored DATA frame received without
|
||||
connection-level WINDOW_UPDATE. Since we do not call
|
||||
on_data_chunk_recv_callback for ignored DATA chunk, if
|
||||
nghttp2_option_set_no_auto_connection_window_update is used,
|
||||
application may not have a chance to send connection
|
||||
WINDOW_UPDATE. To fix this, we accumulate those received bytes,
|
||||
and if it exceeds certain number, we automatically send
|
||||
connection-level WINDOW_UPDATE. */
|
||||
int32_t recv_ign_window_size;
|
||||
/* The amount of recv_window_size cut using submitting negative
|
||||
value to WINDOW_UPDATE */
|
||||
int32_t recv_reduction;
|
||||
|
|
|
@ -348,6 +348,11 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
|||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* recv_ign_window_size keeps track of ignored DATA bytes before
|
||||
any connection-level WINDOW_UPDATE therefore, we can reset it
|
||||
here. */
|
||||
session->recv_ign_window_size = 0;
|
||||
} else {
|
||||
stream = nghttp2_session_get_stream(session, stream_id);
|
||||
if(stream) {
|
||||
|
@ -362,6 +367,7 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
|||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if(window_size_increment > 0) {
|
||||
return nghttp2_session_add_window_update(session, flags, stream_id,
|
||||
window_size_increment);
|
||||
|
|
Loading…
Reference in New Issue