Description: Add DirectoryCheckHandler to allow a 2.2-like behavior,
 skipping execution when handler is already set.
Bug: https://bz.apache.org/bugzilla/show_bug.cgi?id=53929#c10
Bug-Ubuntu: https://bugs.launchpad.net/bugs/1394403
Origin: upstream, https://github.com/apache/httpd/commit/f0529e54b8d889322b5113eb623e263556bfa28e
Last-Update: 2015-08-18

Index: apache2-2.4.7/modules/mappers/mod_dir.c
===================================================================
--- apache2-2.4.7.orig/modules/mappers/mod_dir.c
+++ apache2-2.4.7/modules/mappers/mod_dir.c
@@ -33,17 +33,18 @@
 module AP_MODULE_DECLARE_DATA dir_module;
 
 typedef enum {
-    SLASH_OFF = 0,
-    SLASH_ON,
-    SLASH_UNSET
-} slash_cfg;
+    MODDIR_OFF = 0,
+    MODDIR_ON,
+    MODDIR_UNSET
+} moddir_cfg;
 
 #define REDIRECT_OFF   0
 #define REDIRECT_UNSET 1
 
 typedef struct dir_config_struct {
     apr_array_header_t *index_names;
-    slash_cfg do_slash;
+    moddir_cfg do_slash;
+    moddir_cfg checkhandler;
     int redirect_index;
     const char *dflt;
 } dir_config_rec;
@@ -83,7 +84,14 @@ static const char *configure_slash(cmd_p
 {
     dir_config_rec *d = d_;
 
-    d->do_slash = arg ? SLASH_ON : SLASH_OFF;
+    d->do_slash = arg ? MODDIR_ON : MODDIR_OFF;
+    return NULL;
+}
+static const char *configure_checkhandler(cmd_parms *cmd, void *d_, int arg)
+{
+    dir_config_rec *d = d_;
+
+    d->checkhandler = arg ? MODDIR_ON : MODDIR_OFF;
     return NULL;
 }
 static const char *configure_redirect(cmd_parms *cmd, void *d_, const char *arg1)
@@ -123,6 +131,8 @@ static const command_rec dir_cmds[] =
                     "a list of file names"),
     AP_INIT_FLAG("DirectorySlash", configure_slash, NULL, DIR_CMD_PERMS,
                  "On or Off"),
+    AP_INIT_FLAG("DirectoryCheckHandler", configure_checkhandler, NULL, DIR_CMD_PERMS,
+                 "On or Off"),
     AP_INIT_TAKE1("DirectoryIndexRedirect", configure_redirect,
                    NULL, DIR_CMD_PERMS, "On, Off, or a 3xx status code."),
 
@@ -134,7 +144,8 @@ static void *create_dir_config(apr_pool_
     dir_config_rec *new = apr_pcalloc(p, sizeof(dir_config_rec));
 
     new->index_names = NULL;
-    new->do_slash = SLASH_UNSET;
+    new->do_slash = MODDIR_UNSET;
+    new->checkhandler = MODDIR_UNSET;
     new->redirect_index = REDIRECT_UNSET;
     return (void *) new;
 }
@@ -147,7 +158,9 @@ static void *merge_dir_configs(apr_pool_
 
     new->index_names = add->index_names ? add->index_names : base->index_names;
     new->do_slash =
-        (add->do_slash == SLASH_UNSET) ? base->do_slash : add->do_slash;
+        (add->do_slash == MODDIR_UNSET) ? base->do_slash : add->do_slash;
+    new->checkhandler =
+        (add->checkhandler == MODDIR_UNSET) ? base->checkhandler : add->checkhandler;
     new->redirect_index=
         (add->redirect_index == REDIRECT_UNSET) ? base->redirect_index : add->redirect_index;
     new->dflt = add->dflt ? add->dflt : base->dflt;
@@ -260,6 +273,10 @@ static int fixup_dir(request_rec *r)
         return HTTP_MOVED_PERMANENTLY;
     }
 
+    if (d->checkhandler == MODDIR_ON && strcmp(r->handler, DIR_MAGIC_TYPE)) {
+        return DECLINED;
+    }
+
     if (d->index_names) {
         names_ptr = (char **)d->index_names->elts;
         num_names = d->index_names->nelts;
