# HG changeset patch # User Roman Arutyunyan # Date 1709374556 -14400 # Sat Mar 02 14:15:56 2024 +0400 # Node ID b71f25f24f633ebdd75e6a7ddd87826239def54f # Parent 44da04c2d4db94ad4eefa84b299e07c5fa4a00b9 Fixed 413 custom error page for HTTP/2 and HTTP/3. Previously an attempt to return a custom 413 error page for these protocols resulted in the standard 413 page (if recursive_error_pages was off) or otherwise internal redirection cycle followed by the 500 error. Discarding request body for HTTP/1 results in setting r->discard_body which indicates the body is currently being discarded. If and when the entire body is read and discarded, the flag is cleared and r->headers_in.content_length_n is set to zero. Both r->discard_body and r->headers_in.content_length_n prevent nginx from re-genereting 413 error after internal redirect in ngx_http_core_find_config_phase(). However the above does not work for HTTP/2 and HTTP/3. Discarding request body for these protocols does not change the request flags and data (except skip_data internal HTTP/2 field), which provides no protection against re-generating the 413 error. The fix is to assign zero to r->headers_in.content_length_n much like in HTTP/1 case after the body is entirely read and discarded, except for these protocols no active discard is needed. diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c --- a/src/http/ngx_http_request_body.c +++ b/src/http/ngx_http_request_body.c @@ -640,12 +640,14 @@ ngx_http_discard_request_body(ngx_http_r #if (NGX_HTTP_V2) if (r->stream) { r->stream->skip_data = 1; + r->headers_in.content_length_n = 0; return NGX_OK; } #endif #if (NGX_HTTP_V3) if (r->http_version == NGX_HTTP_VERSION_30) { + r->headers_in.content_length_n = 0; return NGX_OK; } #endif