From cb6cb37705632f037880ede2b9ff876baf9a7081 Mon Sep 17 00:00:00 2001 From: Joe Orton Date: Wed, 20 Dec 2023 13:34:54 +0000 Subject: [PATCH] * modules/http/chunk_filter.c (ap_http_chunk_filter): For a brigade containing [FLUSH EOS], insert the last-chunk terminator before the FLUSH rather than between the FLUSH and the EOS. --- modules/http/chunk_filter.c | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) diff --git a/modules/http/chunk_filter.c b/modules/http/chunk_filter.c index f44543a7657..3975106d0ed 100644 --- a/modules/http/chunk_filter.c +++ b/modules/http/chunk_filter.c @@ -64,7 +64,7 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) for (more = tmp = NULL; b; b = more, more = NULL) { apr_off_t bytes = 0; - apr_bucket *eos = NULL; + apr_bucket *eos = NULL; /* EOS bucket, or FLUSH preceding EOS */ apr_bucket *flush = NULL; /* XXX: chunk_hdr must remain at this scope since it is used in a * transient bucket. @@ -99,8 +99,20 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) } if (APR_BUCKET_IS_FLUSH(e)) { flush = e; + + /* Special case to catch common brigade ending of + * [FLUSH] [EOS] - insert the last_chunk before + * the FLUSH rather than between the FLUSH and the + * EOS. */ if (e != APR_BRIGADE_LAST(b)) { - more = apr_brigade_split_ex(b, APR_BUCKET_NEXT(e), tmp); + if (APR_BUCKET_IS_EOS(APR_BUCKET_NEXT(e))) { + eos = e; + /* anything after EOS is dropped, no need + * to split. */ + } + else { + more = apr_brigade_split_ex(b, APR_BUCKET_NEXT(e), tmp); + } } break; } @@ -173,10 +185,10 @@ apr_status_t ap_http_chunk_filter(ap_filter_t *f, apr_bucket_brigade *b) * FLUSH bucket, or appended to the brigade */ e = apr_bucket_immortal_create(CRLF_ASCII, 2, c->bucket_alloc); - if (eos != NULL) { + if (flush != NULL) { APR_BUCKET_INSERT_BEFORE(eos, e); } - else if (flush != NULL) { + else if (eos != NULL) { APR_BUCKET_INSERT_BEFORE(flush, e); } else {