]> granicus.if.org Git - apache/commitdiff
Fix the mod_dir/mod_negotiation bug, where redirects and sub requests
authorRyan Bloom <rbb@apache.org>
Sun, 3 Mar 2002 02:15:52 +0000 (02:15 +0000)
committerRyan Bloom <rbb@apache.org>
Sun, 3 Mar 2002 02:15:52 +0000 (02:15 +0000)
were not getting the correct filters.  This is done by creating a location
in the request rec that holds protocol level filters.  Protocol level
filters survive for one request, from the time the request is received
from the user to the time the response is sent.  r->output_filters now
stores the request level filters, which are only valid for the lifetime
of one request_rec.

This patch works, but it is not complete.  The second half of the problem
is that add_any_filter doesn't check where it puts the filters that it
adds, so it is possible for filters to be put on this wrong list, and
for filters to be lost completely during request processing.  That half
of the fix will be coming in the next day or so.

Submitted by: Will Rowe, Justin Erenkrantz, Ryan Bloom

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

include/httpd.h
modules/http/http_request.c
server/protocol.c
server/request.c
server/util_filter.c

index c6f6d1da8f0622f988b3b499cdc72a1467569f88..fa57f9818307fac0d29d08e6d43bb7c05c1e748c 100644 (file)
@@ -905,6 +905,14 @@ struct request_rec {
     struct ap_filter_t *output_filters;
     /** A list of input filters to be used for this request */
     struct ap_filter_t *input_filters;
+
+    /** A list of protocol level output filters to be used for this
+     *  request */
+    struct ap_filter_t *proto_output_filters;
+    /** A list of protocol level input filters to be used for this
+     *  request */
+    struct ap_filter_t *proto_input_filters;
+
     /** A flag to determine if the eos bucket has been sent yet */
     int eos_sent;
 
index 244c346cf1b0e9dddfa488f337c71903f68412a1..b1763edbe95b59a247a79c10809f3decbccf4300 100644 (file)
@@ -391,8 +391,11 @@ static request_rec *internal_internal_redirect(const char *new_uri,
     new->read_length     = r->read_length;     /* We can only read it once */
     new->vlist_validator = r->vlist_validator;
 
-    new->output_filters  = r->connection->output_filters;
-    new->input_filters   = r->connection->input_filters;
+    new->proto_output_filters  = r->proto_output_filters;
+    new->proto_input_filters   = r->proto_input_filters;
+
+    new->output_filters  = new->proto_output_filters;
+    new->input_filters   = new->proto_input_filters;
 
     ap_add_input_filter("HTTP_IN", NULL, new, new->connection);
 
@@ -441,6 +444,9 @@ AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r)
                                         r->err_headers_out);
     r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
                                        r->subprocess_env);
+
+    r->output_filters = rr->output_filters;
+    r->input_filters = rr->input_filters;
 }
 
 AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
index 923c6de854ef1f04955911a3c980c1f12da3cda0..a902d55a179391288939aac1e4caa1f31d53a261 100644 (file)
@@ -776,8 +776,10 @@ request_rec *ap_read_request(conn_rec *conn)
 
     r->request_config  = ap_create_request_config(r->pool);
     /* Must be set before we run create request hook */
-    r->output_filters  = conn->output_filters;
-    r->input_filters   = conn->input_filters;
+    r->proto_output_filters = conn->output_filters;
+    r->output_filters  = r->proto_output_filters;
+    r->proto_input_filters = conn->input_filters;
+    r->input_filters   = r->proto_input_filters;
     ap_run_create_request(r);
     r->per_dir_config  = r->server->lookup_defaults;
 
index 7d3cc6c22b6d5ff2718f419d45f289968541c6d7..69d6df5954a87e894dcd990e499e6a2638628de9 100644 (file)
@@ -1492,13 +1492,23 @@ static request_rec *make_sub_request(const request_rec *r,
 
     /* start with the same set of output filters */
     if (next_filter) {
+        /* no input filters for a subrequest */
         rnew->output_filters = next_filter;
+        ap_add_output_filter_handle(ap_subreq_core_filter_handle,
+                                    NULL, rnew, rnew->connection); 
     }
     else {
-        rnew->output_filters = r->output_filters;
+        /* If NULL - we are expecting to be internal_fast_redirect'ed
+         * to this subrequest - or this request will never be invoked.
+         * Ignore the original request filter stack entirely, and
+         * drill the input and output stacks back to the connection.
+         */
+        rnew->proto_input_filters = r->proto_input_filters;
+        rnew->proto_output_filters = r->proto_output_filters;
+
+        rnew->input_filters = r->proto_input_filters;
+        rnew->output_filters = r->proto_output_filters;
     }
-    ap_add_output_filter_handle(ap_subreq_core_filter_handle,
-                                NULL, rnew, rnew->connection); 
 
     /* no input filters for a subrequest */
 
index afc0731de233b9eef93716b8cd1cee0d06f44dd7..e457aaf9c98b805975e8df05bbb61a4085511268 100644 (file)
@@ -294,7 +294,8 @@ AP_DECLARE(ap_filter_rec_t *) ap_register_output_filter(const char *name,
 static ap_filter_t *add_any_filter(const char *name, void *ctx, 
                                    request_rec *r, conn_rec *c, 
                                    const filter_trie_node *reg_filter_set,
-                                   ap_filter_t **r_filters,
+                                   ap_filter_t **r_filters, 
+                                   ap_filter_t **p_filters,
                                    ap_filter_t **c_filters)
 {
     if (reg_filter_set) {
@@ -329,7 +330,7 @@ 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 : c_filters;
+            ap_filter_t **outf = r ? (r_filters ? r_filters : p_filters) : c_filters;
 
             f->frec = node->frec;
             f->ctx = ctx;
@@ -360,11 +361,12 @@ static ap_filter_t *add_any_filter(const char *name, void *ctx,
 static ap_filter_t *add_any_filter_handle(ap_filter_rec_t *frec, void *ctx, 
                                           request_rec *r, conn_rec *c, 
                                           ap_filter_t **r_filters,
+                                          ap_filter_t **p_filters,
                                           ap_filter_t **c_filters)
 {
     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 : c_filters;
+    ap_filter_t **outf = r ? (r_filters ? r_filters : p_filters) : c_filters;
 
     f->frec = frec;
     f->ctx = ctx;
@@ -390,7 +392,8 @@ AP_DECLARE(ap_filter_t *) ap_add_input_filter(const char *name, void *ctx,
                                               request_rec *r, conn_rec *c)
 {
     return add_any_filter(name, ctx, r, c, registered_input_filters,
-                          r ? &r->input_filters : NULL, &c->input_filters);
+                          r ? &r->input_filters : NULL, 
+                          r ? &r->proto_input_filters : NULL, &c->input_filters);
 }
 
 AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
@@ -399,6 +402,7 @@ AP_DECLARE(ap_filter_t *) ap_add_input_filter_handle(ap_filter_rec_t *f,
                                                      conn_rec *c)
 {
     return add_any_filter_handle(f, ctx, r, c, r ? &r->input_filters : NULL,
+                                 r ? &r->proto_input_filters : NULL, 
                                  &c->input_filters);
 }
 
@@ -406,7 +410,8 @@ AP_DECLARE(ap_filter_t *) ap_add_output_filter(const char *name, void *ctx,
                                                request_rec *r, conn_rec *c)
 {
     return add_any_filter(name, ctx, r, c, registered_output_filters,
-                          r ? &r->output_filters : NULL, &c->output_filters);
+                          r ? &r->output_filters : NULL, 
+                          r ? &r->proto_output_filters : NULL, &c->output_filters);
 }
 
 AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
@@ -415,6 +420,7 @@ AP_DECLARE(ap_filter_t *) ap_add_output_filter_handle(ap_filter_rec_t *f,
                                                       conn_rec *c)
 {
     return add_any_filter_handle(f, ctx, r, c, r ? &r->output_filters : NULL,
+                                 r ? &r->proto_output_filters : NULL,
                                  &c->output_filters);
 }