]> granicus.if.org Git - apache/commitdiff
PR 45687: Detect and pass along error buckets
authorGreg Ames <gregames@apache.org>
Fri, 5 Sep 2008 22:21:36 +0000 (22:21 +0000)
committerGreg Ames <gregames@apache.org>
Fri, 5 Sep 2008 22:21:36 +0000 (22:21 +0000)
Submitted by: Dan Poirier <poirier pobox.org>
Reviewed by:  trawick

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

modules/filters/mod_charset_lite.c

index a5221aea299c55d952c100efc58d8b8325943e02..dda44bf6bef7dc8c595d42fc47064936da548a44 100644 (file)
@@ -414,6 +414,23 @@ static apr_status_t send_eos(ap_filter_t *f)
     return rv;
 }
 
+static apr_status_t send_bucket_downstream(ap_filter_t *f, apr_bucket *b)
+{
+    request_rec *r = f->r;
+    conn_rec *c = r->connection;
+    apr_bucket_brigade *bb;
+    charset_filter_ctx_t *ctx = f->ctx;
+    apr_status_t rv;
+
+    bb = apr_brigade_create(r->pool, c->bucket_alloc);
+    APR_BRIGADE_INSERT_TAIL(bb, b);
+    rv = ap_pass_brigade(f->next, bb);
+    if (rv != APR_SUCCESS) {
+        ctx->ees = EES_DOWNSTREAM;
+    }
+    return rv;
+}
+
 static apr_status_t set_aside_partial_char(charset_filter_ctx_t *ctx,
                                            const char *partial,
                                            apr_size_t partial_len)
@@ -632,12 +649,12 @@ static void chk_filter_chain(ap_filter_t *f)
  * we'll stop when one of the following occurs:
  * . we run out of buckets
  * . we run out of space in the output buffer
- * . we hit an error
+ * . we hit an error or metadata
  *
  * inputs:
  *   bb:               brigade to process
  *   buffer:           storage to hold the translated characters
- *   buffer_size:      size of buffer
+ *   buffer_avail:     size of buffer
  *   (and a few more uninteresting parms)
  *
  * outputs:
@@ -646,7 +663,7 @@ static void chk_filter_chain(ap_filter_t *f)
  *                     translated characters; the eos bucket, if
  *                     present, will be left in the brigade
  *   buffer:           filled in with translated characters
- *   buffer_size:      updated with the bytes remaining
+ *   buffer_avail:     updated with the bytes remaining
  *   hit_eos:          did we hit an EOS bucket?
  */
 static apr_status_t xlate_brigade(charset_filter_ctx_t *ctx,
@@ -673,7 +690,7 @@ static apr_status_t xlate_brigade(charset_filter_ctx_t *ctx,
             }
             b = APR_BRIGADE_FIRST(bb);
             if (b == APR_BRIGADE_SENTINEL(bb) ||
-                APR_BUCKET_IS_EOS(b)) {
+                APR_BUCKET_IS_METADATA(b)) {
                 break;
             }
             rv = apr_bucket_read(b, &bucket, &bytes_in_bucket, APR_BLOCK_READ);
@@ -892,6 +909,17 @@ static apr_status_t xlate_out_filter(ap_filter_t *f, apr_bucket_brigade *bb)
                 }
                 break;
             }
+            if (APR_BUCKET_IS_METADATA(dptr)) {
+                apr_bucket *metadata_bucket;
+                metadata_bucket = dptr;
+                dptr = APR_BUCKET_NEXT(dptr);
+                APR_BUCKET_REMOVE(metadata_bucket);
+                rv = send_bucket_downstream(f, metadata_bucket);
+                if (rv != APR_SUCCESS) {
+                    done = 1;
+                }
+                continue;
+            }
             rv = apr_bucket_read(dptr, &cur_str, &cur_len, APR_BLOCK_READ);
             if (rv != APR_SUCCESS) {
                 done = 1;
@@ -1078,6 +1106,18 @@ static int xlate_in_filter(ap_filter_t *f, apr_bucket_brigade *bb,
              * empty brigade
              */
         }
+        /* If we have any metadata at the head of ctx->bb, go ahead and move it
+         * onto the end of bb to be returned to our caller.
+         */
+        if (!APR_BRIGADE_EMPTY(ctx->bb)) {
+            apr_bucket *b = APR_BRIGADE_FIRST(ctx->bb);
+            while (b != APR_BRIGADE_SENTINEL(ctx->bb)
+                   && APR_BUCKET_IS_METADATA(b)) {
+                APR_BUCKET_REMOVE(b);
+                APR_BRIGADE_INSERT_TAIL(bb, b);
+                b = APR_BRIGADE_FIRST(ctx->bb);
+            }
+        }
     }
     else {
         log_xlate_error(f, rv);