changeset 8847:e29c1ede905f quic

HTTP/3: reading body buffering in filters. This change follows similar changes in HTTP/1 and HTTP/2 in 9cf043a5d9ca.
author Roman Arutyunyan <arut@nginx.com>
date Thu, 09 Sep 2021 15:47:29 +0300
parents cbbe901c199d
children b5a305db30e0
files src/http/v3/ngx_http_v3_request.c
diffstat 1 files changed, 35 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/http/v3/ngx_http_v3_request.c
+++ b/src/http/v3/ngx_http_v3_request.c
@@ -822,7 +822,7 @@ ngx_http_v3_read_request_body(ngx_http_r
         return rc;
     }
 
-    if (rb->rest == 0) {
+    if (rb->rest == 0 && rb->last_saved) {
         /* the whole request body was pre-read */
         r->request_body_no_buffering = 0;
         rb->post_handler(r);
@@ -895,6 +895,7 @@ ngx_http_v3_do_read_client_request_body(
     size_t                     size;
     ssize_t                    n;
     ngx_int_t                  rc;
+    ngx_uint_t                 flush;
     ngx_chain_t                out;
     ngx_connection_t          *c;
     ngx_http_request_body_t   *rb;
@@ -902,12 +903,17 @@ ngx_http_v3_do_read_client_request_body(
 
     c = r->connection;
     rb = r->request_body;
+    flush = 1;
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http3 read client request body");
 
     for ( ;; ) {
         for ( ;; ) {
+            if (rb->rest == 0) {
+                break;
+            }
+
             if (rb->buf->last == rb->buf->end) {
 
                 /* update chains */
@@ -931,12 +937,25 @@ ngx_http_v3_do_read_client_request_body(
                         return NGX_AGAIN;
                     }
 
+                    if (rb->filter_need_buffering) {
+                        clcf = ngx_http_get_module_loc_conf(r,
+                                                         ngx_http_core_module);
+                        ngx_add_timer(c->read, clcf->client_body_timeout);
+
+                        if (ngx_handle_read_event(c->read, 0) != NGX_OK) {
+                            return NGX_HTTP_INTERNAL_SERVER_ERROR;
+                        }
+
+                        return NGX_AGAIN;
+                    }
+
                     ngx_log_error(NGX_LOG_ALERT, c->log, 0,
                                   "busy buffers after request body flush");
 
                     return NGX_HTTP_INTERNAL_SERVER_ERROR;
                 }
 
+                flush = 0;
                 rb->buf->pos = rb->buf->start;
                 rb->buf->last = rb->buf->start;
             }
@@ -948,6 +967,10 @@ ngx_http_v3_do_read_client_request_body(
                 size = (size_t) rest;
             }
 
+            if (size == 0) {
+                break;
+            }
+
             n = c->recv(c, rb->buf->last, size);
 
             ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
@@ -970,6 +993,7 @@ ngx_http_v3_do_read_client_request_body(
 
             /* pass buffer to request body filter chain */
 
+            flush = 0;
             out.buf = rb->buf;
             out.next = NULL;
 
@@ -991,11 +1015,19 @@ ngx_http_v3_do_read_client_request_body(
         ngx_log_debug1(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http3 client request body rest %O", rb->rest);
 
-        if (rb->rest == 0) {
+        if (flush) {
+            rc = ngx_http_v3_request_body_filter(r, NULL);
+
+            if (rc != NGX_OK) {
+                return rc;
+            }
+        }
+
+        if (rb->rest == 0 && rb->last_saved) {
             break;
         }
 
-        if (!c->read->ready) {
+        if (!c->read->ready || rb->rest == 0) {
 
             clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
             ngx_add_timer(c->read, clcf->client_body_timeout);