mod_dir.c revision f06e7c4b1bce6b6491e5de0b7998d3f5696b293d
208651a016b098f4fa1f6279559f104d70f1632dtakashi/* Licensed to the Apache Software Foundation (ASF) under one or more
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki * contributor license agreements. See the NOTICE file distributed with
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki * this work for additional information regarding copyright ownership.
a99c5d4cc3cab6a62b04d52000dbc22ce1fa2d94coar * The ASF licenses this file to You under the Apache License, Version 2.0
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki * (the "License"); you may not use this file except in compliance with
acc36ab93565d2880447d535da6ca6e5feac7a70nd * the License. You may obtain a copy of the License at
031b91a62d25106ae69d4693475c79618dd5e884fielding * Unless required by applicable law or agreed to in writing, software
031b91a62d25106ae69d4693475c79618dd5e884fielding * distributed under the License is distributed on an "AS IS" BASIS,
031b91a62d25106ae69d4693475c79618dd5e884fielding * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
acc36ab93565d2880447d535da6ca6e5feac7a70nd * See the License for the specific language governing permissions and
acc36ab93565d2880447d535da6ca6e5feac7a70nd * limitations under the License.
acc36ab93565d2880447d535da6ca6e5feac7a70nd * mod_dir.c: handle default index files, and trailing-/ redirects
75429b361faff4e3109d7e5962f70d2d65271f60yoshikitypedef enum {
75429b361faff4e3109d7e5962f70d2d65271f60yoshikitypedef struct dir_config_struct {
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki const char *dflt;
75429b361faff4e3109d7e5962f70d2d65271f60yoshikistatic const char *add_index(cmd_parms *cmd, void *dummy, const char *arg)
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki const char *t, *w;
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki d->index_names = apr_array_make(cmd->pool, 2, sizeof(char *));
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki while ((w = ap_getword_conf(cmd->pool, &t)) && w[0]) {
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* peek to see if "disabled" is first in a series of arguments */
208651a016b098f4fa1f6279559f104d70f1632dtakashi const char *tt = t;
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki const char *ww = ap_getword_conf(cmd->temp_pool, &tt);
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki /* "disabled" is first, and alone */
75429b361faff4e3109d7e5962f70d2d65271f60yoshikistatic const char *configure_slash(cmd_parms *cmd, void *d_, int arg)
208651a016b098f4fa1f6279559f104d70f1632dtakashistatic const char *configure_checkhandler(cmd_parms *cmd, void *d_, int arg)
208651a016b098f4fa1f6279559f104d70f1632dtakashistatic const char *configure_redirect(cmd_parms *cmd, void *d_, const char *arg1)
208651a016b098f4fa1f6279559f104d70f1632dtakashi return "DirectoryIndexRedirect only accepts values between 300 and 399";
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki return "DirectoryIndexRedirect ON|OFF|permanent|temp|seeother|3xx";
208651a016b098f4fa1f6279559f104d70f1632dtakashi AP_INIT_TAKE1("FallbackResource", ap_set_string_slot,
208651a016b098f4fa1f6279559f104d70f1632dtakashi AP_INIT_RAW_ARGS("DirectoryIndex", add_index, NULL, DIR_CMD_PERMS,
208651a016b098f4fa1f6279559f104d70f1632dtakashi "a list of file names"),
208651a016b098f4fa1f6279559f104d70f1632dtakashi AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS,
208651a016b098f4fa1f6279559f104d70f1632dtakashi "On or Off"),
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki AP_INIT_FLAG("DirectoryCheckHandler", configure_checkhandler, NULL, DIR_CMD_PERMS,
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki "On or Off"),
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki AP_INIT_TAKE1("DirectoryIndexRedirect", configure_redirect,
208651a016b098f4fa1f6279559f104d70f1632dtakashi NULL, DIR_CMD_PERMS, "On, Off, or a 3xx status code."),
208651a016b098f4fa1f6279559f104d70f1632dtakashistatic void *create_dir_config(apr_pool_t *p, char *dummy)
208651a016b098f4fa1f6279559f104d70f1632dtakashi dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec));
208651a016b098f4fa1f6279559f104d70f1632dtakashi return (void *) new;
208651a016b098f4fa1f6279559f104d70f1632dtakashistatic void *merge_dir_configs(apr_pool_t *p, void *basev, void *addv)
208651a016b098f4fa1f6279559f104d70f1632dtakashi dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec));
208651a016b098f4fa1f6279559f104d70f1632dtakashi new->index_names = add->index_names ? add->index_names : base->index_names;
57fbfdce466d9a43dd4c161c901360f8f2ad2757yoshiki (add->do_slash == MODDIR_UNSET) ? base->do_slash : add->do_slash;
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki (add->checkhandler == MODDIR_UNSET) ? base->checkhandler : add->checkhandler;
208651a016b098f4fa1f6279559f104d70f1632dtakashi (add->redirect_index == REDIRECT_UNSET) ? base->redirect_index : add->redirect_index;
208651a016b098f4fa1f6279559f104d70f1632dtakashi dir_config_rec *d = ap_get_module_config(r->per_dir_config, &dir_module);
208651a016b098f4fa1f6279559f104d70f1632dtakashi const char *name_ptr;
208651a016b098f4fa1f6279559f104d70f1632dtakashi if ((name_ptr == NULL) || !(strcasecmp(name_ptr,"disabled"))){
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki /* XXX: if FallbackResource points to something that doesn't exist,
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki * this may recurse until it hits the limit for internal redirects
208651a016b098f4fa1f6279559f104d70f1632dtakashi * before returning an Internal Server Error.
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* The logic of this function is basically cloned and simplified
208651a016b098f4fa1f6279559f104d70f1632dtakashi * from fixup_dir below. See the comments there.
208651a016b098f4fa1f6279559f104d70f1632dtakashi name_ptr = apr_pstrcat(r->pool, name_ptr, "?", r->args, NULL);
208651a016b098f4fa1f6279559f104d70f1632dtakashi rr = ap_sub_req_lookup_uri(name_ptr, r, r->output_filters);
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki && ( (rr->handler && !strcmp(rr->handler, "proxy-server"))
498e8a909bc308283d3713bb348246fe51de059cyoshiki r->notes = apr_table_overlay(r->pool, r->notes, rr->notes);
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki r->headers_out = apr_table_overlay(r->pool, r->headers_out,
208651a016b098f4fa1f6279559f104d70f1632dtakashi r->err_headers_out = apr_table_overlay(r->pool, r->err_headers_out,
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki /* nothing for us to do, pass on through */
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* In case mod_mime wasn't present, and no handler was assigned. */
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* Never tolerate path_info on dir requests */
208651a016b098f4fa1f6279559f104d70f1632dtakashi d = (dir_config_rec *)ap_get_module_config(r->per_dir_config,
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* Redirect requests that are not '/' terminated */
208651a016b098f4fa1f6279559f104d70f1632dtakashi if (r->uri[0] == '\0' || r->uri[strlen(r->uri) - 1] != '/')
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* Only redirect non-get requests if we have no note to warn
208651a016b098f4fa1f6279559f104d70f1632dtakashi * that this browser cannot handle redirs on non-GET requests
208651a016b098f4fa1f6279559f104d70f1632dtakashi * (such as Microsoft's WebFolders).
75429b361faff4e3109d7e5962f70d2d65271f60yoshiki && apr_table_get(r->subprocess_env, "redirect-carefully")) {
208651a016b098f4fa1f6279559f104d70f1632dtakashi ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
208651a016b098f4fa1f6279559f104d70f1632dtakashi ifile = apr_pstrcat(r->pool, ap_escape_uri(r->pool, r->uri),
208651a016b098f4fa1f6279559f104d70f1632dtakashi if (r->method_number != M_GET && r->method_number != M_POST) {
208651a016b098f4fa1f6279559f104d70f1632dtakashi if (d->checkhandler == MODDIR_ON && strcmp(r->handler, DIR_MAGIC_TYPE)) {
208651a016b098f4fa1f6279559f104d70f1632dtakashi /* we're running between mod_rewrites fixup and its internal redirect handler, step aside */
208651a016b098f4fa1f6279559f104d70f1632dtakashi if (!strcmp(r->handler, REWRITE_REDIRECT_HANDLER_NAME)) {
* handler will almost always result in HTTP_OK as /foo/index.html
* may be /foo with PATH_INFO="/index.html", or even / with
* PATH_INFO="/foo/index.html". To get around this we insist that the
return d->redirect_index;
return OK;
return error_notfound;
if (error_notfound) {
return error_notfound;
d->index_names ?
return DECLINED;
return fixup_dir(r);
return fixup_dflt(r);
return DECLINED;