Tempo fa per un progetto ho avuto la necessità di sviluppare una soluzione che permettesse di gestire dinamicamente i virtual host di apache, facendo in modo che questo interrogasse (in seguito a una richiesta relativa a un particolare virtual host) un backend che restituisse la configurazione del virtualhost stesso (se presente e supportato) con tutte le caratteristiche necessarie: in pratica senza avere una configurazione statica per ciascun virtualhost (sarebbe stato impossibile essendo questi migliaia) ma una configurazione generata a runtime.
Girando in rete ho intrapreso la strada del mod_perl (mi piace il perl
) e devo dire che ho trovato questo modulo molto potente: permette di “registrarsi” a vari livelli nel processamento delle richieste da parte di apache e di intervenire in moltissimi aspetti di queste… Riguardo la mia necessità, ho registrato il mio script a livello di PerlTransHandler, ovvero in corrispondenza del livello in cui apache trasforma la richiesta nei valori da utilizzare (per esempio il path fisico) per servire le pagine
Dopo di che ho inserito il codice in conf.d/perl.conf (file di configurazione di mod_perl in apache)
<Perl>
package My::Trans;
use Apache2::Const -compile => qw(OK DECLINED);
use DBI;
use Data::Dumper;
use HTTP::Request;
use HTTP::Request::Common;
use LWP::UserAgent;
sub handler {
# Debug level: 0 no debug – 1 debug
my $debuglevel = 0;
# Path to root storage
my $rootvhost = ‘/var/www/vhostpath’;
# Backend host to query
my $backendservice = ‘http://192.168.2.111:8080′;
# Backend script to query
my $beScript = ‘/query.php’
my $r = shift;
my $url = $r->uri();
my $rlog = $r->log;
my $hostname = $r->hostname();
$debuglevel && $rlog->error(‘VirtualHost – Hostname requested ‘.$hostname);
my $ua = LWP::UserAgent->new;
$ua->timeout(10);
my $response = $ua->get($backendservice.$beScript.’?vhost=’.$hostname);
my $backendresponse = $response->as_string;
my $vpath = ”;
$backendresponse =~ /\<vpath\>(.*)\<\/vpath\>/ and $vpath = $1;
$debuglevel && $rlog->error(“VirtualHost – BackEnd Response “.$backendresponse);
if ($vpath ne ”) {
$debuglevel && $rlog->error(“VirtualHost – VPath “.$vpath);
$r->document_root($rootvhost.$vpath);
$r->subprocess_env(VHOST=>$hostname);
}
return Apache2::Const::DECLINED;
}
</Perl>
L’ultima direttiva return Apache2::Const::DECLINED; indica ad apache di continuare il processamento con le altre fasi del mod_perl e dei moduli.
Vi invito a leggere la documentazione di mod_perl per il resto degli aspetti tecnici e di configurazione del modulo.
Nota: per far in modo che apache accetti ogni virtualhost e risolva in nome in base al backend in httpd.conf la sezione virtual host va settata in questo modo
NameVirtualHost *:80
<VirtualHost *:80>
# don’t loose time with IP address lookups
HostnameLookups Off
# needed for named virtual hosts
UseCanonicalName Off
ServerAdmin admin@%0
ServerName %0
ErrorLog logs/virtual_server_error.log
CustomLog logs/virtual_server_access.log common
</VirtualHost>



