# HG changeset patch # User Valentin Bartenev # Date 1477920782 -10800 # Node ID 9027991e2f37d3b939093ca470aa5a61e506c5b2 # Parent b123eae3fd4e72e430247690e0cec5838b546055 HTTP/2: limited maximum number of requests in connection. The new directive "http2_max_requests" is introduced. From users point of view it works quite similar to "keepalive_requests" but has significantly bigger default value that is more suitable for HTTP/2. diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -326,16 +326,21 @@ ngx_http_v2_read_handler(ngx_event_t *re if (c->close) { c->close = 0; - h2c->goaway = 1; - - if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) { - ngx_http_v2_finalize_connection(h2c, 0); - return; - } - - if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { - ngx_http_v2_finalize_connection(h2c, 0); - return; + + if (!h2c->goaway) { + h2c->goaway = 1; + + if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) + == NGX_ERROR) + { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } + + if (ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) { + ngx_http_v2_finalize_connection(h2c, 0); + return; + } } h2c->blocked = 0; @@ -1177,6 +1182,15 @@ ngx_http_v2_state_headers(ngx_http_v2_co ngx_http_v2_set_dependency(h2c, node, depend, excl); } + if (h2c->connection->requests >= h2scf->max_requests) { + h2c->goaway = 1; + + if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) { + return ngx_http_v2_connection_error(h2c, + NGX_HTTP_V2_INTERNAL_ERROR); + } + } + return ngx_http_v2_state_header_block(h2c, pos, end); rst_stream: diff --git a/src/http/v2/ngx_http_v2_module.c b/src/http/v2/ngx_http_v2_module.c --- a/src/http/v2/ngx_http_v2_module.c +++ b/src/http/v2/ngx_http_v2_module.c @@ -73,6 +73,13 @@ static ngx_command_t ngx_http_v2_comman offsetof(ngx_http_v2_srv_conf_t, concurrent_streams), NULL }, + { ngx_string("http2_max_requests"), + NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, + ngx_conf_set_num_slot, + NGX_HTTP_SRV_CONF_OFFSET, + offsetof(ngx_http_v2_srv_conf_t, max_requests), + NULL }, + { ngx_string("http2_max_field_size"), NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_CONF_TAKE1, ngx_conf_set_size_slot, @@ -322,6 +329,7 @@ ngx_http_v2_create_srv_conf(ngx_conf_t * h2scf->pool_size = NGX_CONF_UNSET_SIZE; h2scf->concurrent_streams = NGX_CONF_UNSET_UINT; + h2scf->max_requests = NGX_CONF_UNSET_UINT; h2scf->max_field_size = NGX_CONF_UNSET_SIZE; h2scf->max_header_size = NGX_CONF_UNSET_SIZE; @@ -347,6 +355,7 @@ ngx_http_v2_merge_srv_conf(ngx_conf_t *c ngx_conf_merge_uint_value(conf->concurrent_streams, prev->concurrent_streams, 128); + ngx_conf_merge_uint_value(conf->max_requests, prev->max_requests, 1000); ngx_conf_merge_size_value(conf->max_field_size, prev->max_field_size, 4096); diff --git a/src/http/v2/ngx_http_v2_module.h b/src/http/v2/ngx_http_v2_module.h --- a/src/http/v2/ngx_http_v2_module.h +++ b/src/http/v2/ngx_http_v2_module.h @@ -23,6 +23,7 @@ typedef struct { typedef struct { size_t pool_size; ngx_uint_t concurrent_streams; + ngx_uint_t max_requests; size_t max_field_size; size_t max_header_size; size_t preread_size;