diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/http/v2/ngx_http_v2.c | 47 | ||||
-rw-r--r-- | src/http/v2/ngx_http_v2.h | 1 |
2 files changed, 39 insertions, 9 deletions
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 235092b21..959f0e725 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -136,6 +136,8 @@ static ngx_int_t ngx_http_v2_send_window_update(ngx_http_v2_connection_t *h2c, ngx_uint_t sid, size_t window); static ngx_int_t ngx_http_v2_send_rst_stream(ngx_http_v2_connection_t *h2c, ngx_uint_t sid, ngx_uint_t status); +static ngx_int_t ngx_http_v2_send_goaway(ngx_http_v2_connection_t *h2c, + ngx_uint_t status); static ngx_http_v2_out_frame_t *ngx_http_v2_get_frame( ngx_http_v2_connection_t *h2c, size_t length, ngx_uint_t type, @@ -293,6 +295,8 @@ ngx_http_v2_init(ngx_event_t *rev) rev->handler = ngx_http_v2_read_handler; c->write->handler = ngx_http_v2_write_handler; + c->idle = 1; + ngx_http_v2_read_handler(rev); } @@ -320,6 +324,25 @@ ngx_http_v2_read_handler(ngx_event_t *rev) h2c->blocked = 1; + 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; + } + + h2c->blocked = 0; + + return; + } + h2mcf = ngx_http_get_module_main_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); @@ -633,6 +656,11 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) /* rc == NGX_OK */ } + if (h2c->goaway) { + ngx_http_close_connection(c); + return; + } + h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, ngx_http_v2_module); if (h2c->state.incomplete) { @@ -640,11 +668,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) return; } - if (ngx_terminate || ngx_exiting) { - ngx_http_v2_finalize_connection(h2c, NGX_HTTP_V2_NO_ERROR); - return; - } - ngx_destroy_pool(h2c->pool); h2c->pool = NULL; @@ -658,7 +681,6 @@ ngx_http_v2_handle_connection(ngx_http_v2_connection_t *h2c) #endif c->destroyed = 1; - c->idle = 1; ngx_reusable_connection(c, 1); c->write->handler = ngx_http_empty_handler; @@ -1027,6 +1049,12 @@ ngx_http_v2_state_headers(ngx_http_v2_connection_t *h2c, u_char *pos, return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } + if (h2c->goaway) { + ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0, + "skipping http2 HEADERS frame"); + return ngx_http_v2_state_skip(h2c, pos, end); + } + if ((size_t) (end - pos) < size) { return ngx_http_v2_state_save(h2c, pos, end, ngx_http_v2_state_headers); @@ -4162,7 +4190,6 @@ ngx_http_v2_idle_handler(ngx_event_t *rev) #endif c->destroyed = 0; - c->idle = 0; ngx_reusable_connection(c, 0); h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx, @@ -4197,8 +4224,10 @@ ngx_http_v2_finalize_connection(ngx_http_v2_connection_t *h2c, h2c->blocked = 1; - if (!c->error && ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) { - (void) ngx_http_v2_send_output_queue(h2c); + if (!c->error && !h2c->goaway) { + if (ngx_http_v2_send_goaway(h2c, status) != NGX_ERROR) { + (void) ngx_http_v2_send_output_queue(h2c); + } } c->error = 1; diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h index d712d3816..63bbdad54 100644 --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h @@ -146,6 +146,7 @@ struct ngx_http_v2_connection_s { unsigned closed_nodes:8; unsigned settings_ack:1; unsigned blocked:1; + unsigned goaway:1; }; |