]> granicus.if.org Git - apache/commitdiff
Merge r1829038, r1829039, r1830523 from trunk:
authorYann Ylavic <ylavic@apache.org>
Fri, 22 Jun 2018 10:44:13 +0000 (10:44 +0000)
committerYann Ylavic <ylavic@apache.org>
Fri, 22 Jun 2018 10:44:13 +0000 (10:44 +0000)
mod_xml2enc: Fix forwarding of error metadata/responses. PR 62180.

All meta buckets are now aggregated (besides FLUSH) and forwarded down
the chain, and the output filter bails out on EOS.

Proposed by: Micha Lenk <micha lenk.info>

mod_xml2enc: follow up to r1829038.

If any, pass pending meta bucket down the chain before leaving.

mod_xml2enc: follow up to r1829038 and r1829039.

Use below pending_data logic for EOS bucket.
This closes #48

Submitted by: ylavic
Reviewed by: ylavic, jim, rpluem

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1834104 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
modules/filters/mod_xml2enc.c

diff --git a/CHANGES b/CHANGES
index a1dc7c18f21a3bdaa447d6c2984b5b7557d43935..9615f692d15d535b3b7c0b8aee27465a95759d6a 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,6 +1,9 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache 2.4.34
 
+  *) mod_xml2enc: Fix forwarding of error metadata/responses. PR 62180.
+     [Micha Lenk <micha lenk.info>, Yann Ylavic]
+
   *) mod_proxy_http: Fix response header thrown away after the previous one
      was considered too large and truncated. PR 62196. [Yann Ylavic]
 
index 7b34c717af99af403138de9c086faf664252aa3d..05a4e9a9a4901a2b26e7e4667123391ec9feba57 100644 (file)
@@ -303,6 +303,7 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
     apr_bucket* b;
     apr_bucket* bstart;
     apr_size_t insz = 0;
+    int pending_meta = 0;
     char *ctype;
     char *p;
 
@@ -390,20 +391,36 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
     /* move the data back to bb */
     APR_BRIGADE_CONCAT(bb, ctx->bbsave);
 
-    while (b = APR_BRIGADE_FIRST(bb), b != APR_BRIGADE_SENTINEL(bb)) {
+    while (!APR_BRIGADE_EMPTY(bb)) {
+        b = APR_BRIGADE_FIRST(bb);
         ctx->bytes = 0;
         if (APR_BUCKET_IS_METADATA(b)) {
             APR_BUCKET_REMOVE(b);
+            APR_BRIGADE_INSERT_TAIL(ctx->bbnext, b);
+            /* Besides FLUSH, aggregate meta buckets to send them at
+             * once below. This resource filter is over on EOS.
+             */
+            pending_meta = 1;
             if (APR_BUCKET_IS_EOS(b)) {
-                /* send remaining data */
-                APR_BRIGADE_INSERT_TAIL(ctx->bbnext, b);
-                return ap_fflush(f->next, ctx->bbnext);
-            } else if (APR_BUCKET_IS_FLUSH(b)) {
-                ap_fflush(f->next, ctx->bbnext);
+                ap_remove_output_filter(f);
+                APR_BRIGADE_CONCAT(ctx->bbnext, bb);
             }
-            apr_bucket_destroy(b);
+            else if (!APR_BUCKET_IS_FLUSH(b)) {
+                continue;
+            }
+        }
+        if (pending_meta) {
+            pending_meta = 0;
+            /* passing meta bucket down the chain */
+            rv = ap_pass_brigade(f->next, ctx->bbnext);
+            apr_brigade_cleanup(ctx->bbnext);
+            if (rv != APR_SUCCESS) {
+                return rv;
+            }
+            continue;
         }
-        else {        /* data bucket */
+        /* data bucket */
+        {
             char* buf;
             apr_size_t bytes = 0;
             char fixbuf[BUFLEN];
@@ -508,8 +525,7 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
                         if (rv != APR_SUCCESS)
                             ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, f->r, APLOGNO(01446)
                                           "ap_fflush failed");
-                        else
-                            rv = ap_pass_brigade(f->next, ctx->bbnext);
+                        apr_brigade_cleanup(ctx->bbnext);
                     }
                 }
             } else {
@@ -522,8 +538,18 @@ static apr_status_t xml2enc_ffunc(ap_filter_t* f, apr_bucket_brigade* bb)
                 return rv;
         }
     }
+    if (pending_meta) {
+        /* passing pending meta bucket down the chain before leaving */
+        rv = ap_pass_brigade(f->next, ctx->bbnext);
+        apr_brigade_cleanup(ctx->bbnext);
+        if (rv != APR_SUCCESS) {
+            return rv;
+        }
+    }
+
     return APR_SUCCESS;
 }
+
 static apr_status_t xml2enc_charset(request_rec* r, xmlCharEncoding* encp,
                                     const char** encoding)
 {