]> granicus.if.org Git - apache/commitdiff
For safety, pass trailing buckets following EOS down the stack. Pass flush
authorGraham Leggett <minfrin@apache.org>
Thu, 9 Jun 2011 23:41:00 +0000 (23:41 +0000)
committerGraham Leggett <minfrin@apache.org>
Thu, 9 Jun 2011 23:41:00 +0000 (23:41 +0000)
buckets down the stack immediately. Move apr_brigade_partition() to be
called as late as possible.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1134130 13f79535-47bb-0310-9956-ffa450edef68

modules/filters/mod_data.c

index 7798a3483352786ea7ea2912e1b741bae1ac5b58..0688f8622a55f19765356e768dce4054208416a2 100644 (file)
@@ -64,7 +64,7 @@ typedef struct data_ctx
  */
 static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
 {
-    apr_bucket *e;
+    apr_bucket *e, *ee;
     request_rec *r = f->r;
     data_ctx *ctx = f->ctx;
     apr_status_t rv = APR_SUCCESS;
@@ -134,9 +134,6 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
         char buffer[APR_BUCKET_BUFF_SIZE + 1];
         char encoded[((sizeof(ctx->overflow)) / 3) * 4 + 1];
 
-        /* make sure we don't read more than 6000 bytes at a time */
-        apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &e);
-
         e = APR_BRIGADE_FIRST(bb);
 
         /* EOS means we are done. */
@@ -157,6 +154,23 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
             /* pass what we have down the chain */
             ap_remove_output_filter(f);
             rv = ap_pass_brigade(f->next, ctx->bb);
+
+            /* pass any stray buckets after the EOS down the stack */
+            if ((APR_SUCCESS == rv) && (!APR_BRIGADE_EMPTY(bb))) {
+               rv = ap_pass_brigade(f->next, bb);
+            }
+            continue;
+        }
+
+        /* flush what we can, we can't flush the tail until EOS */
+        if (APR_BUCKET_IS_FLUSH(e)) {
+
+            /* pass the flush bucket across */
+            APR_BUCKET_REMOVE(e);
+            APR_BRIGADE_INSERT_TAIL(ctx->bb, e);
+
+            /* pass what we have down the chain */
+            rv = ap_pass_brigade(f->next, ctx->bb);
             continue;
         }
 
@@ -171,6 +185,9 @@ static apr_status_t data_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
             continue;
         }
 
+        /* make sure we don't read more than 6000 bytes at a time */
+        apr_brigade_partition(bb, (APR_BUCKET_BUFF_SIZE / 4 * 3), &ee);
+
         /* size will never be more than 6000 bytes */
         if (APR_SUCCESS == (rv = apr_bucket_read(e, &data, &size,
                 APR_BLOCK_READ))) {