]> git.kaiwu.me - nginx.git/commitdiff
Output chain: clear the last_buf flag unless inherited.
authorSergey Kandaurov <pluknet@nginx.com>
Wed, 24 Dec 2025 21:21:52 +0000 (01:21 +0400)
committerSergey Kandaurov <s.kandaurov@f5.com>
Thu, 29 Jan 2026 10:52:41 +0000 (14:52 +0400)
For instance, the last_buf flag is used in the http proxy module when
creating HTTP/2 requests to indicate the output is closed.  The flag
is inherited in ngx_output_chain() to a destination buffer when reading
the buffered request body.  Then it is used in the proxy output filter
to mark the last HTTP/2 DATA frame with END_STREAM.

The problem happens when reusing the destination buffer, such as to
re-read the buffered request body on next upstream, because this buffer
may contain a dirty last_buf value, which breaks sending HTTP/2 request
body in multiple output filter calls.

The flush and last_in_chain flags are cleared for consistency.

src/core/ngx_output_chain.c

index a46209c170010def73b7fec1bb352ab5565b5f97..eb467e06a845ae80c723c9ed14e42e1f44d09c8c 100644 (file)
@@ -552,6 +552,11 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
             dst->flush = src->flush;
             dst->last_buf = src->last_buf;
             dst->last_in_chain = src->last_in_chain;
+
+        } else {
+            dst->flush = 0;
+            dst->last_buf = 0;
+            dst->last_in_chain = 0;
         }
 
     } else {
@@ -648,6 +653,11 @@ ngx_output_chain_copy_buf(ngx_output_chain_ctx_t *ctx)
             dst->flush = src->flush;
             dst->last_buf = src->last_buf;
             dst->last_in_chain = src->last_in_chain;
+
+        } else {
+            dst->flush = 0;
+            dst->last_buf = 0;
+            dst->last_in_chain = 0;
         }
     }