aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/http/v2/ngx_http_v2.c47
-rw-r--r--src/http/v2/ngx_http_v2.h1
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;
};