Add NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS option
And utilize it in nghttp to limit initial max concurrent streams.
This commit is contained in:
parent
c5d7d570e3
commit
99ba622fed
|
@ -1202,7 +1202,21 @@ typedef enum {
|
|||
* 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_NO_AUTO_CONNECTION_WINDOW_UPDATE = 2,
|
||||
/**
|
||||
* This option sets the SETTINGS_MAX_CONCURRENT_STREAMS value of
|
||||
* remote endpoint as if it is received in SETTINGS frame. Without
|
||||
* specifying this option, before the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS in SETTINGS frame from remote
|
||||
* endpoint, SETTINGS_MAX_CONCURRENT_STREAMS is unlimited. This may
|
||||
* cause problem if local endpoint submits lots of requests
|
||||
* initially and sending them at once to the remote peer may lead to
|
||||
* the rejection of some requests. Specifying this option to the
|
||||
* sensible value, say 100, may avoid this kind of issue. This value
|
||||
* will be overwritten if the local endpoint receives
|
||||
* SETTINGS_MAX_CONCURRENT_STREAMS from the remote endpoint.
|
||||
*/
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS = 3
|
||||
} nghttp2_opt;
|
||||
|
||||
/**
|
||||
|
@ -1230,6 +1244,10 @@ typedef enum {
|
|||
* sending WINDOW_UPDATE using
|
||||
* `nghttp2_submit_window_update`. This option defaults to 0.
|
||||
*
|
||||
* :enum:`NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS`
|
||||
* The |optval| must be a pointer to ``ssize_t``. It is an error
|
||||
* if |*optval| is 0 or negative.
|
||||
*
|
||||
* This function returns 0 if it succeeds, or one of the following
|
||||
* negative error codes:
|
||||
*
|
||||
|
|
|
@ -3264,6 +3264,19 @@ int nghttp2_session_set_option(nghttp2_session *session,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS: {
|
||||
ssize_t sszval;
|
||||
if(optlen != sizeof(ssize_t)) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
sszval = *(ssize_t*)optval;
|
||||
if(sszval <= 0) {
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
session->remote_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS] =
|
||||
sszval;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
return NGHTTP2_ERR_INVALID_ARGUMENT;
|
||||
}
|
||||
|
|
|
@ -91,6 +91,7 @@ struct Config {
|
|||
std::map<std::string, std::string> headers;
|
||||
std::string datafile;
|
||||
size_t output_upper_thres;
|
||||
ssize_t peer_max_concurrent_streams;
|
||||
Config()
|
||||
: null_out(false),
|
||||
remote_name(false),
|
||||
|
@ -103,7 +104,8 @@ struct Config {
|
|||
multiply(1),
|
||||
timeout(-1),
|
||||
window_bits(-1),
|
||||
output_upper_thres(1024*1024)
|
||||
output_upper_thres(1024*1024),
|
||||
peer_max_concurrent_streams(NGHTTP2_INITIAL_MAX_CONCURRENT_STREAMS)
|
||||
{}
|
||||
};
|
||||
|
||||
|
@ -623,6 +625,13 @@ struct HttpClient {
|
|||
if(rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
rv = nghttp2_session_set_option(session,
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS,
|
||||
&config.peer_max_concurrent_streams,
|
||||
sizeof(config.peer_max_concurrent_streams));
|
||||
if(rv != 0) {
|
||||
return -1;
|
||||
}
|
||||
if(need_upgrade()) {
|
||||
// Adjust stream user-data depending on the existence of upload
|
||||
// data
|
||||
|
@ -1471,6 +1480,11 @@ void print_help(std::ostream& out)
|
|||
<< " -p, --pri=<PRIORITY>\n"
|
||||
<< " Sets stream priority. Default: "
|
||||
<< NGHTTP2_PRI_DEFAULT << "\n"
|
||||
<< " --peer-max-concurrent-streams=<N>\n"
|
||||
<< " Use <N> as SETTINGS_MAX_CONCURRENT_STREAMS\n"
|
||||
<< " value of remote endpoint as if it is\n"
|
||||
<< " received in SETTINGS frame. The default\n"
|
||||
<< " is large enough as it is seen as unlimited.\n"
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
|
@ -1495,6 +1509,7 @@ int main(int argc, char **argv)
|
|||
{"no-flow-control", no_argument, nullptr, 'f'},
|
||||
{"upgrade", no_argument, nullptr, 'u'},
|
||||
{"pri", required_argument, nullptr, 'p'},
|
||||
{"peer-max-concurrent-streams", required_argument, &flag, 3},
|
||||
{nullptr, 0, nullptr, 0 }
|
||||
};
|
||||
int option_index = 0;
|
||||
|
@ -1602,6 +1617,10 @@ int main(int argc, char **argv)
|
|||
// key option
|
||||
config.keyfile = optarg;
|
||||
break;
|
||||
case 3:
|
||||
// peer-max-concurrent-streams option
|
||||
config.peer_max_concurrent_streams = strtoul(optarg, nullptr, 10);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
|
@ -3248,6 +3248,7 @@ void test_nghttp2_session_set_option(void)
|
|||
nghttp2_session_callbacks callbacks;
|
||||
int intval;
|
||||
char charval;
|
||||
ssize_t sszval;
|
||||
memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
|
||||
nghttp2_session_client_new(&session, &callbacks, NULL);
|
||||
|
||||
|
@ -3288,6 +3289,29 @@ void test_nghttp2_session_set_option(void)
|
|||
CU_ASSERT(session->opt_flags &
|
||||
NGHTTP2_OPTMASK_NO_AUTO_CONNECTION_WINDOW_UPDATE);
|
||||
|
||||
sszval = 100;
|
||||
CU_ASSERT(0 ==
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS,
|
||||
&sszval, sizeof(sszval)));
|
||||
CU_ASSERT(sszval ==
|
||||
session->remote_settings[NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS]);
|
||||
|
||||
sszval = 0;
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS,
|
||||
&sszval, sizeof(sszval)));
|
||||
|
||||
intval = 100;
|
||||
CU_ASSERT(NGHTTP2_ERR_INVALID_ARGUMENT ==
|
||||
nghttp2_session_set_option
|
||||
(session,
|
||||
NGHTTP2_OPT_PEER_MAX_CONCURRENT_STREAMS,
|
||||
&intval, sizeof(intval)));
|
||||
|
||||
nghttp2_session_del(session);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue