This section explains a configuration setup for proxying your backend mod_perl servers when you need to use virtual hosts. See perl.apache.org/guide/scenario.html, from which we have quoted freely. While you are better off getting it right in the first place (i.e. using different URLs for the different servers), there are at least three reasons you might want to rewrite:
Because you didn’t think of it in the first place and you are now fighting fires.
Because you want to save page size by using relative URLs instead of full ones.
You might improve performance by, for instance, caching the results of expensive CGIs.
The term virtual host refers to the practice of maintaining more than one server on one machine, as differentiated by their apparent hostname. For example, it is often desirable for companies sharing a web server to have their own domains, with web servers accessible as www.company1.com and www.company2.com, without requiring the user to know any extra path information.
One approach is to use a unique port number for each virtual host at the backend server, so you can redirect from the frontend server to localhost:1234 and name-based virtual servers on the frontend, though any technique on the frontend will do.
If you run the frontend and the backend servers on the same machine, you can prevent any direct outside connections to the backend server if you bind tightly to address 127.0.0.1 (localhost), as you will see in the following configuration example.
This is the frontend (light) server configuration:
<VirtualHost 10.10.10.10> ServerName www.example.com ServerAlias example.com RewriteEngine On RewriteOptions 'inherit' RewriteRule \.(gif|jpg|png|txt|html)$ - [last] RewriteRule ^/(.*)$ http://localhost:4077/$1 [proxy] </VirtualHost> <VirtualHost 10.10.10.10> ServerName foo.example.com RewriteEngine On RewriteOptions 'inherit' RewriteRule \.(gif|jpg|png|txt|html)$ - [last] RewriteRule ^/(.*)$ http://localhost:4078/$1 [proxy] </VirtualHost>
This frontend configuration handles two virtual hosts: www.example.com and foo.example.com. The two setups are almost identical.
The frontend server will handle files with the extensions .gif, .jpg, .png, .txt, and .html internally; the rest will be proxied to be handled by the backend server.
The only difference between the two virtual-host settings is that the former rewrites requests to port 4077 at the backend machine and the latter to port 4078.
If your server is configured to run traditional CGI scripts (under
mod_cgi), as well as
mod_perl CGI programs, then it would be
beneficial to configure the frontend server to run the traditional
CGI scripts directly. This can be done by altering the
gif|jpg|png|txt Rewrite
rule to add
|cgi
at the end if all your
mod_cgi scripts have the .cgi extension, or by
adding a new rule to handle all /cgi-bin/*
locations locally.
Here is the backend (heavy) server configuration:
Port 80 PerlPostReadRequestHandler My::ProxyRemoteAddr Listen 4077 <VirtualHost localhost:4077> ServerName www.example.com DocumentRoot /home/httpd/docs/www.example.com DirectoryIndex index.shtml index.html </VirtualHost> Listen 4078 <VirtualHost localhost:4078> ServerName foo.example.com DocumentRoot /home/httpd/docs/foo.example.com DirectoryIndex index.shtml index.html </VirtualHost>
The backend server knows to tell to which virtual host the request is made, by checking the port number to which the request was proxied and using the appropriate virtual host section to handle it.
We set Port 80
so that any redirects use 80 as the
port for the URL, rather than the port on which the backend server is
actually running.
To get the real remote IP addresses from proxy,
My::ProxyRemoteAddr
handler is used based on the
mod_proxy_add_forward Apache module. Prior to
mod_perl 1.22, this setting must have been set
per-virtual host, since it wasn’t inherited by the
virtual hosts.
The following configuration is yet another useful example showing the other way around. It specifies what is to be proxied, and then the rest is served by the frontend:
RewriteEngine on RewriteLogLevel 0 RewriteRule ^/(perl.*)$ http://127.0.0.1:8052/$1 [P,L] NoCache * ProxyPassReverse / http://www.example.com/
So we don’t have to specify the rule for static objects to be served by the frontend, as we did in the previous example, to handle files with the extensions .gif, .jpg, .png and .txt internally.