Allow disabling auto WINDOW_UPDATE for connection and stream individually
Now NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is split into 2 options: NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE and NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE. This is preparation for the upcoming removal of END_FLOW_CONTROL flag. For nghttpx, instead of using END_FLOW_CONTROL to disable connection-level flow control, increase window size by large enough value, which is friendly way to current chromium implementation.
This commit is contained in:
parent
b979d2e8d2
commit
19377fb3cd
|
@ -1063,12 +1063,19 @@ void nghttp2_session_del(nghttp2_session *session);
|
|||
*/
|
||||
typedef enum {
|
||||
/**
|
||||
* This option prevents the library from sending WINDOW_UPDATE
|
||||
* automatically. If this option is set, the application is
|
||||
* This option prevents the library from sending WINDOW_UPDATE for a
|
||||
* stream automatically. If this option is set, the application is
|
||||
* responsible for sending WINDOW_UPDATE using
|
||||
* `nghttp2_submit_window_update`.
|
||||
*/
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE = 1,
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE = 1,
|
||||
/**
|
||||
* This option prevents the library from sending WINDOW_UPDATE for a
|
||||
* connection automatically. If this option is set, the application
|
||||
* is responsible for sending WINDOW_UPDATE with stream ID 0 using
|
||||
* `nghttp2_submit_window_update`.
|
||||
*/
|
||||
NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE = 2
|
||||
} nghttp2_opt;
|
||||
|
||||
/**
|
||||
|
|
|
@ -1935,7 +1935,8 @@ static int nghttp2_update_local_initial_window_size_func
|
|||
return nghttp2_session_add_rst_stream(arg->session, stream->stream_id,
|
||||
NGHTTP2_FLOW_CONTROL_ERROR);
|
||||
}
|
||||
if(!(arg->session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
|
||||
if(!(arg->session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE)) {
|
||||
if(nghttp2_should_send_window_update(stream->local_window_size,
|
||||
stream->recv_window_size)) {
|
||||
rv = nghttp2_session_add_window_update(arg->session,
|
||||
|
@ -2651,8 +2652,8 @@ static int adjust_recv_window_size(int32_t *recv_window_size_ptr,
|
|||
/*
|
||||
* Accumulates received bytes |delta_size| for stream-level flow
|
||||
* control and decides whether to send WINDOW_UPDATE to that
|
||||
* stream. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set, WINDOW_UPDATE
|
||||
* will not be sent.
|
||||
* stream. If NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE is set,
|
||||
* WINDOW_UPDATE will not be sent.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
|
@ -2671,7 +2672,7 @@ static int nghttp2_session_update_recv_stream_window_size
|
|||
return nghttp2_session_add_rst_stream(session, stream->stream_id,
|
||||
NGHTTP2_ERR_FLOW_CONTROL);
|
||||
}
|
||||
if(!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
|
||||
if(!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE)) {
|
||||
/* We have to use local_settings here because it is the constraint
|
||||
the remote endpoint should honor. */
|
||||
if(nghttp2_should_send_window_update(stream->local_window_size,
|
||||
|
@ -2693,8 +2694,8 @@ static int nghttp2_session_update_recv_stream_window_size
|
|||
/*
|
||||
* Accumulates received bytes |delta_size| for connection-level flow
|
||||
* control and decides whether to send WINDOW_UPDATE to the
|
||||
* connection. If NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE is set,
|
||||
* WINDOW_UPDATE will not be sent.
|
||||
* connection. If NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE is
|
||||
* set, WINDOW_UPDATE will not be sent.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
|
@ -2711,7 +2712,8 @@ static int nghttp2_session_update_recv_connection_window_size
|
|||
if(rv != 0) {
|
||||
return nghttp2_session_fail_session(session, NGHTTP2_ERR_FLOW_CONTROL);
|
||||
}
|
||||
if(!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE)) {
|
||||
if(!(session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE)) {
|
||||
if(nghttp2_should_send_window_update(session->local_window_size,
|
||||
session->recv_window_size)) {
|
||||
/* Use stream ID 0 to update connection-level flow control
|
||||
|
@ -3094,18 +3096,26 @@ int nghttp2_session_set_option(nghttp2_session *session,
|
|||
int optname, void *optval, size_t optlen)
|
||||
{
|
||||
switch(optname) {
|
||||
case NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE:
|
||||
case NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE:
|
||||
case NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE: {
|
||||
int flag;
|
||||
if(optname == NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE) {
|
||||
flag = NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE;
|
||||
} else {
|
||||
flag = NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE;
|
||||
}
|
||||
if(optlen == sizeof(int)) {
|
||||
int intval = *(int*)optval;
|
||||
if(intval) {
|
||||
session->opt_flags |= NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE;
|
||||
session->opt_flags |= flag;
|
||||
} else {
|
||||
session->opt_flags &= ~NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE;
|
||||
session->opt_flags &= ~flag;
|
||||
}
|
||||
} else {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
|
|
@ -42,7 +42,8 @@
|
|||
* Option flags.
|
||||
*/
|
||||
typedef enum {
|
||||
NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE = 1 << 0
|
||||
NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE = 1 << 0,
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE = 1 << 1
|
||||
} nghttp2_optmask;
|
||||
|
||||
typedef struct {
|
||||
|
|
|
@ -241,7 +241,8 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
|||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
if(!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
|
||||
if(!(session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE) &&
|
||||
window_size_increment < 0 &&
|
||||
nghttp2_should_send_window_update(session->local_window_size,
|
||||
session->recv_window_size)) {
|
||||
|
@ -260,7 +261,8 @@ int nghttp2_submit_window_update(nghttp2_session *session, uint8_t flags,
|
|||
if(rv != 0) {
|
||||
return rv;
|
||||
}
|
||||
if(!(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) &&
|
||||
if(!(session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE) &&
|
||||
window_size_increment < 0 &&
|
||||
nghttp2_should_send_window_update(stream->local_window_size,
|
||||
stream->recv_window_size)) {
|
||||
|
|
|
@ -403,8 +403,8 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
flow_control_ = true;
|
||||
initial_window_size_ = (1 << get_config()->spdy_upstream_window_bits) - 1;
|
||||
rv = nghttp2_session_set_option(session_,
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE, &val,
|
||||
sizeof(val));
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE,
|
||||
&val, sizeof(val));
|
||||
assert(rv == 0);
|
||||
|
||||
// TODO Maybe call from outside?
|
||||
|
@ -418,9 +418,10 @@ Http2Upstream::Http2Upstream(ClientHandler *handler)
|
|||
rv = nghttp2_submit_settings
|
||||
(session_, entry, sizeof(entry)/sizeof(nghttp2_settings_entry));
|
||||
assert(rv == 0);
|
||||
// Disable connection-level flow control
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_END_FLOW_CONTROL,
|
||||
0, 0);
|
||||
// Set large connection-level window size to effectively disable
|
||||
// connection-level flow control.
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE,
|
||||
0, 1000000007);
|
||||
assert(rv == 0);
|
||||
}
|
||||
|
||||
|
|
|
@ -1057,8 +1057,8 @@ int SpdySession::on_connect()
|
|||
int val = 1;
|
||||
flow_control_ = true;
|
||||
rv = nghttp2_session_set_option(session_,
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE, &val,
|
||||
sizeof(val));
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE,
|
||||
&val, sizeof(val));
|
||||
assert(rv == 0);
|
||||
|
||||
nghttp2_settings_entry entry[2];
|
||||
|
@ -1073,9 +1073,10 @@ int SpdySession::on_connect()
|
|||
if(rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
// Disable connection-level flow control
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_END_FLOW_CONTROL,
|
||||
0, 0);
|
||||
// Set large connection-level window size to effectively disable
|
||||
// connection-level flow control.
|
||||
rv = nghttp2_submit_window_update(session_, NGHTTP2_FLAG_NONE,
|
||||
0, 1000000007);
|
||||
if(rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
|
|
|
@ -3091,17 +3091,20 @@ void test_nghttp2_session_set_option(void)
|
|||
|
||||
intval = 1;
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_session_set_option(session,
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE,
|
||||
&intval, sizeof(intval)));
|
||||
CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE);
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE,
|
||||
&intval, sizeof(intval)));
|
||||
CU_ASSERT(session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE);
|
||||
|
||||
intval = 0;
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_session_set_option(session,
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE,
|
||||
&intval, sizeof(intval)));
|
||||
CU_ASSERT((session->opt_flags & NGHTTP2_OPTMASK_NO_AUTO_WINDOW_UPDATE) == 0);
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE,
|
||||
&intval, sizeof(intval)));
|
||||
CU_ASSERT((session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_STREAM_WINDOW_UPDATE) == 0);
|
||||
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||
nghttp2_session_set_option(session, 0, /* 0 is invalid optname */
|
||||
|
@ -3109,9 +3112,19 @@ void test_nghttp2_session_set_option(void)
|
|||
|
||||
charval = 1;
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||
nghttp2_session_set_option(session,
|
||||
NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE,
|
||||
&charval, sizeof(charval)));
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_NO_AUTO_STREAM_WINDOW_UPDATE,
|
||||
&charval, sizeof(charval)));
|
||||
|
||||
intval = 1;
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_NO_AUTO_CONNECTION_WINDOW_UPDATE,
|
||||
&intval, sizeof(intval)));
|
||||
CU_ASSERT(session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE);
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue