[PATCH] HTTP/3: skip empty request body buffers (ticket #2374)

Sergey Kandaurov pluknet at nginx.com
Thu Aug 4 14:54:12 UTC 2022



> On 4 Aug 2022, at 13:43, Roman Arutyunyan <arut at nginx.com> wrote:
> 
> # HG changeset patch
> # User Roman Arutyunyan <arut at nginx.com>
> # Date 1659531591 -14400
> #      Wed Aug 03 16:59:51 2022 +0400
> # Branch quic
> # Node ID 999e6a73ff50a41bdbce467e9572f4ad52bbf2cf
> # Parent  f919f13cb11e3bc106e9c4bc2aeadd12b43e7e97
> HTTP/3: skip empty request body buffers (ticket #2374).
> 
> When client DATA frame header and its content come in different QUIC packets,
> it may happen that only the header is processed by the first
> ngx_http_v3_request_body_filter() call.  In this case an empty request body
> buffer is added to r->request_body->bufs, which is later reused in a
> subsequent ngx_http_v3_request_body_filter() call without being removed from
> the body chain.  As a result, rb->request_body->bufs ends up with two copies of
> the same buffer.

It can also happen with empty DATA frames ("\x00\x00") each in its own packet.
This results in buffer copies multiplied by the number of such empty frames.

> 
> The fix is to avoid adding empty request body buffers to r->request_body->bufs.
> 
> diff --git a/src/http/v3/ngx_http_v3_request.c b/src/http/v3/ngx_http_v3_request.c
> --- a/src/http/v3/ngx_http_v3_request.c
> +++ b/src/http/v3/ngx_http_v3_request.c
> @@ -1552,15 +1552,17 @@ ngx_http_v3_request_body_filter(ngx_http
>                 }
> 
>                 /* rc == NGX_OK */
> -            }
> 
> -            if (max != -1 && (uint64_t) (max - rb->received) < st->length) {
> -                ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
> -                              "client intended to send too large "
> -                              "body: %O+%ui bytes",
> -                              rb->received, st->length);
> +                if (max != -1 && (uint64_t) (max - rb->received) < st->length) {
> +                    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
> +                                  "client intended to send too large "
> +                                  "body: %O+%ui bytes",
> +                                  rb->received, st->length);
> 
> -                return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
> +                    return NGX_HTTP_REQUEST_ENTITY_TOO_LARGE;
> +                }
> +
> +                continue;
>             }
> 
>             if (b
> 

Looks good.

-- 
Sergey Kandaurov



More information about the nginx-devel mailing list