=encoding utf8
=head1 NAME
Any::Daemon::HTTP::VirtualHost - webserver virtual hosts
=head1 SYNOPSIS
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);
=head1 DESCRIPTION
These virtual host definitions are used by L<Any::Daemon::HTTP|Any::Daemon::HTTP>, to
implement (server) name based data seperation. Its features resemble those
of Apache virtual hosts.
Each virtual host usually has to L<Any::Daemon::HTTP::Directory|Any::Daemon::HTTP::Directory> slaves: one
which describes the permissions for user directories (url paths in the
form C< /~user/ >) and one for data outside the user space.
=head1 METHODS
=head2 Constructors
You may avoid the creation of extension classes for each virtual host,
by using these options.
=over 4
=item Any::Daemon::HTTP::VirtualHost-E<gt>B<new>(OPTIONS|HASH-of-OPTIONS)
-Option --Default
aliases []
directories <see text>
documents <undef>
handlers {}
name <required>
redirect <undef>
rewrite <undef>
user_dirs undef
=over 2
=item aliases => HOSTNAME|ARRAY-of-HOSTNAMES
=item directories => OBJECT|HASH|ARRAY
Pass one or more L<Any::Daemon::HTTP::Directory|Any::Daemon::HTTP::Directory> OBJECTS, or HASHes which will
be used to initialize them.
=item documents => DIRECTORY
An absolute DIRECTORY for the location of the source files. Creates the
most free L<Any::Daemon::HTTP::Directory|Any::Daemon::HTTP::Directory> object. If you need things like
access restrictions, then do not use this option but the C<directories>
option.
=item handlers => CODE|HASH
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 L</DETAILS> for the details.
=item name => HOSTNAME
=item redirect => CODE|METHOD|HASH
[0.21] Automatically redirect the browser to some other url, maybe to
an other host. Configuration like for C<rewrite>.
=item rewrite => CODE|METHOD|HASH
When a request arrives, the URI can be rewritten to become an other
request. See L</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.
=item user_dirs => undef|OBJECT|HASH
With an (empty?) HASH which contains instantiation parameter, an
L<Any::Daemon::HTTP::UserDirs|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.
=back
=back
=head2 Attributes
=over 4
=item $obj-E<gt>B<aliases>()
Returns a list of all aliases (alternative names) for this server.
=item $obj-E<gt>B<name>()
Returns the primary name for this server.
=back
=head2 Handler
=over 4
=item $obj-E<gt>B<addHandler>(CODE|(PATH => CODE)-LIST|HASH)
Handlers are called to dynamically generate responses, for instance
to fill-in templates. The L</DETAILS> section below explains how
handlers work.
When only CODE is given, then this will be the default handler for all
paths (under '/', top). You may also pass a list or HASH of PAIRS.
[0.21] CODE may also be a method name.
example:
$vhost->addHandler('/' => \&default_handler,
'/upload' => \&upload_handler);
$vhost->addHandler(\&default_handler);
# [0.21] will call $vhost->formHandle
$vhost->addHandler('/form' => 'formHandler');
=item $obj-E<gt>B<addHandlers>(PARAMS)
Same as L<addHandler()|Any::Daemon::HTTP::VirtualHost/"Handler">.
=item $obj-E<gt>B<findHandler>(URI|PATH|PATH-SEGMENTS)
=back
=head2 Access permissions
=over 4
=item $obj-E<gt>B<handleRequest>(SERVER, SESSION, REQUEST, [URI])
=back
=head2 Basic daemon actions
=over 4
=item $obj-E<gt>B<mustRedirect>(URI)
[0.21] Returns an HTTP::Response object if the URI needs to be
redirected, according to the vhost configuration.
=item $obj-E<gt>B<redirect>(URI, [HTTP_CODE])
[0.21] Returns an HTTP::Response object of the URI.
=item $obj-E<gt>B<rewrite>(URI)
Returns an URI object as result, which may be the original in case of
no rewrite was needed. See L</URI Rewrite>.
=back
=head2 Directories
=over 4
=item $obj-E<gt>B<addDirectory>(OBJECT|HASH|OPTIONS)
Either pass a L<Any::Daemon::HTTP::Directory|Any::Daemon::HTTP::Directory> OBJECT or the OPTIONS to
create the object. When OPTIONS are provided, they are passed to
L<Any::Daemon::HTTP::Directory::new()|Any::Daemon::HTTP::Directory/"Constructors"> to create the OBJECT.
=item $obj-E<gt>B<directoryOf>(PATH|PATH_SEGMENTS)
Find the best matching L<Any::Daemon::HTTP::Directory|Any::Daemon::HTTP::Directory> object.
=item $obj-E<gt>B<filename>(URI)
Translate the URI into a filename, without checking for existence. Returns
C<undef> is not possible.
=back
=head1 DETAILS
=head2 Handlers
Handlers are called to dynamically generate responses, for instance
to fill-in templates.
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->addHandler
( '/' => \&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
=over 4
=item * C<$vhost> is an C<Any::Daemon::HTTP::VirtualHost>,
=item * C<$session> is an L<Any::Daemon::HTTP::Session|Any::Daemon::HTTP::Session>,
=item * C<$req> is an HTTP::Request,
=item * C<$uri> an URI after rewrite rules, and
=item * C<$tree> the selected C<Any::Daemon::HTTP::Directory>.
=back
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, ...);
}
=head2 Your virtual host as class
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 L<Any::Daemon::HTTP::Session|Any::Daemon::HTTP::Session>.
=head2 URI Rewrite
For each request, the L<rewrite()|Any::Daemon::HTTP::VirtualHost/"Basic daemon actions"> 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.
=head2 Using Template::Toolkit
Connecting this server with TT is quite simple:
# Use TT only for pages under /status
$vhost->addHandler('/status' => 'ttStatus');
sub ttStatus($$$$)
{ my ($self, $session, $request, $uri, $tree) = @_;;
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"
);
}
=head1 SEE ALSO
This module is part of Any-Daemon-HTTP distribution version 0.22,
built on October 28, 2013. Website: F<http://perl.overmeer.net/any-daemon/>
=head1 LICENSE
Copyrights 2013 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 F<http://www.perl.com/perl/misc/Artistic.html>