From: Zhidao HONG Date: Mon, 1 Jun 2026 08:41:33 +0000 (+0000) Subject: HTTP/2: fixed INITIAL_WINDOW_SIZE with saved state X-Git-Url: http://git.kaiwu.me/http/$%7BGITURL%7D/$%7BGITURL%7D$%7Bcid%7D?a=commitdiff_plain;h=5f92d7afb8b55f9ae5bb67256fa52f96c59eda3e;p=nginx.git HTTP/2: fixed INITIAL_WINDOW_SIZE with saved state The window size change was previously kept in a local variable while processing SETTINGS parameters. If parsing was suspended after SETTINGS_INITIAL_WINDOW_SIZE, the value was lost on resume and was acknowledged without being applied. Store the initial window size change in the HTTP/2 state until the SETTINGS frame is fully processed. --- diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c index 69cb0ae09..f8f876725 100644 --- a/src/http/v2/ngx_http_v2.c +++ b/src/http/v2/ngx_http_v2.c @@ -2181,6 +2181,8 @@ ngx_http_v2_state_settings(ngx_http_v2_connection_t *h2c, u_char *pos, return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR); } + h2c->state.window_delta = 0; + return ngx_http_v2_state_settings_params(h2c, pos, end); } @@ -2189,12 +2191,9 @@ static u_char * ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end) { - ssize_t window_delta; ngx_uint_t id, value; ngx_http_v2_out_frame_t *frame; - window_delta = 0; - while (h2c->state.length) { if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) { return ngx_http_v2_state_save(h2c, pos, end, @@ -2222,7 +2221,8 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, NGX_HTTP_V2_FLOW_CTRL_ERROR); } - window_delta = value - h2c->init_window; + h2c->state.window_delta = (ssize_t) value + - (ssize_t) h2c->init_window; break; case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING: @@ -2275,13 +2275,16 @@ ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos, ngx_http_v2_queue_ordered_frame(h2c, frame); - if (window_delta) { - h2c->init_window += window_delta; + if (h2c->state.window_delta) { + h2c->init_window += h2c->state.window_delta; - if (ngx_http_v2_adjust_windows(h2c, window_delta) != NGX_OK) { + if (ngx_http_v2_adjust_windows(h2c, h2c->state.window_delta) != NGX_OK) + { return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_INTERNAL_ERROR); } + + h2c->state.window_delta = 0; } return ngx_http_v2_state_complete(h2c, pos, end); diff --git a/src/http/v2/ngx_http_v2.h b/src/http/v2/ngx_http_v2.h index 9605c8a23..beb77a5c1 100644 --- a/src/http/v2/ngx_http_v2.h +++ b/src/http/v2/ngx_http_v2.h @@ -80,6 +80,7 @@ typedef struct { ngx_uint_t sid; size_t length; size_t padding; + ssize_t window_delta; unsigned flags:8; unsigned incomplete:1;