﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc	uname	nginx_version
2068	ngx_http_copy_pipelined_header didn't adjust buffer pointer after copy data	zhuizhuhaomeng@…		"we have found a bug with our test suite with our ngx module.

when HTTP pipelined request arrived, the header of the next request will be copied to r->header_in, but the original request buffer was not adjust.
I think it is better to adjust the original request body buffer last pointer after copy the data to new buffer.

The patch is bellow:

{{{
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index 71d7e9ab..fe075a87 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -472,6 +472,7 @@ ngx_http_copy_pipelined_header(ngx_http_request_t *r, ngx_buf_t *buf)
     }
 
     ngx_memcpy(b->last, buf->pos, n);
+    buf->last -= n;
 
     b->last += n;
     r->request_length -= n;

}}}

{{{

   401	static ngx_int_t
   402	ngx_http_copy_pipelined_header(ngx_http_request_t *r, ngx_buf_t *buf)
   403	{
   404	    size_t                     n;
   405	    ngx_buf_t                 *b;
   406	    ngx_chain_t               *cl;
   407	    ngx_http_connection_t     *hc;
   408	    ngx_http_core_srv_conf_t  *cscf;
   409	
   410	    b = r->header_in;
   411	    n = buf->last - buf->pos;
   412	
   413	    if (buf == b || n == 0) {
   414	        return NGX_OK;
   415	    }
   416	
   417	    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
   418	                   ""http body pipelined header: %uz"", n);
   419	
   420	    /*
   421	     * if there is a pipelined request in the client body buffer,
   422	     * copy it to the r->header_in buffer if there is enough room,
   423	     * or allocate a large client header buffer
   424	     */
   425	
   426	    if (n > (size_t) (b->end - b->last)) {
   427	
   428	        hc = r->http_connection;
   429	
   430	        if (hc->free) {
   431	            cl = hc->free;
   432	            hc->free = cl->next;
   433	
   434	            b = cl->buf;
   435	
   436	            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
   437	                           ""http large header free: %p %uz"",
   438	                           b->pos, b->end - b->last);
   439	
   440	        } else {
   441	            cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
   442	
   443	            b = ngx_create_temp_buf(r->connection->pool,
   444	                                    cscf->large_client_header_buffers.size);
   445	            if (b == NULL) {
   446	                return NGX_ERROR;
   447	            }
   448	
   449	            cl = ngx_alloc_chain_link(r->connection->pool);
   450	            if (cl == NULL) {
   451	                return NGX_ERROR;
   452	            }
   453	
   454	            cl->buf = b;
   455	
   456	            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
   457	                           ""http large header alloc: %p %uz"",
   458	                           b->pos, b->end - b->last);
   459	        }
   460	
   461	        cl->next = hc->busy;
   462	        hc->busy = cl;
   463	        hc->nbusy++;
   464	
   465	        r->header_in = b;
   466	
   467	        if (n > (size_t) (b->end - b->last)) {
   468	            ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
   469	                          ""too large pipelined header after reading body"");
   470	            return NGX_ERROR;
   471	        }
   472	    }
   473	
   474	    ngx_memcpy(b->last, buf->pos, n);
   475	    buf->last -= n;  //here is the modification
   476	
   477	    b->last += n;
   478	    r->request_length -= n;
   479	
   480	    return NGX_OK;
   481	}
}}}"	defect	new	major	nginx-1.19	nginx-core	1.19.x				Linux localhost.localdomain 4.18.0-193.6.3.el8_2.x86_64 #1 SMP Wed Jun 10 11:09:32 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux	"nginx version: openresty/1.19.3.1rc0
built by gcc 8.3.1 20191121 (Red Hat 8.3.1-5) (GCC) 
built with OpenSSL 1.1.1g  21 Apr 2020
TLS SNI support enabled
configure arguments: --prefix=/usr/local/openresty/nginx --with-debug --with-cc-opt='-DNGX_LUA_USE_ASSERT -DNGX_LUA_ABORT_AT_PANIC -O2 -DNGX_LUA_ABORT_AT_PANIC -I/usr/local/openresty/zlib/include -I/usr/local/openresty/pcre/include -I/usr/local/openresty/openssl111/include' --add-module=../ngx_devel_kit-0.3.1 --add-module=../echo-nginx-module-0.62 --add-module=../xss-nginx-module-0.06 --add-module=../ngx_coolkit-0.2 --add-module=../set-misc-nginx-module-0.32 --add-module=../form-input-nginx-module-0.12 --add-module=../encrypted-session-nginx-module-0.08 --add-module=../srcache-nginx-module-0.32 --add-module=../ngx_lua-0.10.18rc3 --add-module=../ngx_lua_upstream-0.07 --add-module=../headers-more-nginx-module-0.33 --add-module=../array-var-nginx-module-0.05 --add-module=../memc-nginx-module-0.19 --add-module=../redis2-nginx-module-0.15 --add-module=../redis-nginx-module-0.3.7 --add-module=../ngx_stream_lua-0.0.9rc3 --with-ld-opt='-Wl,-rpath,/usr/local/openresty/luajit/lib -L/usr/local/openresty/zlib/lib -L/usr/local/openresty/pcre/lib -L/usr/local/openresty/openssl111/lib -Wl,-rpath,/usr/local/openresty/zlib/lib:/usr/local/openresty/pcre/lib:/usr/local/openresty/openssl111/lib' --with-cc='ccache gcc -fdiagnostics-color=always' --with-pcre-jit --with-stream --with-stream_ssl_module --with-stream_ssl_preread_module --with-http_v2_module --without-mail_pop3_module --without-mail_imap_module --without-mail_smtp_module --with-http_stub_status_module --with-http_realip_module --with-http_addition_module --with-http_auth_request_module --with-http_secure_link_module --with-http_random_index_module --with-http_gzip_static_module --with-http_sub_module --with-http_dav_module --with-http_flv_module --with-http_mp4_module --with-http_gunzip_module --with-threads --with-compat --with-stream --with-http_ssl_module
"
