I've made a simple patch to mod_vhost_alias. I've never done this before, so I'm probably going about it the wrong way, but here it is.

Problem: mod_vhost_alias provides no ability to failover in the event that the transformed VirtualDocumentRoot does not exist.

Solution: Check transformed VDR and return DECLINE if directory does not exist. Then, httpd will default to the regular DocumentRoot (if it was defined alongside VirtualDocumentRoot).

I'm not even sure if this behavior is considered "OK" - it's just what I needed and I grew a bit frustrated that it was not available. It might be more prudent to put such a thing in a separate config option in case someone depends on the 404 that they get from a failed VDR transformation (I can't think of any situation that would require this, but who knows?)

Here's my patch that implements this; it might be a bit dirty but it seems to work fine. It does introduce an additional access() call per request; I don't really see that as a problem but maybe someone else does. (This patch is against the debian package source of 2.2.3; again, not sure if that's OK)

--- mod_vhost_alias.c   2008-09-28 17:06:52.000000000 -0700
+++ mod_vhost_alias_mine.c      2008-09-28 17:02:51.000000000 -0700
@@ -37,7 +37,7 @@
 #include "apr_strings.h"
 #include "apr_hooks.h"
 #include "apr_lib.h"
-
+#include <unistd.h>
 #define APR_WANT_STRFUNC
 #include "apr_want.h"

@@ -250,7 +250,7 @@
     }
 }

-static void vhost_alias_interpolate(request_rec *r, const char *name,
+static int vhost_alias_interpolate(request_rec *r, const char *name,
                                     const char *map, const char *uri)
 {
     /* 0..9 9..0 */
@@ -372,12 +372,19 @@
         ++uri;
     }

+    /* Check accessibility of transformed directory path */
+    if(access(buf, R_OK)) {
+        return 0;
+    }
+
     if (r->filename) {
         r->filename = apr_pstrcat(r->pool, r->filename, buf, uri, NULL);
     }
     else {
         r->filename = apr_pstrcat(r->pool, buf, uri, NULL);
     }
+
+    return 1;
 }

 static int mva_translate(request_rec *r)
@@ -426,7 +433,8 @@
      * canonical_path buffer.
      */
     r->canonical_filename = "";
-    vhost_alias_interpolate(r, name, map, uri);
+    if(!vhost_alias_interpolate(r, name, map, uri))
+       return DECLINED;

     if (cgi) {
         /* see is_scriptaliased() in mod_cgi */


Reply via email to