diff --git a/data/System/VirtualHostingContrib.txt b/data/System/VirtualHostingContrib.txt index 1badac7..1a522a8 100644 --- a/data/System/VirtualHostingContrib.txt +++ b/data/System/VirtualHostingContrib.txt @@ -15,7 +15,7 @@ prefer. ---++ Overview -VirtualHostingContrib provides the ability of using a single Foswiki +!VirtualHostingContrib provides the ability of using a single Foswiki installation to serve differents sets of webs under different host names. Such different hostnames by which users access different content are known as _virtual hosts_. @@ -31,7 +31,7 @@ Foswiki systems without having a linear increase in maintainance effort. ---++ Configuration -VirtualHostingContrib works by providing an alternative entry point to the +!VirtualHostingContrib works by providing an alternative entry point to the classic Foswiki scripts interface. To use it, you need to configure your webserver so that requests to e.g. =/foswiki/bin/view= are actually handled by the =/foswiki/bin/virtualhosts= CGI script. Such script will play the role of @@ -46,11 +46,11 @@ TODO TODO ----+++ Using FastCGI +---+++ Using FastCGI The =virtualhosts= script is a regular CGI script, and as such it may exhibit poor performance in sites with low computing power or high usage, just like -regular Foswiki. VirtualHostingContrib provides a !FastCGI version of the +regular Foswiki. !VirtualHostingContrib provides a !FastCGI version of the script. To use it: @@ -59,7 +59,7 @@ To use it: installed and properly working on your system. 1 In your web server configuration, replace the references to the =foswiki.fcgi= script provided by !FastCGIEngineContrib with - =virtualhosts.fcgi= provided by VirtualHostingContrib. + =virtualhosts.fcgi= provided by !VirtualHostingContrib. 1 Reload your web server configuration to apply the changes. ---++ Virtual hosts management @@ -140,8 +140,8 @@ $Foswiki::cfg{AuthScripts} .= ',view'; %RED% *Warning:* %ENDCOLOR% just like Foswiki's global configuration file =LocalSite.cfg=, virtual host configuration files are executed as Perl code. -%So the system administrator must be completely sure of what to put in that -%configuration file. +So the system administrator must be completely sure of what to put in that +configuration file. ---+++ Creating/removing/renaming virtual hosts @@ -173,7 +173,7 @@ created later. If you have a text file called =_template.conf= in your virtual hosts directory, when you create a virtual host for example.com you'll also get a =example.com.conf= file which is just equal to the =_template.conf= file, -except that all occurrences of =%VIRTUALHOST%= will be replaced by the +except that all occurrences of =%VIRTUALHOST%= will be replaced by the virtual host name (=example.com= in this example). __Note__ that !VirtualHostingContrib does not care about the contents of the file, it just takes the content of =_template.conf=, replaces all occurrences of @@ -190,13 +190,63 @@ the case, change the configuration files accordingly. Beware that after renaming a virtual host its data will _no longer_ be available at the old domain name. +*To create an alias name for a virtual host*, add a name mapping to the +=ServeraAlias= hash of your global configuration in =LocalSite.cfg=. For +instance use the following to access the =example.com= domain using the +a different network interface as well: + + +$Foswiki::cfg{VirtualHostingContrib}{ServerAlias} = { + '127.0.0.1' => 'example.com', + + +Note that you also need to configure your http server to listen to +the alias name to make use of this feature. + +%RED% *Warning:* %ENDCOLOR% in most cases where both domains, the canonical domain +and the alias one, are reachable on the same network interface it is preferable +to use a http redirect from one domain to the other instead of creating another +domain that basically serves the same content. Also, SSL certificates appear to +be invalid when served from the wrong domain. Don't use server aliases for in +that case. + +Using a server alias does make sense when the same domain isn't +reachable on a second network interface from where you'll only be able to +reach the server using the alias name. This might also be the case when +maintaining the site on a different server offline and syncing content later on +to the machine that is able to serve the canonical domain. + ---+++ Running command line tools against the virtual hosts -TODO +!VirtualHostingContrib comes with a set of tools to run specific tasks on the +commandline, such as + + * virtualhosts-mailnotify: a vhost-aware replacement for the standard mailnotify + script used in cronjobs to send out mail notifications + * virtualhosts-rest: call a rest handler for a specific virtual host on the commandline + * virtualhosts-tick-foswiki: a vhost-aware replacement for the standard tick-foswiki + maintenance script used in cronjobs + * virtualhost-view: render a page of a virtual host on the commandline + +These scripts are located in the =tools/= subdirectory of your Foswiki installation +and can be called from the commandline. They all understand the usual parameters +that their non-vhost-aware counterparts have. In addition, they all take an +optional =host= parameter that lets you specify on which virtual host to run +the command. When no host parameter is specified, the command will be run on +all known virtual hosts known. + +For example, to run a REST handler =check= implemented by a !MyNewPlugin extension, use + + +cd tools +./virtualhosts-rest host=example.com /MyNewPlugin/check topic=Main.WebHome option=foo + + +(TODO: virtualhosts-mailnotify doe not yet understand =host=). ---++ How it works -This section describes the internals of VirtualHostingContrib, and is intended +This section describes the internals of !VirtualHostingContrib, and is intended for developers and system administrators. If it's not your case, please feel free to skip it. @@ -304,11 +354,11 @@ installed in your system). ---+++ Wrapping it up -What VirtualHostingContrib does is to wrap the Foswiki::UI::handleRequest so +What !VirtualHostingContrib does is to wrap the Foswiki::UI::handleRequest so that the configuration is tweaked just before actually handling the request, using the approach described above. The two extra CGI scripts provided are equal to the ones in Foswiki core and !FastCGIEngineContrib, but after loading -Foswiki::UI, they load the VirtualHostingContrib module that does the wrapping +Foswiki::UI, they load the !VirtualHostingContrib module that does the wrapping around Foswiki::UI::handleRequest. ---++ Info for developers @@ -429,12 +479,13 @@ Many thanks to [[http://colivre.coop.br/][Colivre]] for supporting this work. | Release: | %$RELEASE% | | Version: | %$VERSION% | | Change History: |   | +| 04 Jul 2012: | added foswiki maintenance tools for virtual hosting; -- Foswiki:Main/MichaelDaum | | 20 Aug 2011: | added server aliases; fixed interfacing new logger api; added =run_on()= api; -- Foswiki:Main/MichaelDaum | | 02 Nov 2010(2): | code cleanup and performance optimization -- Foswiki:Main/AntonioTerceiro | | 02 Nov 2010: | added support for listening on non-standard ports; performance optimization -- Foswiki:Main/AntonioTerceiro | | 16 Jul 2010: | first release ([[Foswiki:Main/AntonioTerceiro][Antonio Terceiro]]) | | Dependencies: | %$DEPENDENCIES% | -| Home page: | http://foswiki.org/bin/view/Extensions/VirtualHostingContrib | -| Support: | http://foswiki.org/bin/view/Support/VirtualHostingContrib | +| Home page: | Foswiki:Extensions/VirtualHostingContrib | +| Support: | Foswiki:Support/VirtualHostingContrib | diff --git a/lib/Foswiki/Contrib/VirtualHostingContrib.pm b/lib/Foswiki/Contrib/VirtualHostingContrib.pm index da19941..48f3371 100644 --- a/lib/Foswiki/Contrib/VirtualHostingContrib.pm +++ b/lib/Foswiki/Contrib/VirtualHostingContrib.pm @@ -31,7 +31,7 @@ our $VERSION = '$Rev$'; # version of *this file*. # date - a date in 1 Jun 2009 format. Three letter English month names only. # Note: it's important that this string is exactly the same in the extension # topic - if you use %$RELEASE% with BuildContrib this is done automatically. -our $RELEASE = '0.4.0'; +our $RELEASE = '1.0.0'; our $SHORTDESCRIPTION = 'Adds virtual hosting support for Foswiki.'; diff --git a/lib/Foswiki/Contrib/VirtualHostingContrib/MANIFEST b/lib/Foswiki/Contrib/VirtualHostingContrib/MANIFEST index 8c6dbf6..ee8239f 100644 --- a/lib/Foswiki/Contrib/VirtualHostingContrib/MANIFEST +++ b/lib/Foswiki/Contrib/VirtualHostingContrib/MANIFEST @@ -10,4 +10,7 @@ bin/virtualhosts.fcgi 0755 FastCGI script tools/virtualhosts-lighttpd.pl 0755 Development server script tools/virtualhosts-create.sh 0755 Utility script tools/virtualhosts-mailnotify 0755 Utility script +tools/virtualhosts-rest 0755 Utility script +tools/virtualhosts-tick-foswiki 0755 Utility script +tools/virtualhosts-view 0755 Utility script pub/System/VirtualHostingContrib/logo-colivre.png 0644 Sponsor logo diff --git a/lib/Foswiki/Contrib/VirtualHostingContrib/VirtualHost.pm b/lib/Foswiki/Contrib/VirtualHostingContrib/VirtualHost.pm index 95cf176..cd004b8 100644 --- a/lib/Foswiki/Contrib/VirtualHostingContrib/VirtualHost.pm +++ b/lib/Foswiki/Contrib/VirtualHostingContrib/VirtualHost.pm @@ -47,7 +47,6 @@ sub find { }, Cache => { RootDir => $WorkingDir."/cache", - DBFile => $WorkingDir."/cache/foswiki_db", }, RCS => { WorkAreaDir => "$WorkingDir/work_areas", @@ -114,14 +113,10 @@ sub run_on_each { sub run_on { my ($class, $hostname, $code) = @_; - my %hostnames = - map { $_ => 1 } - grep { $class->exists($_) && $_ ne '_template' } - map { basename $_} glob($Foswiki::cfg{VirtualHostingContrib}{VirtualHostsDir} . '/*'); + my $virtual_host = $class->find($hostname); - die "ERROR: unknown virtual host $hostname" unless defined $hostnames{$hostname}; + die "ERROR: unknown virtual host $hostname" unless defined $virtual_host; - my $virtual_host = $class->find($hostname); $virtual_host->run($code); } diff --git a/test/unit/VirtualHostingContrib/VirtualHostTests.pm b/test/unit/VirtualHostingContrib/VirtualHostTests.pm index 1478ff7..eda4721 100644 --- a/test/unit/VirtualHostingContrib/VirtualHostTests.pm +++ b/test/unit/VirtualHostingContrib/VirtualHostTests.pm @@ -1,6 +1,7 @@ package VirtualHostTests; use strict; +use Error qw(:try); use Foswiki::Contrib::VirtualHostingContrib::VirtualHost; our $ROOT = '/tmp/foswiki-virtualhosts'; @@ -212,6 +213,49 @@ sub test_run_on_each { $this->assert_deep_equals(\@expected, \@list, 'must run a block inside each virtual host') } +sub test_run_on { + my $this = shift; + create_vhost('example.com'); + my @list = (); + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on('example.com', sub { + push @list, $Foswiki::cfg{DataDir}; + } + ); + @list = sort @list; + my @expected = ("$ROOT/example.com/data"); + $this->assert_deep_equals(\@expected, \@list, 'must run a block inside a virtual host') +} + +sub test_run_on_alias { + my $this = shift; + + create_vhost('example.com'); + $Foswiki::cfg{VirtualHostingContrib}{ServerAlias}{'example'} = 'example.com'; + + my @list = (); + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on('example', sub { + push @list, $Foswiki::cfg{DataDir}; + } + ); + + my $error; + try { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on('unknown', sub { + push @list, $Foswiki::cfg{DataDir}; + } + ); + } catch Error::Simple with { + $error = shift; + }; + + $this->assert(defined($error)); + + @list = sort @list; + my @expected = ("$ROOT/example.com/data"); + $this->assert_deep_equals(\@expected, \@list, 'must run a block inside a virtual host') +} + + sub test_run_on_each_ignores_template { my $this = shift; create_vhost('_template'); diff --git a/tools/virtualhosts-rest b/tools/virtualhosts-rest new file mode 100755 index 0000000..7475cff --- /dev/null +++ b/tools/virtualhosts-rest @@ -0,0 +1,72 @@ +#!/usr/bin/perl -wT +# See bottom of file for license and copyright information +use strict; +use warnings; + +BEGIN { + $Foswiki::cfg{Engine} = 'Foswiki::Engine::CLI'; + require Carp; + $SIG{__DIE__} = \&Carp::confess; + if (-e './setlib.cfg') { + unshift @INC, '.'; + } elsif (-e '../bin/setlib.cfg') { + unshift @INC, '../bin'; + } + require 'setlib.cfg'; + $ENV{FOSWIKI_ACTION} = 'rest'; +} + +use Foswiki (); +use Foswiki::UI (); +use Foswiki::Contrib::VirtualHostingContrib::VirtualHost (); + +my $verbose = 1; +my $hostname = ''; + +foreach my $arg (@ARGV) { + if ($arg =~ /^(.*)=(.*)$/) { + if ($1 eq 'verbose') { + $verbose = ($2 eq 'on')?1:0; + } elsif ($1 eq 'host') { + $hostname = $2; + } + } +} + +if ($hostname) { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on($hostname, \&doit); +} else { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on_each(\&doit); +} + +sub doit { + printf("=> Processing %s\n", $Foswiki::Contrib::VirtualHostingContrib::VirtualHost::CURRENT) if $verbose; + $Foswiki::engine->run(); +} + +__END__ +Foswiki - The Free and Open Source Wiki, http://foswiki.org/ + +Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors +are listed in the AUTHORS file in the root of this distribution. +NOTE: Please extend that file, not this notice. + +Additional copyrights apply to some or all of the code in this +file as follows: + +Copyright (C) 1999-2007 Peter Thoeny, peter@thoeny.org +and TWiki Contributors. All Rights Reserved. TWiki Contributors +are listed in the AUTHORS file in the root of this distribution. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. For +more details read LICENSE in the root of this distribution. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +As per the GPL, removal of this notice is prohibited. + diff --git a/tools/virtualhosts-tick-foswiki b/tools/virtualhosts-tick-foswiki new file mode 100755 index 0000000..22e9bdd --- /dev/null +++ b/tools/virtualhosts-tick-foswiki @@ -0,0 +1,84 @@ +#!/usr/bin/perl -w +# See bottom of file for license and copyright information +# +# The Foswiki 'bin' directory must be on your include path when you run +# this script. This is so it can pick up the right environment +# from setlib.cfg. +# You can add a directory to your include path using the -I option +# to the perl command e.g. perl -I /usr/local/foswiki/bin tick_foswiki.pl +# +# It executes a number of non-essential regular administration +# tasks that will help keep your Foswiki healthy and happy. +# +# It is intended to be run as a cron job (remember it has to be run +# by a user who can write files created by the webserver user!) +# For example, +# +# 0 0 * * * (cd /usr/foswiki/bin && ./tools/virtualhost-tick-foswiki) +# +use strict; +use warnings; + +BEGIN { + $Foswiki::cfg{Engine} = 'Foswiki::Engine::CLI'; + if ( -e './setlib.cfg' ) { + unshift @INC, '.'; + } + elsif ( -e '../bin/setlib.cfg' ) { + unshift @INC, '../bin'; + } # otherwise rely on the user-set path + require 'setlib.cfg'; +} + +use Foswiki (); +use Foswiki::LoginManager (); +use Foswiki::Request::Cache (); +use Foswiki::Meta (); +use Foswiki::Contrib::VirtualHostingContrib::VirtualHost (); + +my $verbose = 0; +my $hostname = ''; + +foreach my $arg (@ARGV) { + if ($arg =~ /^(.*)=(.*)$/) { + if ($1 eq 'verbose') { + $verbose = ($2 eq 'on')?1:0; + } elsif ($1 eq 'host') { + $hostname = $2; + } + } +} + +if ($hostname) { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on($hostname, \&doit); +} else { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on_each(\&doit); +} + +sub doit { + printf("=> Processing %s\n", $Foswiki::Contrib::VirtualHostingContrib::VirtualHost::CURRENT) if $verbose; + Foswiki::LoginManager::expireDeadSessions(); + Foswiki::Request::Cache::cleanup(); + my $root = new Foswiki::Meta( new Foswiki() ); + $root->onTick( time() ); +} + +__END__ +Foswiki - The Free and Open Source Wiki, http://foswiki.org/ + +Copyright (C) 2009-2012 Foswiki Contributors. Foswiki Contributors +are listed in the AUTHORS file in the root of this distribution. +NOTE: Please extend that file, not this notice. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. For +more details read LICENSE in the root of this distribution. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +As per the GPL, removal of this notice is prohibited. + diff --git a/tools/virtualhosts-view b/tools/virtualhosts-view new file mode 100755 index 0000000..2719da8 --- /dev/null +++ b/tools/virtualhosts-view @@ -0,0 +1,72 @@ +#!/usr/bin/perl -wT +# See bottom of file for license and copyright information +use strict; +use warnings; + +BEGIN { + $Foswiki::cfg{Engine} = 'Foswiki::Engine::CLI'; + require Carp; + $SIG{__DIE__} = \&Carp::confess; + if (-e './setlib.cfg') { + unshift @INC, '.'; + } elsif (-e '../bin/setlib.cfg') { + unshift @INC, '../bin'; + } + require 'setlib.cfg'; + $ENV{FOSWIKI_ACTION} = 'view'; +} + +use Foswiki (); +use Foswiki::UI (); +use Foswiki::Contrib::VirtualHostingContrib::VirtualHost (); + +my $verbose = 1; +my $hostname = ''; + +foreach my $arg (@ARGV) { + if ($arg =~ /^(.*)=(.*)$/) { + if ($1 eq 'verbose') { + $verbose = ($2 eq 'on')?1:0; + } elsif ($1 eq 'host') { + $hostname = $2; + } + } +} + +if ($hostname) { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on($hostname, \&doit); +} else { + Foswiki::Contrib::VirtualHostingContrib::VirtualHost->run_on_each(\&doit); +} + +sub doit { + printf("=> Processing %s\n", $Foswiki::Contrib::VirtualHostingContrib::VirtualHost::CURRENT) if $verbose; + $Foswiki::engine->run(); +} + +__END__ +Foswiki - The Free and Open Source Wiki, http://foswiki.org/ + +Copyright (C) 2008-2010 Foswiki Contributors. Foswiki Contributors +are listed in the AUTHORS file in the root of this distribution. +NOTE: Please extend that file, not this notice. + +Additional copyrights apply to some or all of the code in this +file as follows: + +Copyright (C) 1999-2007 Peter Thoeny, peter@thoeny.org +and TWiki Contributors. All Rights Reserved. TWiki Contributors +are listed in the AUTHORS file in the root of this distribution. + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. For +more details read LICENSE in the root of this distribution. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + +As per the GPL, removal of this notice is prohibited. +