mod_dir.c revision 0958c822c32923b9848a73b2f4c94eab07fb416d
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/* ====================================================================
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * The Apache Software License, Version 1.1
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * Copyright (c) 2000-2001 The Apache Software Foundation. All rights
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * reserved.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Redistribution and use in source and binary forms, with or without
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * modification, are permitted provided that the following conditions
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * are met:
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 1. Redistributions of source code must retain the above copyright
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * notice, this list of conditions and the following disclaimer.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * 2. Redistributions in binary form must reproduce the above copyright
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * notice, this list of conditions and the following disclaimer in
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * the documentation and/or other materials provided with the
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * distribution.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * 3. The end-user documentation included with the redistribution,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * if any, must include the following acknowledgment:
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * "This product includes software developed by the
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * Apache Software Foundation (http://www.apache.org/)."
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * Alternately, this acknowledgment may appear in the software itself,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * if and wherever such third-party acknowledgments normally appear.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * 4. The names "Apache" and "Apache Software Foundation" must
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * not be used to endorse or promote products derived from this
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * software without prior written permission. For written
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * permission, please contact apache@apache.org.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * 5. Products derived from this software may not be called "Apache",
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * nor may "Apache" appear in their name, without prior written
64185f9824e42f21ca7b9ae6c004484215c031a7rbb * permission of the Apache Software Foundation.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * SUCH DAMAGE.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * ====================================================================
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * This software consists of voluntary contributions made by many
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * individuals on behalf of the Apache Software Foundation. For more
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * information on the Apache Software Foundation, please see
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * <http://www.apache.org/>.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding *
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * Portions of this software are based upon public domain software
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * originally written at the National Center for Supercomputing Applications,
7e79e8fd53348f9fc6e8009a4a2522425ab6f08ffielding * University of Illinois, Urbana-Champaign.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding/*
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * mod_dir.c: handle default index files, and trailing-/ redirects
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "apr_strings.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "ap_config.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "httpd.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_config.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_core.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_request.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_protocol.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_log.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "http_main.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#include "util_script.h"
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingmodule AP_MODULE_DECLARE_DATA dir_module;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingtypedef struct dir_config_struct {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_array_header_t *index_names;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding} dir_config_rec;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding#define DIR_CMD_PERMS OR_INDEXES
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const char *add_index(cmd_parms *cmd, void *dummy, const char *arg)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *d = dummy;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (!d->index_names) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding d->index_names = apr_array_make(cmd->pool, 2, sizeof(char *));
2d71630471d1c23f0137309e3c3957c633ecbfd6rbb }
ab5581cc78e9d865b0a6ab1404c53347b3276968rbb *(const char **)apr_array_push(d->index_names) = arg;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic const command_rec dir_cmds[] =
404e2e1f8ad30c2d996f5fb6b3a9a4a4a14a004brbb{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding AP_INIT_ITERATE("DirectoryIndex", add_index, NULL, DIR_CMD_PERMS,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "a list of file names"),
b8dd12594991e5c275d82fca865d13c5f9775f4efielding {NULL}
b8dd12594991e5c275d82fca865d13c5f9775f4efielding};
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic void *create_dir_config(apr_pool_t *p, char *dummy)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *new =
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding (dir_config_rec *) apr_pcalloc(p, sizeof(dir_config_rec));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new->index_names = NULL;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return (void *) new;
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick}
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawickstatic void *merge_dir_configs(apr_pool_t *p, void *basev, void *addv)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *new = (dir_config_rec *) apr_pcalloc(p, sizeof(dir_config_rec));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *base = (dir_config_rec *) basev;
b8dd12594991e5c275d82fca865d13c5f9775f4efielding dir_config_rec *add = (dir_config_rec *) addv;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new->index_names = add->index_names ? add->index_names : base->index_names;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return new;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int fixup_dir(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *d;
404e2e1f8ad30c2d996f5fb6b3a9a4a4a14a004brbb
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (r->finfo.filetype != APR_DIR) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return DECLINED;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding d = (dir_config_rec *) ap_get_module_config(r->per_dir_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding &dir_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (r->uri[0] == '\0' || r->uri[strlen(r->uri) - 1] != '/') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *ifile;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (r->args != NULL)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "/", "?", r->args, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding "/", NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding apr_table_setn(r->headers_out, "Location",
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_construct_url(r->pool, ifile, r));
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return HTTP_MOVED_PERMANENTLY;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return OK;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fieldingstatic int handle_dir(request_rec *r)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dir_config_rec *d;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *dummy_ptr[1];
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char **names_ptr;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int num_names;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding int error_notfound = 0;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (strcmp(r->handler,DIR_MAGIC_TYPE)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return DECLINED;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding d = (dir_config_rec *) ap_get_module_config(r->per_dir_config,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding &dir_module);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* KLUDGE --- make the sub_req lookups happen in the right directory.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * Fixing this in the sub_req_lookup functions themselves is difficult,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * and would probably break virtual includes...
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (r->filename[strlen(r->filename) - 1] != '/') {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->filename = apr_pstrcat(r->pool, r->filename, "/", NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (d->index_names) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding names_ptr = (char **)d->index_names->elts;
b8dd12594991e5c275d82fca865d13c5f9775f4efielding num_names = d->index_names->nelts;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding dummy_ptr[0] = AP_DEFAULT_INDEX;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding names_ptr = dummy_ptr;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding num_names = 1;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding for (; num_names; ++names_ptr, --num_names) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *name_ptr = *names_ptr;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding request_rec *rr = ap_sub_req_lookup_uri(name_ptr, r, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (rr->status == HTTP_OK && rr->finfo.filetype == APR_REG) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding char *new_uri = ap_escape_uri(r->pool, rr->uri);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (rr->args != NULL)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new_uri = apr_pstrcat(r->pool, new_uri, "?", rr->args, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding else if (r->args != NULL)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding new_uri = apr_pstrcat(r->pool, new_uri, "?", r->args, NULL);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_destroy_sub_req(rr);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_internal_redirect(new_uri, r);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return OK;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding /* If the request returned a redirect, propagate it to the client */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick if (ap_is_HTTP_REDIRECT(rr->status) ||
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick (rr->status == HTTP_NOT_ACCEPTABLE && num_names == 1)) {
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
b8dd12594991e5c275d82fca865d13c5f9775f4efielding apr_pool_join(r->pool, rr->pool);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding error_notfound = rr->status;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->notes = apr_table_overlay(r->pool, r->notes, rr->notes);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->headers_out = apr_table_overlay(r->pool, r->headers_out,
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick rr->headers_out);
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out,
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding rr->err_headers_out);
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick return error_notfound;
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick }
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick /* If the request returned something other than 404 (or 200),
2eaf6dbe7ea643b3a2b8e1973d9684fac6372c46trawick * it means the module encountered some sort of problem. To be
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb * secure, we should return the error, rather than create
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb * along a (possibly unsafe) directory index.
0a09a4a642f7c0d367598394411dbdd4a6d8cd09fielding *
0a09a4a642f7c0d367598394411dbdd4a6d8cd09fielding * So we store the error, and if none of the listed files
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding * exist, we return the last error response we got, instead
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb * of a directory listing.
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding */
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding if (rr->status && rr->status != HTTP_NOT_FOUND && rr->status != HTTP_OK)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding error_notfound = rr->status;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding ap_destroy_sub_req(rr);
404e2e1f8ad30c2d996f5fb6b3a9a4a4a14a004brbb }
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
b8dd12594991e5c275d82fca865d13c5f9775f4efielding if (error_notfound)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return error_notfound;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
8e56baa9aadebffd9713a70d05a7d6f0e3e6dbabdreid if (r->method_number != M_GET)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return DECLINED;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb /* nothing for us to do, pass on through */
7431131ef5bf15f103cf5f338407ccabb716c0c0rbb
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding return DECLINED;
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding}
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
7431131ef5bf15f103cf5f338407ccabb716c0c0rbbstatic void register_hooks(apr_pool_t *p)
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding{
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding static const char * const aszSucc[]={"mod_autoindex.c", NULL};
09fe0b69d3d1e8c8041c9ce99ee77b8b44b5e3b1fielding
0a09a4a642f7c0d367598394411dbdd4a6d8cd09fielding ap_hook_fixups(fixup_dir,NULL,NULL,APR_HOOK_MIDDLE);
ap_hook_handler(handle_dir,NULL,aszSucc,APR_HOOK_MIDDLE);
}
module AP_MODULE_DECLARE_DATA dir_module = {
STANDARD20_MODULE_STUFF,
create_dir_config, /* create per-directory config structure */
merge_dir_configs, /* merge per-directory config structures */
NULL, /* create per-server config structure */
NULL, /* merge per-server config structures */
dir_cmds, /* command apr_table_t */
register_hooks /* register hooks */
};