diff src/http/ngx_http_request_body.c @ 8689:6bd8ed493b85 quic

HTTP/3: refactored request body parser. The change reduces diff to the default branch for src/http/ngx_http_request_body.c. Also, client Content-Length, if present, is now checked against the real body size sent by client.
author Roman Arutyunyan <arut@nginx.com>
date Mon, 25 Jan 2021 16:16:47 +0300
parents 507da0d3b070
children fac88e160653
line wrap: on
line diff
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -87,6 +87,13 @@ ngx_http_read_client_request_body(ngx_ht
     }
 #endif
 
+#if (NGX_HTTP_V3)
+    if (r->http_version == NGX_HTTP_VERSION_30) {
+        rc = ngx_http_v3_read_request_body(r);
+        goto done;
+    }
+#endif
+
     preread = r->header_in->last - r->header_in->pos;
 
     if (preread) {
@@ -229,6 +236,18 @@ ngx_http_read_unbuffered_request_body(ng
     }
 #endif
 
+#if (NGX_HTTP_V3)
+    if (r->http_version == NGX_HTTP_VERSION_30) {
+        rc = ngx_http_v3_read_unbuffered_request_body(r);
+
+        if (rc == NGX_OK) {
+            r->reading_body = 0;
+        }
+
+        return rc;
+    }
+#endif
+
     if (r->connection->read->timedout) {
         r->connection->timedout = 1;
         return NGX_HTTP_REQUEST_TIME_OUT;
@@ -333,10 +352,11 @@ ngx_http_do_read_client_request_body(ngx
             }
 
             if (n == 0) {
-                rb->buf->last_buf = 1;
+                ngx_log_error(NGX_LOG_INFO, c->log, 0,
+                              "client prematurely closed connection");
             }
 
-            if (n == NGX_ERROR) {
+            if (n == 0 || n == NGX_ERROR) {
                 c->error = 1;
                 return NGX_HTTP_BAD_REQUEST;
             }
@@ -583,8 +603,8 @@ ngx_http_discard_request_body(ngx_http_r
     }
 #endif
 
-#if (NGX_HTTP_QUIC)
-    if (r->connection->quic) {
+#if (NGX_HTTP_V3)
+    if (r->http_version == NGX_HTTP_VERSION_30) {
         return NGX_OK;
     }
 #endif
@@ -956,15 +976,6 @@ ngx_http_request_body_length_filter(ngx_
             break;
         }
 
-        size = cl->buf->last - cl->buf->pos;
-
-        if (cl->buf->last_buf && (off_t) size < rb->rest) {
-            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                          "client prematurely closed connection");
-            r->connection->error = 1;
-            return NGX_HTTP_BAD_REQUEST;
-        }
-
         tl = ngx_chain_get_free_buf(r->pool, &rb->free);
         if (tl == NULL) {
             return NGX_HTTP_INTERNAL_SERVER_ERROR;
@@ -982,6 +993,8 @@ ngx_http_request_body_length_filter(ngx_
         b->end = cl->buf->end;
         b->flush = r->request_body_no_buffering;
 
+        size = cl->buf->last - cl->buf->pos;
+
         if ((off_t) size < rb->rest) {
             cl->buf->pos = cl->buf->last;
             rb->rest -= size;
@@ -1053,16 +1066,7 @@ ngx_http_request_body_chunked_filter(ngx
                            cl->buf->file_pos,
                            cl->buf->file_last - cl->buf->file_pos);
 
-            switch (r->http_version) {
-#if (NGX_HTTP_V3)
-            case NGX_HTTP_VERSION_30:
-                rc = ngx_http_v3_parse_request_body(r, cl->buf, rb->chunked);
-                break;
-#endif
-
-            default: /* HTTP/1.x */
-                rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked);
-            }
+            rc = ngx_http_parse_chunked(r, cl->buf, rb->chunked);
 
             if (rc == NGX_OK) {
 
@@ -1146,20 +1150,6 @@ ngx_http_request_body_chunked_filter(ngx
                 continue;
             }
 
-            if (rc == NGX_AGAIN && cl->buf->last_buf) {
-
-                /* last body buffer */
-
-                if (rb->chunked->length > 0) {
-                    ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                                  "client prematurely closed connection");
-                    r->connection->error = 1;
-                    return NGX_HTTP_BAD_REQUEST;
-                }
-
-                rc = NGX_DONE;
-            }
-
             if (rc == NGX_DONE) {
 
                 /* a whole response has been parsed successfully */