From: brian This document describes how to efficiently serve an arbitrary number
+of virtual hosts with Apache 1.3. Some familiarity with
+ The techniques described here are of interest if your
+Dynamically configured mass virtual hosting
+
+mod_rewrite is
+useful.Contents:
+
+
+
+
+Motivation
+
+httpd.conf contains hundreds of
+<VirtualHost> sections that are substantially the
+same, for example:
+
+NameVirtualHost 111.22.33.44
+<VirtualHost 111.22.33.44>
+ ServerName www.customer-1.com
+ DocumentRoot /www/hosts/www.customer-1.com/docs
+ ScriptAlias /cgi-bin/ /www/hosts/www.customer-1.com/cgi-bin
+</VirtualHost>
+<VirtualHost 111.22.33.44>
+ ServerName www.customer-2.com
+ DocumentRoot /www/hosts/www.customer-2.com/docs
+ ScriptAlias /cgi-bin/ /www/hosts/www.customer-2.com/cgi-bin
+</VirtualHost>
+# blah blah blah
+<VirtualHost 111.22.33.44>
+ ServerName www.customer-N.com
+ DocumentRoot /www/hosts/www.customer-N.com/docs
+ ScriptAlias /cgi-bin/ /www/hosts/www.customer-N.com/cgi-bin
+</VirtualHost>
+
+
The basic idea is to replace all of the static
+<VirtualHost> configuration with a mechanism that
+works it out dynamically. This has a number of advantages:
+
The main disadvantage is that you cannot have a different log file
+for each server; however if you have very many virtual hosts then
+doing this is dubious anyway because it eats file descriptors. It's
+better to log to a pipe or a fifo and arrange for the process at the
+other end to distribute the logs (and perhaps accumulate statistics,
+etc.). A LogFormat directive that includes
+%v for the virtual host makes it easy to do this.
All of the dynamic virtual hosts will either be configured as part
+of the main server configuration, or within a
+<VirtualHost> section. For a simple (very uniform)
+setup, <VirtualHost> sections aren't needed at all.
A couple of things need to be `faked' to make the dynamic virtual
+host look like a normal one. The most important is the server name
+(configured with ServerName and available to CGIs via the
+SERVER_NAME environment variable). The way it is
+determined is controlled by the UseCanonicalName
+directive: with UseCanonicalName off the server name
+comes from the contents of the Host: header in the
+request. If there is no Host: header then the value
+configured with ServerName is used instead.
The other one is the document root (configured with
+DocumentRoot and available to CGIs via the
+DOCUMENT_ROOT environment variable). This is used by the
+core module when mapping URIs to filenames, but in the context of
+dynamic virtual hosting its value only matters if any CGIs or SSI
+documents make use of the DOCUMENT_ROOT environment
+variable. This is an Apache extension to the CGI specification and as
+such shouldn't really be relied upon, especially because this
+technique breaks it: there isn't currently a way of setting
+DOCUMENT_ROOT dynamically.
The meat of the mechanism works via Apache's URI-to-filename
+translation API phase. This is used by a number of modules:
+mod_rewrite,
+mod_alias,
+mod_userdir,
+and the core module.
+In the default configuration these modules are called in that order
+and given a chance to say that they know what the filename is. Most of
+these modules do it in a fairly simple fashion (e.g. the core module
+concatenates the document root and the URI) except for
+mod_rewrite, which provides enough functionality to do
+all sorts of sick and twisted things (like dynamic virtual hosting).
+Note that because of the order in which the modules are called, using
+a mod_rewrite configuration that matches any URI means
+that the other modules (particularly mod_alias) will
+cease to function. The examples below show how to deal with this.
The dynamic virtual hosting idea is very simple: use the +server name as well as the URI to determine the corresponding +filename.
+ + +This extract from httpd.conf implements the virtual
+host arrangement outlined in the Motivation
+section above, but in a generic fashion.
The first half shows some other configuration options that are
+needed to make the mod_rewrite part work as expected; the
+second half uses mod_rewrite to do the actual work. Some
+care is taken to do a per-dynamic-virtual-host equivalent of
+ScriptAlias.
+# dynamic ServerName
+UseCanonicalName Off
+
+# splittable logs
+LogFormat "%v %h %l %u %t \"%r\" %s %b" vcommon
+CustomLog logs/access_log vcommon
+
+<Directory /www/hosts>
+ # ExecCGI is needed here because we can't force
+ # CGI execution in the way that ScriptAlias does
+ Options FollowSymLinks ExecCGI
+</Directory>
+
+# now for the hard bit
+
+RewriteEngine On
+
+# a ServerName derived from a Host: header may be any case at all
+RewriteMap lowercase int:tolower
+
+## deal with normal documents first:
+# allow Alias /icons/ to work - repeat for other aliases
+RewriteCond %{REQUEST_URI} !^/icons/
+# allow CGIs to work
+RewriteCond %{REQUEST_URI} !^/cgi-bin/
+# do the magic
+RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/docs/$1
+
+## and now deal with CGIs - we have to force a MIME type
+RewriteCond %{REQUEST_URI} ^/cgi-bin/
+RewriteRule ^/(.*)$ /www/hosts/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
+
+# that's it!
+
+
+
+This is an adjustment of the above system tailored for an ISP's
+homepages server. Using slightly more complicated rewriting rules we
+can select substrings of the server name to use in the filename so
+that e.g. the documents for www.user.isp.com are found in
+/home/user/. It uses a single cgi-bin
+directory instead of one per virtual host.
+RewriteEngine on
+
+RewriteMap lowercase int:tolower
+
+# allow CGIs to work
+RewriteCond %{REQUEST_URI} !^/cgi-bin/
+
+# check the hostname is right so that the RewriteRule works
+RewriteCond ${lowercase:%{HTTP_HOST}} ^www\.[a-z-]+\.isp\.com$
+
+# concatenate the virtual host name onto the start of the URI
+# the [C] means do the next rewrite on the result of this one
+RewriteRule ^(.+) ${lowercase:%{HTTP_HOST}}$1 [C]
+
+# now create the real file name
+RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2
+
+# define the global CGI directory
+ScriptAlias /cgi-bin/ /www/std-cgi/
+
+
+
+This arrangement uses a separate configuration file to specify the +translation from virtual host to document root. This provides more +flexibility but requires more configuration.
+ +The vhost.map file contains something like this:
+
+www.customer-1.com /www/customers/1 +www.customer-2.com /www/customers/2 +# ... +www.customer-N.com /www/customers/N ++ + +
The http.conf contains this:
+
+RewriteEngine on
+
+RewriteMap lowercase int:tolower
+
+# define the map file
+RewriteMap vhost txt:/www/conf/vhost.map
+
+# deal with aliases as above
+RewriteCond %{REQUEST_URI} !^/icons/
+RewriteCond %{REQUEST_URI} !^/cgi-bin/
+RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
+# this does the file-based remap
+RewriteCond ${vhost:%1} ^(/.*)$
+RewriteRule ^/(.*)$ %1/docs/$1
+
+RewriteCond %{REQUEST_URI} ^/cgi-bin/
+RewriteCond ${lowercase:%{SERVER_NAME}} ^(.+)$
+RewriteCond ${vhost:%1} ^(/.*)$
+RewriteRule ^/(.*)$ %1/cgi-bin/$1
+
+
+
+
+With more complicated setups, you can use Apache's normal
+<VirtualHost> directives to control the scope of
+the various rewrite configurations. For example, you could have one IP
+address for homepages customers and another for commercial customers
+with the following setup. This can of course be combined with
+convential <VirtualHost> configuration
+sections.
+UseCanonicalName Off
+
+LogFormat "%v %h %l %u %t \"%r\" %s %b" vcommon
+CustomLog logs/access_log vcommon
+
+<Directory /www/commercial>
+ Options FollowSymLinks ExecCGI
+ AllowOverride All
+</Directory>
+
+<Directory /www/homepages>
+ Options FollowSymLinks
+ AllowOverride None
+</Directory>
+
+<VirtualHost 111.22.33.44>
+ ServerName www.commercial.isp.com
+
+ RewriteEngine On
+ RewriteMap lowercase int:tolower
+
+ RewriteCond %{REQUEST_URI} !^/icons/
+ RewriteCond %{REQUEST_URI} !^/cgi-bin/
+ RewriteRule ^/(.*)$ /www/commercial/${lowercase:%{SERVER_NAME}}/docs/$1
+
+ RewriteCond %{REQUEST_URI} ^/cgi-bin/
+ RewriteRule ^/(.*)$ /www/commercial/${lowercase:%{SERVER_NAME}}/cgi-bin/$1 [T=application/x-httpd-cgi]
+</VirtualHost>
+
+<VirtualHost 111.22.33.45>
+ ServerName www.homepages.isp.com
+
+ RewriteEngine on
+ RewriteMap lowercase int:tolower
+
+ RewriteCond %{REQUEST_URI} !^/cgi-bin/
+
+ RewriteCond ${lowercase:%{HTTP_HOST}} ^www\.[a-z-]+\.isp\.com$
+ RewriteRule ^(.+) ${lowercase:%{HTTP_HOST}}$1 [C]
+ RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /www/homepages/$1/$2
+
+ ScriptAlias /cgi-bin/ /www/std-cgi/
+</VirtualHost>
+
+
+
+
+
+
+
+