Mercurial > hg > nginx
comparison src/http/v2/ngx_http_v2.c @ 7922:e9f402bfe37e
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.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Mon, 06 Sep 2021 14:54:47 +0300 |
parents | 2245324a507a |
children | 4775c1d27378 |
comparison
equal
deleted
inserted
replaced
7921:2245324a507a | 7922:e9f402bfe37e |
---|---|
1146 if (rc != NGX_OK && rc != NGX_AGAIN) { | 1146 if (rc != NGX_OK && rc != NGX_AGAIN) { |
1147 stream->skip_data = 1; | 1147 stream->skip_data = 1; |
1148 ngx_http_finalize_request(r, rc); | 1148 ngx_http_finalize_request(r, rc); |
1149 } | 1149 } |
1150 | 1150 |
1151 if (rc == NGX_AGAIN && !stream->no_flow_control) { | 1151 if (rc == NGX_AGAIN |
1152 && !stream->no_flow_control | |
1153 && !r->request_body_no_buffering) | |
1154 { | |
1152 buf = r->request_body->buf; | 1155 buf = r->request_body->buf; |
1156 | |
1157 if (r->request_body->busy == NULL) { | |
1158 buf->pos = buf->start; | |
1159 buf->last = buf->start; | |
1160 } | |
1161 | |
1153 window = buf->end - buf->last; | 1162 window = buf->end - buf->last; |
1154 | |
1155 window -= h2c->state.length - size; | 1163 window -= h2c->state.length - size; |
1156 | 1164 |
1157 if (window < stream->recv_window) { | 1165 if (window < stream->recv_window) { |
1158 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0, | 1166 ngx_log_error(NGX_LOG_ALERT, h2c->connection->log, 0, |
1159 "http2 negative window update"); | 1167 "http2 negative window update"); |
4457 | 4465 |
4458 if (r->request_body->rest == 0) { | 4466 if (r->request_body->rest == 0) { |
4459 return; | 4467 return; |
4460 } | 4468 } |
4461 | 4469 |
4470 if (r->request_body->busy != NULL) { | |
4471 return; | |
4472 } | |
4473 | |
4462 stream = r->stream; | 4474 stream = r->stream; |
4463 h2c = stream->connection; | 4475 h2c = stream->connection; |
4464 | 4476 |
4465 buf = r->request_body->buf; | 4477 buf = r->request_body->buf; |
4478 | |
4479 buf->pos = buf->start; | |
4480 buf->last = buf->start; | |
4481 | |
4466 window = buf->end - buf->start; | 4482 window = buf->end - buf->start; |
4467 | 4483 |
4468 if (h2c->state.stream == stream) { | 4484 if (h2c->state.stream == stream) { |
4469 window -= h2c->state.length; | 4485 window -= h2c->state.length; |
4470 } | 4486 } |