(An addendum to the previous mod_acceptfilter proposal.)

From my experience on #apache, it appears that Mere Mortals have
a great deal of difficulty successfully configuring virtual hosts.
I think this is understandable; the algorithm used to allocate
requests to virtual host sections is complicated, and it conflates
two radically different concepts: the assignment of a listener to
a particular ip:port (or a particular ip), and the assignment of
named virtual hosts within an ip[:port] listener.

Successfully configuring a name virtual host, in the current
configuration system, requires co-ordinating three directives
which often appear in different parts of the configuration:
Listen, NameVirtualHost, and <VirtualHost>

Minor discrepancies in the ip:port specifications in these
directives can cause named virtual hosts to fail to work
without providing any useful error messages.

In addition, not all protocols support the concept of named
virtual hosts.

I'm interested in peoples' reactions to the following proposal:

Directive:
  <Listen ([<transport> "/"](ip | "*" | "_default_")[":" <port>])+>
Context: main configuration

This is the combination of an existing Listen directive with an
existing (non-named) Virtual Host directive; that is, you could
replace

Listen 1.2.3.4:80
<VirtualHost 1.2.3.4:80>
  #...
</VirtualHost>

with

<Listen 1.2.3.4:80>
  # ...
</Listen>

Directive:
  <NameVirtualHost (<name> | "_default_")+>
Context: <Listen> section

This provides the definition of a single named virtual host within
a single Listener; it replaces the existing NameVirtualHost and
<VirtualHost> directives. Exactly one <NameVirtualHost> must be
tagged with the _default_ name; if there is one it will be used
if no <name> matches or no virtual host name is provided by the
client.

It is an error to provide a <NameVirtualHost> in a <Listen> section
for a protocol which does not support named virtual hosts.

It is an error to provide more than one <NameVirtualHost _default_>
section in the same <Listen> section.

If no <NameVirtualHost _default_> is provided, the first <NameVirtualHost>
section will be used as a default, for backwards pseudo-compatibility,
but a warning will be generated.


-------------------

Example configurations:

1) Simple configuration, a number of virtual hosts with
   different document roots:

Current:
--------

Listen *:80
#...
#...
NameVirtualHost *:80
#...
#...
<VirtualHost *:80>
  ServerName this.does.not.match.any.name.com
  DocumentRoot /var/www/noname
  DirectoryIndex stopUsingNetscape2.html
</VirtualHost>

<VirtualHost *:80>
  ServerName www.example.com
  ServerAlias example.com
  DocumentRoot /var/www/example
</VirtualHost>

<VirtualHost *:80>
  ServerName www.example2.com
  ServerAlias example2.com
  DocumentRoot /var/www/example2
</VirtualHost>


Proposed: ---------

<Listen *:http>
  <NameVirtualHost _default_>
    DocumentRoot /var/www/noname
    DirectoryIndex stopUsingNetscape2.html
  </NameVirtualHost>

  <NameVirtualHost www.example.com example.com>
    DocumentRoot /var/www/example
  </NameVirtualHost>

  <NameVirtualHost www.example2.com example2.com>
    DocumentRoot /var/www/example2
  </NameVirtualHost>
</Listen>

----------------------------------------------------

2) A configuration with named virtual hosts on one
ip and non named virtual hosts on another one

Current:
--------

Listen *:80
#...
#...
NameVirtualHost 1.2.3.4:80
#...
#...
<VirtualHost 1.2.3.4:80>
  ServerName this.does.not.match.any.name.com
  DocumentRoot /var/www/noname
  DirectoryIndex stopUsingNetscape2.html
</VirtualHost>

<VirtualHost 1.2.3.4:80>
  ServerName www.example.com
  ServerAlias example.com
  DocumentRoot /var/www/example
</VirtualHost>

<VirtualHost 1.2.3.4:80>
  ServerName www.example2.com
  ServerAlias example2.com
  DocumentRoot /var/www/example2
</VirtualHost>

<VirtualHost 1.2.3.5:80>
  # This is not a named virtual host, but it is
  # not locally obvious
  ServerName www.example3.com
  DocumentRoot /var/www/example3
</VirtualHost>

Proposed:
---------

<Listen 1.2.3.4:http>
  <NameVirtualHost _default_>
    DocumentRoot /var/www/noname
    DirectoryIndex stopUsingNetscape2.html
  </NameVirtualHost>

  <NameVirtualHost www.example.com example.com>
    DocumentRoot /var/www/example
  </NameVirtualHost>

  <NameVirtualHost www.example2.com example2.com>
    DocumentRoot /var/www/example2
  </NameVirtualHost>
</Listen>

<Listen 1.2.3.5:http>
  ServerName www.example3.com
  DocumentRoot /var/www/example3
</Listen>

------------------------------------------------------

3) I am aware that this proposal does not provide for the
current possibility of doing something like:

Listen 1.2.3.4:80
Listen 192.168.1.1:80

NameVirtualHost *:80
<VirtualHost 1.2.3.4:80>
  # Only available on the external interface
  ServerName www.example.com
</VirtualHost>

<VirtualHost *:80>
  # Available on both interfaces
  ServerName www.example2.com
</VirtualHost>

<VirtualHost 192.168.1.1:80>
  # Only available on the internal interface
  ServerName www.example3.com
</VirtualHost>

I don't believe this is a common configuration case, although
it certainly exists. Such configurations could continue to use
the current mechanism, or they could use something like:

<Listen 1.2.3.4:80>
  Include conf/example.conf
  Include conf/example2.conf
</Listen>

<Listen 192.168.1.1:80>
  Include conf/example3.conf
  Include conf/example2.conf
</Listen>

This is, of course, subtly different: the default named
virtual host assignment is example.com on the external
port and example3.com (instead of example2.com) on the
internal port.

Also, there are various alternatives to include files,
such as mod_macro.



Reply via email to