A glance behind the curtain
How does virtual hosting, address rewriting and proxying work
Virtual hosting with Zope
The virtual host monster adds some magic to the traversal process of Zope. Two special keywords are added (VirtualHostBase and VirtualHostRoot) which allows you to configure the virtual host and the base folder inside your Zope instance.
The VHM part of an ordinary rewrite rules looks like this:
^/(.*) \ http://localhost:10080/VirtualHostBase/http/www.example.org:80/example_site/VirtualHostRoot/$1
The address has seven parts:
- http://localhost:10080
- This is only for apache's mod_proxy module. It configures what server should be accessed including protocol, host and port. In this example mod_proxy is accessing the ZServer at port 100080 on the same host using http.
- VirtualHostBase
- This is the magic keyword to start virtual hosting. You must not add an object called VirtualHostBase to your zope root!
- http
- The first path segment after VirtualHostBase defines the protocol of the vhost url.
- www.example.org:80
- The second segment after VirtualHostBase defines the server and the port. Together with the protocol it's the base part of the url, in this example http://www.example.org:80. Like VirtualHostBase the protocol and server are no real objects. They are just put into the url for configuration purpose and they are stripped of the url after configuring the virtual host for a request.
- example_site
- Now the real traversal through Zope starts. After setting up the protocol and server part of the new url we are traversing through Zope to the new virtual root for the vhost. You can add zero or more objects here.
- VirtualHostRoot
- Finally the magic keyword that we have reached the new virtual root for the vhost. Everything after VirtualHostRoot is visible to the browser.
- $1 and ^/(.*)
- $1 and ^/(.*) are some regex foo. ^/(.*) means "Match everything starting with a / and save every char after the / in the var $1.
- Special case _vh_foo
Imagen you want to have http://www.example.org/foo/ as the root url of your virtual url. You can get the effect by using the special _vh_ declaration. Any path segment starting with _vh_ is stripped of the url for traversal through zope and readded without _vh_ after traversal. Example:
^/foo/(.*) \ http://localhost:10080/VirtualHostBase/http/www.example.org:80/example_site/VirtualHostRoot/_vh_foo/$1
Note You are neither allowed to create an object called VirtualHostBase or VirtualHostRoot in your zope nor should you add an object with the same id of your VHM. It may work but it may also break your site.
mod_proxy vs. mod_ssl vars
You can't access the special environment vars added by mod_ssl (SSLOptions +StdEnvVars) inside of Zope if you are using mod_proxy to access Zope. This is due the way how proxying works internally. Every transparent proxy access to Zope is a new request and has no SSL context. In order to see the special environment vars you have to setup a CGI access to Zope. The best and fasted method is FastCGI http://www.fastcgi.com.
At first you have to Install FastCGI for Apache2. After mod_fastcgi is compiled, installed and loaded you have to reconfigure both Zope and Apache2.
Next you must enable the fast-cgi server of Zope. You can choose between socket and tcp (host:port) where socket is a little bit faster but Apache2 must have read access to the directory where the socket lifes. In this example INSTANCE_HOME is /var/lib/zope/example and the fastcgi address is $INSTANCE/var/zope.soc.
At last you have to reconfigure Apache2. The following example conf has only the necessary parts for fastcgi. Note that the DocumentRoot must exists and must be accessable by Apache2 but the zope.fcgi file must not exist. Also you should remove all proxy RewriteRules.
Apache2 config:
<IfModule mod_fastcgi.c>
FastCGIExternalServer /var/www/secure.example.org-ssl/zope.fcgi \
-socket /var/lib/zope/example/var/zope.soc \
-pass-header Authorization \
-pass-header Cookie \
-idle-timeout 60 \
-appConnTimeout 0
</IfModule>
<VirtualHost ...>
...
DocumentRoot /var/www/secure.example.org-ssl
...
<IfModule mod_fastcgi.c>
<Directory /var/www/secure.example.org-ssl>
AddHandler fastcgi-script .fcgi
</Directory>
</IfModule>
...
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteRule ^/(.*) \
/zope.fcgi/VirtualHostBase/https/secure.example.org:443/VirtualHostRoot/_vh_zope/_vh_example_instance/$1 [L]
</IfModule>
...
</VirtualHost>