From: William A. Rowe Jr Date: Fri, 28 Sep 2001 18:56:21 +0000 (+0000) Subject: Split out (soon to be) common code for all _walk functions X-Git-Tag: 2.0.26~163 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=8e82ad3743ab4eedbfd55e59e942196388c95918;p=thirdparty%2Fapache%2Fhttpd.git Split out (soon to be) common code for all _walk functions (no net change to location_walk). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@91185 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/request.c b/server/request.c index b7bb3ee7db3..1086bc833cc 100644 --- a/server/request.c +++ b/server/request.c @@ -275,6 +275,63 @@ AP_DECLARE(int) ap_process_request_internal(request_rec *r) } +/* Useful caching structures to repeat _walk/merge sequences as required + * when a subrequest or redirect reuses substantially the same config. + * + * Directive order in the httpd.conf file and its Includes significantly + * impact this optimization. Grouping common blocks at the front of the + * config that are less likely to change between a request and + * its subrequests, or between a request and its redirects reduced + * the work of these functions significantly. + */ + + typedef struct walk_walked_t { + ap_conf_vector_t *matched; /* A dir_conf sections we matched */ + ap_conf_vector_t *merged; /* The dir_conf merged result */ +} walk_walked_t; + +typedef struct walk_cache_t { + const char *cached; /* The identifier we matched */ + ap_conf_vector_t **dir_conf_tested;/* The sections we matched against */ + ap_conf_vector_t *per_dir_result; /* per_dir_config += walked result */ + apr_array_header_t *walked; /* The list of walk_walked_t results */ +} walk_cache_t; + +static walk_cache_t *prep_walk_cache(const char *cache_name, request_rec *r) +{ + walk_cache_t *cache; + + /* Find the most relevant, recent entry to work from. That would be + * this request (on the second call), or the parent request of a + * subrequest, or the prior request of an internal redirect. Provide + * this _walk()er with a copy it is allowed to munge. If there is no + * parent or prior cached request, then create a new walk cache. + */ + if ((apr_pool_userdata_get((void **)&cache, + cache_name, r->pool) + != APR_SUCCESS) || !cache) + { + if ((r->main && (apr_pool_userdata_get((void **)&cache, + cache_name, + r->main->pool) + == APR_SUCCESS) && cache) + || (r->prev && (apr_pool_userdata_get((void **)&cache, + cache_name, + r->prev->pool) + == APR_SUCCESS) && cache)) { + cache = apr_pmemdup(r->pool, cache, sizeof(*cache)); + cache->walked = apr_array_copy(r->pool, cache->walked); + } + else { + cache = apr_pcalloc(r->pool, sizeof(*cache)); + cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t)); + } + apr_pool_userdata_set(cache, cache_name, + apr_pool_cleanup_null, r->pool); + } + return cache; +} + /***************************************************************** * * Getting and checking directory configuration. Also checks the @@ -1126,18 +1183,6 @@ AP_DECLARE(int) ap_directory_walk(request_rec *r) #endif /* defined REPLACE_PATH_INFO_METHOD */ -typedef struct walk_walked_t { - ap_conf_vector_t *matched; /* A dir_conf sections we matched */ - ap_conf_vector_t *merged; /* The dir_conf merged result */ -} walk_walked_t; - -typedef struct walk_cache_t { - const char *cached; /* The identifier we matched */ - ap_conf_vector_t **dir_conf_tested;/* The sections we matched against */ - ap_conf_vector_t *per_dir_result; /* per_dir_config += walked result */ - apr_array_header_t *walked; /* The list of walk_walked_t results */ -} walk_cache_t; - AP_DECLARE(int) ap_location_walk(request_rec *r) { ap_conf_vector_t *now_merged = NULL; @@ -1151,32 +1196,7 @@ AP_DECLARE(int) ap_location_walk(request_rec *r) const char *entry_uri; int len, j; - /* Find the most relevant, recent entry to work from. That would be - * this request (on the second call), or the parent request of a - * subrequest, or the prior request of an internal redirect. - */ - if ((apr_pool_userdata_get((void **)&cache, - "ap_location_walk::cache", r->pool) - != APR_SUCCESS) || !cache) - { - if ((r->main && (apr_pool_userdata_get((void **)&cache, - "ap_location_walk::cache", - r->main->pool) - == APR_SUCCESS) && cache) - || (r->prev && (apr_pool_userdata_get((void **)&cache, - "ap_location_walk::cache", - r->prev->pool) - == APR_SUCCESS) && cache)) { - cache = apr_pmemdup(r->pool, cache, sizeof(*cache)); - cache->walked = apr_array_copy(r->pool, cache->walked); - } - else { - cache = apr_pcalloc(r->pool, sizeof(*cache)); - cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t)); - } - apr_pool_userdata_set(cache, "ap_location_walk::cache", - apr_pool_cleanup_null, r->pool); - } + cache = prep_walk_cache("ap_location_walk::cache", r); /* No tricks here, there are no to parse in this vhost. * We won't destroy the cache, just in case _this_ redirect is later