diff src/http/ngx_http_request_body.c @ 9259:81082b5521dd

Request body: body is now cleared on errors. Previously, after errors the request body was left in a potentially inconsistent state, with r->headers_in.content_length_n which might be larger than buffers actually stored in r->request_body->bufs (or not set at all, in case of HTTP/2 and HTTP/3). This can cause issues if the request body is subsequently used during error_page handling, such as when proxying. Fix is to clear r->request_body->bufs if this happens, and set r->headers_in.content_length_n to 0, much like it happens when ngx_http_discard_request_body() is called when returning 413 from ngx_http_core_find_config_phase() for requests with Content-Length.
author Maxim Dounin <mdounin@mdounin.ru>
date Sat, 27 Apr 2024 18:21:38 +0300
parents 0748264a1278
children ac5635650bc6
line wrap: on
line diff
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -228,6 +228,11 @@ done:
     }
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+
+        r->lingering_close = 1;
+        r->headers_in.content_length_n = 0;
+        r->request_body->bufs = NULL;
+
         r->main->count--;
         r->read_event_handler = ngx_http_block_reading;
     }
@@ -298,6 +303,11 @@ ngx_http_read_client_request_body_handle
     rc = ngx_http_do_read_client_request_body(r);
 
     if (rc >= NGX_HTTP_SPECIAL_RESPONSE) {
+
+        r->lingering_close = 1;
+        r->headers_in.content_length_n = 0;
+        r->request_body->bufs = NULL;
+
         r->read_event_handler = ngx_http_block_reading;
         ngx_http_finalize_request(r, rc);
     }
@@ -1161,8 +1171,6 @@ ngx_http_request_body_chunked_filter(ngx
                     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                                   "client sent too many chunk extensions");
 
-                    r->lingering_close = 1;
-
                     return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
                 }
 
@@ -1176,8 +1184,6 @@ ngx_http_request_body_chunked_filter(ngx
                                   r->headers_in.content_length_n,
                                   rb->chunked->size);
 
-                    r->lingering_close = 1;
-
                     return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
                 }
 
@@ -1276,8 +1282,6 @@ ngx_http_request_body_chunked_filter(ngx
                                   "client sent too many chunk extensions "
                                   "or trailer headers");
 
-                    r->lingering_close = 1;
-
                     return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
                 }