Apache DevCenter
oreilly.comSafari Books Online.Conferences.


O'Reilly Book Excerpts: Apache Cookbook

Cooking with Apache

by Ken Coar and Rich Bowen

Editor's note: The recently released Apache Cookbook contains over 100 solutions to problems that webmasters, web administrators, programmers, and anyone who works with Apache have come upon at one time or another. This week we've excerpted sample recipes from the book that contain solutions to problems with virtual hosting, highlighting PHP source, and enabling WebDAV.

Recipe 4.7: Mass Virtual Hosting Using Rewrite Rules


Although there is a module - mod_vhost_alias - which is explicitly for the purpose of supporting large numbers of virtual hosts, it is very limiting and requires that every virtual host be configured exactly the same way. You want to support a large number of vhosts, configured dynamically, but, at the same time, you want to avoid mod_vhost_alias.


Use directives from mod_rewrite to map to a directory based on the hostname:

RewriteEngine on
RewriteCond   %{HTTP_HOST}     ^(www\.)?([^.]+)\.com$
RewriteRule   ^(.*)$   /home/%2$1


mod_vhost_alias is useful, but it is best for settings where each virtual host is identical in every way but hostname. Using mod_vhost_alias precludes the use of other URL-mapping modules, such as mod_userdir, mod_rewrite, and mod_alias, and it can be very restrictive. Using mod_rewrite is less efficient, but it is more flexible.

For example, when using mod_vhost_alias, you must do all of your hosts with mod_vhost_alias; whereas with this alternate approach, you can do some of your hosts using the rewrite rules and others using conventional virtual host configuration techniques.

The directives in the Solution map requests for www.something.com (or without the www) to the directory /home/something.

See Also


Recipe 5.1: Showing Highlighted PHP Source Without Symlinking


You want to be able to see the syntax-enhanced source to your PHP scripts without having to set up symbolic links for all of them.


Add a line such as the following to your httpd.conf file:

RewriteRule "^(.*\.php)s$" "/cgi-bin/show.php?file=$1" [PT,L]

Create a file named show.php as shown below, and put it in your server's /cgi-bin/ directory:

 * Show the highlighted source of a PHP script without a symlink or copy.
if ((! isset($_GET))
    || (! isset($_GET['file']))
    || (! ($file = $_GET['file']))) {
     * Missing required arguments, so bail.
    return status('400 Bad Request',
                  "Data insufficient or invalid.\r\n");

$file = preg_replace('/\.phps$/', '.php', $file);
if (! preg_match('/\.php$/', $file)) {
    return status('403 Forbidden',
                  "Invalid document.\r\n");
$docroot = $_SERVER['DOCUMENT_ROOT'];
if ((! preg_match(";^$docroot;", $file))
    || (! preg_match(";^/home/[^/]+/public_html;", $file))) {
    return status('403 Forbidden',
                  "Invalid document requested.\r\n");
Header('Content-type: text/html; charset=iso-8859-1');
print highlight_file($file);

function status($msg, $text) {
    Header("Status: $msg");
    Header('Content-type: text/plain; charset=iso-8859-1');
    Header('Content-length: ' . strlen($text));
    print $text;


The script in the solution uses a built-in PHP function to display the script's source in highlighted form. The preg_match against $docroot verifies the requested file is under the server's DocumentRoot. The next preg_match also permits files in users' public_html directories.

See Also

  • Recipe 2.5 of Apache Cookbook


Related Reading

Apache Cookbook
By Ken Coar, Rich Bowen

Recipe 6.19: Enabling WebDAV Without Making Files Writable by the Web User


You want to run WebDAV but don't want to make your document files writable by the Apache server user.


Run two web servers as different users. The DAV-enabled server, for example, might run as User dav, Group dav, while the other server, which is responsible for serving your content, might run as User nobody, Group nobody. Make the web content writable by the dav user, or the dav group.

TIP: Remember that only a single web server can be handling a particular port/IP address combination. This means that your WebDAV-enabled server will have to be using either a different address, a different port, or both than the non-WebDAV server.


A big security concern with DAV is that the content must be modifiable by the web server user for DAV to be able to update that content. This means that any content can also be edited by CGI programs, SSI directives, or other programs running under the web server. While the Apache security guidelines caution against having any files writable by the web server user, DAV requires it.

By running two Apache servers, you can move around this limitation. The DAV-enabled web server, running on an alternate port, has the User and Group directives set to an alternate user and group, such as:

User dav
Group dav

which is the owner of the web content in question. The other web server, which will be responsible for serving content to users, runs as a user who does not have permission to write to any of the documents.

The DAV-enabled web server should be well authenticated, so that only those who are permitted to edit the site can access that portion of the server. You should probably also set up this server to be very lightweight, both in the modules that you install as well as in the number of child processes (or threads) that you run.

Finally, it should be noted that the perchild MPM, under Apache 2.0, supports the idea of running different virtual hosts with different user ids, so that this recipe could be accomplished by enabling DAV just for the one particular vhost. However, as of this writing, the perchild MPM is not working yet.

See Also

Stay tuned for more recipes from Apache Cookbook here on ONLamp beginning in early 2004.

Ken Coar is a member of the Apache Software Foundation, the body that oversees Apache development.

Rich Bowen is a member of the Apache Software Foundation, working primarily on the documentation for the Apache Web Server. DrBacchus, Rich's handle on IRC, can be found on the web at www.drbacchus.com/journal.

Return to the Apache DevCenter.

Sponsored by: