jim 99/06/21 17:51:44
Modified: . STATUS htdocs/manual/mod core.html index.html mod_log_config.html mod_rewrite.html htdocs/manual/vhosts mass.html src CHANGES Configuration.tmpl src/include http_core.h httpd.h src/main http_core.c http_main.c util_script.c src/modules/standard mod_log_config.c mod_rewrite.c src/support suexec.c Added: htdocs/manual/mod mod_vhost_alias.html src/modules/standard mod_vhost_alias.c Log: Submitted by: Tony Finch <[EMAIL PROTECTED]> Reviewed by: Dean, Randy, Jim, Lars, Martin Add the new mod_vhost_alias.c modules for better mass-hosting. This has been used at Demon Internet with excellent results and basically replaces the "old" method of using mod_rewrite. Big advantage is that adding new vhosts can be done without restarting the server. Revision Changes Path 1.719 +1 -9 apache-1.3/STATUS Index: STATUS =================================================================== RCS file: /export/home/cvs/apache-1.3/STATUS,v retrieving revision 1.718 retrieving revision 1.719 diff -u -r1.718 -r1.719 --- STATUS 1999/06/21 21:41:37 1.718 +++ STATUS 1999/06/22 00:51:21 1.719 @@ -1,5 +1,5 @@ 1.3 STATUS: - Last modified at [$Date: 1999/06/21 21:41:37 $] + Last modified at [$Date: 1999/06/22 00:51:21 $] Release: @@ -109,14 +109,6 @@ Ken -1 for pre-2.0 if it will: a) force a new release of mod_perl or mod_php in order to maintain compatibility OR b) require a version bump to 1.4.0 and a beta cycle - - * Tony Finch's patch to support mass virtual hosting - Message-ID: <[EMAIL PROTECTED]> - Message-ID: <[EMAIL PROTECTED]> - Message-ID: <[EMAIL PROTECTED]> - Status: Dean +1, Randy +1, Jim +1, Lars +1, Martin +1 (untested) - Previous Status: Dean +1, Randy +1, Jim +1, - Lars +1 (if someone writes the docs) * Brian Havard's patch to remove dependency of mod_auth_dbm on mod_auth. (PR#2598) 1.151 +7 -2 apache-1.3/htdocs/manual/mod/core.html Index: core.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/core.html,v retrieving revision 1.150 retrieving revision 1.151 diff -u -r1.150 -r1.151 --- core.html 1999/06/17 11:49:26 1.150 +++ core.html 1999/06/22 00:51:23 1.151 @@ -3109,8 +3109,7 @@ <A HREF="directive-dict.html#Default" REL="Help"> <STRONG>Default:</STRONG></A> <CODE>UseCanonicalName on</CODE><BR> <A HREF="directive-dict.html#Context" REL="Help"> -<STRONG>Context:</STRONG></A> server config, virtual host, directory, .htaccess -<BR> +<STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Override" REL="Help"> <STRONG>Override:</STRONG></A> Options<BR> <A HREF="directive-dict.html#Compatibility" REL="Help"> @@ -3144,6 +3143,12 @@ for <CODE>www</CODE> and once again for <CODE>www.domain.com</CODE>). But if <CODE>UseCanonicalName</CODE> is set off, then Apache will redirect to <CODE>http://www/splat/</CODE>. + +<P>There is a third option, <CODE>UseCanonicalName DNS</CODE>, which +is intended for use with mass IP-based virtual hosting to support +ancient clients that do not provide a <CODE>Host:</CODE> header. With +this option Apache does a reverse DNS lookup on the server IP address +that the client connected to in order to work out self-referential URLs. <P><STRONG>Warning:</STRONG> if CGIs make assumptions about the values of <CODE>SERVER_NAME</CODE> they may be broken by this option. The client 1.27 +2 -0 apache-1.3/htdocs/manual/mod/index.html Index: index.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/index.html,v retrieving revision 1.26 retrieving revision 1.27 diff -u -r1.26 -r1.27 --- index.html 1998/04/03 16:07:14 1.26 +++ index.html 1999/06/22 00:51:23 1.27 @@ -113,6 +113,8 @@ <DD>Generate unique request identifier for every request <DT><A HREF="mod_usertrack.html">mod_usertrack</A> Apache 1.2 and up <DD>User tracking using Cookies (replacement for mod_cookies.c) +<DT><A HREF="mod_vhost_alias.html">mod_vhost_alias</A> Apache 1.3.7 and up +<DD>Support for dynamically configured mass virtual hosting </DL> <!--#include virtual="footer.html" --> 1.34 +1 -0 apache-1.3/htdocs/manual/mod/mod_log_config.html Index: mod_log_config.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/mod_log_config.html,v retrieving revision 1.33 retrieving revision 1.34 diff -u -r1.33 -r1.34 --- mod_log_config.html 1999/05/16 23:39:42 1.33 +++ mod_log_config.html 1999/06/22 00:51:23 1.34 @@ -126,6 +126,7 @@ %...{FOOBAR}e: The contents of the environment variable FOOBAR %...h: Remote host %...a: Remote IP-address +%...A: Local IP-address %...{Foobar}i: The contents of Foobar: header line(s) in the request sent to the server. %...l: Remote logname (from identd, if supplied) 1.43 +1 -0 apache-1.3/htdocs/manual/mod/mod_rewrite.html Index: mod_rewrite.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/mod/mod_rewrite.html,v retrieving revision 1.42 retrieving revision 1.43 diff -u -r1.42 -r1.43 --- mod_rewrite.html 1999/04/22 09:58:03 1.42 +++ mod_rewrite.html 1999/06/22 00:51:23 1.43 @@ -1078,6 +1078,7 @@ DOCUMENT_ROOT<BR> SERVER_ADMIN<BR> SERVER_NAME<BR> +SERVER_ADDR<BR> SERVER_PORT<BR> SERVER_PROTOCOL<BR> SERVER_SOFTWARE<BR> 1.1 apache-1.3/htdocs/manual/mod/mod_vhost_alias.html Index: mod_vhost_alias.html =================================================================== <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN"> <HTML> <HEAD> <TITLE>Apache module mod_vhost_alias</TITLE> </HEAD> <!-- Background white, links blue (unvisited), navy (visited), red (active) --> <BODY BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#0000FF" VLINK="#000080" ALINK="#FF0000" > <DIV ALIGN="CENTER"> <IMG SRC="../images/sub.gif" ALT="[APACHE DOCUMENTATION]"> <H3> Apache HTTP Server Version 1.3 </H3> </DIV> <H1 ALIGN="CENTER">Module mod_vhost_alias</H1> <P> This module is contained in the <CODE>mod_vhost_alias.c</CODE> file and is not compiled in by default. It should be mentioned near the start of the <CODE>Configuration</CODE> file so that it doesn't override the behaviour of other modules that do filename translation, e.g. <A HREF="mod_userdir.html"><CODE>mod_userdir</CODE></A> and <A HREF="mod_alias.html"><CODE>mod_alias</CODE></A>. It provides support for <A HREF="../vhost/mass.html">dynamically configured mass virtual hosting</A>. </P> <H2>Directory Name Interpolation</H2> <P> All the directives in this module interpolate a string into a pathname. The interpolated string (henceforth called the "name") may be either the server name (see the <A HREF="core.html#usecanonicalname"><CODE>UseCanonicalName</CODE></A> directive for details on how this is determined) or the IP address of the virtual host on the server in dotted-quad format. The interpolation is controlled by specifiers inspired by <CODE>printf</CODE> which have a number of formats: <DL> <DT><CODE>%%</CODE> <DD>insert a <CODE>%</CODE> <DT><CODE>%p</CODE> <DD>insert the port number of the virtual host <DT><CODE>%N.M</CODE> <DD>insert (part of) the name </DL> </P> <P> <CODE>N</CODE> and <CODE>M</CODE> are used to specify substrings of the name. <CODE>N</CODE> selects from the dot-separated components of the name, and <CODE>M</CODE> selects characters within whatever <CODE>N</CODE> has selected. <CODE>M</CODE> is optional and defaults to zero if it isn't present; the dot must be present if and only if <CODE>M</CODE> is present. The interpretation is as follows: <DL> <DT><CODE>0</CODE> <DD>the whole name <DT><CODE>1</CODE> <DD>the first part <DT><CODE>2</CODE> <DD>the second part <DT><CODE>-1</CODE> <DD>the last part <DT><CODE>-2</CODE> <DD>the penultimate part <DT><CODE>2+</CODE> <DD>the second and all subsequent parts <DT><CODE>-2+</CODE> <DD>the penultimate and all preceding parts <DT><CODE>1+</CODE> and <CODE>-1+</CODE> <DD>the same as <CODE>0</CODE> </DL> If <CODE>N</CODE> or <CODE>M</CODE> is greater than the number of parts available a single underscore is interpolated. </P> <H3>Examples</H3> <P> For simple name-based virtual hosts you might use the following directives in your server configuration file: <PRE> UseCanonicalName Off VirtualDocumentRoot /usr/local/apache/vhosts/%0 </PRE> A request for <CODE>http://www.example.com/directory/file.html</CODE> will be satisfied by the file <CODE>/usr/local/apache/vhosts/www.example.com/directory/file.html</CODE>. </P> <P> For a very large number of virtual hosts it is a good idea to arrange the files to reduce the size of the <CODE>vhosts</CODE> directory. To do this you might use the following in your configuration file: <PRE> UseCanonicalName Off VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2 </PRE> A request for <CODE>http://www.example.isp.com/directory/file.html</CODE> will be satisfied by the file <CODE>/usr/local/apache/isp.com/e/x/a/example/directory/file.html</CODE>. A more even spread of files can be acheived by hashing from the end of the name, for example: <PRE> VirtualDocumentRoot /u/%3+/%2.-1/%2.-2/%2.-3/%2 </PRE> The example request would come from <CODE>/usr/local/apache/vhosts/isp.com/e/l/p/example/directory/file.html</CODE>. Alternatively you might use: <PRE> VirtualDocumentRoot /usr/local/apache/vhosts/%3+/%2.1/%2.2/%2.3/%2.4+ </PRE> The example request would come from <CODE>/usr/local/apache/vhosts/isp.com/e/x/a/mple/directory/file.html</CODE>. </P> <P> For IP-based virtual hosting you might use the following in your configuration file: <PRE> UseCanonicalName DNS VirtualDocumentRootIP /usr/local/apache/vhost/%1/%2/%3/%4/docs VirtualScriptAliasIP /usr/local/apache/vhost/%1/%2/%3/%4/cgi-bin </PRE> A request for <CODE>http://www.example.isp.com/directory/file.html</CODE> would be satisfied by the file <CODE>/usr/local/apache/10/20/30/40/docs/directory/file.html</CODE> if the IP address of <CODE>www.example.com</CODE> were 10.20.30.40. A request for <CODE>http://www.example.isp.com/cgi-bin/script.pl</CODE> would be satisfied by executing the program <CODE>/usr/local/apache/10/20/30/40/cgi-bin/script.pl</CODE>. </P> <P> The <A HREF="mod_log_config.html#formats">LogFormat directives</A> <CODE>%V</CODE> and <CODE>%A</CODE> are useful in conjunction with this module. </P> <HR> <H2>Directives</H2> <UL> <LI><A HREF="#VirtualDocumentRoot">VirtualDocumentRoot</A> <LI><A HREF="#VirtualDocumentRootIP">VirtualDocumentRootIP</A> <LI><A HREF="#VirtualScriptAlias">VirtualScriptAlias</A> <LI><A HREF="#VirtualScriptAliasIP">VirtualScriptAliasIP</A> </UL> <HR> <H2><A NAME="VirtualDocumentRoot">VirtualDocumentRoot directive</A></H2> <P> <A HREF="directive-dict.html#Syntax" REL="Help" ><STRONG>Syntax:</STRONG></A> VirtualDocumentRoot <EM>interpolated-directory</EM><BR> <A HREF="directive-dict.html#Default" REL="Help" ><STRONG>Default:</STRONG></A> None<BR> <A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Extension<BR> <A HREF="directive-dict.html#Module" REL="Help" ><STRONG>Module:</STRONG></A> mod_vhost_alias<BR> <A HREF="directive-dict.html#Compatibility" REL="Help" ><STRONG>Compatibility:</STRONG></A> VirtualDocumentRoot is only available in 1.3.5 and later.</P> <P> The <CODE>VirtualDocumentRoot</CODE> directive allows you to determine where Apache will find your documents based on the value of the server name. The result of expanding <EM>interpolated-directory</EM> is used as the root of the document tree in a similar manner to the <A HREF="core.html#documentroot"><CODE>DocumentRoot</CODE></A> directive's argument. If <EM>interpolated-directory</EM> is <CODE>none</CODE> then <CODE>VirtaulDocumentRoot</CODE> is turned off. This directive cannot be used in the same context as <A HREF="#VirtualDocumentRootIP"><CODE>VirtualDocumentRootIP</CODE></A>. </P> <HR> <H2><A NAME="VirtualDocumentRootIP">VirtualDocumentRootIP directive</A></H2> <P> <A HREF="directive-dict.html#Syntax" REL="Help" ><STRONG>Syntax:</STRONG></A> VirtualDocumentRootIP <EM>interpolated-directory</EM><BR> <A HREF="directive-dict.html#Default" REL="Help" ><STRONG>Default:</STRONG></A> None<BR> <A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Extension<BR> <A HREF="directive-dict.html#Module" REL="Help" ><STRONG>Module:</STRONG></A> mod_vhost_alias<BR> <A HREF="directive-dict.html#Compatibility" REL="Help" ><STRONG>Compatibility:</STRONG></A> VirtualDocumentRootIP is only available in 1.3.5 and later.</P> <P> The <CODE>VirtualDocumentRootIP</CODE> directive is like the <A HREF="#VirtualDocumentRoot"><CODE>VirtualDocumentRoot</CODE></A> directive, except that it uses the IP address of the server end of the connection instead of the server name. </P> <HR> <H2><A NAME="VirtualScriptAlias">VirtualScriptAlias directive</A></H2> <P> <A HREF="directive-dict.html#Syntax" REL="Help" ><STRONG>Syntax:</STRONG></A> VirtualScriptAlias <EM>interpolated-directory</EM><BR> <A HREF="directive-dict.html#Default" REL="Help" ><STRONG>Default:</STRONG></A> None<BR> <A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Extension<BR> <A HREF="directive-dict.html#Module" REL="Help" ><STRONG>Module:</STRONG></A> mod_vhost_alias<BR> <A HREF="directive-dict.html#Compatibility" REL="Help" ><STRONG>Compatibility:</STRONG></A> VirtualScriptAlias is only available in 1.3.5 and later.</P> <P> The <CODE>VirtualScriptAlias</CODE> directive allows you to determine where Apache will find CGI scripts in a similar manner to <A HREF="#VirtualDocumentRoot"><CODE>VirtualDocumentRoot</CODE></A> does for other documents. It matches requests for URIs starting <CODE>/cgi-bin/</CODE>, much like <CODE><A HREF="mod_alias.html#scriptalias">ScriptAlias</A> /cgi-bin/</CODE> would. </P> <HR> <H2><A NAME="VirtualScriptAlias">VirtualScriptAliasIP directive</A></H2> <P> <A HREF="directive-dict.html#Syntax" REL="Help" ><STRONG>Syntax:</STRONG></A> VirtualScriptAliasIP <EM>interpolated-directory</EM><BR> <A HREF="directive-dict.html#Default" REL="Help" ><STRONG>Default:</STRONG></A> None<BR> <A HREF="directive-dict.html#Context" REL="Help" ><STRONG>Context:</STRONG></A> server config, virtual host<BR> <A HREF="directive-dict.html#Status" REL="Help" ><STRONG>Status:</STRONG></A> Extension<BR> <A HREF="directive-dict.html#Module" REL="Help" ><STRONG>Module:</STRONG></A> mod_vhost_alias<BR> <A HREF="directive-dict.html#Compatibility" REL="Help" ><STRONG>Compatibility:</STRONG></A> VirtualScriptAliasIP is only available in 1.3.5 and later.</P> <P> The <CODE>VirtualScriptAliasIP</CODE> directibe is like the <A HREF="#VirtualScriptAlias"><CODE>VirtualScriptAlias</CODE></A> directive, except that it uses the IP address of the server end of the connection instead of the server name. </P> <HR> <H3 ALIGN="CENTER"> Apache HTTP Server Version 1.3 </H3> <A HREF="./"><IMG SRC="../images/index.gif" ALT="Index"></A> <A HREF="../"><IMG SRC="../images/home.gif" ALT="Home"></A> </BODY> </HTML> 1.3 +219 -137 apache-1.3/htdocs/manual/vhosts/mass.html Index: mass.html =================================================================== RCS file: /export/home/cvs/apache-1.3/htdocs/manual/vhosts/mass.html,v retrieving revision 1.2 retrieving revision 1.3 diff -u -r1.2 -r1.3 --- mass.html 1999/01/20 04:47:08 1.2 +++ mass.html 1999/06/22 00:51:25 1.3 @@ -15,9 +15,7 @@ <H1 ALIGN="CENTER">Dynamically configured mass virtual hosting</H1> <P>This document describes how to efficiently serve an arbitrary number -of virtual hosts with Apache 1.3. Some familiarity with -<A HREF="../mod/mod_rewrite.html"><CODE>mod_rewrite</CODE></A> is -useful.</P> +of virtual hosts with Apache 1.3. <!-- @@ -34,17 +32,21 @@ <UL> <LI><A HREF="#motivation">Motivation</A> -<LI><A HREF="#overview">Overview of the technique</A> -<LI><A HREF="#simple">Simple name-based dynamic virtual hosts</A> +<LI><A HREF="#overview">Overview</A> +<LI><A HREF="#simple">Simple dynamic virtual hosts</A> <LI><A HREF="#homepages">A virtually hosted homepages system</A> -<LI><A HREF="#xtra-conf">Using a separate virtual host configuration file</A> <LI><A HREF="#combinations">Using more than one virtual hosting system on the same server</A> +<LI><A HREF="#ipbased">More efficient IP-based virtual hosting</A> +<LI><A HREF="#oldversion">Using older versions of Apache</A> +<LI><A HREF="#simple.rewrite">Simple dynamic virtual hosts using <CODE>mod_rewrite</CODE></A> +<LI><A HREF="#homepages.rewrite">A homepages system using <CODE>mod_rewrite</CODE></A> +<LI><A HREF="#xtra-conf">Using a separate virtual host configuration file</A> </UL> <HR><H2><A NAME="motivation">Motivation</A></H2> <P>The techniques described here are of interest if your -<CODE>httpd.conf</CODE> contains hundreds of +<CODE>httpd.conf</CODE> contains many <CODE><VirtualHost></CODE> sections that are substantially the same, for example: <PRE> @@ -81,82 +83,221 @@ </P> <P>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 <CODE>LogFormat</CODE> directive that includes -<CODE>%{SERVER_NAME}e</CODE> for the virtual host makes it easy to do this.</P> - - -<HR><H2><A NAME="overview">Overview of the technique</A></H2> - -<P>All of the dynamic virtual hosts will either be configured as part -of the main server configuration, or within a -<CODE><VirtualHost></CODE> section. For a simple (very uniform) -setup, <CODE><VirtualHost></CODE> sections aren't needed at all.</P> +for each virtual host; however if you have very many virtual hosts +then doing this is dubious anyway because it eats file descriptors. It +is better to log to a pipe or a fifo and arrange for the process at +the other end to distribute the logs to the customers (it can also +accumulate statistics, etc.).</P> + + +<HR><H2><A NAME="overview">Overview</A></H2> + +<P>A virtual host is defined by two pieces of information: its IP +address, and the contents of the <CODE>Host:</CODE> header in the HTTP +request. The dynamic mass virtual hosting technique is based on +automatically inserting this information into the pathname of the file +that is used to satisfy the request. This is done most easily using +<A HREF="../mod/mod_vhost_alias.html"><CODE>mod_vhost_alias</CODE></A>, +but if you are using a version of Apache up to 1.3.6 then you must use +<A HREF="../mod/mod_rewrite.html"><CODE>mod_rewrite</CODE></A>. Both +of these modules are disabled by default; you must enable one of them +when configuring and building Apache if you want to use this technique.</P> <P>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 <CODE>ServerName</CODE> and available to CGIs via the -<CODE>SERVER_NAME</CODE> environment variable). The way it is -determined is controlled by the <CODE>UseCanonicalName</CODE> -directive: with <CODE>UseCanonicalName off</CODE> the server name +which is used by Apache to generate self-referential URLs, etc. It +is configured with the <CODE>ServerName</CODE> directive, and it is +available to CGIs via the <CODE>SERVER_NAME</CODE> environment +variable. The actual value used at run time is controlled by the +<A HREF="../mod/core.html#usecanonicalname"><CODE>UseCanonicalName</CODE></A> +setting. With <CODE>UseCanonicalName Off</CODE> the server name comes from the contents of the <CODE>Host:</CODE> header in the -request. If there is no <CODE>Host:</CODE> header then the value -configured with <CODE>ServerName</CODE> is used instead.</P> +request. With <CODE>UseCanonicalName DNS</CODE> it comes from a +reverse DNS lookup of the virtual host's IP address. The former +setting is used for name-based dynamic virtual hosting, and the latter +is used for IP-based hosting. If Apache cannot work out the server +name because there is no <CODE>Host:</CODE> header or the DNS lookup +fails then the value configured with <CODE>ServerName</CODE> is used +instead.</P> + +<P>The other thing to `fake' is the document root (configured +with <CODE>DocumentRoot</CODE> and available to CGIs via the +<CODE>DOCUMENT_ROOT</CODE> environment variable). This setting +is used by the core module when mapping URIs to filenames, but +when the server is configured to do dynamic virtual hosting that +job is taken over by another module. If any CGIs or SSI documents +make use of the <CODE>DOCUMENT_ROOT</CODE> environment variable +they will therefore get a misleading value; there isn't any way to +change <CODE>DOCUMENT_ROOT</CODE> dynamically.</P> -<P>The other one is the document root (configured with -<CODE>DocumentRoot</CODE> and available to CGIs via the -<CODE>DOCUMENT_ROOT</CODE> 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 <CODE>DOCUMENT_ROOT</CODE> 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 -<CODE>DOCUMENT_ROOT</CODE> dynamically.</P> - -<P>The meat of the mechanism works via Apache's URI-to-filename -translation API phase. This is used by a number of modules: -<A HREF="../mod/mod_rewrite.html"><CODE>mod_rewrite</CODE></A>, -<A HREF="../mod/mod_alias.html"><CODE>mod_alias</CODE></A>, -<A HREF="../mod/mod_userdir.html"><CODE>mod_userdir</CODE></A>, -and <A HREF="../mod/core.html">the core module</A>. -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 -<CODE>mod_rewrite</CODE>, 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 <CODE>mod_rewrite</CODE> configuration that matches any URI means -that the other modules (particularly <CODE>mod_alias</CODE>) will -cease to function. The examples below show how to deal with this.</P> - -<P><STRONG>The dynamic virtual hosting idea is very simple: use the -server name as well as the URI to determine the corresponding -filename.</STRONG></P> +<HR><H2><A NAME="simple">Simple dynamic virtual hosts</A></H2> -<HR><H2><A NAME="simple">Simple name-based dynamic virtual hosts</A></H2> - <P>This extract from <CODE>httpd.conf</CODE> implements the virtual host arrangement outlined in the <A HREF="#motivation">Motivation</A> -section above, but in a generic fashion.</P> +section above, but in a generic fashion using +<CODE>mod_vhost_alias</CODE>.</P> + +<PRE> +# get the server name from the Host: header +UseCanonicalName Off + +# this log format can be split per-virtual-host based on the first field +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon +CustomLog logs/access_log vcommon + +# include the server name in the filenames used to satisfy requests +VirtualDocumentRoot /www/hosts/%0/docs +VirtualScriptAlias /www/hosts/%0/cgi-bin +</PRE> + +<P>This configuration can be changed into an IP-based virtual hosting +solution by just turning <CODE>UseCanonicalName Off</CODE> into +<CODE>UseCanonicalName DNS</CODE>. The server name that is inserted +into the filename is then derived from the IP address of the virtual +host.</P> + + +<HR><H2><A NAME="homepages">A virtually hosted homepages system</A></H2> + +<P>This is an adjustment of the above system tailored for an ISP's +homepages server. Using a slightly more complicated configuration we +can select substrings of the server name to use in the filename so +that e.g. the documents for <SAMP>www.user.isp.com</SAMP> are found in +<CODE>/home/user/</CODE>. It uses a single <CODE>cgi-bin</CODE> +directory instead of one per virtual host.</P> + +<PRE> +# all the preliminary stuff is the same as above, then + +# include part of the server name in the filenames +VirtualDocumentRoot /www/hosts/%2/docs + +# single cgi-bin directory +ScriptAlias /cgi-bin/ /www/std-cgi/ +</PRE> + +<P>There are examples of more complicated +<CODE>VirtualDocumentRoot</CODE> settings in +<A HREF="../mod/mod_vhost_alias.html">the +<CODE>mod_vhost_alias</CODE> documentation</A>.</P> + + +<HR><H2><A NAME="combinations">Using more than one virtual hosting +system on the same server</A></H2> + +<P>With more complicated setups you can use Apache's normal +<CODE><VirtualHost></CODE> directives to control the scope of +the various virtual hosting 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 conventional <CODE><VirtualHost></CODE> configuration +sections.</P> + +<PRE> +UseCanonicalName Off + +LogFormat "%V %h %l %u %t \"%r\" %s %b" vcommon + +<Directory /www/commercial> + Options FollowSymLinks + AllowOverride All +</Directory> + +<Directory /www/homepages> + Options FollowSymLinks + AllowOverride None +</Directory> + +<VirtualHost 111.22.33.44> + ServerName www.commercial.isp.com + + CustomLog logs/access_log.commercial vcommon + + VirtualDocumentRoot /www/commercial/%0/docs + VirtualScriptAlias /www/commercial/%0/cgi-bin +</VirtualHost> + +<VirtualHost 111.22.33.45> + ServerName www.homepages.isp.com -<P>The first half shows some other configuration options that are -needed to make the <CODE>mod_rewrite</CODE> part work as expected; the -second half uses <CODE>mod_rewrite</CODE> to do the actual work. Some -care is taken to do a per-dynamic-virtual-host equivalent of -<CODE>ScriptAlias</CODE>.</P> + CustomLog logs/access_log.homepages vcommon + VirtualDocumentRoot /www/homepages/%0/docs + ScriptAlias /cgi-bin/ /www/std-cgi/ +</VirtualHost> +</PRE> + + +<HR><H2><A NAME="ipbased">More efficient IP-based virtual hosting</A></H2> + +<P>After <A HREF="#simple">the first example</A> I noted that it is +easy to turn it into an IP-based virtual hosting setup. Unfortunately +that configuration is not very efficient because it requires a DNS +lookup for every request. This can be avoided by laying out the +filesystem according to the IP addresses themselves rather than the +corresponding names and changing the logging similarly. Apache will +then usually not need to work out the server name and so incur a DNS +lookup.</P> + +<PRE> +# get the server name from the reverse DNS of the IP address +UseCanonicalName DNS + +# include the IP address in the logs so they may be split +LogFormat "%A %h %l %u %t \"%r\" %s %b" vcommon +CustomLog logs/access_log vcommon + +# include the IP address in the filenames +VirtualDocumentRootIP /www/hosts/%0/docs +VirtualScriptAliasIP /www/hosts/%0/cgi-bin +</PRE> + + +<HR><H2><A NAME="oldversion">Using older versions of Apache</A></H2> + +<P>The examples above rely on <CODE>mod_vhost_alias</CODE> which +appeared after version 1.3.6. If you are using a version of Apache +without <CODE>mod_vhost_alias</CODE> then you can implement this +technique with <CODE>mod_rewrite</CODE> as illustrated below, but +only for Host:-header-based virtual hosts.</P> + +<P>In addition there are some things to beware of with logging. Apache +1.3.6 is the first version to include the <CODE>%V</CODE> log format +directive; in versions 1.3.0 - 1.3.3 the <CODE>%v</CODE> option did +what <CODE>%V</CODE> does; version 1.3.4 has no equivalent. In +all these versions of Apache the <CODE>UseCanonicalName</CODE> +directive can appear in <CODE>.htaccess</CODE> files which means that +customers can cause the wrong thing to be logged. Therefore the best +thing to do is use the <CODE>%{Host}i</CODE> directive which logs the +<CODE>Host:</CODE> header directly; note that this may include +<CODE>:port</CODE> on the end which is not the case for +<CODE>%V</CODE>.</P> + + +<HR><H2><A NAME="simple.rewrite">Simple dynamic virtual hosts +using <CODE>mod_rewrite</CODE></A></H2> + +<P>This extract from <CODE>httpd.conf</CODE> does the same thing as +<A HREF="#simple">the first example</A>. The first half is very +similar to the corresponding part above but with some changes for +backward compatibility and to make the <CODE>mod_rewrite</CODE> part +work properly; the second half configures <CODE>mod_rewrite</CODE> to +do the actual work.</P> + +<P>There are a couple of especially tricky bits: By default, +<CODE>mod_rewrite</CODE> runs before the other URI translation modules +(<CODE>mod_alias</CODE> etc.) so if they are used then +<CODE>mod_rewrite</CODE> must be configured to accommodate them. +Also, mome magic must be performed to do a per-dynamic-virtual-host +equivalent of <CODE>ScriptAlias</CODE>.</P> + <PRE> -# dynamic ServerName +# get the server name from the Host: header UseCanonicalName Off # splittable logs -LogFormat "%{SERVER_NAME}e %h %l %u %t \"%r\" %s %b" vcommon +LogFormat "%{Host}i %h %l %u %t \"%r\" %s %b" vcommon CustomLog logs/access_log vcommon <Directory /www/hosts> @@ -188,14 +329,11 @@ </PRE> -<HR><H2><A NAME="homepages">A virtually hosted homepages system</A></H2> +<HR><H2><A NAME="homepages.rewrite">A homepages system +using <CODE>mod_rewrite</CODE></A></H2> -<P>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 <SAMP>www.user.isp.com</SAMP> are found in -<CODE>/home/user/</CODE>. It uses a single <CODE>cgi-bin</CODE> -directory instead of one per virtual host.</P> +<P>This does the same thing as <A HREF="#homepages">the +second example</A>.</P> <PRE> RewriteEngine on @@ -206,11 +344,11 @@ RewriteCond %{REQUEST_URI} !^/cgi-bin/ # check the hostname is right so that the RewriteRule works -RewriteCond ${lowercase:%{HTTP_HOST}} ^www\.[a-z-]+\.isp\.com$ +RewriteCond ${lowercase:%{SERVER_NAME}} ^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] +RewriteRule ^(.+) ${lowercase:%{SERVER_NAME}}$1 [C] # now create the real file name RewriteRule ^www\.([a-z-]+)\.isp\.com/(.*) /home/$1/$2 @@ -222,9 +360,10 @@ <HR><H2><A NAME="xtra-conf">Using a separate virtual host configuration file</A></H2> -<P>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.</P> +<P>This arrangement uses more advanced <CODE>mod_rewrite</CODE> +features to get the translation from virtual host to document root +from a separate configuration file. This provides more flexibility but +requires more complicated configuration.</P> <P>The <CODE>vhost.map</CODE> file contains something like this: <PRE> @@ -258,63 +397,6 @@ RewriteRule ^/(.*)$ %1/cgi-bin/$1 </PRE> </P> - - -<HR><H2><A NAME="combinations">Using more than one virtual hosting system on the same server</A></H2> - -<P>With more complicated setups, you can use Apache's normal -<CODE><VirtualHost></CODE> 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 <CODE><VirtualHost></CODE> configuration -sections.</P> - -<PRE> -UseCanonicalName Off - -LogFormat "%{SERVER_NAME}e %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> -</PRE> <HR> 1.1383 +4 -1 apache-1.3/src/CHANGES Index: CHANGES =================================================================== RCS file: /export/home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1382 retrieving revision 1.1383 diff -u -r1.1382 -r1.1383 --- CHANGES 1999/06/18 07:58:34 1.1382 +++ CHANGES 1999/06/22 00:51:26 1.1383 @@ -1,5 +1,8 @@ Changes with Apache 1.3.7 - + + *) Add the new mass-vhost module (mod_vhost_alias.c) developed and + used by Demon Internet, LTD. [Tony Finch <[EMAIL PROTECTED]>] + *) Better GCC detection for DSO flags under Solaris 2 where the `cc' command potentially _is_ GCC. [Ralf S. Engelschall] 1.116 +7 -0 apache-1.3/src/Configuration.tmpl Index: Configuration.tmpl =================================================================== RCS file: /export/home/cvs/apache-1.3/src/Configuration.tmpl,v retrieving revision 1.115 retrieving revision 1.116 diff -u -r1.115 -r1.116 --- Configuration.tmpl 1999/05/31 11:57:57 1.115 +++ Configuration.tmpl 1999/06/22 00:51:27 1.116 @@ -214,6 +214,13 @@ # AddModule modules/experimental/mod_mmap_static.o +## mod_vhost_alias provides support for mass virtual hosting +## by dynamically changing the document root and CGI directory +## based on the host header or local IP address of the request. +## See "../htdocs/manual/vhosts/mass.html". + +# AddModule modules/extra/mod_vhost_alias.o + ## ## Config manipulation modules ## 1.58 +7 -3 apache-1.3/src/include/http_core.h Index: http_core.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/http_core.h,v retrieving revision 1.57 retrieving revision 1.58 diff -u -r1.57 -r1.58 --- http_core.h 1999/05/07 00:16:10 1.57 +++ http_core.h 1999/06/22 00:51:28 1.58 @@ -128,8 +128,8 @@ /* Used for constructing self-referencing URLs, and things like SERVER_PORT, * and SERVER_NAME. */ -API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, const request_rec *r); -API_EXPORT(const char *) ap_get_server_name(const request_rec *r); +API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, request_rec *r); +API_EXPORT(const char *) ap_get_server_name(request_rec *r); API_EXPORT(unsigned) ap_get_server_port(const request_rec *r); API_EXPORT(unsigned long) ap_get_limit_req_body(const request_rec *r); API_EXPORT(void) ap_custom_response(request_rec *r, int status, char *string); @@ -230,7 +230,11 @@ signed int content_md5 : 2; /* calculate Content-MD5? */ - unsigned use_canonical_name : 2; /* bit 0 = on/off, bit 1 = unset/set */ +#define USE_CANONICAL_NAME_OFF (0) +#define USE_CANONICAL_NAME_ON (1) +#define USE_CANONICAL_NAME_DNS (2) +#define USE_CANONICAL_NAME_UNSET (3) + unsigned use_canonical_name : 2; /* since is_fnmatch(conf->d) was being called so frequently in * directory_walk() and its relatives, this field was created and 1.282 +4 -0 apache-1.3/src/include/httpd.h Index: httpd.h =================================================================== RCS file: /export/home/cvs/apache-1.3/src/include/httpd.h,v retrieving revision 1.281 retrieving revision 1.282 diff -u -r1.281 -r1.282 --- httpd.h 1999/06/05 15:48:08 1.281 +++ httpd.h 1999/06/22 00:51:29 1.282 @@ -827,6 +827,10 @@ * "" if it has and no address was found. * N.B. Only access this though * get_remote_host() */ + char *local_ip; /* server IP address */ + char *local_host; /* used for ap_get_server_name when + * UseCanonicalName is set to DNS + * (ignores setting of HostnameLookups) */ char *remote_logname; /* Only ever set if doing rfc1413 lookups. * N.B. Only access this through * get_remote_logname() */ 1.265 +61 -39 apache-1.3/src/main/http_core.c Index: http_core.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_core.c,v retrieving revision 1.264 retrieving revision 1.265 diff -u -r1.264 -r1.265 --- http_core.c 1999/06/17 11:49:32 1.264 +++ http_core.c 1999/06/22 00:51:30 1.265 @@ -130,7 +130,7 @@ conf->content_md5 = 2; - conf->use_canonical_name = 1 | 2; /* 2 = unset, default on */ + conf->use_canonical_name = USE_CANONICAL_NAME_UNSET; conf->hostname_lookups = HOSTNAME_LOOKUP_UNSET; conf->do_rfc1413 = DEFAULT_RFC1413 | 2; /* set bit 1 to indicate default */ @@ -242,7 +242,7 @@ if ((new->content_md5 & 2) == 0) { conf->content_md5 = new->content_md5; } - if ((new->use_canonical_name & 2) == 0) { + if (new->use_canonical_name != USE_CANONICAL_NAME_UNSET) { conf->use_canonical_name = new->use_canonical_name; } @@ -672,17 +672,47 @@ * name" as supplied by a possible Host: header or full URI. We never * trust the port passed in the client's headers, we always use the * port of the actual socket. + * + * The DNS option to UseCanonicalName causes this routine to do a + * reverse lookup on the local IP address of the connectiona and use + * that for the ServerName. This makes its value more reliable while + * at the same time allowing Demon's magic virtual hosting to work. + * The assumption is that DNS lookups are sufficiently quick... + * -- fanf 1998-10-03 */ -API_EXPORT(const char *) ap_get_server_name(const request_rec *r) +API_EXPORT(const char *) ap_get_server_name(request_rec *r) { + conn_rec *conn = r->connection; core_dir_config *d; d = (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - if (d->use_canonical_name & 1) { - return r->server->server_hostname; + + if (d->use_canonical_name == USE_CANONICAL_NAME_OFF) { + return r->hostname ? r->hostname : r->server->server_hostname; } - return r->hostname ? r->hostname : r->server->server_hostname; + if (d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + if (conn->local_host == NULL) { + struct in_addr *iaddr; + struct hostent *hptr; + int old_stat; + old_stat = ap_update_child_status(conn->child_num, SERVER_BUSY_DNS, r); + iaddr = &(conn->local_addr.sin_addr); + hptr = gethostbyaddr((char *)iaddr, sizeof(struct in_addr), AF_INET); + if (hptr != NULL) { + conn->local_host = ap_pstrdup(conn->pool, (void *)hptr->h_name); + ap_str_tolower(conn->local_host); + } + else { + conn->local_host = ap_pstrdup(conn->pool, + r->server->server_hostname); + } + (void) ap_update_child_status(conn->child_num, old_stat, r); + } + return conn->local_host; + } + /* default */ + return r->server->server_hostname; } API_EXPORT(unsigned) ap_get_server_port(const request_rec *r) @@ -693,38 +723,21 @@ port = r->server->port ? r->server->port : ap_default_port(r); - if (d->use_canonical_name & 1) { - return port; + if (d->use_canonical_name == USE_CANONICAL_NAME_OFF + || d->use_canonical_name == USE_CANONICAL_NAME_DNS) { + return r->hostname ? ntohs(r->connection->local_addr.sin_port) + : port; } - return r->hostname ? ntohs(r->connection->local_addr.sin_port) - : port; + /* default */ + return port; } API_EXPORT(char *) ap_construct_url(pool *p, const char *uri, - const request_rec *r) + request_rec *r) { - unsigned port; - const char *host; - core_dir_config *d = - (core_dir_config *)ap_get_module_config(r->per_dir_config, &core_module); - - if (d->use_canonical_name & 1) { - port = r->server->port ? r->server->port : ap_default_port(r); - host = r->server->server_hostname; - } - else { - if (r->hostname) { - port = ntohs(r->connection->local_addr.sin_port); - } - else if (r->server->port) { - port = r->server->port; - } - else { - port = ap_default_port(r); - } + unsigned port = ap_get_server_port(r); + const char *host = ap_get_server_name(r); - host = r->hostname ? r->hostname : r->server->server_hostname; - } if (ap_is_default_port(port, r)) { return ap_pstrcat(p, ap_http_method(r), "://", host, uri, NULL); } @@ -2124,15 +2137,25 @@ } static const char *set_use_canonical_name(cmd_parms *cmd, core_dir_config *d, - int arg) + char *arg) { const char *err = ap_check_cmd_context(cmd, NOT_IN_LIMIT); - if (err != NULL) { return err; } - - d->use_canonical_name = arg != 0; + + if (!strcasecmp(arg, "on")) { + d->use_canonical_name = USE_CANONICAL_NAME_ON; + } + else if (!strcasecmp(arg, "off")) { + d->use_canonical_name = USE_CANONICAL_NAME_OFF; + } + else if (!strcasecmp(arg, "dns")) { + d->use_canonical_name = USE_CANONICAL_NAME_DNS; + } + else { + return "parameter must be 'on', 'off', or 'dns'"; + } return NULL; } @@ -2813,9 +2836,8 @@ { "ContentDigest", set_content_md5, NULL, OR_OPTIONS, FLAG, "whether or not to send a Content-MD5 header with each request" }, { "UseCanonicalName", set_use_canonical_name, NULL, - OR_OPTIONS, FLAG, - "Whether or not to always use the canonical ServerName : Port when " - "constructing URLs" }, + RSRC_CONF, TAKE1, + "How to work out the ServerName : Port when constructing URLs" }, { "StartServers", set_daemons_to_start, NULL, RSRC_CONF, TAKE1, "Number of child processes launched at server startup" }, { "MinSpareServers", set_min_free_servers, NULL, RSRC_CONF, TAKE1, 1.447 +2 -0 apache-1.3/src/main/http_main.c Index: http_main.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/http_main.c,v retrieving revision 1.446 retrieving revision 1.447 diff -u -r1.446 -r1.447 --- http_main.c 1999/06/17 11:49:33 1.446 +++ http_main.c 1999/06/22 00:51:30 1.447 @@ -3068,6 +3068,8 @@ conn->pool = p; conn->local_addr = *saddr; + conn->local_ip = ap_pstrdup(conn->pool, + inet_ntoa(conn->local_addr.sin_addr)); conn->server = server; /* just a guess for now */ ap_update_vhost_given_ip(conn); conn->base_server = conn->server; 1.141 +1 -0 apache-1.3/src/main/util_script.c Index: util_script.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/main/util_script.c,v retrieving revision 1.140 retrieving revision 1.141 diff -u -r1.140 -r1.141 --- util_script.c 1999/04/08 11:36:33 1.140 +++ util_script.c 1999/06/22 00:51:31 1.141 @@ -265,6 +265,7 @@ ap_table_addn(e, "SERVER_SIGNATURE", ap_psignature("", r)); ap_table_addn(e, "SERVER_SOFTWARE", ap_get_server_version()); ap_table_addn(e, "SERVER_NAME", ap_get_server_name(r)); + ap_table_addn(e, "SERVER_ADDR", r->connection->local_ip); /* Apache */ ap_table_addn(e, "SERVER_PORT", ap_psprintf(r->pool, "%u", ap_get_server_port(r))); host = ap_get_remote_host(c, r->per_dir_config, REMOTE_HOST); 1.78 +9 -0 apache-1.3/src/modules/standard/mod_log_config.c Index: mod_log_config.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_log_config.c,v retrieving revision 1.77 retrieving revision 1.78 diff -u -r1.77 -r1.78 --- mod_log_config.c 1999/05/16 23:39:44 1.77 +++ mod_log_config.c 1999/06/22 00:51:35 1.78 @@ -122,6 +122,7 @@ * %...f: filename * %...h: remote host * %...a: remote IP-address + * %...A: local IP-address * %...{Foobar}i: The contents of Foobar: header line(s) in the request * sent to the client. * %...l: remote logname (from identd, if supplied) @@ -289,6 +290,11 @@ return r->connection->remote_ip; } +static const char *log_local_address(request_rec *r, char *a) +{ + return r->connection->local_ip; +} + static const char *log_remote_logname(request_rec *r, char *a) { return ap_get_remote_logname(r); @@ -445,6 +451,9 @@ }, { 'a', log_remote_address, 0 + }, + { + 'A', log_local_address, 0 }, { 'l', log_remote_logname, 0 1.140 +3 -0 apache-1.3/src/modules/standard/mod_rewrite.c Index: mod_rewrite.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/modules/standard/mod_rewrite.c,v retrieving revision 1.139 retrieving revision 1.140 diff -u -r1.139 -r1.140 --- mod_rewrite.c 1999/05/21 12:16:24 1.139 +++ mod_rewrite.c 1999/06/22 00:51:37 1.140 @@ -3614,6 +3614,9 @@ else if (strcasecmp(var, "SERVER_NAME") == 0) { result = ap_get_server_name(r); } + else if (strcasecmp(var, "SERVER_ADDR") == 0) { /* non-standard */ + result = r->connection->local_ip; + } else if (strcasecmp(var, "SERVER_PORT") == 0) { ap_snprintf(resultbuf, sizeof(resultbuf), "%u", ap_get_server_port(r)); result = resultbuf; 1.1 apache-1.3/src/modules/standard/mod_vhost_alias.c Index: mod_vhost_alias.c =================================================================== /* ==================================================================== * Copyright (c) 1995-1999 The Apache Group. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. All advertising materials mentioning features or use of this * software must display the following acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * 4. The names "Apache Server" and "Apache Group" must not be used to * endorse or promote products derived from this software without * prior written permission. For written permission, please contact * [EMAIL PROTECTED] * * 5. Products derived from this software may not be called "Apache" * nor may "Apache" appear in their names without prior written * permission of the Apache Group. * * 6. Redistributions of any form whatsoever must retain the following * acknowledgment: * "This product includes software developed by the Apache Group * for use in the Apache HTTP server project (http://www.apache.org/)." * * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE APACHE GROUP OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Group and was originally based * on public domain software written at the National Center for * Supercomputing Applications, University of Illinois, Urbana-Champaign. * For more information on the Apache Group and the Apache HTTP server * project, please see <http://www.apache.org/>. * */ /* * mod_vhost_alias.c: support for dynamically configured mass virtual hosting * * Copyright (c) 1998-1999 Demon Internet Ltd. * * This software was submitted by Demon Internet to the Apache Group * in May 1999. Future revisions and derivatives of this source code * must acknowledge Demon Internet as the original contributor of * this module. All other licensing and usage conditions are those * of the Apache Group. * * Originally written by Tony Finch <[EMAIL PROTECTED]> <[EMAIL PROTECTED]>. * * Implementation ideas were taken from mod_alias.c. The overall * concept is derived from the OVERRIDE_DOC_ROOT/OVERRIDE_CGIDIR * patch to Apache 1.3b3 and a similar feature in Demon's thttpd, * both written by James Grinter <[EMAIL PROTECTED]>. */ #include "httpd.h" #include "http_config.h" #include "http_core.h" module MODULE_VAR_EXPORT vhost_alias_module; /* basic configuration things */ typedef enum { VHOST_ALIAS_UNSET, VHOST_ALIAS_NONE, VHOST_ALIAS_NAME, VHOST_ALIAS_IP } vhost_alias_mode; typedef struct vhost_alias_server_conf { char *doc_root; char *cgi_root; vhost_alias_mode doc_root_mode; vhost_alias_mode cgi_root_mode; } vhost_alias_server_conf; static void *vhost_alias_create_config(pool *p, server_rec *s) { vhost_alias_server_conf *conf = (vhost_alias_server_conf *) ap_pcalloc(p, sizeof(vhost_alias_server_conf)); conf->doc_root = NULL; conf->cgi_root = NULL; conf->doc_root_mode = VHOST_ALIAS_UNSET; conf->cgi_root_mode = VHOST_ALIAS_UNSET; return conf; } static void *vhost_alias_merge_config(pool *p, void *parentv, void *childv) { vhost_alias_server_conf *parent = (vhost_alias_server_conf *)parentv; vhost_alias_server_conf *child = (vhost_alias_server_conf *)childv; vhost_alias_server_conf *conf = (vhost_alias_server_conf *) ap_pcalloc(p, sizeof(*conf)); if (child->doc_root_mode == VHOST_ALIAS_UNSET) { conf->doc_root_mode = parent->doc_root_mode; conf->doc_root = parent->doc_root; } else { conf->doc_root_mode = child->doc_root_mode; conf->doc_root = child->doc_root; } if (child->cgi_root_mode == VHOST_ALIAS_UNSET) { conf->cgi_root_mode = parent->cgi_root_mode; conf->cgi_root = parent->cgi_root; } else { conf->cgi_root_mode = child->cgi_root_mode; conf->cgi_root = child->cgi_root; } return conf; } /* * These are just here to tell us what vhost_alias_set should do. */ static int vhost_alias_set_doc_root_ip, vhost_alias_set_cgi_root_ip, vhost_alias_set_doc_root_name, vhost_alias_set_cgi_root_name; static const char *vhost_alias_set(cmd_parms *cmd, void *dummy, char *map) { vhost_alias_server_conf *conf = (vhost_alias_server_conf *) ap_get_module_config(cmd->server->module_config, &vhost_alias_module); vhost_alias_mode mode, *pmode; char **pmap; char *p; /* there ought to be a better way of doing this */ if (&vhost_alias_set_doc_root_ip == cmd->info) { mode = VHOST_ALIAS_IP; pmap = &conf->doc_root; pmode = &conf->doc_root_mode; } else if (&vhost_alias_set_cgi_root_ip == cmd->info) { mode = VHOST_ALIAS_IP; pmap = &conf->cgi_root; pmode = &conf->cgi_root_mode; } else if (&vhost_alias_set_doc_root_name == cmd->info) { mode = VHOST_ALIAS_NAME; pmap = &conf->doc_root; pmode = &conf->doc_root_mode; } else if (&vhost_alias_set_cgi_root_name == cmd->info) { mode = VHOST_ALIAS_NAME; pmap = &conf->cgi_root; pmode = &conf->cgi_root_mode; } else return "INTERNAL ERROR: unknown command info"; if (*map != '/') { if (strcasecmp(map, "none")) return "format string must start with '/' or be 'none'"; *pmap = NULL; *pmode = VHOST_ALIAS_NONE; return NULL; } /* sanity check */ p = map; while (*p != '\0') { if (*p++ != '%') continue; /* we just found a '%' */ if (*p == 'p' || *p == '%') { ++p; continue; } /* optional dash */ if (*p == '-') ++p; /* digit N */ if (ap_isdigit(*p)) ++p; else return "syntax error in format string"; /* optional plus */ if (*p == '+') ++p; /* do we end here? */ if (*p != '.') continue; ++p; /* optional dash */ if (*p == '-') ++p; /* digit M */ if (ap_isdigit(*p)) ++p; else return "syntax error in format string"; /* optional plus */ if (*p == '+') ++p; } *pmap = map; *pmode = mode; return NULL; } static const command_rec vhost_alias_commands[] = { {"VirtualScriptAlias", vhost_alias_set, &vhost_alias_set_cgi_root_name, RSRC_CONF, TAKE1, "how to create a ScriptAlias based on the host"}, {"VirtualDocumentRoot", vhost_alias_set, &vhost_alias_set_doc_root_name, RSRC_CONF, TAKE1, "how to create the DocumentRoot based on the host"}, {"VirtualScriptAliasIP", vhost_alias_set, &vhost_alias_set_cgi_root_ip, RSRC_CONF, TAKE1, "how to create a ScriptAlias based on the host"}, {"VirtualDocumentRootIP", vhost_alias_set, &vhost_alias_set_doc_root_ip, RSRC_CONF, TAKE1, "how to create the DocumentRoot based on the host"}, { NULL } }; /* * This really wants to be a nested function * but C is too feeble to support them. */ static ap_inline void vhost_alias_checkspace(request_rec *r, char *buf, char **pdest, int size) { /* XXX: what if size > HUGE_STRING_LEN? */ if (*pdest + size > buf + HUGE_STRING_LEN) { **pdest = '\0'; if (r->filename) r->filename = ap_pstrcat(r->pool, r->filename, buf, NULL); else r->filename = ap_pstrdup(r->pool, buf); *pdest = buf; } } static void vhost_alias_interpolate(request_rec *r, const char *name, const char *map, const char *uri) { /* 0..9 9..0 */ enum { MAXDOTS = 19 }; const char *dots[MAXDOTS+1]; int ndots; char buf[HUGE_STRING_LEN]; char *dest, last; int N, M, Np, Mp, Nd, Md; const char *start, *end; const char *p; ndots = 0; dots[ndots++] = name-1; /* slightly naughty */ for (p = name; *p; ++p) if (*p == '.' && ndots < MAXDOTS) dots[ndots++] = p; dots[ndots] = p; r->filename = NULL; dest = buf; last = '\0'; while (*map) { if (*map != '%') { /* normal characters */ vhost_alias_checkspace(r, buf, &dest, 1); last = *dest++ = *map++; continue; } /* we are in a format specifier */ ++map; /* can't be a slash */ last = '\0'; /* %% -> % */ if (*map == '%') { ++map; vhost_alias_checkspace(r, buf, &dest, 1); *dest++ = '%'; continue; } /* port number */ if (*map == 'p') { ++map; /* no. of decimal digits in a short plus one */ vhost_alias_checkspace(r, buf, &dest, 7); dest += ap_snprintf(dest, 7, "%d", ap_get_server_port(r)); continue; } /* deal with %-N+.-M+ -- syntax is already checked */ N = M = 0; /* value */ Np = Mp = 0; /* is there a plus? */ Nd = Md = 0; /* is there a dash? */ if (*map == '-') ++map, Nd = 1; N = *map++ - '0'; if (*map == '+') ++map, Np = 1; if (*map == '.') { ++map; if (*map == '-') ++map, Md = 1; M = *map++ - '0'; if (*map == '+') ++map, Mp = 1; } /* note that N and M are one-based indices, not zero-based */ start = dots[0]+1; /* ptr to the first character */ end = dots[ndots]; /* ptr to the character after the last one */ if (N != 0) { if (N > ndots) { start = "_"; end = start+1; } else if (!Nd) { start = dots[N-1]+1; if (!Np) end = dots[N]; } else { if (!Np) start = dots[ndots-N]+1; end = dots[ndots-N+1]; } } if (M != 0) { if (M > end - start) { start = "_"; end = start+1; } else if (!Md) { start = start+M-1; if (!Mp) end = start+1; } else { if (!Mp) start = end-M; end = end-M+1; } } vhost_alias_checkspace(r, buf, &dest, end - start); for (p = start; p < end; ++p) *dest++ = ap_tolower(*p); } *dest = '\0'; /* no double slashes */ if (last == '/') ++uri; if (r->filename) r->filename = ap_pstrcat(r->pool, r->filename, buf, uri, NULL); else r->filename = ap_pstrcat(r->pool, buf, uri, NULL); } static int vhost_alias_translate(request_rec *r) { vhost_alias_server_conf *conf = (vhost_alias_server_conf *) ap_get_module_config(r->server->module_config, &vhost_alias_module); const char *name, *map, *uri; vhost_alias_mode mode; int cgi; if (!strncmp(r->uri, "/cgi-bin/", 9)) { mode = conf->cgi_root_mode; map = conf->cgi_root; uri = r->uri + 8; /* * can't force cgi immediately because we might not handle this * call if the mode is wrong */ cgi = 1; } else if (r->uri[0] == '/') { mode = conf->doc_root_mode; map = conf->doc_root; uri = r->uri; cgi = 0; } else return DECLINED; if (mode == VHOST_ALIAS_NAME) name = ap_get_server_name(r); else if (mode == VHOST_ALIAS_IP) name = r->connection->local_ip; else return DECLINED; vhost_alias_interpolate(r, name, map, uri); if (cgi) { /* see is_scriptaliased() in mod_cgi */ r->handler = "cgi-script"; ap_table_setn(r->notes, "alias-forced-type", r->handler); } return OK; } module MODULE_VAR_EXPORT vhost_alias_module = { STANDARD_MODULE_STUFF, NULL, /* initializer */ NULL, /* dir config creater */ NULL, /* dir merger --- default is to override */ vhost_alias_create_config, /* server config */ vhost_alias_merge_config, /* merge server configs */ vhost_alias_commands, /* command table */ NULL, /* handlers */ vhost_alias_translate, /* filename translation */ NULL, /* check_user_id */ NULL, /* check auth */ NULL, /* check access */ NULL, /* type_checker */ NULL, /* fixups */ NULL, /* logger */ NULL, /* header parser */ NULL, /* child_init */ NULL, /* child_exit */ NULL /* post read-request */ }; 1.51 +1 -0 apache-1.3/src/support/suexec.c Index: suexec.c =================================================================== RCS file: /export/home/cvs/apache-1.3/src/support/suexec.c,v retrieving revision 1.50 retrieving revision 1.51 diff -u -r1.50 -r1.51 --- suexec.c 1999/02/21 20:36:44 1.50 +++ suexec.c 1999/06/22 00:51:41 1.51 @@ -145,6 +145,7 @@ "SCRIPT_URL", "SERVER_ADMIN", "SERVER_NAME", + "SERVER_ADDR", "SERVER_PORT", "SERVER_PROTOCOL", "SERVER_SOFTWARE",