<directivesynopsis>
<name>DirectorySlash</name>
<description>Toggle trailing slash redirects on or off</description>
-<syntax>DirectorySlash On|Off</syntax>
+<syntax>DirectorySlash On|Off|NotFound</syntax>
<default>DirectorySlash On</default>
<contextlist><context>server config</context><context>virtual host</context>
<context>directory</context><context>.htaccess</context></contextlist>
<override>Indexes</override>
+<compatibility>Argument NotFound added in 2.5.1</compatibility>
<usage>
- <p>The <directive>DirectorySlash</directive> directive determines whether
+ <p>The <directive>DirectorySlash</directive> directive determines how
<module>mod_dir</module> should fixup URLs pointing to a directory or
not.</p>
<p>Typically if a user requests a resource without a trailing slash, which
- points to a directory, <module>mod_dir</module> redirects him to the same
+ points to a directory, <module>mod_dir</module> redirects them to the same
resource, but <em>with</em> trailing slash for some good reasons:</p>
<ul>
</note>
<p>Also note that some browsers may erroneously change POST requests into GET
(thus discarding POST data) when a redirect is issued.</p>
-</usage>
-</directivesynopsis>
-<directivesynopsis>
-<name>DirectorySlashNotFound</name>
-<description>Toggle sending a HTTP 404 error in place of a trailing slash</description>
-<syntax>DirectorySlashNotFound On|Off</syntax>
-<default>DirectorySlashNotFound Off</default>
-<contextlist><context>server config</context><context>virtual host</context>
-<context>directory</context><context>.htaccess</context></contextlist>
-<override>Indexes</override>
-<compatibility>Added in 2.5.1</compatibility>
-<usage>
- <p>The <directive>DirectorySlashNotFound</directive> directive determines whether
- <module>mod_dir</module> should return an HTTP 404 status code where it would
- otherwise have redirected the request to include a trailing slash. </p>
+ <p>To avoid the risks of the "off" behavior above, or to avoid disclosing
+ that a directory is present via the behavior of "on", an argument of
+ "NotFound" can be used to tell <module>mod_dir</module> to return an HTTP
+ 404 status code redirected the request to include a trailing slash.</p>
+
</usage>
</directivesynopsis>
<directivesynopsis>
MODDIR_UNSET
} moddir_cfg;
+typedef enum {
+ SLASH_OFF = 0,
+ SLASH_ON,
+ SLASH_NOTFOUND,
+ SLASH_UNSET
+} moddir_doslash;
+
+
#define REDIRECT_OFF 0
#define REDIRECT_UNSET 1
typedef struct dir_config_struct {
apr_array_header_t *index_names;
- moddir_cfg do_slash;
+ moddir_doslash do_slash;
moddir_cfg checkhandler;
int redirect_index;
const char *dflt;
- moddir_cfg do_slash_notfound;
} dir_config_rec;
#define DIR_CMD_PERMS OR_INDEXES
return NULL;
}
-static const char *configure_slash(cmd_parms *cmd, void *d_, int arg)
-{
- dir_config_rec *d = d_;
-
- d->do_slash = arg ? MODDIR_ON : MODDIR_OFF;
- return NULL;
-}
-static const char *configure_slash_notfound(cmd_parms *cmd, void *d_, int arg)
+static const char *configure_slash(cmd_parms *cmd, void *d_, const char *arg1)
{
dir_config_rec *d = d_;
- d->do_slash_notfound = arg ? MODDIR_ON : MODDIR_OFF;
+ if (!ap_cstr_casecmp(arg1, "on")) {
+ d->do_slash = SLASH_ON;
+ }
+ else if (!ap_cstr_casecmp(arg1, "off")) {
+ d->do_slash = SLASH_OFF;
+ }
+ else if (!ap_cstr_casecmp(arg1, "NotFound")) {
+ d->do_slash = SLASH_NOTFOUND;
+ }
+ else {
+ return "DirectorySlash only accepts ON, OFF, or 'NotFound'";
+ }
return NULL;
}
static const char *configure_checkhandler(cmd_parms *cmd, void *d_, int arg)
DIR_CMD_PERMS, "Set a default handler"),
AP_INIT_RAW_ARGS("DirectoryIndex", add_index, NULL, DIR_CMD_PERMS,
"a list of file names"),
- AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS,
- "On or Off"),
- AP_INIT_FLAG("DirectorySlashNotFound", configure_slash_notfound, NULL, DIR_CMD_PERMS,
+ AP_INIT_TAKE1("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS,
"On or Off"),
AP_INIT_FLAG("DirectoryCheckHandler", configure_checkhandler, NULL, DIR_CMD_PERMS,
"On or Off"),
dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec));
new->index_names = NULL;
- new->do_slash = MODDIR_UNSET;
- new->do_slash_notfound = MODDIR_UNSET;
+ new->do_slash = SLASH_UNSET;
new->checkhandler = MODDIR_UNSET;
new->redirect_index = REDIRECT_UNSET;
return (void *) new;
new->index_names = add->index_names ? add->index_names : base->index_names;
new->do_slash =
- (add->do_slash == MODDIR_UNSET) ? base->do_slash : add->do_slash;
- new->do_slash_notfound =
- (add->do_slash_notfound == MODDIR_UNSET) ? base->do_slash_notfound : add->do_slash_notfound;
+ (add->do_slash == SLASH_UNSET) ? base->do_slash : add->do_slash;
new->checkhandler =
(add->checkhandler == MODDIR_UNSET) ? base->checkhandler : add->checkhandler;
new->redirect_index=
{
char *ifile;
- if (!d->do_slash) {
+ if (d->do_slash == SLASH_OFF) {
return DECLINED;
}
-
- if (d->do_slash_notfound == MODDIR_ON) {
+ if (d->do_slash == SLASH_NOTFOUND) {
return HTTP_NOT_FOUND;
}
+
/* Only redirect non-get requests if we have no note to warn
* that this browser cannot handle redirs on non-GET requests
* (such as Microsoft's WebFolders).