# HG changeset patch # User Maxim Dounin # Date 1630929287 -10800 # Node ID e9f402bfe37efe964b984a088dc667fee92e44be # Parent 2245324a507abc54cf0274fd1b1e81bfac7c1c73 HTTP/2: fixed window updates when buffering in filters. In the body read handler, the window was incorrectly calculated based on the full buffer size instead of the amount of free space in the buffer. If the request body is buffered by a filter, and the buffer is not empty after the read event is generated by the filter to resume request body processing, this could result in "http2 negative window update" alerts. Further, in the body ready handler and in ngx_http_v2_state_read_data() the buffer wasn't cleared when the data were already written to disk, so the client might stuck without window updates. diff -r 2245324a507a -r e9f402bfe37e src/http/v2/ngx_http_v2.c --- a/src/http/v2/ngx_http_v2.c Thu Sep 02 12:25:37 2021 +0300 +++ b/src/http/v2/ngx_http_v2.c Mon Sep 06 14:54:47 2021 +0300 @@ -1148,10 +1148,18 @@ ngx_http_finalize_request(r, rc); } - if (rc == NGX_AGAIN && !stream->no_flow_control) { + if (rc == NGX_AGAIN + && !stream->no_flow_control + && !r->request_body_no_buffering) + { buf = r->request_body->buf; + + if (r->request_body->busy == NULL) { + buf->pos = buf->start; + buf->last = buf->start; + } + window = buf->end - buf->last; - window -= h2c->state.length - size; if (window < stream->recv_window) { @@ -4459,10 +4467,18 @@ return; } + if (r->request_body->busy != NULL) { + return; + } + stream = r->stream; h2c = stream->connection; buf = r->request_body->buf; + + buf->pos = buf->start; + buf->last = buf->start; + window = buf->end - buf->start; if (h2c->state.stream == stream) {