You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by co...@apache.org on 2008/09/14 17:24:13 UTC
svn commit: r695234 - in /httpd/httpd/branches/2.2.x: CHANGES STATUS
modules/filters/mod_charset_lite.c
Author: covener
Date: Sun Sep 14 08:24:12 2008
New Revision: 695234
URL: http://svn.apache.org/viewvc?rev=695234&view=rev
Log:
Merge r692567, r693564, r693577 from trunk:
PR 45687: Detect and pass along error buckets
Submitted by: Dan Poirier <poirier pobox.org>
Reviewed by: trawick
* stash the brigade used by send_bucket_downstream in the filter context for
reuse.
Submitted by: Dan Poirier <poirier pobox.com>
Reviewed by: gregames, covener
* Use send_bucket_downstream to send data down the chain instead of creating
a brigade each time.
Submitted by: Dan Poirier <poirier pobox.com>
Reviewed by: rpluem
Modified:
httpd/httpd/branches/2.2.x/CHANGES
httpd/httpd/branches/2.2.x/STATUS
httpd/httpd/branches/2.2.x/modules/filters/mod_charset_lite.c
Modified: httpd/httpd/branches/2.2.x/CHANGES
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/CHANGES?rev=695234&r1=695233&r2=695234&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/CHANGES [utf-8] (original)
+++ httpd/httpd/branches/2.2.x/CHANGES [utf-8] Sun Sep 14 08:24:12 2008
@@ -5,6 +5,9 @@
mod_proxy_ftp: Prevent XSS attacks when using wildcards in the path of
the FTP URL. Discovered by Marc Bevand of Rapid7. [Ruediger Pluem]
+ *) mod_charset_lite: Avoid dropping error responses by handling meta buckets
+ correctly. PR 45687 [Dan Poirier <poirier pobox.com>]
+
*) mod_proxy_http: Introduce environment variable proxy-initial-not-pooled to
avoid reusing pooled connections if the client connection is an initial
connection. PR 37770. [Ruediger Pluem]
Modified: httpd/httpd/branches/2.2.x/STATUS
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/STATUS?rev=695234&r1=695233&r2=695234&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/STATUS (original)
+++ httpd/httpd/branches/2.2.x/STATUS Sun Sep 14 08:24:12 2008
@@ -92,16 +92,6 @@
http://svn.apache.org/viewvc?rev=639010&view=rev (mmn)
+1: niq, rpluem, mturk
- * mod_charset_lite: detect and pass along error buckets.
- PR: 45687
- Trunk version of patches:
- http://svn.apache.org/viewvc?rev=692567&view=rev
- http://svn.apache.org/viewvc?rev=693564&view=rev
- http://svn.apache.org/viewvc?rev=693577&view=rev
- Backport version for 2.2.x of patch:
- Trunk version of patches works
- +1: gregames, rpluem, covener
-
PATCHES PROPOSED TO BACKPORT FROM TRUNK:
[ New proposals should be added at the end of the list ]
Modified: httpd/httpd/branches/2.2.x/modules/filters/mod_charset_lite.c
URL: http://svn.apache.org/viewvc/httpd/httpd/branches/2.2.x/modules/filters/mod_charset_lite.c?rev=695234&r1=695233&r2=695234&view=diff
==============================================================================
--- httpd/httpd/branches/2.2.x/modules/filters/mod_charset_lite.c (original)
+++ httpd/httpd/branches/2.2.x/modules/filters/mod_charset_lite.c Sun Sep 14 08:24:12 2008
@@ -96,6 +96,7 @@
int noop; /* should we pass brigades through unchanged? */
char *tmp; /* buffer for input filtering */
apr_bucket_brigade *bb; /* input buckets we couldn't finish translating */
+ apr_bucket_brigade *tmpbb; /* used for passing downstream */
} charset_filter_ctx_t;
/* charset_req_t is available via r->request_config if any translation is
@@ -266,6 +267,8 @@
reqinfo->dc = dc;
output_ctx->dc = dc;
+ output_ctx->tmpbb = apr_brigade_create(r->pool,
+ r->connection->bucket_alloc);
ap_set_module_config(r->request_config, &charset_lite_module, reqinfo);
reqinfo->output_ctx = output_ctx;
@@ -373,6 +376,20 @@
* will be generated
*/
+static apr_status_t send_bucket_downstream(ap_filter_t *f, apr_bucket *b)
+{
+ charset_filter_ctx_t *ctx = f->ctx;
+ apr_status_t rv;
+
+ APR_BRIGADE_INSERT_TAIL(ctx->tmpbb, b);
+ rv = ap_pass_brigade(f->next, ctx->tmpbb);
+ if (rv != APR_SUCCESS) {
+ ctx->ees = EES_DOWNSTREAM;
+ }
+ apr_brigade_cleanup(ctx->tmpbb);
+ return rv;
+}
+
/* send_downstream() is passed the translated data; it puts it in a single-
* bucket brigade and passes the brigade to the next filter
*/
@@ -380,19 +397,10 @@
{
request_rec *r = f->r;
conn_rec *c = r->connection;
- apr_bucket_brigade *bb;
apr_bucket *b;
- charset_filter_ctx_t *ctx = f->ctx;
- apr_status_t rv;
- bb = apr_brigade_create(r->pool, c->bucket_alloc);
b = apr_bucket_transient_create(tmp, len, 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;
+ return send_bucket_downstream(f, b);
}
static apr_status_t send_eos(ap_filter_t *f)
@@ -632,12 +640,12 @@
* 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 +654,7 @@
* 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 +681,7 @@
}
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 +900,17 @@
}
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 +1097,18 @@
* 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);