httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Jim Carlson <jcarl...@jnous.com>
Subject [PATCH] bug? in util_filter, with patch
Date Tue, 11 Mar 2003 00:52:51 GMT
Hello,
   I'm currently writing a module for 2.0 which needs to observe the 
traffic to and from various handlers.  The approach I'm using is to 
register input and output filters of type AP_FTYPE_PROTOCOL+1 (so I get 
headers, but don't see encrypted traffic), and add them in a 
create_request hook.  However, when I do this, I see some odd behavour, 
which I think is a bug.
   Long story short, it looks like the HTTP input and output handlers 
don't get added properly.  First, when I send a GET with a body, Apache 
blocks hangs in an attempt to read HUGE_STRING_LEN from core_in, which 
is caused by the HTTP input filter's absence, since normally it would 
trim that down based on the content-length or chunk size.  Second, 
Apache's responses are missing their HTTP headers.  (Under 2.0, I get 
both problems; with the latest 2.1 I only see the latter).  I can 
provide code for a module that will create the problems.
   I found a logic problem in util_filter.c, add_any_filter_handle(), 
which explains this.  Basically, if more than one protocol filter is 
added to a request, the request->{input,output}_filters ptr isn't 
updated properly.  Below is a patch.  I've tested it with a 2.1 build 
that I got from CVS earlier today, and it solves my problem without 
noticably causing any others.  Perhaps someone with a test environment 
can run this through some hoops.

Thanks,
Jim


--- server/util_filter.c.orig	2003-03-10 15:19:47.809999000 -0800
+++ server/util_filter.c	2003-03-10 16:25:52.199998000 -0800
@@ -340,24 +340,30 @@
      if (INSERT_BEFORE(f, *outf)) {
          f->next = *outf;

-        if (*outf) {
-            ap_filter_t *first = NULL;
+        if (r) {
+            /* push the p_filter back */
+            if (outf == c_filters && *p_filters == *outf)
+                *p_filters = f;
+
+            /* push the r_filter back */
+            if ( (outf == c_filters || outf == p_filters) &&
+                    *r_filters == *outf) {
+                *r_filters = f;
+            }
+            /* now set the previous filter's next ptr (unless we just
+             * changed r_filter) */
+            else if (outf != r_filters) {
+                ap_filter_t *first = NULL;
+
+                first = *r_filters;
+                while (first && (first->next != (*outf))) {
+                    first = first->next;
+                }

-            if (r) {
-                /* If we are adding our first non-connection filter,
-                 * Then don't try to find the right location, it is
-                 * automatically first.
-                 */
-                if (*r_filters != *c_filters) {
-                    first = *r_filters;
-                    while (first && (first->next != (*outf))) {
-                        first = first->next;
-                    }
+                if (first && first != (*outf)) {
+                    first->next = f;
                  }
              }
-            if (first && first != (*outf)) {
-                first->next = f;
-            }
          }
          *outf = f;
      }


Mime
View raw message