Any::Daemon::HTTP::VirtualHost - webserver virtual hosts
my $vhost = Any::Daemon::HTTP::VirtualHost->new ( directories => ... , rewrite => ... , handlers => ... ); my $daemon = Any::Daemon::HTTP->new ( @other_options , vhosts => $vhost # or \@vhosts ); # or my $daemon = Any::Daemon::HTTP->new(@other_opts); $daemon->addVirtualHost($vhost); $daemon->addVirtualHost(@vhost2_opts); # create object which extends Any::Daemon::HTTP::VirtualHost my $myvhost = MyVHost->new(...); $daemon->addVirtualHost($myvhost);
These virtual host (vhost) configuration are used by Any::Daemon::HTTP, to implement (server) name based data separation. Its features resemble those of Apache virtual hosts.
Each vhost usually has two Any::Daemon::HTTP::Directory slaves: one which describes the permissions for user directories (url paths in the form /~user/ ), the other for data outside the user space.
/~user/
You may avoid the creation of extension classes for each virtual host, by using these options.
-Option --Default aliases 'AUTO' directories <see text> directory undef documents <undef> handler undef handlers {} name <required> proxies undef proxy undef redirect <undef> rewrite <undef> user_dirs undef
[0.26] Alternative host components which indicate the same virtual host. When 'AUTO' is given (the default since [0.28]), then generateAliases() is used to produce a convenient list.
Pass one or more Any::Daemon::HTTP::Directory OBJECTS, or HASHes which will be used to initialize them.
[0.28] Alias for directories.
directories
An absolute DIRECTORY for the location of the source files. Creates the most free Any::Daemon::HTTP::Directory object. If you need things like access restrictions, then do not use this option but the directories option.
Alias for handlers.
handlers
The keys are path names, part of the request URIs. The values are CODE-references, called when that URI is addressed. The access rules are taken from the directory definition which is selected by the path. Read "DETAILS" for the details.
Pass one or more Any::Daemon::HTTP::Proxy OBJECTS, or HASHes which will be used to initialize them.
[0.28] Alias for proxies.
proxies
[0.21] Automatically redirect the browser to some other url, maybe to an other host. Configuration like for rewrite.
rewrite
When a request arrives, the URI can be rewritten to become an other request. See "URI Rewrite".
[0.21] When a METHOD name is specified, that will be called on the virtual host object. An HASH as parameter is interpreted as a simple lookup table.
With an (empty?) HASH which contains instantiation parameter, an Any::Daemon::HTTP::UserDirs is created for you, with standard Apache behavior. You may provide your own OBJECT. Without this parameter, there are no public user pages.
Returns a list of all aliases (alternative names) for this server.
Returns the primary name for this server.
Handlers are called to dynamically generate responses, for instance to fill-in templates. The "DETAILS" section below explains how handlers work.
When only CODE is given, then this will be the default handler for all paths (under '/', top). [0.21] CODE may also be a $method name.
Usually, you pass some PAIRS or a HASH, relating PATH names inside the virtual host into function references or method names to be used for that tree.
example:
$vhost->addHandler('/' => \&default_handler , '/upload' => \&upload_handler); $vhost->addHandler(\&default_handler); # [0.21] will call $vhost->formHandle $vhost->addHandler('/form' => 'formHandler');
Alias for addHandler().
Find the handler which matches the given $uri best. The $uri is the rewritten URI of the request, an URI object. It's $path is sufficient, may also be broken into path @segments already.
The $source objects extend Any::Daemon::HTTP::Source, for instance a ::Directory or a ::Proxy. You can find them back via sourceFor().
::Directory
::Proxy
[0.21] Returns an HTTP::Response object if the $uri needs to be redirected, according to the vhost configuration.
[0.21] Returns an HTTP::Response object of the $uri.
Returns an $uri object as result, which may be the original in case of no rewrite was needed. See "URI Rewrite".
Either pass a Any::Daemon::HTTP::Directory $object or the %options to create the object. When %options are provided, they are passed to Any::Daemon::HTTP::Directory::new() to create the $object.
Translate the $uri into a filename, without checking for existence. Returns undef is not possible.
undef
Find the best matching Any::Daemon::HTTP::Source object, which might be a ::UserDirs, a ::Directory, or a ::Proxy.
::UserDirs
Either pass a Any::Daemon::HTTP::Proxy $object or the %options to create the object. When %options are provided, they are passed to Any::Daemon::HTTP::Proxy::new() to create the $object.
Handlers are called to dynamically generate responses, for instance to fill-in templates. In other frameworks, they are called 'routes' or 'get'.
When a request for an URI is received, it is first checked whether a static file can fulfil the request. If not, a search is started for the handler with the longest path.
# /upload($|/*) goes to the upload_handler $vhost->addHandlers ( '/' => \&default_handler , '/upload' => \&upload_handler ); # Missing files go to the default_handler # which is actually replacing the existing one $vhost->addHandler(\&default_handler); # [0.21] This will call $vhost->formHandle(...), especially # useful in your virtual host sub-class. $vhost->addHandler('/form' => 'formHandler');
The handlers are called with many arguments, and should return an HTTP::Response object:
$vhost->addHandler('/upload' => $handler); my $resp = $hander->($vhost, $session, $req, $uri, $tree); $vhost->addHandler('/form' => $method); my $resp = $vhost->$method($session, $req, $uri, $tree);
In which
$vhost is an Any::Daemon::HTTP::VirtualHost,
$vhost
Any::Daemon::HTTP::VirtualHost
$session is an Any::Daemon::HTTP::Session,
$session
$req is an HTTP::Request,
$req
$uri an URI after rewrite rules, and
$uri
$tree the selected Any::Daemon::HTTP::Directory.
$tree
Any::Daemon::HTTP::Directory
The handler could work like this:
sub formHandler($$$$) { my ($vhost, $session, $req, $uri, $tree) = @_; # in OO extended vhosts, then $vhost => $self # Decode path parameters in Plack style # ignore two components: '/' and 'form' from the path my (undef, undef, $name, @more) = $uri->path_segments; HTTP::Response->new(HTTP_OK, ...); }
When your virtual host has larger configuration or many handlers --or when you like clean programming--, it may be a good choice to put your code in a separate package with the normal Object Oriented extension mechanism.
You may need to implement your own information persistence via databases or configation files. For that, extend Any::Daemon::HTTP::Session.
. Example: own virtual host
package My::Service; use parent 'Any::Daemon::HTTP::VirtualHost'; sub init($) { my ($self, $args) = @_; $args->{session_class} = 'My::Service::Session'; $self->SUPER::init($args); $self->addDirectory(...); $self->addHandler(a => 'ah'); ... etc ... $self; } sub ah($$$$) { my ($self, $session, $request, $uri, $tree) = @_; return HTTP::Response->new(...); } package My::Service::Session; use parent 'Any::Daemon::HTTP::Session';
For each request, the rewrite() method is called to see whether a rewrite of the URI is required. The method must return the original URI object (the only parameter) or a new URI object.
. Example: usage
my $vhost = Any::Daemon::HTTP::VirtualHost ->new(..., rewrite => \&rewrite); my $vhost = My::Service # see above ->new(..., rewrite => 'rewrite'); my $vhost = My::Service # see above ->new(..., rewrite => \%lookup_table);
. Example: rewrite URI
my %lookup = ( '/' => '/index-en.html' , '/news' => '/news/2013/index.html' ); sub rewrite($) { my ($vhost, $uri) = @_; # when called as method, $vhost --> $self # with lookup table $uri = URI->new_abs($lookup{$uri->path}, $uri) if exists $lookup{$uri->path}; # whole directory trees $uri = URI->new_abs('/somewhere/else'.$1, $uri) if $uri->path =~ m!^/some/dir(/.*|$)!; $uri; }
Connecting this server to the popular Template Toolkit web-page framework is quite simple:
# Use TT only for pages under /status $vhost->addHandler('/status' => 'ttStatus'); sub ttStatus($$$$) { my ($self, $session, $request, $uri, $tree) = @_;; # Often, this object is global or an attribute my $template = Template->new(...); my $output; my $values = {...}; # collect the values $template->process($fn, $values, \$output) or die $template->error, "\n"; HTTP::Response->new(HTTP_OK, undef , ['Content-Type' => 'text/html'] , "$output" ); }
See Log::Report::Template if you need translations as well.
This module is part of Any-Daemon-HTTP distribution version 0.30, built on April 06, 2020. Website: http://perl.overmeer.net/any-daemon/
Copyrights 2013-2020 by [Mark Overmeer]. For other contributors see ChangeLog.
This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself. See http://dev.perl.org/licenses/
To install Any::Daemon::HTTP, copy and paste the appropriate command in to your terminal.
cpanm
cpanm Any::Daemon::HTTP
CPAN shell
perl -MCPAN -e shell install Any::Daemon::HTTP
For more information on module installation, please visit the detailed CPAN module installation guide.