>> We could do something interesting with moving this to the req rec in 2.4
>> (on 2.3 trunk) but it wouldn't solve your issue today with 2.2 or 2.0,
>> which will not change.
>
> I am fine with that it doesn't get into 2.2 or 2.0. But I think that
> fixing this in the right place would allow all other vhost modules to
> benefit from that. mod-vhost-alias could be fixed as well.

Here's the first version of patch for 2.3-trunk which implements
per-request document_root.

I have also updated m-v-a to use this new functionality.

It compiles cleanly, however I'm not sure it it's complete. I hope I
found all places where new request_rec is initialized, but I may have
missed something.

Ondrej
-- 
Ondřej Surý <[email protected]>
http://blog.rfc1925.org/
Index: server/core.c
===================================================================
--- server/core.c	(revision 965372)
+++ server/core.c	(working copy)
@@ -717,11 +717,15 @@
 AP_DECLARE(const char *) ap_document_root(request_rec *r) /* Don't use this! */
 {
     core_server_config *conf;
+    if (r->document_root == NULL) {
+        ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
+		      "ap_document_root: r->document_root is not set");
+	conf = (core_server_config *)ap_get_module_config(r->server->module_config,
+							  &core_module);
+	return conf->ap_document_root;
+    }
 
-    conf = (core_server_config *)ap_get_module_config(r->server->module_config,
-                                                      &core_module);
-
-    return conf->ap_document_root;
+    return r->document_root;
 }
 
 /* Should probably just get rid of this... the only code that cares is
@@ -3521,7 +3525,7 @@
         while (*path == '/') {
             ++path;
         }
-        if ((rv = apr_filepath_merge(&r->filename, conf->ap_document_root, path,
+        if ((rv = apr_filepath_merge(&r->filename, ap_document_root(r), path,
                                      APR_FILEPATH_TRUENAME
                                    | APR_FILEPATH_SECUREROOT, r->pool))
                     != APR_SUCCESS) {
@@ -3544,7 +3548,7 @@
         while (*path == '/') {
             ++path;
         }
-        if ((rv = apr_filepath_merge(&r->filename, conf->ap_document_root, path,
+        if ((rv = apr_filepath_merge(&r->filename, ap_document_root(r), path,
                                      APR_FILEPATH_TRUENAME
                                    | APR_FILEPATH_SECUREROOT, r->pool))
                     != APR_SUCCESS) {
Index: server/protocol.c
===================================================================
--- server/protocol.c	(revision 965372)
+++ server/protocol.c	(working copy)
@@ -866,6 +866,7 @@
     apr_bucket_brigade *tmp_bb;
     apr_socket_t *csd;
     apr_interval_time_t cur_timeout;
+    core_server_config *server_conf;
 
 
     apr_pool_create(&p, conn->pool);
@@ -910,6 +911,12 @@
      */
     r->used_path_info = AP_REQ_DEFAULT_PATH_INFO;
 
+    /* Clone DocumentRoot so it can be changed per request
+     */
+    server_conf = (core_server_config *)ap_get_module_config(r->server->module_config,
+							     &core_module);
+    r->document_root  = server_conf->ap_document_root;
+
     tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc);
 
     /* Get the request... */
Index: server/request.c
===================================================================
--- server/request.c	(revision 965372)
+++ server/request.c	(working copy)
@@ -1693,6 +1693,10 @@
     /* Pass on the kept body (if any) into the new request. */
     rnew->kept_body = r->kept_body;
 
+    /* Copy DocumentRoot to sub-request
+     */
+    rnew->document_root  = r->document_root;
+
     return rnew;
 }
 
Index: modules/http/http_request.c
===================================================================
--- modules/http/http_request.c	(revision 965372)
+++ modules/http/http_request.c	(working copy)
@@ -456,6 +456,7 @@
     new->hostname        = r->hostname;
     new->request_time    = r->request_time;
     new->main            = r->main;
+    new->document_root   = r->document_root;
 
     new->headers_in      = r->headers_in;
     new->headers_out     = apr_table_make(r->pool, 12);
@@ -558,6 +559,8 @@
     r->content_encoding = rr->content_encoding;
     r->content_languages = rr->content_languages;
     r->per_dir_config = rr->per_dir_config;
+    r->document_root = rr->document_root;
+
     /* copy output headers from subrequest, but leave negotiation headers */
     r->notes = apr_table_overlay(r->pool, rr->notes, r->notes);
     r->headers_out = apr_table_overlay(r->pool, rr->headers_out,
Index: modules/mappers/mod_vhost_alias.c
===================================================================
--- modules/mappers/mod_vhost_alias.c	(revision 965372)
+++ modules/mappers/mod_vhost_alias.c	(working copy)
@@ -373,11 +373,12 @@
     }
 
     if (r->filename) {
-        r->filename = apr_pstrcat(r->pool, r->filename, buf, uri, NULL);
+	r->document_root = apr_pstrcat(r->pool, r->filename, buf, NULL);
     }
     else {
-        r->filename = apr_pstrcat(r->pool, buf, uri, NULL);
+	r->document_root = apr_pstrdup(r->pool, buf);
     }
+    r->filename = apr_pstrcat(r->pool, r->document_root, uri, NULL);
 }
 
 static int mva_translate(request_rec *r)
Index: include/httpd.h
===================================================================
--- include/httpd.h	(revision 965372)
+++ include/httpd.h	(working copy)
@@ -996,6 +996,14 @@
     apr_uri_t parsed_uri;
     /**  finfo.protection (st_mode) set to zero if no such file */
     apr_finfo_t finfo;
+
+    /* Various config pulled from r->server which could be set by
+     * vhost modules
+     */
+
+    /** Where is the per requests document root **/
+    const char *document_root;
+
 };
 
 /**

Reply via email to