Mercurial > hg > nginx
comparison src/http/ngx_http_request.c @ 9261:f798ecafec05
Request body: error_page 413 handling with HTTP/2 and HTTP/3.
When the client_max_body_size limit in ngx_http_core_find_config_phase()
is hit, nginx calls the ngx_http_discard_request_body() function, which
normally sets the r->discard_body flag while discarding the body, and then
reduces the r->headers_in.content_length_n field to 0 when the body is
completely discarded. As such, the client_max_body_size check is skipped
if the request is redirected to an error page, and this makes it possible
to use "error_page 413" without additional settings.
This only works with HTTP/1.x though. The HTTP/2 and HTTP/3 request body
discarding code paths failed to set r->discard_body or reset
r->headers_in.content_length_n, so configuring "error_page 413" did notwork
without additionally clearing the client_max_body_size limit in the
location with error page.
Fix is to set r->headers_in.content_length_n to 0 in the HTTP/2 and HTTP/3
request body discarding code paths (if there is a body). This is essentially
what happens with HTTP/1.x when the body is completely discarded, and makes
it possible to use "error_page 413" with HTTP/2 and HTTP/3 without additional
settings.
Additionally, r->discard_body flag is also set. For HTTP/2, it is not needed,
but serves as an optimization. For HTTP/3, it ensures that the request body
cannot be read after it was discarded, thus bypassing the client_max_body_size
limit.
Further, the r->discard_body flag is now always set after the request body
is discarded (and not cleared once it is fully discarded). While the body
is being discarded, the new r->discarding_body flag is now used. This
slightly optimizes existing code paths in ngx_http_read_client_request_body()
and ngx_http_discard_request_body(), and also makes it easier to only set
ngx_http_discarded_request_body_handler() for HTTP/1.x.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Sat, 27 Apr 2024 18:22:38 +0300 |
parents | 55a5a40dccde |
children | 199dc0d6b05b |
comparison
equal
deleted
inserted
replaced
9260:ac5635650bc6 | 9261:f798ecafec05 |
---|---|
2760 | 2760 |
2761 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | 2761 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); |
2762 | 2762 |
2763 if (r->main->count != 1) { | 2763 if (r->main->count != 1) { |
2764 | 2764 |
2765 if (r->discard_body) { | 2765 if (r->discarding_body) { |
2766 r->read_event_handler = ngx_http_discarded_request_body_handler; | 2766 r->read_event_handler = ngx_http_discarded_request_body_handler; |
2767 ngx_add_timer(r->connection->read, clcf->lingering_timeout); | 2767 ngx_add_timer(r->connection->read, clcf->lingering_timeout); |
2768 | 2768 |
2769 if (r->lingering_time == 0) { | 2769 if (r->lingering_time == 0) { |
2770 r->lingering_time = ngx_time() | 2770 r->lingering_time = ngx_time() |
2818 ngx_event_t *wev; | 2818 ngx_event_t *wev; |
2819 ngx_http_core_loc_conf_t *clcf; | 2819 ngx_http_core_loc_conf_t *clcf; |
2820 | 2820 |
2821 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; | 2821 r->http_state = NGX_HTTP_WRITING_REQUEST_STATE; |
2822 | 2822 |
2823 r->read_event_handler = r->discard_body ? | 2823 r->read_event_handler = r->discarding_body ? |
2824 ngx_http_discarded_request_body_handler: | 2824 ngx_http_discarded_request_body_handler: |
2825 ngx_http_test_reading; | 2825 ngx_http_test_reading; |
2826 r->write_event_handler = ngx_http_writer; | 2826 r->write_event_handler = ngx_http_writer; |
2827 | 2827 |
2828 wev = r->connection->write; | 2828 wev = r->connection->write; |