id summary reporter owner description type status priority milestone component version resolution keywords cc uname nginx_version 2374 HTTP3 sent too much body data to upstream when use POST request himac@… Roman Arutyunyan "source code version: nginx-quic-8d0753760546 While use a client send http3 POST request to nginx proxy server, nginx would sent more body data to upstream upload server I found in ngx_http_v3_request_body_filter function, after ngx_http_v3_parse_data parse http3 DATA frame, the cl buf maybe empty (because real data in DATA frame would not contain at this time): (gdb) p b $11 = (ngx_buf_t *) 0x5555559f8740 (gdb) p *b $12 = {pos = 0x5555559eefd8 """", last = 0x5555559eefd8 """", file_pos = 0, file_last = 0, start = 0x5555559eefd8 """", end = 0x5555559ef3a8 ""www.google.com:4443"", tag = 0x5555555df5a5 , file = 0x0, shadow = 0x0, temporary = 1, memory = 0, mmap = 0, recycled = 0, in_file = 0, flush = 1, sync = 0, last_buf = 0, last_in_chain = 0, last_shadow = 0, temp_file = 0, num = 0} (gdb) p tl $13 = (ngx_chain_t *) 0x5555559f7e28 (gdb) p *tl $14 = {buf = 0x5555559f8740, next = 0x0} (gdb) list 1603 b->pos = cl->buf->pos; 1604 b->last = cl->buf->last; after ngx_http_top_request_body_filter, the empty buf chain will be linked to ngx_http_request_t->request_body->bufs: 1680 rc = ngx_http_top_request_body_filter(r, out); (gdb) 1682 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, (gdb) p r->request_body->bufs $15 = (ngx_chain_t *) 0x5555559f7e38 (gdb) p *r->request_body->bufs $16 = {buf = 0x5555559f8740, next = 0x0} (gdb) p r->request_body->free $17 = (ngx_chain_t *) 0x0 then ngx_chain_update_chains will link the empty buf chain to ngx_http_request_t->request_body->free , because it is empty: (gdb) n 1685 return rc; (gdb) p *r->request_body->bufs $18 = {buf = 0x5555559f8740, next = 0x0} (gdb) p r->request_body->free $19 = (ngx_chain_t *) 0x5555559f7e28 (gdb) p r->request_body->free->buf $20 = (ngx_buf_t *) 0x5555559f8740 when the data of this HTTP3 DATA frame comes, ngx_http_top_request_body_filter called again, and will call ngx_chain_get_free_buf to get buf from ngx_http_request_t->request_body->free 1591 tl = ngx_chain_get_free_buf(r->pool, &rb->free); (gdb) 1592 if (tl == NULL) { (gdb) p tl $21 = (ngx_chain_t *) 0x5555559f7e28 gdb) p tl->buf $22 = (ngx_buf_t *) 0x5555559f8740 thus after ngx_http_top_request_body_filter, there will be two same buf in ngx_http_request_t->request_body->bufs 1680 rc = ngx_http_top_request_body_filter(r, out); (gdb) 1682 ngx_chain_update_chains(r->pool, &rb->free, &rb->busy, &out, (gdb) p *r->request_body->bufs $1 = {buf = 0x5555559f8740, next = 0x5555559f87e0} (gdb) p *r->request_body->bufs->next $2 = {buf = 0x5555559f8740, next = 0x0} (gdb) p *r->request_body->bufs->buf $3 = {pos = 0x5555559f8e80 """", last = 0x5555559f8e8d """", file_pos = 0, file_last = 0, start = 0x5555559f8e80 """", end = 0x5555559fae80 """", tag = 0x5555555df5a5 , file = 0x0, shadow = 0x0, temporary = 1, memory = 0, mmap = 0, recycled = 0, in_file = 0, flush = 0, sync = 0, last_buf = 0, last_in_chain = 0, last_shadow = 0, temp_file = 0, num = 0} thus too much data will be sent to upstream." defect closed minor http/3 fixed http3 quic post Linux pekphis107316 4.15.0-156-generic #163-Ubuntu SMP Thu Aug 19 23:31:58 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux "nginx version: nginx/1.23.0 built by gcc 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04) built with OpenSSL 1.1.1 (compatible; BoringSSL) (running with BoringSSL) TLS SNI support enabled configure arguments: --prefix=/usr/local/nginx_http3/nginx --with-debug --with-ld-opt='-Wl,-rpath, -L/work/unitrans90/boringssl/src/build/ssl/ -L//work/boringssl/src/build/crypto' --with-cc-opt='-I//work//boringssl/src/include/ ' --with-stream --with-stream_quic_module --with-http_v2_module --with-http_v3_module --with-http_stub_status_module --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_ssl_module"