summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Orton <jorton@apache.org>2023-12-20 16:56:15 +0100
committerJoe Orton <jorton@apache.org>2023-12-20 16:56:15 +0100
commitb5b2ca3f3e6e95257c6d2a31278bf1f58e83c1bb (patch)
tree310ddd521e8722f81e81028572f5f2d4c41e7920
parentmod_deflate: remove filter after seeing EOS (diff)
downloadapache2-b5b2ca3f3e6e95257c6d2a31278bf1f58e83c1bb.tar.xz
apache2-b5b2ca3f3e6e95257c6d2a31278bf1f58e83c1bb.zip
* 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. Github: closes #400 git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1914804 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--changes-entries/flushing-chunks.txt2
-rw-r--r--modules/http/chunk_filter.c24
2 files changed, 20 insertions, 6 deletions
diff --git a/changes-entries/flushing-chunks.txt b/changes-entries/flushing-chunks.txt
new file mode 100644
index 0000000000..7e9519f118
--- /dev/null
+++ b/changes-entries/flushing-chunks.txt
@@ -0,0 +1,2 @@
+ *) http/1.1: For a chunked response body, ensure the last-chunk
+ terminator is flushed if necessary. [Joe Orton]
diff --git a/modules/http/chunk_filter.c b/modules/http/chunk_filter.c
index f44543a765..1fa3fa9352 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,12 +185,12 @@ 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) {
- APR_BUCKET_INSERT_BEFORE(eos, e);
- }
- else if (flush != NULL) {
+ if (flush != NULL) {
APR_BUCKET_INSERT_BEFORE(flush, e);
}
+ else if (eos != NULL) {
+ APR_BUCKET_INSERT_BEFORE(eos, e);
+ }
else {
APR_BRIGADE_INSERT_TAIL(b, e);
}