]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
This finishes the mod_dir/mod_negotiation bug. This final part of the
authorRyan Bloom <rbb@apache.org>
Sun, 3 Mar 2002 06:04:08 +0000 (06:04 +0000)
committerRyan Bloom <rbb@apache.org>
Sun, 3 Mar 2002 06:04:08 +0000 (06:04 +0000)
solution ensures that we don't lose filters if they are added later than
we expect.  The problem could be seen if a connection filter was added
after a request-based filter was added in the past.  The problem was that
the request-based filters pointed to the first filter in the connection
record, so the new connection filter was never called.  Now, all filters
are put on their correct filter lists, and we are sure to always update
all pointers when adding a filter.

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

STATUS
include/util_filter.h
server/util_filter.c

diff --git a/STATUS b/STATUS
index 6deb0b81455811e390962d2327c0aedcac085ef4..d01d075ff0025b93b37b702685d4dd60f003783b 100644 (file)
--- a/STATUS
+++ b/STATUS
@@ -1,5 +1,5 @@
 APACHE 2.0 STATUS:                                              -*-text-*-
-Last modified at [$Date: 2002/03/02 19:10:07 $]
+Last modified at [$Date: 2002/03/03 06:04:08 $]
 
 Release:
 
@@ -50,19 +50,6 @@ CURRENT RELEASE NOTES:
 
 FINAL RELEASE SHOWSTOPPERS:
 
-    * All ap_internal_fast_redirect()ed requests are losing their filters
-      and output headers.  mod_negotiation derived Multiviewed documents
-      and mod_dir DirectoryIndex documents both demonstrate this behavior.
-      [PR 9963, 10001]
-        cf reply:  <007c01c1b3d1$46714650$94c0b0d0@v505>
-        to thread: <200202121332.IAA27467@web.turner.com>
-      Solutions:
-        Ditch fast_redirect, it was bogus in 1.3 and it's bogus now.
-          In Agreement? : Justin, Aaron
-        Fix [and *Maintain*] fast_redirect, it was useful to our redirects
-        in negotiation and dir, and it's useful to 3rd parties.
-          In Agreement? :
-
     * If any request gets to the core handler, without a flag that this 
       r->filename was tested by dir/file_walk, we need to 500 at the very 
       end of the ap_process_request_internal() processing.  This provides
index 19d845afb96a3b70c4dbd9619778330f5be2ca84..60ea804b94bc16fbbb3635632996bd66b009e39d 100644 (file)
@@ -263,6 +263,9 @@ struct ap_filter_t {
     /** The next filter in the chain */
     ap_filter_t *next;
 
+    /** The previous filter in the chain */
+    ap_filter_t *prev;
+
     /** The request_rec associated with the current filter.  If a sub-request
      *  adds filters, then the sub-request is the request associated with the
      *  filter.
index e457aaf9c98b805975e8df05bbb61a4085511268..5b37a91239bd2e792cf63db6dd0be3009ca8d102 100644 (file)
@@ -330,7 +330,31 @@ static ap_filter_t *add_any_filter(const char *name, void *ctx,
         if (node && node->frec) {
             apr_pool_t* p = r ? r->pool : c->pool;
             ap_filter_t *f = apr_palloc(p, sizeof(*f));
-            ap_filter_t **outf = r ? (r_filters ? r_filters : p_filters) : c_filters;
+            ap_filter_t **outf;
+
+            if (node->frec->ftype < AP_FTYPE_HTTP_HEADER) {
+                if (r) {
+                    outf = r_filters;
+                }
+                else {
+                    ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
+                                 "a content filter was added without a request: %s", name);
+                    return NULL;
+                }
+            }
+            else if (node->frec->ftype < AP_FTYPE_CONNECTION) {
+                if (r) {
+                    outf = p_filters;
+                }
+                else {
+                    ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
+                                 "a protocol filter was added without a request: %s", name);
+                    return NULL;
+                }
+            }
+            else {
+                outf = c_filters;
+            }
 
             f->frec = node->frec;
             f->ctx = ctx;
@@ -339,13 +363,24 @@ static ap_filter_t *add_any_filter(const char *name, void *ctx,
 
             if (INSERT_BEFORE(f, *outf)) {
                 f->next = *outf;
+                if ((*outf) && (*outf)->prev) {
+                    f->prev = (*outf)->prev;
+                    (*outf)->prev->next = f;
+                    (*outf)->prev = f;
+                }
+                else {
+                    f->prev = NULL;
+                }
                 *outf = f;
             }
             else {
                 ap_filter_t *fscan = *outf;
                 while (!INSERT_BEFORE(f, fscan->next))
                     fscan = fscan->next;
+
                 f->next = fscan->next;
+                f->prev = fscan;
+                fscan->next->prev = f;
                 fscan->next = f;
             }
 
@@ -366,7 +401,31 @@ static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
 {
     apr_pool_t* p = r ? r->pool : c->pool;
     ap_filter_t *f = apr_palloc(p, sizeof(*f));
-    ap_filter_t **outf = r ? (r_filters ? r_filters : p_filters) : c_filters;
+    ap_filter_t **outf;
+
+    if (frec->ftype < AP_FTYPE_HTTP_HEADER) {
+        if (r) {
+            outf = r_filters;
+        }
+        else {
+            ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
+                      "a content filter was added without a request: %s", frec->name);
+            return NULL;
+        }
+    }
+    else if (frec->ftype < AP_FTYPE_CONNECTION) {
+        if (r) {
+            outf = p_filters;
+        }
+        else {
+            ap_log_error(APLOG_MARK, APLOG_ERR|APLOG_NOERRNO, 0, NULL,
+                         "a protocol filter was added without a request: %s", frec->name);
+            return NULL;
+        }
+    }
+    else {
+        outf = c_filters;
+    }
 
     f->frec = frec;
     f->ctx = ctx;
@@ -375,13 +434,24 @@ static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx,
 
     if (INSERT_BEFORE(f, *outf)) {
         f->next = *outf;
+        if ((*outf) && (*outf)->prev) {
+            f->prev = (*outf)->prev;
+            (*outf)->prev->next = f;
+            (*outf)->prev = f;
+        }
+        else {
+            f->prev = NULL;
+        }
         *outf = f;
     }
     else {
         ap_filter_t *fscan = *outf;
         while (!INSERT_BEFORE(f, fscan->next))
             fscan = fscan->next;
+
         f->next = fscan->next;
+        f->prev = fscan;
+        fscan->next->prev = f;
         fscan->next = f;
     }