view src/http/v3/ngx_http_v3_encode.h @ 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 0ac25efb2da3
children
line wrap: on
line source


/*
 * Copyright (C) Roman Arutyunyan
 * Copyright (C) Nginx, Inc.
 */


#ifndef _NGX_HTTP_V3_ENCODE_H_INCLUDED_
#define _NGX_HTTP_V3_ENCODE_H_INCLUDED_


#include <ngx_config.h>
#include <ngx_core.h>
#include <ngx_http.h>


uintptr_t ngx_http_v3_encode_varlen_int(u_char *p, uint64_t value);
uintptr_t ngx_http_v3_encode_prefix_int(u_char *p, uint64_t value,
    ngx_uint_t prefix);

uintptr_t ngx_http_v3_encode_field_section_prefix(u_char *p,
    ngx_uint_t insert_count, ngx_uint_t sign, ngx_uint_t delta_base);
uintptr_t ngx_http_v3_encode_field_ri(u_char *p, ngx_uint_t dynamic,
    ngx_uint_t index);
uintptr_t ngx_http_v3_encode_field_lri(u_char *p, ngx_uint_t dynamic,
    ngx_uint_t index, u_char *data, size_t len);
uintptr_t ngx_http_v3_encode_field_l(u_char *p, ngx_str_t *name,
    ngx_str_t *value);
uintptr_t ngx_http_v3_encode_field_pbi(u_char *p, ngx_uint_t index);
uintptr_t ngx_http_v3_encode_field_lpbi(u_char *p, ngx_uint_t index,
    u_char *data, size_t len);


#endif /* _NGX_HTTP_V3_ENCODE_H_INCLUDED_ */