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);
|
session->recv_window_size);
|
||||||
if(rv == 0) {
|
if(rv == 0) {
|
||||||
session->recv_window_size = 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 {
|
} else {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
@ -5027,12 +5031,30 @@ ssize_t nghttp2_session_mem_recv(nghttp2_session *session,
|
||||||
readlen, iframe->payloadleft));
|
readlen, iframe->payloadleft));
|
||||||
|
|
||||||
if(readlen > 0) {
|
if(readlen > 0) {
|
||||||
|
session->recv_ign_window_size += readlen;
|
||||||
|
|
||||||
/* Update connection-level flow control window for ignored
|
/* Update connection-level flow control window for ignored
|
||||||
DATA frame too */
|
DATA frame too */
|
||||||
rv = session_update_recv_connection_window_size(session, readlen);
|
rv = session_update_recv_connection_window_size(session, readlen);
|
||||||
if(nghttp2_is_fatal(rv)) {
|
if(nghttp2_is_fatal(rv)) {
|
||||||
return 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) {
|
if(iframe->payloadleft) {
|
||||||
|
|
|
@ -200,6 +200,15 @@ struct nghttp2_session {
|
||||||
WINDOW_UPDATE. This could be negative after submitting negative
|
WINDOW_UPDATE. This could be negative after submitting negative
|
||||||
value to WINDOW_UPDATE. */
|
value to WINDOW_UPDATE. */
|
||||||
int32_t recv_window_size;
|
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
|
/* The amount of recv_window_size cut using submitting negative
|
||||||
value to WINDOW_UPDATE */
|
value to WINDOW_UPDATE */
|
||||||
int32_t recv_reduction;
|
int32_t recv_reduction;
|
||||||
|
|
|
@ -348,6 +348,11 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||||
if(rv != 0) {
|
if(rv != 0) {
|
||||||
return rv;
|
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 {
|
} else {
|
||||||
stream = nghttp2_session_get_stream(session, stream_id);
|
stream = nghttp2_session_get_stream(session, stream_id);
|
||||||
if(stream) {
|
if(stream) {
|
||||||
|
@ -362,6 +367,7 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(window_size_increment > 0) {
|
if(window_size_increment > 0) {
|
||||||
return nghttp2_session_add_window_update(session, flags, stream_id,
|
return nghttp2_session_add_window_update(session, flags, stream_id,
|
||||||
window_size_increment);
|
window_size_increment);
|
||||||
|
|
Loading…
Reference in New Issue