[nginx] HTTP/2: fixed timers left after request body reading.

Maxim Dounin mdounin at mdounin.ru
Mon Sep 6 13:41:01 UTC 2021


details:   https://hg.nginx.org/nginx/rev/4775c1d27378
branches:  
changeset: 7923:4775c1d27378
user:      Maxim Dounin <mdounin at mdounin.ru>
date:      Mon Sep 06 14:54:48 2021 +0300
description:
HTTP/2: fixed timers left after request body reading.

Following rb->filter_need_buffering changes, request body reading is
only finished after the filter chain is called and rb->last_saved is set.
As such, with r->request_body_no_buffering, timer on fc->read is no
longer removed when the last part of the body is received, potentially
resulting in incorrect behaviour.

The fix is to call ngx_http_v2_process_request_body() from the
ngx_http_v2_read_unbuffered_request_body() function instead of
directly calling ngx_http_v2_filter_request_body(), so the timer
is properly removed.

diffstat:

 src/http/v2/ngx_http_v2.c |  26 +++++++++++++-------------
 1 files changed, 13 insertions(+), 13 deletions(-)

diffs (75 lines):

diff -r e9f402bfe37e -r 4775c1d27378 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c	Mon Sep 06 14:54:47 2021 +0300
+++ b/src/http/v2/ngx_http_v2.c	Mon Sep 06 14:54:48 2021 +0300
@@ -4263,7 +4263,7 @@ ngx_http_v2_process_request_body(ngx_htt
                 rb->rest = 0;
             }
 
-            if (r->request_body_no_buffering) {
+            if (r->request_body_no_buffering && !flush) {
                 break;
             }
 
@@ -4296,7 +4296,10 @@ ngx_http_v2_process_request_body(ngx_htt
             ngx_add_timer(fc->read, clcf->client_body_timeout);
 
             if (r->request_body_no_buffering) {
-                ngx_post_event(fc->read, &ngx_posted_events);
+                if (!flush) {
+                    ngx_post_event(fc->read, &ngx_posted_events);
+                }
+
                 return NGX_AGAIN;
             }
 
@@ -4309,7 +4312,10 @@ ngx_http_v2_process_request_body(ngx_htt
     }
 
     if (r->request_body_no_buffering) {
-        ngx_post_event(fc->read, &ngx_posted_events);
+        if (!flush) {
+            ngx_post_event(fc->read, &ngx_posted_events);
+        }
+
         return NGX_OK;
     }
 
@@ -4527,7 +4533,6 @@ ngx_http_v2_read_unbuffered_request_body
     ngx_connection_t          *fc;
     ngx_http_v2_stream_t      *stream;
     ngx_http_v2_connection_t  *h2c;
-    ngx_http_core_loc_conf_t  *clcf;
 
     stream = r->stream;
     fc = r->connection;
@@ -4551,14 +4556,14 @@ ngx_http_v2_read_unbuffered_request_body
         return NGX_HTTP_BAD_REQUEST;
     }
 
-    rc = ngx_http_v2_filter_request_body(r);
-
-    if (rc != NGX_OK) {
+    rc = ngx_http_v2_process_request_body(r, NULL, 0, r->stream->in_closed, 1);
+
+    if (rc != NGX_OK && rc != NGX_AGAIN) {
         stream->skip_data = 1;
         return rc;
     }
 
-    if (r->request_body->rest == 0 && r->request_body->last_saved) {
+    if (rc == NGX_OK) {
         return NGX_OK;
     }
 
@@ -4606,11 +4611,6 @@ ngx_http_v2_read_unbuffered_request_body
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    if (stream->recv_window == 0) {
-        clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-        ngx_add_timer(fc->read, clcf->client_body_timeout);
-    }
-
     stream->recv_window = window;
 
     return NGX_AGAIN;


More information about the nginx-devel mailing list