request.c revision cbd8d35ca8d9780f1081f30ebfe4abda44cab7eb
2d2eda71267231c2526be701fe655db125852c1ffielding/* ====================================================================
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * The Apache Software License, Version 1.1
b99dbaab171d91e1b664397cc40e039d0c087c65fielding * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * reserved.
2d2eda71267231c2526be701fe655db125852c1ffielding * Redistribution and use in source and binary forms, with or without
2d2eda71267231c2526be701fe655db125852c1ffielding * modification, are permitted provided that the following conditions
2d2eda71267231c2526be701fe655db125852c1ffielding * 1. Redistributions of source code must retain the above copyright
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * notice, this list of conditions and the following disclaimer.
2d2eda71267231c2526be701fe655db125852c1ffielding * 2. Redistributions in binary form must reproduce the above copyright
2d2eda71267231c2526be701fe655db125852c1ffielding * notice, this list of conditions and the following disclaimer in
2d2eda71267231c2526be701fe655db125852c1ffielding * the documentation and/or other materials provided with the
2d2eda71267231c2526be701fe655db125852c1ffielding * distribution.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * 3. The end-user documentation included with the redistribution,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * if any, must include the following acknowledgment:
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * "This product includes software developed by the
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * Apache Software Foundation (http://www.apache.org/)."
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * Alternately, this acknowledgment may appear in the software itself,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * if and wherever such third-party acknowledgments normally appear.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * 4. The names "Apache" and "Apache Software Foundation" must
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * not be used to endorse or promote products derived from this
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * software without prior written permission. For written
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * permission, please contact apache@apache.org.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * 5. Products derived from this software may not be called "Apache",
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * nor may "Apache" appear in their name, without prior written
64185f9824e42f21ca7b9ae6c004484215c031a7rbb * permission of the Apache Software Foundation.
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
2d2eda71267231c2526be701fe655db125852c1ffielding * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * SUCH DAMAGE.
2d2eda71267231c2526be701fe655db125852c1ffielding * ====================================================================
2d2eda71267231c2526be701fe655db125852c1ffielding * This software consists of voluntary contributions made by many
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * individuals on behalf of the Apache Software Foundation. For more
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * information on the Apache Software Foundation, please see
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * Portions of this software are based upon public domain software
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * originally written at the National Center for Supercomputing Applications,
f062ed7bd262a37a909dd77ce5fc23b446818823fielding * University of Illinois, Urbana-Champaign.
2d2eda71267231c2526be701fe655db125852c1ffielding * http_request.c: functions to get and process requests
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * Rob McCool 3/21/93
0432a26b69eedfb9ca5f34fba590236378a24851ben * Thoroughly revamped by rst for Apache. NB this file reads
2d2eda71267231c2526be701fe655db125852c1ffielding * best from the bottom up.
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbAP_IMPLEMENT_HOOK_VOID(insert_filter, (request_rec *r), (r))
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbAP_IMPLEMENT_HOOK_RUN_ALL(int,create_request,(request_rec *r),(r),OK,DECLINED)
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic int decl_die(int status, char *phase, request_rec *r)
2d2eda71267231c2526be701fe655db125852c1ffielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_CRIT, 0, r,
2d2eda71267231c2526be701fe655db125852c1ffielding "configuration error: couldn't %s: %s", phase, r->uri);
2d2eda71267231c2526be701fe655db125852c1ffielding/* This is the master logic for processing requests. Do NOT duplicate
2d2eda71267231c2526be701fe655db125852c1ffielding * this logic elsewhere, or the security model will be broken by future
2d2eda71267231c2526be701fe655db125852c1ffielding * API changes. Each phase must be individually optimized to pick up
2d2eda71267231c2526be701fe655db125852c1ffielding * redundant/duplicate calls by subrequests, and redirects.
2d2eda71267231c2526be701fe655db125852c1ffieldingAP_DECLARE(int) ap_process_request_internal(request_rec *r)
2d2eda71267231c2526be701fe655db125852c1ffielding /* Ignore embedded %2F's in path for proxy requests */
2d2eda71267231c2526be701fe655db125852c1ffielding access_status = ap_unescape_url(r->parsed_uri.path);
2d2eda71267231c2526be701fe655db125852c1ffielding ap_getparents(r->uri); /* OK --- shrinking transformations... */
2d2eda71267231c2526be701fe655db125852c1ffielding /* All file subrequests are a huge pain... they cannot bubble through the
2d2eda71267231c2526be701fe655db125852c1ffielding * next several steps. Only file subrequests are allowed an empty uri,
2d2eda71267231c2526be701fe655db125852c1ffielding * otherwise let translate_name kill the request.
2d2eda71267231c2526be701fe655db125852c1ffielding /* Reset to the server default config prior to running map_to_storage
2d2eda71267231c2526be701fe655db125852c1ffielding /* This request wasn't in storage (e.g. TRACE) */
2d2eda71267231c2526be701fe655db125852c1ffielding /* Excluding file-specific requests with no 'true' URI...
2d2eda71267231c2526be701fe655db125852c1ffielding /* Rerun the location walk, which overrides any map_to_storage config.
2d2eda71267231c2526be701fe655db125852c1ffielding /* Only on the main request! */
2d2eda71267231c2526be701fe655db125852c1ffielding /* Skip authn/authz if the parent or prior request passed the authn/authz,
2d2eda71267231c2526be701fe655db125852c1ffielding * and that configuration didn't change (this requires optimized _walk()
2d2eda71267231c2526be701fe655db125852c1ffielding * functions in map_to_storage that use the same merge results given
2d2eda71267231c2526be701fe655db125852c1ffielding * identical input.) If the config changes, we must re-auth.
2d2eda71267231c2526be701fe655db125852c1ffielding if (r->main && (r->main->per_dir_config == r->per_dir_config)) {
2d2eda71267231c2526be701fe655db125852c1ffielding else if (r->prev && (r->prev->per_dir_config == r->per_dir_config)) {
2d2eda71267231c2526be701fe655db125852c1ffielding switch (ap_satisfies(r)) {
2efb935ae8fe12d5192a3bf2c52c28461b6c68afdgaudet if ((access_status = ap_run_access_checker(r)) != 0) {
2efb935ae8fe12d5192a3bf2c52c28461b6c68afdgaudet if (((access_status = ap_run_check_user_id(r)) != 0)
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ? "check user. No user file?"
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb : "perform authentication. AuthType not set!",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ? "check access. No groups file?"
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb : "perform authentication. AuthType not set!",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb if (((access_status = ap_run_access_checker(r)) != 0) ||
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ? "check access"
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb : "perform authentication. AuthType not set!",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ? "check user. No user file?"
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb : "perform authentication. AuthType not set!",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ? "check access. No groups file?"
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb : "perform authentication. AuthType not set!",
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb /* XXX Must make certain the ap_run_type_checker short circuits mime
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * in mod-proxy for r->proxyreq && r->parsed_uri.scheme
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * && !strcmp(r->parsed_uri.scheme, "http")
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb/* Useful caching structures to repeat _walk/merge sequences as required
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * when a subrequest or redirect reuses substantially the same config.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * Directive order in the httpd.conf file and its Includes significantly
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * impact this optimization. Grouping common blocks at the front of the
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * config that are less likely to change between a request and
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * its subrequests, or between a request and its redirects reduced
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * the work of these functions significantly.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7bentypedef struct walk_walked_t {
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben ap_conf_vector_t *matched; /* A dir_conf sections we matched */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ap_conf_vector_t *merged; /* The dir_conf merged result */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbbtypedef struct walk_cache_t {
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ap_conf_vector_t **dir_conf_tested;/* The sections we matched against */
1374444b4fab1475091e12a81663f379b73005efrbb ap_conf_vector_t *dir_conf_merged;/* Base per_dir_config */
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb ap_conf_vector_t *per_dir_result; /* per_dir_config += walked result */
c8aa00ee0cfc17b5fa08fb8a2b08d30dc9e4f1b1wrowe apr_array_header_t *walked; /* The list of walk_walked_t results */
c8aa00ee0cfc17b5fa08fb8a2b08d30dc9e4f1b1wrowestatic walk_cache_t *prep_walk_cache(apr_size_t t, request_rec *r)
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb /* Find the most relevant, recent entry to work from. That would be
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * this request (on the second call), or the parent request of a
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * subrequest, or the prior request of an internal redirect. Provide
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * this _walk()er with a copy it is allowed to munge. If there is no
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb * parent or prior cached request, then create a new walk cache.
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb if ((r->main &&
b0f20a4a26bcfa85724b1c2e5ec6a077f12ef44crbb sizeof(*cache));
2e123e8beedc9f921448c113e2d6823a92fd5261fielding cache->walked = apr_array_copy(r->pool, cache->walked);
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben cache->walked = apr_array_make(r->pool, 4, sizeof(walk_walked_t));
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben/*****************************************************************
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * Getting and checking directory configuration. Also checks the
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * FollowSymlinks and FollowSymOwner stuff, since this is really the
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * only place that can happen (barring a new mid_dir_walk callout).
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * We can't do it as an access_checker module function which gets
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * called with the final per_dir_config, since we could have a directory
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * with FollowSymLinks disabled, which contains a symlink to another
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * with a .htaccess file which turns FollowSymLinks back on --- and
64b9fa4bc3e79b0eefb2d93fb56eae40d88e0f06wrowe * access in such a case must be denied. So, whatever it is that
64b9fa4bc3e79b0eefb2d93fb56eae40d88e0f06wrowe * checks FollowSymLinks needs to know the state of the options as
64b9fa4bc3e79b0eefb2d93fb56eae40d88e0f06wrowe * they change, all the way down.
64b9fa4bc3e79b0eefb2d93fb56eae40d88e0f06wrowe * We don't want people able to serve up pipes, or unix sockets, or other
64b9fa4bc3e79b0eefb2d93fb56eae40d88e0f06wrowe * scary things. Note that symlink tests are performed later.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben "object is not a file, directory or symlink: %s",
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * resolve_symlink must _always_ be called on an APR_LNK file type!
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * It will resolve the actual target file type, modification date, etc,
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * and provide any processing required for symlink evaluation.
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * Path must already be cleaned, no trailing slash, no multi-slashes,
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * and don't call this on the root!
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * Simply, the number of times we deref a symlink are minimal compared
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * to the number of times we had an extra lstat() since we 'weren't sure'.
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * To optimize, we stat() anything when given (opts & OPT_SYM_LINKS), otherwise
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * we start off with an lstat(). Every lstat() must be dereferenced in case
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * it points at a 'nasty' - we must always rerun check_safe_file (or similar.)
a520b923984f45daeaf0741d5c7e3de1f2d24509rbbstatic int resolve_symlink(char *d, apr_finfo_t *lfi, int opts, apr_pool_t *p)
2d2eda71267231c2526be701fe655db125852c1ffielding if ((res = apr_stat(&fi, d, lfi->valid, p)) != APR_SUCCESS) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* Give back the target */
2d2eda71267231c2526be701fe655db125852c1ffielding /* OPT_SYM_OWNER only works if we can get the owner of
2d2eda71267231c2526be701fe655db125852c1ffielding * both the file and symlink. First fill in a missing
2d2eda71267231c2526be701fe655db125852c1ffielding * owner of the symlink, then get the info of the target.
2d2eda71267231c2526be701fe655db125852c1ffielding if ((res = apr_lstat(&fi, d, lfi->valid | APR_FINFO_OWNER, p))
2d2eda71267231c2526be701fe655db125852c1ffielding if ((res = apr_stat(&fi, d, lfi->valid, p)) != APR_SUCCESS) {
2d2eda71267231c2526be701fe655db125852c1ffielding if (apr_compare_users(fi.user, lfi->user) != APR_SUCCESS) {
2d2eda71267231c2526be701fe655db125852c1ffielding /* Give back the target */
2d2eda71267231c2526be701fe655db125852c1ffielding/*****************************************************************
2d2eda71267231c2526be701fe655db125852c1ffielding * Getting and checking directory configuration. Also checks the
2d2eda71267231c2526be701fe655db125852c1ffielding * FollowSymlinks and FollowSymOwner stuff, since this is really the
2d2eda71267231c2526be701fe655db125852c1ffielding * only place that can happen (barring a new mid_dir_walk callout).
2d2eda71267231c2526be701fe655db125852c1ffielding * We can't do it as an access_checker module function which gets
2d2eda71267231c2526be701fe655db125852c1ffielding * called with the final per_dir_config, since we could have a directory
2d2eda71267231c2526be701fe655db125852c1ffielding * with FollowSymLinks disabled, which contains a symlink to another
2d2eda71267231c2526be701fe655db125852c1ffielding * with a .htaccess file which turns FollowSymLinks back on --- and
2d2eda71267231c2526be701fe655db125852c1ffielding * access in such a case must be denied. So, whatever it is that
2d2eda71267231c2526be701fe655db125852c1ffielding * checks FollowSymLinks needs to know the state of the options as
2d2eda71267231c2526be701fe655db125852c1ffielding * they change, all the way down.
2d2eda71267231c2526be701fe655db125852c1ffielding core_server_config *sconf = ap_get_module_config(r->server->module_config,
2d2eda71267231c2526be701fe655db125852c1ffielding ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) sconf->sec_dir->elts;
2d2eda71267231c2526be701fe655db125852c1ffielding /* XXX: Better (faster) tests needed!!!
2d2eda71267231c2526be701fe655db125852c1ffielding * "OK" as a response to a real problem is not _OK_, but to allow broken
2d2eda71267231c2526be701fe655db125852c1ffielding * modules to proceed, we will permit the not-a-path filename to pass the
2d2eda71267231c2526be701fe655db125852c1ffielding * following two tests. This behavior may be revoked in future versions
2d2eda71267231c2526be701fe655db125852c1ffielding * of Apache. We still must catch it later if it's heading for the core
2d2eda71267231c2526be701fe655db125852c1ffielding * handler. Leave INFO notes here for module debugging.
2d2eda71267231c2526be701fe655db125852c1ffielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
2d2eda71267231c2526be701fe655db125852c1ffielding "Module bug? Request filename is missing for URI %s",
2d2eda71267231c2526be701fe655db125852c1ffielding /* Canonicalize the file path without resolving filename case or aliases
2d2eda71267231c2526be701fe655db125852c1ffielding * so we can begin by checking the cache for a recent directory walk.
763f7b125b6d3dd1e4992a3822005efa2616f983coar * This call will ensure we have an absolute path in the same pass.
2d2eda71267231c2526be701fe655db125852c1ffielding if ((rv = apr_filepath_merge(&entry_dir, NULL, r->filename,
2d2eda71267231c2526be701fe655db125852c1ffielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, 0, r,
2d2eda71267231c2526be701fe655db125852c1ffielding "Module bug? Request filename path %s is invalid or "
2d2eda71267231c2526be701fe655db125852c1ffielding "or not absolute for uri %s",
2d2eda71267231c2526be701fe655db125852c1ffielding /* XXX Notice that this forces path_info to be canonical. That might
2d2eda71267231c2526be701fe655db125852c1ffielding * not be desired by all apps. However, some of those same apps likely
2d2eda71267231c2526be701fe655db125852c1ffielding * have significant security holes.
2d2eda71267231c2526be701fe655db125852c1ffielding cache = prep_walk_cache(AP_NOTE_DIRECTORY_WALK, r);
2d2eda71267231c2526be701fe655db125852c1ffielding /* If this is not a dirent subrequest with a preconstructed
2d2eda71267231c2526be701fe655db125852c1ffielding * r->finfo value, then we can simply stat the filename to
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * save burning mega-cycles with unneeded stats - if this is
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * an exact file match. We don't care about failure... we
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * will stat by component failing this meager attempt.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * It would be nice to distinguish APR_ENOENT from other
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar * types of failure, such as APR_ENOTDIR. We can do something
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * with APR_ENOENT, knowing that the path is good.
91f0d8da77152d24e4bbb31ce199282b3fd6e3b2coar if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) {
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb apr_stat(&r->finfo, r->filename, APR_FINFO_MIN, r->pool);
2d2eda71267231c2526be701fe655db125852c1ffielding entry_dir = ap_make_dirstr_parent(r->pool, entry_dir);
2d2eda71267231c2526be701fe655db125852c1ffielding else if (r->filename[strlen(r->filename) - 1] != '/') {
2d2eda71267231c2526be701fe655db125852c1ffielding entry_dir = apr_pstrcat(r->pool, r->filename, "/", NULL);
db3fa7db7c7910f2f23c3e3ffe0cf9f41a1899b9trawick /* If we have a file already matches the path of r->filename,
2d2eda71267231c2526be701fe655db125852c1ffielding * and the vhost's list of directory sections hasn't changed,
2d2eda71267231c2526be701fe655db125852c1ffielding * we can skip rewalking the directory_walk entries.
54e94821097724bf413d2d4cc70711760f7494e1trawick /* Well this looks really familiar! If our end-result (per_dir_result)
54e94821097724bf413d2d4cc70711760f7494e1trawick * didn't change, we have absolutely nothing to do :)
54e94821097724bf413d2d4cc70711760f7494e1trawick * Otherwise (as is the case with most dir_merged/file_merged requests)
54e94821097724bf413d2d4cc70711760f7494e1trawick * we must merge our dir_conf_merged onto this new r->per_dir_config.
2d2eda71267231c2526be701fe655db125852c1ffielding /* We start now_merged from NULL since we want to build
2d2eda71267231c2526be701fe655db125852c1ffielding * a locations list that can be merged to any vhost.
2d2eda71267231c2526be701fe655db125852c1ffielding walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Invariant: from the first time filename_len is set until
952908500d5f99f35afc5ed510391b9bdc3833farbb * it goes out of scope, filename_len==strlen(r->filename)
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * We must play our own mimi-merge game here, for the few
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * running dir_config values we care about within dir_walk.
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * We didn't start the merge from r->per_dir_config, so we
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * accumulate opts and override as we merge, from the globals.
3887202241db08986e94b252fbd06a55e55d4b2dbhyde this_dir = ap_get_module_config(r->per_dir_config, &core_module);
7c7372abe2484e7fcf81937b93496d1246e5b816gstein /* Set aside path_info to merge back onto path_info later.
7c7372abe2484e7fcf81937b93496d1246e5b816gstein * If r->filename is a directory, we must remerge the path_info,
864c5615d55b8ebbde24e72043f6325741335a74fielding * before we continue! [Directories cannot, by defintion, have
2d2eda71267231c2526be701fe655db125852c1ffielding * path info. Either the next segment is not-found, or a file.]
3887202241db08986e94b252fbd06a55e55d4b2dbhyde * r->path_info tracks the unconsumed source path.
952908500d5f99f35afc5ed510391b9bdc3833farbb * r->filename tracks the path as we process it
952908500d5f99f35afc5ed510391b9bdc3833farbb if ((r->finfo.filetype == APR_DIR) && r->path_info && *r->path_info)
952908500d5f99f35afc5ed510391b9bdc3833farbb if ((rv = apr_filepath_merge(&r->path_info, r->filename, r->path_info,
952908500d5f99f35afc5ed510391b9bdc3833farbb "dir_walk error, path_info %s is not relative "
3887202241db08986e94b252fbd06a55e55d4b2dbhyde "to the filename path %s for uri %s",
952908500d5f99f35afc5ed510391b9bdc3833farbb while (r->canonical_filename && r->canonical_filename[canonical_len]
952908500d5f99f35afc5ed510391b9bdc3833farbb * Now build r->filename component by component, starting
952908500d5f99f35afc5ed510391b9bdc3833farbb * with the root (on Unix, simply "/"). We will make a huge
853a0c44563b056e40e9cffe911190f554e63ec3chuck * assumption here for efficiency, that any canonical path
853a0c44563b056e40e9cffe911190f554e63ec3chuck * already given included a canonical root.
952908500d5f99f35afc5ed510391b9bdc3833farbb (const char **)&r->path_info,
952908500d5f99f35afc5ed510391b9bdc3833farbb * Bad assumption above? If the root's length is longer
952908500d5f99f35afc5ed510391b9bdc3833farbb * than the canonical length, then it cannot be trusted as
952908500d5f99f35afc5ed510391b9bdc3833farbb * a truename. So try again, this time more seriously.
952908500d5f99f35afc5ed510391b9bdc3833farbb (const char **)&r->path_info,
2d2eda71267231c2526be701fe655db125852c1ffielding#else /* ndef CASE_BLIND_FILESYSTEM, really this simple for Unix today; */
952908500d5f99f35afc5ed510391b9bdc3833farbb (const char **)&r->path_info,
952908500d5f99f35afc5ed510391b9bdc3833farbb "dir_walk error, could not determine the root "
952908500d5f99f35afc5ed510391b9bdc3833farbb "path of filename %s%s for uri %s",
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Working space for terminating null and an extra / is required.
9f9307bbe539dbcf96919715315eb64ce3465f5bben thisinfo.filetype = APR_DIR; /* It's the root, of course it's a dir */
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * seg keeps track of which segment we've copied.
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * sec_idx keeps track of which section we're on, since sections are
a520b923984f45daeaf0741d5c7e3de1f2d24509rbb * ordered by number of segments. See core_reorder_directories
952908500d5f99f35afc5ed510391b9bdc3833farbb * Go down the directory hierarchy. Where we have to check for
952908500d5f99f35afc5ed510391b9bdc3833farbb * symlinks, do so. Where a .htaccess file has permission to
952908500d5f99f35afc5ed510391b9bdc3833farbb * override anything, try to find one.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* We have no trailing slash, but we sure would appreciate one...
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Begin *this* level by looking for matching <Directory> sections
952908500d5f99f35afc5ed510391b9bdc3833farbb * from the server config.
2d2eda71267231c2526be701fe655db125852c1ffielding entry_core = ap_get_module_config(entry_config, &core_module);
2d2eda71267231c2526be701fe655db125852c1ffielding /* No more possible matches for this many segments?
2d2eda71267231c2526be701fe655db125852c1ffielding * We are done when we find relative/regex/longer components.
2d2eda71267231c2526be701fe655db125852c1ffielding if (entry_core->r || entry_core->d_components > seg) {
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* We will never skip '0' element components, e.g. plain old
2d2eda71267231c2526be701fe655db125852c1ffielding * <Directory >, and <Directory "/"> are classified as zero
2d2eda71267231c2526be701fe655db125852c1ffielding * so that Win32/Netware/OS2 etc all pick them up.
2d2eda71267231c2526be701fe655db125852c1ffielding * Otherwise, skip over the mismatches.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* If we merged this same section last time, reuse it
952908500d5f99f35afc5ed510391b9bdc3833farbb /* We fell out of sync. This is our own copy of walked,
2d2eda71267231c2526be701fe655db125852c1ffielding * so truncate the remaining matches and reset remaining.
952908500d5f99f35afc5ed510391b9bdc3833farbb last_walk = (walk_walked_t*)apr_array_push(cache->walked);
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Do a mini-merge to our globally-based running calculations of
2d2eda71267231c2526be701fe655db125852c1ffielding * core_dir->override and core_dir->opts, since now_merged
2d2eda71267231c2526be701fe655db125852c1ffielding * never considered the global config. Of course, if there is
2d2eda71267231c2526be701fe655db125852c1ffielding * no core config at this level, continue without a thought.
2d2eda71267231c2526be701fe655db125852c1ffielding * See core.c::merge_core_dir_configs() for explanation.
952908500d5f99f35afc5ed510391b9bdc3833farbb this_dir = ap_get_module_config(sec_ent[sec_idx], &core_module);
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein /* If .htaccess files are enabled, check for one, provided we
2d2eda71267231c2526be701fe655db125852c1ffielding * have reached a real path.
2d2eda71267231c2526be701fe655db125852c1ffielding res = ap_parse_htaccess(&htaccess_conf, r, override,
da76b1004afd7a8785684c84e4d4b5c893c65572rbb /* If we merged this same htaccess last time, reuse it...
777a2b42697cb8cb94ac4e73774862f879259c45rbb * this wouldn't work except that we cache the htaccess
2d2eda71267231c2526be701fe655db125852c1ffielding * sections for the lifetime of the request, so we match
2d2eda71267231c2526be701fe655db125852c1ffielding * the same conf. Good planning (no, pure luck ;)
9f9307bbe539dbcf96919715315eb64ce3465f5bben /* We fell out of sync. This is our own copy of walked,
853a0c44563b056e40e9cffe911190f554e63ec3chuck * so truncate the remaining matches and reset
853a0c44563b056e40e9cffe911190f554e63ec3chuck * remaining.
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm last_walk = (walk_walked_t*)apr_array_push(cache->walked);
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Do a mini-merge to our globally-based running
2d2eda71267231c2526be701fe655db125852c1ffielding * calculations of core_dir->override and core_dir->opts,
2d2eda71267231c2526be701fe655db125852c1ffielding * since now_merged never considered the global config.
2d2eda71267231c2526be701fe655db125852c1ffielding * Of course, if there is no core config at this level,
952908500d5f99f35afc5ed510391b9bdc3833farbb * continue without a thought.
0ff36975b1f5fef1ccc0429bb76bcdaccd5d122brbb * See core.c::merge_core_dir_configs() for explanation.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* That temporary trailing slash was useful, now drop it.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Time for all good things to come to an end?
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Now it's time for the next segment...
952908500d5f99f35afc5ed510391b9bdc3833farbb * We will assume the next element is an end node, and fix it up
a6b9ed64fdf548c61de9714e2cfb999ec59d149cgstein * below as necessary...
9f9307bbe539dbcf96919715315eb64ce3465f5bben delim = strchr(r->path_info + (*r->path_info == '/' ? 1 : 0), '/');
2d2eda71267231c2526be701fe655db125852c1ffielding /* If nothing remained but a '/' string, we are finished
952908500d5f99f35afc5ed510391b9bdc3833farbb /* First optimization;
2d2eda71267231c2526be701fe655db125852c1ffielding * If...we knew r->filename was a file, and
2d2eda71267231c2526be701fe655db125852c1ffielding * if...we have strict (case-sensitive) filenames, or
952908500d5f99f35afc5ed510391b9bdc3833farbb * we know the canonical_filename matches to _this_ name, and
2d2eda71267231c2526be701fe655db125852c1ffielding * if...we have allowed symlinks
952908500d5f99f35afc5ed510391b9bdc3833farbb * skip the lstat and dummy up an APR_DIR value for thisinfo.
2d2eda71267231c2526be701fe655db125852c1ffielding && ((opts & (OPT_SYM_OWNER | OPT_SYM_LINKS)) == OPT_SYM_LINKS))
952908500d5f99f35afc5ed510391b9bdc3833farbb /* We choose apr_lstat here, rather that apr_stat, so that we
2d2eda71267231c2526be701fe655db125852c1ffielding * capture this path object rather than its target. We will
952908500d5f99f35afc5ed510391b9bdc3833farbb * replace the info with our target's info below. We especially
dad234382d8424e1c5a30af2838e172aec9d6d1bdreid * want the name of this 'link' object, not the name of its
2d2eda71267231c2526be701fe655db125852c1ffielding * target, if we are fixing the filename case/resolving aliases.
1ccd992d37d62c8cb2056126f2234f64ec189bfddougm /* Nothing? That could be nice. But our directory
952908500d5f99f35afc5ed510391b9bdc3833farbb * walk is done.
169f62b04de69074b561b4e6dcf6f82572a5e367trawick else if ((rv != APR_SUCCESS && rv != APR_INCOMPLETE)
952908500d5f99f35afc5ed510391b9bdc3833farbb /* If we hit ENOTDIR, we must have over-optimized, deny
2d2eda71267231c2526be701fe655db125852c1ffielding * rather than assume not found.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Fix up the path now if we have a name, and they don't agree
952908500d5f99f35afc5ed510391b9bdc3833farbb /* TODO: provide users an option that an internal/external
952908500d5f99f35afc5ed510391b9bdc3833farbb * redirect is required here? We need to walk the URI and
952908500d5f99f35afc5ed510391b9bdc3833farbb * filename in tandem to properly correlate these.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Is this a possibly acceptable symlink?
2d2eda71267231c2526be701fe655db125852c1ffielding ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
2d2eda71267231c2526be701fe655db125852c1ffielding "Symbolic link not allowed: %s",
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Ok, we are done with the link's info, test the real target
3d96ee83babeec32482c9082c9426340cee8c44dwrowe /* That was fun, nothing left for us here
952908500d5f99f35afc5ed510391b9bdc3833farbb ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
952908500d5f99f35afc5ed510391b9bdc3833farbb "symlink doesn't point to a file or directory: %s",
2d2eda71267231c2526be701fe655db125852c1ffielding /* If we have _not_ optimized, this is the time to recover
952908500d5f99f35afc5ed510391b9bdc3833farbb * the final stat result.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben if (!r->finfo.filetype || r->finfo.filetype == APR_LNK) {
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Now splice the saved path_info back onto any new path_info
952908500d5f99f35afc5ed510391b9bdc3833farbb * Now we'll deal with the regexes, note we pick up sec_idx
952908500d5f99f35afc5ed510391b9bdc3833farbb * where we left off (we gave up after we hit entry_core->r)
3d96ee83babeec32482c9082c9426340cee8c44dwrowe entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben if (ap_regexec(entry_core->r, r->filename, 0, NULL, REG_NOTEOL)) {
952908500d5f99f35afc5ed510391b9bdc3833farbb /* If we merged this same section last time, reuse it
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben /* We fell out of sync. This is our own copy of walked,
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * so truncate the remaining matches and reset remaining.
952908500d5f99f35afc5ed510391b9bdc3833farbb last_walk = (walk_walked_t*)apr_array_push(cache->walked);
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Whoops - everything matched in sequence, but the original walk
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * found some additional matches. Truncate them.
952908500d5f99f35afc5ed510391b9bdc3833farbb/* It seems this shouldn't be needed anymore. We translated the
952908500d5f99f35afc5ed510391b9bdc3833farbb x symlink above into a real resource, and should have died up there.
952908500d5f99f35afc5ed510391b9bdc3833farbb x Even if we keep this, it needs more thought (maybe an r->file_is_symlink)
952908500d5f99f35afc5ed510391b9bdc3833farbb x perhaps it should actually happen in file_walk, so we catch more
952908500d5f99f35afc5ed510391b9bdc3833farbb x obscure cases in autoindex sub requests, etc.
952908500d5f99f35afc5ed510391b9bdc3833farbb x * Symlink permissions are determined by the parent. If the request is
952908500d5f99f35afc5ed510391b9bdc3833farbb x * for a directory then applying the symlink test here would use the
952908500d5f99f35afc5ed510391b9bdc3833farbb x * permissions of the directory as opposed to its parent. Consider a
3d96ee83babeec32482c9082c9426340cee8c44dwrowe x * symlink pointing to a dir with a .htaccess disallowing symlinks. If
2d2eda71267231c2526be701fe655db125852c1ffielding x * you access /symlink (or /symlink/) you would get a 403 without this
952908500d5f99f35afc5ed510391b9bdc3833farbb x * APR_DIR test. But if you accessed /symlink/index.html, for example,
952908500d5f99f35afc5ed510391b9bdc3833farbb x * you would *not* get the 403.
952908500d5f99f35afc5ed510391b9bdc3833farbb x if (r->finfo.filetype != APR_DIR
952908500d5f99f35afc5ed510391b9bdc3833farbb x && (res = resolve_symlink(r->filename, r->info, ap_allow_options(r),
952908500d5f99f35afc5ed510391b9bdc3833farbb x r->pool))) {
952908500d5f99f35afc5ed510391b9bdc3833farbb x ap_log_rerror(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, 0, r,
952908500d5f99f35afc5ed510391b9bdc3833farbb x "Symbolic link not allowed: %s", r->filename);
952908500d5f99f35afc5ed510391b9bdc3833farbb x return res;
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Save future sub-requestors much angst in processing
952908500d5f99f35afc5ed510391b9bdc3833farbb * this subrequest. If dir_walk couldn't canonicalize
952908500d5f99f35afc5ed510391b9bdc3833farbb * the file path, nothing can.
952908500d5f99f35afc5ed510391b9bdc3833farbb cache->cached = ap_make_dirstr_parent(r->pool, r->filename);
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,
952908500d5f99f35afc5ed510391b9bdc3833farbb * and note the end result to (potentially) skip this step next time.
2d2eda71267231c2526be701fe655db125852c1ffielding r->per_dir_config = ap_merge_per_dir_configs(r->pool,
952908500d5f99f35afc5ed510391b9bdc3833farbb core_server_config *sconf = ap_get_module_config(r->server->module_config,
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) sconf->sec_url->elts;
952908500d5f99f35afc5ed510391b9bdc3833farbb const char *entry_uri;
952908500d5f99f35afc5ed510391b9bdc3833farbb /* No tricks here, there are no <Locations > to parse in this vhost.
952908500d5f99f35afc5ed510391b9bdc3833farbb * We won't destroy the cache, just in case _this_ redirect is later
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * redirected again to a vhost with <Location > blocks to optimize.
2d2eda71267231c2526be701fe655db125852c1ffielding /* Location and LocationMatch differ on their behaviour w.r.t. multiple
952908500d5f99f35afc5ed510391b9bdc3833farbb * slashes. Location matches multiple slashes with a single slash,
952908500d5f99f35afc5ed510391b9bdc3833farbb * LocationMatch doesn't. An exception, for backwards brokenness is
952908500d5f99f35afc5ed510391b9bdc3833farbb * absoluteURIs... in which case neither match multiple slashes.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* If we have an cache->cached location that matches r->uri,
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * and the vhost's list of locations hasn't changed, we can skip
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * rewalking the location_walk entries.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben /* Well this looks really familiar! If our end-result (per_dir_result)
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * didn't change, we have absolutely nothing to do :)
952908500d5f99f35afc5ed510391b9bdc3833farbb * Otherwise (as is the case with most dir_merged/file_merged requests)
952908500d5f99f35afc5ed510391b9bdc3833farbb * we must merge our dir_conf_merged onto this new r->per_dir_config.
952908500d5f99f35afc5ed510391b9bdc3833farbb /* We start now_merged from NULL since we want to build
952908500d5f99f35afc5ed510391b9bdc3833farbb * a locations list that can be merged to any vhost.
952908500d5f99f35afc5ed510391b9bdc3833farbb walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben /* Go through the location entries, and check for matches.
952908500d5f99f35afc5ed510391b9bdc3833farbb * We apply the directive sections in given order, we should
952908500d5f99f35afc5ed510391b9bdc3833farbb * really try them with the most general first.
952908500d5f99f35afc5ed510391b9bdc3833farbb entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
952908500d5f99f35afc5ed510391b9bdc3833farbb /* ### const strlen can be optimized in location config parsing */
952908500d5f99f35afc5ed510391b9bdc3833farbb /* Test the regex, fnmatch or string as appropriate.
952908500d5f99f35afc5ed510391b9bdc3833farbb * If it's a strcmp, and the <Location > pattern was
3d96ee83babeec32482c9082c9426340cee8c44dwrowe * not slash terminated, then this uri must be slash
dad234382d8424e1c5a30af2838e172aec9d6d1bdreid * terminated (or at the end of the string) to match.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME)
952908500d5f99f35afc5ed510391b9bdc3833farbb /* If we merged this same section last time, reuse it
952908500d5f99f35afc5ed510391b9bdc3833farbb /* We fell out of sync. This is our own copy of walked,
952908500d5f99f35afc5ed510391b9bdc3833farbb * so truncate the remaining matches and reset remaining.
58619148951981bcfa5c506ad8ce745aa8831980rbb last_walk = (walk_walked_t*)apr_array_push(cache->walked);
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben /* Whoops - everything matched in sequence, but the original walk
58619148951981bcfa5c506ad8ce745aa8831980rbb * found some additional matches. Truncate them.
58619148951981bcfa5c506ad8ce745aa8831980rbb /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,
58619148951981bcfa5c506ad8ce745aa8831980rbb * and note the end result to (potentially) skip this step next time.
58619148951981bcfa5c506ad8ce745aa8831980rbb core_dir_config *dconf = ap_get_module_config(r->per_dir_config,
58619148951981bcfa5c506ad8ce745aa8831980rbb ap_conf_vector_t **sec_ent = (ap_conf_vector_t **) dconf->sec_file->elts;
58619148951981bcfa5c506ad8ce745aa8831980rbb const char *test_file;
58619148951981bcfa5c506ad8ce745aa8831980rbb /* To allow broken modules to proceed, we allow missing filenames to pass.
58619148951981bcfa5c506ad8ce745aa8831980rbb * We will catch it later if it's heading for the core handler.
58619148951981bcfa5c506ad8ce745aa8831980rbb * directory_walk already posted an INFO note for module debugging.
30c095035b1d5910cc239a1384c816aef228beb5jim /* No tricks here, there are just no <Files > to parse in this context.
30c095035b1d5910cc239a1384c816aef228beb5jim * We won't destroy the cache, just in case _this_ redirect is later
bdadc326446cae4a51bf75811fbe01a3a362df64gstein * redirected again to a context containing the same or similar <Files >.
58619148951981bcfa5c506ad8ce745aa8831980rbb /* Get the basename .. and copy for the cache just
58619148951981bcfa5c506ad8ce745aa8831980rbb * in case r->filename is munged by another module
3d96ee83babeec32482c9082c9426340cee8c44dwrowe /* If we have an cache->cached file name that matches test_file,
58619148951981bcfa5c506ad8ce745aa8831980rbb * and the directory's list of file sections hasn't changed, we
2d2eda71267231c2526be701fe655db125852c1ffielding * can skip rewalking the file_walk entries.
58619148951981bcfa5c506ad8ce745aa8831980rbb /* Well this looks really familiar! If our end-result (per_dir_result)
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * didn't change, we have absolutely nothing to do :)
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * Otherwise (as is the case with most dir_merged requests)
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * we must merge our dir_conf_merged onto this new r->per_dir_config.
58619148951981bcfa5c506ad8ce745aa8831980rbb /* We start now_merged from NULL since we want to build
58619148951981bcfa5c506ad8ce745aa8831980rbb * a file section list that can be merged to any dir_walk.
58619148951981bcfa5c506ad8ce745aa8831980rbb walk_walked_t *last_walk = (walk_walked_t*)cache->walked->elts;
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben /* Go through the location entries, and check for matches.
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * We apply the directive sections in given order, we should
759f4a24d09e28c4eaca9f97311b497fc15cb5c7ben * really try them with the most general first.
58619148951981bcfa5c506ad8ce745aa8831980rbb entry_core = ap_get_module_config(sec_ent[sec_idx], &core_module);
58619148951981bcfa5c506ad8ce745aa8831980rbb ? apr_fnmatch(entry_core->d, cache->cached, FNM_PATHNAME)
58619148951981bcfa5c506ad8ce745aa8831980rbb /* If we merged this same section last time, reuse it
58619148951981bcfa5c506ad8ce745aa8831980rbb /* We fell out of sync. This is our own copy of walked,
58619148951981bcfa5c506ad8ce745aa8831980rbb * so truncate the remaining matches and reset remaining.
3d96ee83babeec32482c9082c9426340cee8c44dwrowe last_walk = (walk_walked_t*)apr_array_push(cache->walked);
58619148951981bcfa5c506ad8ce745aa8831980rbb /* Whoops - everything matched in sequence, but the original walk
58619148951981bcfa5c506ad8ce745aa8831980rbb * found some additional matches. Truncate them.
58619148951981bcfa5c506ad8ce745aa8831980rbb /* Merge our cache->dir_conf_merged construct with the r->per_dir_configs,
58619148951981bcfa5c506ad8ce745aa8831980rbb * and note the end result to (potentially) skip this step next time.
2d2eda71267231c2526be701fe655db125852c1ffielding r->per_dir_config = ap_merge_per_dir_configs(r->pool,
2d2eda71267231c2526be701fe655db125852c1ffielding/*****************************************************************
58619148951981bcfa5c506ad8ce745aa8831980rbb * The sub_request mechanism.
58619148951981bcfa5c506ad8ce745aa8831980rbb * Fns to look up a relative URI from, e.g., a map file or SSI document.
58619148951981bcfa5c506ad8ce745aa8831980rbb * These do all access checks, etc., but don't actually run the transaction
30c095035b1d5910cc239a1384c816aef228beb5jim * ... use run_sub_req below for that. Also, be sure to use destroy_sub_req
47ab8dcf8ad581569376f2e04ef16bc785bb122aake * as appropriate if you're likely to be creating more than a few of these.
7c7372abe2484e7fcf81937b93496d1246e5b816gstein * (An early Apache version didn't destroy the sub_reqs used in directory
30c095035b1d5910cc239a1384c816aef228beb5jim * indexing. The result, when indexing a directory with 800-odd files in
30c095035b1d5910cc239a1384c816aef228beb5jim * it, was massively excessive storage allocation).
30c095035b1d5910cc239a1384c816aef228beb5jim * Note more manipulation of protocol-specific vars in the request
30c095035b1d5910cc239a1384c816aef228beb5jim * structure...
2d2eda71267231c2526be701fe655db125852c1ffieldingstatic request_rec *make_sub_request(const request_rec *r,
0186cb43574836fc95a0506456210c94cfc3ea6ftrawick rnew->request_config = ap_create_request_config(rnew->pool);
6e70165f24ec2e664764a9402e358eb0f6e99a3dtrawick /* Start a clean config from this subrequest's vhost. Optimization in
0186cb43574836fc95a0506456210c94cfc3ea6ftrawick * Location/File/Dir walks from the parent request assure that if the
2d2eda71267231c2526be701fe655db125852c1ffielding * config blocks of the subrequest match the parent request, no merges
58619148951981bcfa5c506ad8ce745aa8831980rbb * will actually occur (and generally a minimal number of merges are
58619148951981bcfa5c506ad8ce745aa8831980rbb * required, even if the parent and subrequest aren't quite identical.)
3d96ee83babeec32482c9082c9426340cee8c44dwrowe rnew->allowed_methods = ap_make_method_list(rnew->pool, 2);
2d2eda71267231c2526be701fe655db125852c1ffielding /* make a copy of the allowed-methods list */
2d2eda71267231c2526be701fe655db125852c1ffielding ap_copy_method_list(rnew->allowed_methods, r->allowed_methods);
6e70165f24ec2e664764a9402e358eb0f6e99a3dtrawick /* start with the same set of output filters */
2d2eda71267231c2526be701fe655db125852c1ffielding ap_add_output_filter("SUBREQ_CORE", NULL, rnew, rnew->connection);
2d2eda71267231c2526be701fe655db125852c1ffielding /* no input filters for a subrequest */
2d2eda71267231c2526be701fe655db125852c1ffielding /* We have to run this after we fill in sub req vars,
2d2eda71267231c2526be701fe655db125852c1ffielding * or the r->main pointer won't be setup
2d2eda71267231c2526be701fe655db125852c1ffieldingAP_CORE_DECLARE_NONSTD(apr_status_t) ap_sub_req_output_filter(ap_filter_t *f,
2d2eda71267231c2526be701fe655db125852c1ffieldingAP_DECLARE(int) ap_some_auth_required(request_rec *r)
0e6e93183d91142d7cf9ffbf502114ff77bd9e19ben /* Is there a require line configured for the type of *this* req? */
18173b5033350759b5aa4f6d9a4fd9e12d440135trawick const apr_array_header_t *reqs_arr = ap_requires(r);
0e6e93183d91142d7cf9ffbf502114ff77bd9e19ben if (reqs[i].method_mask & (AP_METHOD_BIT << r->method_number)) {
dca927eafb338b9de9d0214818136c16d436e3fdrbbAP_DECLARE(request_rec *) ap_sub_req_method_uri(const char *method,
0e6e93183d91142d7cf9ffbf502114ff77bd9e19ben const char *new_file,
0e6e93183d91142d7cf9ffbf502114ff77bd9e19ben /* would be nicer to pass "method" to ap_set_sub_req_protocol */
return rnew;
const request_rec *r,
const request_rec *r,
int res;
char *fdir;
char *udir;
!= OK) {
return rnew;
return rnew;
const request_rec *r,
int res;
char *fdir;
return rnew;
return rnew;
int retval;
return retval;