]> granicus.if.org Git - apache/commitdiff
The real slim shady finally stood up. This patch segregates the fast
authorWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 6 Aug 2001 19:03:37 +0000 (19:03 +0000)
committerWilliam A. Rowe Jr <wrowe@apache.org>
Mon, 6 Aug 2001 19:03:37 +0000 (19:03 +0000)
  internal redirect logic back into http_request, the next patch will
  actually fix it.

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

include/http_request.h
modules/http/http_request.c
modules/mappers/mod_negotiation.c

index 5e779eccc1b2ba4c20d5f5452511f61011b03d5a..a1f8375a579c85efaf4d5f0e0df709124578df2c 100644 (file)
@@ -199,6 +199,16 @@ AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r);
  */
 AP_DECLARE(void) ap_internal_redirect_handler(const char *new_uri, request_rec *r);
 
+/**
+ * Redirect the current request to a sub_req, merging the pools
+ * @param sub_req A subrequest created from this request
+ * @param r The current request
+ * @deffunc void ap_internal_fast_redirect(request_rec *sub_req, request_rec *r)
+ * @tip the sub_req's pool will be merged into r's pool, be very careful
+ * not to destroy this subrequest, it will be destroyed with the main request!
+ */
+AP_DECLARE(void) ap_internal_fast_redirect(request_rec *sub_req, request_rec *r))
+
 /**
  * Can be used within any handler to determine if any authentication
  * is required for the current request
index cfb9eeeb25555ee13eb345c00412f8c94d9a70e1..107436ce255e8ccea8f5d42511cba0b4d5904090 100644 (file)
@@ -556,6 +556,33 @@ static request_rec *internal_internal_redirect(const char *new_uri,
     return new;
 }
 
+AP_DECLARE(void) ap_internal_fast_redirect(request_rec *rr, request_rec *r))
+{
+    /* We need to tell POOL_DEBUG that we're guaranteeing that rr->pool
+     * will exist as long as r->pool.  Otherwise we run into troubles because
+     * some values in this request will be allocated in r->pool, and others in
+     * rr->pool.
+     */
+    apr_pool_join(r->pool, rr->pool);
+    r->mtime = 0; /* reset etag info for subrequest */
+    r->filename = rr->filename;
+    r->handler = rr->handler;
+    r->content_type = rr->content_type;
+    r->content_encoding = rr->content_encoding;
+    r->content_languages = rr->content_languages;
+    r->content_language = rr->content_language;
+    r->finfo = rr->finfo;
+    r->per_dir_config = rr->per_dir_config;
+    /* copy output headers from subrequest, but leave negotiation headers */
+    r->notes = apr_table_overlay(r->pool, rr->notes, r->notes);
+    r->headers_out = apr_table_overlay(r->pool, rr->headers_out,
+                                    r->headers_out);
+    r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out,
+                                        r->err_headers_out);
+    r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env,
+                                       r->subprocess_env);
+}
+
 AP_DECLARE(void) ap_internal_redirect(const char *new_uri, request_rec *r)
 {
     request_rec *new = internal_internal_redirect(new_uri, r);
index 946bac576149b8dffe50855d4ee26c88a8e30da2..9d162a7e5b80e9da37b95aa1d109842286aeebbb 100644 (file)
@@ -911,6 +911,7 @@ static int read_types_multi(negotiation_state *neg)
     struct var_rec mime_info;
     struct accept_rec accept_info;
     void *new_var;
+    int anymatch = 0;
 
     clean_var_rec(&mime_info);
 
@@ -947,6 +948,11 @@ static int read_types_multi(negotiation_state *neg)
             continue;
         }
 
+        /* Ok, something's here.  Maybe nothing useful.  Remember that
+         * we tried, if we completely fail, so we can reject the request!
+         */
+        anymatch = 1;
+
         /* Yep.  See if it's something which we have access to, and 
          * which has a known type and encoding (as opposed to something
          * which we'll be slapping default_type on later).
@@ -954,6 +960,11 @@ static int read_types_multi(negotiation_state *neg)
 
         sub_req = ap_sub_req_lookup_dirent(&dirent, r, NULL);
 
+        /* BLECH --- don't multi-resolve non-ordinary files */
+
+        if (sub_req->finfo.filetype != APR_REG)
+            continue;
+
         /* If it has a handler, we'll pretend it's a CGI script,
          * since that's a good indication of the sort of thing it
          * might be doing.
@@ -2689,43 +2700,16 @@ static int handle_multi(request_rec *r)
         }
     }
 
-    /* BLECH --- don't multi-resolve non-ordinary files */
-
-    if (sub_req->finfo.filetype != APR_REG) {
-        res = HTTP_NOT_FOUND;
-        goto return_from_multi;
-    }
-
-    /* Otherwise, use it. */
+    /* now do a "fast redirect" ... promotes the sub_req into the main req */
+    ap_internal_fast_redirect(sub_req, r);
 
-    /* now do a "fast redirect" ... promote the sub_req into the main req */
-    /* We need to tell POOL_DEBUG that we're guaranteeing that sub_req->pool
-     * will exist as long as r->pool.  Otherwise we run into troubles because
-     * some values in this request will be allocated in r->pool, and others in
-     * sub_req->pool.
+    /* clean up all but our favorite variant, since that sub_req
+     * is now merged into the main request!
      */
-    apr_pool_join(r->pool, sub_req->pool);
-    r->mtime = 0; /* reset etag info for subrequest */
-    r->filename = sub_req->filename;
-    r->handler = sub_req->handler;
-    r->content_type = sub_req->content_type;
-    r->content_encoding = sub_req->content_encoding;
-    r->content_languages = sub_req->content_languages;
-    r->content_language = sub_req->content_language;
-    r->finfo = sub_req->finfo;
-    r->per_dir_config = sub_req->per_dir_config;
-    /* copy output headers from subrequest, but leave negotiation headers */
-    r->notes = apr_table_overlay(r->pool, sub_req->notes, r->notes);
-    r->headers_out = apr_table_overlay(r->pool, sub_req->headers_out,
-                                    r->headers_out);
-    r->err_headers_out = apr_table_overlay(r->pool, sub_req->err_headers_out,
-                                        r->err_headers_out);
-    r->subprocess_env = apr_table_overlay(r->pool, sub_req->subprocess_env,
-                                       r->subprocess_env);
     avail_recs = (var_rec *) neg->avail_vars->elts;
     for (j = 0; j < neg->avail_vars->nelts; ++j) {
         var_rec *variant = &avail_recs[j];
-        if (variant != best && variant->sub_req) {
+        if (variant != best && variant->rr) {
             ap_destroy_sub_req(variant->sub_req);
         }
     }