aboutsummaryrefslogtreecommitdiff
path: root/src/http/v2/ngx_http_v2.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/http/v2/ngx_http_v2.c')
-rw-r--r--src/http/v2/ngx_http_v2.c108
1 files changed, 69 insertions, 39 deletions
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 77b60d42e..a59528494 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -325,7 +325,12 @@ ngx_http_v2_init(ngx_event_t *rev)
rev->handler = ngx_http_v2_read_handler;
c->write->handler = ngx_http_v2_write_handler;
+ if (c->read->timer_set) {
+ ngx_del_timer(c->read);
+ }
+
c->idle = 1;
+ ngx_reusable_connection(c, 0);
ngx_http_v2_read_handler(rev);
}
@@ -362,6 +367,11 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
return;
}
+ if (!h2c->processing && !h2c->pushing) {
+ ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
+ return;
+ }
+
if (!h2c->goaway) {
h2c->goaway = 1;
@@ -449,14 +459,6 @@ ngx_http_v2_read_handler(ngx_event_t *rev)
h2c->blocked = 0;
- if (h2c->processing || h2c->pushing) {
- if (rev->timer_set) {
- ngx_del_timer(rev);
- }
-
- return;
- }
-
ngx_http_v2_handle_connection(h2c);
}
@@ -629,9 +631,9 @@ error:
static void
ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
{
- ngx_int_t rc;
- ngx_connection_t *c;
- ngx_http_v2_srv_conf_t *h2scf;
+ ngx_int_t rc;
+ ngx_connection_t *c;
+ ngx_http_core_loc_conf_t *clcf;
if (h2c->last_out || h2c->processing || h2c->pushing) {
return;
@@ -668,10 +670,16 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
return;
}
- h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
- ngx_http_v2_module);
+ clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
+ ngx_http_core_module);
+
+ if (!c->read->timer_set) {
+ ngx_add_timer(c->read, clcf->keepalive_timeout);
+ }
+
+ ngx_reusable_connection(c, 1);
+
if (h2c->state.incomplete) {
- ngx_add_timer(c->read, h2scf->recv_timeout);
return;
}
@@ -689,7 +697,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
#endif
c->destroyed = 1;
- ngx_reusable_connection(c, 1);
c->write->handler = ngx_http_empty_handler;
c->read->handler = ngx_http_v2_idle_handler;
@@ -697,8 +704,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c)
if (c->write->timer_set) {
ngx_del_timer(c->write);
}
-
- ngx_add_timer(c->read, h2scf->idle_timeout);
}
@@ -767,6 +772,9 @@ ngx_http_v2_lingering_close(ngx_connection_t *c)
return;
}
+ c->close = 0;
+ ngx_reusable_connection(c, 1);
+
ngx_add_timer(rev, clcf->lingering_timeout);
if (rev->ready) {
@@ -791,7 +799,7 @@ ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
"http2 lingering close handler");
- if (rev->timedout) {
+ if (rev->timedout || c->close) {
ngx_http_close_connection(c);
return;
}
@@ -807,6 +815,10 @@ ngx_http_v2_lingering_close_handler(ngx_event_t *rev)
ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0, "lingering read: %z", n);
+ if (n == NGX_AGAIN) {
+ break;
+ }
+
if (n == NGX_ERROR || n == 0) {
ngx_http_close_connection(c);
return;
@@ -1179,12 +1191,15 @@ static u_char *
ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
u_char *end)
{
- size_t size;
- ngx_uint_t padded, priority, depend, dependency, excl, weight;
- ngx_uint_t status;
- ngx_http_v2_node_t *node;
- ngx_http_v2_stream_t *stream;
- ngx_http_v2_srv_conf_t *h2scf;
+ size_t size;
+ ngx_uint_t padded, priority, depend, dependency, excl,
+ weight;
+ ngx_uint_t status;
+ ngx_http_v2_node_t *node;
+ ngx_http_v2_stream_t *stream;
+ ngx_http_v2_srv_conf_t *h2scf;
+ ngx_http_core_srv_conf_t *cscf;
+ ngx_http_core_loc_conf_t *clcf;
padded = h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG;
priority = h2c->state.flags & NGX_HTTP_V2_PRIORITY_FLAG;
@@ -1285,11 +1300,15 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR);
}
+ cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
+ ngx_http_core_module);
+
+ h2c->state.header_limit = cscf->large_client_header_buffers.size
+ * cscf->large_client_header_buffers.num;
+
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
ngx_http_v2_module);
- h2c->state.header_limit = h2scf->max_header_size;
-
if (h2c->processing >= h2scf->concurrent_streams) {
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
"concurrent streams exceeded %ui", h2c->processing);
@@ -1343,7 +1362,10 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos,
ngx_http_v2_set_dependency(h2c, node, depend, excl);
}
- if (h2c->connection->requests >= h2scf->max_requests) {
+ clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
+ ngx_http_core_module);
+
+ if (h2c->connection->requests >= clcf->keepalive_requests) {
h2c->goaway = 1;
if (ngx_http_v2_send_goaway(h2c, NGX_HTTP_V2_NO_ERROR) == NGX_ERROR) {
@@ -1468,10 +1490,10 @@ static u_char *
ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
u_char *end)
{
- size_t alloc;
- ngx_int_t len;
- ngx_uint_t huff;
- ngx_http_v2_srv_conf_t *h2scf;
+ size_t alloc;
+ ngx_int_t len;
+ ngx_uint_t huff;
+ ngx_http_core_srv_conf_t *cscf;
if (!(h2c->state.flags & NGX_HTTP_V2_END_HEADERS_FLAG)
&& h2c->state.length < NGX_HTTP_V2_INT_OCTETS)
@@ -1518,12 +1540,12 @@ ngx_http_v2_state_field_len(ngx_http_v2_connection_t *h2c, u_char *pos,
"http2 %s string, len:%i",
huff ? "encoded" : "raw", len);
- h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
- ngx_http_v2_module);
+ cscf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
+ ngx_http_core_module);
- if ((size_t) len > h2scf->max_field_size) {
+ if ((size_t) len > cscf->large_client_header_buffers.size) {
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
- "client exceeded http2_max_field_size limit");
+ "client sent too large header field");
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
}
@@ -1738,7 +1760,7 @@ ngx_http_v2_state_process_header(ngx_http_v2_connection_t *h2c, u_char *pos,
if (len > h2c->state.header_limit) {
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
- "client exceeded http2_max_header_size limit");
+ "client sent too large header");
return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_ENHANCE_YOUR_CALM);
}
@@ -3272,6 +3294,10 @@ ngx_http_v2_create_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t push)
h2c->priority_limit += h2scf->concurrent_streams;
+ if (h2c->connection->read->timer_set) {
+ ngx_del_timer(h2c->connection->read);
+ }
+
return stream;
}
@@ -4638,6 +4664,7 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
ngx_connection_t *c;
ngx_http_v2_srv_conf_t *h2scf;
ngx_http_v2_connection_t *h2c;
+ ngx_http_core_loc_conf_t *clcf;
c = rev->data;
h2c = c->data;
@@ -4669,10 +4696,10 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
#endif
- h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
- ngx_http_v2_module);
+ clcf = ngx_http_get_module_loc_conf(h2c->http_connection->conf_ctx,
+ ngx_http_core_module);
- if (h2c->idle++ > 10 * h2scf->max_requests) {
+ if (h2c->idle++ > 10 * clcf->keepalive_requests) {
ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
"http2 flood detected");
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR);
@@ -4682,6 +4709,9 @@ ngx_http_v2_idle_handler(ngx_event_t *rev)
c->destroyed = 0;
ngx_reusable_connection(c, 0);
+ h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
+ ngx_http_v2_module);
+
h2c->pool = ngx_create_pool(h2scf->pool_size, h2c->connection->log);
if (h2c->pool == NULL) {
ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_INTERNAL_ERROR);