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,
rev->handler = ngx_http_v2_read_handler;
c->write->handler = ngx_http_v2_write_handler;
+ c->idle = 1;
+
ngx_http_v2_read_handler(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);
/* 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) {
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;
#endif
c->destroyed = 1;
- c->idle = 1;
ngx_reusable_connection(c, 1);
c->write->handler = ngx_http_empty_handler;
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);
#endif
c->destroyed = 0;
- c->idle = 0;
ngx_reusable_connection(c, 0);
h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
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;