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);