| 1 | # HG changeset patch
|
|---|
| 2 | # User Roman Arutyunyan <arut@nginx.com>
|
|---|
| 3 | # Date 1709374556 -14400
|
|---|
| 4 | # Sat Mar 02 14:15:56 2024 +0400
|
|---|
| 5 | # Node ID b71f25f24f633ebdd75e6a7ddd87826239def54f
|
|---|
| 6 | # Parent 44da04c2d4db94ad4eefa84b299e07c5fa4a00b9
|
|---|
| 7 | Fixed 413 custom error page for HTTP/2 and HTTP/3.
|
|---|
| 8 |
|
|---|
| 9 | Previously an attempt to return a custom 413 error page for these protocols
|
|---|
| 10 | resulted in the standard 413 page (if recursive_error_pages was off) or
|
|---|
| 11 | otherwise internal redirection cycle followed by the 500 error.
|
|---|
| 12 |
|
|---|
| 13 | Discarding request body for HTTP/1 results in setting r->discard_body which
|
|---|
| 14 | indicates the body is currently being discarded. If and when the entire body
|
|---|
| 15 | is read and discarded, the flag is cleared and r->headers_in.content_length_n
|
|---|
| 16 | is set to zero. Both r->discard_body and r->headers_in.content_length_n
|
|---|
| 17 | prevent nginx from re-genereting 413 error after internal redirect in
|
|---|
| 18 | ngx_http_core_find_config_phase().
|
|---|
| 19 |
|
|---|
| 20 | However the above does not work for HTTP/2 and HTTP/3. Discarding request
|
|---|
| 21 | body for these protocols does not change the request flags and data
|
|---|
| 22 | (except skip_data internal HTTP/2 field), which provides no protection against
|
|---|
| 23 | re-generating the 413 error. The fix is to assign zero to
|
|---|
| 24 | r->headers_in.content_length_n much like in HTTP/1 case after the body is
|
|---|
| 25 | entirely read and discarded, except for these protocols no active discard is
|
|---|
| 26 | needed.
|
|---|
| 27 |
|
|---|
| 28 | diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
|
|---|
| 29 | --- a/src/http/ngx_http_request_body.c
|
|---|
| 30 | +++ b/src/http/ngx_http_request_body.c
|
|---|
| 31 | @@ -640,12 +640,14 @@ ngx_http_discard_request_body(ngx_http_r
|
|---|
| 32 | #if (NGX_HTTP_V2)
|
|---|
| 33 | if (r->stream) {
|
|---|
| 34 | r->stream->skip_data = 1;
|
|---|
| 35 | + r->headers_in.content_length_n = 0;
|
|---|
| 36 | return NGX_OK;
|
|---|
| 37 | }
|
|---|
| 38 | #endif
|
|---|
| 39 |
|
|---|
| 40 | #if (NGX_HTTP_V3)
|
|---|
| 41 | if (r->http_version == NGX_HTTP_VERSION_30) {
|
|---|
| 42 | + r->headers_in.content_length_n = 0;
|
|---|
| 43 | return NGX_OK;
|
|---|
| 44 | }
|
|---|
| 45 | #endif
|
|---|