summaryrefslogtreecommitdiffstats
path: root/modules/filters
diff options
context:
space:
mode:
authorGreg Ames <gregames@apache.org>2008-09-06 00:21:36 +0200
committerGreg Ames <gregames@apache.org>2008-09-06 00:21:36 +0200
commit0c13c0a269ca163700be20f458088a9b989426da (patch)
tree2cc1d12c816f69716e8c6144ab77e552a22b3349 /modules/filters
parentupdate Japanese translation (diff)
downloadapache2-0c13c0a269ca163700be20f458088a9b989426da.tar.xz
apache2-0c13c0a269ca163700be20f458088a9b989426da.zip
PR 45687: Detect and pass along error buckets
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
Diffstat (limited to 'modules/filters')
-rw-r--r--modules/filters/mod_charset_lite.c48
1 files changed, 44 insertions, 4 deletions
diff --git a/modules/filters/mod_charset_lite.c b/modules/filters/mod_charset_lite.c
index a5221aea29..dda44bf6be 100644
--- a/modules/filters/mod_charset_lite.c
+++ b/modules/filters/mod_charset_lite.c
@@ -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);