blob: ae83e241355914ba50ab2d48cdb7a271084a24f4 [file] [log] [blame]
package Apache::RegistryLoader;
use 5.003_97;
use mod_perl 1.01;
use strict;
use Apache::Registry ();
use Apache::Constants qw(OPT_EXECCGI);
@Apache::RegistryLoader::ISA = qw(Apache::Registry);
$Apache::RegistryLoader::VERSION = '1.91';
sub new {
my $class = shift;
bless {@_} => $class;
}
sub handler {
my($self, $uri, $filename, $virthost) = @_;
Apache::warn(__PACKAGE__.qq{ failed, reason: uri is a required parameter}),
return
unless defined $uri and $uri;
if ($filename) {
Apache::warn(__PACKAGE__.qq{: Cannot find a filename [$filename]}),
return
unless -e $filename;
} else {
# try to translate URI->filename
if (my $func = $self->{trans}) {
no strict 'refs';
$filename = &{$func}($uri);
Apache::warn(__PACKAGE__.
qq{: Translation of uri [$uri] to filename failed [tried: $filename]}),
return
unless -e $filename;
} else {
# try to guess
(my $guess = $uri) =~ s,^/,,;
$filename = Apache->server_root_relative($guess);
Apache::warn(__PACKAGE__.
qq{: No 'trans' sub was passed: tried to guess the filename [tried: $filename], but failed, for uri [$uri]}),
return
unless -e $filename;
}
}
# warn "*** RegistryLoader: uri=$uri, filename=$filename\n";
my $r = bless {
uri => $uri,
filename => $filename,
} => ref($self) || $self;
$r->{virthost} = $virthost if defined $virthost;
$r->SUPER::handler;
}
#override Apache class methods called by Apache::Registry
#normally only available at request-time via blessed request_rec pointer
sub slurp_filename {
my $r = shift;
my $filename = $r->filename;
my $fh = Apache::gensym(__PACKAGE__);
open $fh, $filename;
local $/;
my $code = <$fh>;
return \$code;
}
sub get_server_name { shift->{virthost} }
sub filename { shift->{filename} }
sub uri { shift->{uri} }
sub status {200}
sub path_info {}
sub log_error { shift; die @_ if $@; warn @_; }
*log_reason = \&log_error;
sub allow_options { OPT_EXECCGI } #will be checked again at run-time
sub clear_rgy_endav {}
sub stash_rgy_endav {}
sub request {}
sub seqno {0}
sub server { shift }
sub is_virtual { exists shift->{virthost} }
sub header_out {""}
sub chdir_file {
my($r, $file) = @_;
$file ||= $r->filename;
Apache::chdir_file(undef, $file);
}
1;
__END__
=head1 NAME
Apache::RegistryLoader - Compile Apache::Registry scripts at server startup
=head1 SYNOPSIS
#in PerlScript
use Apache::RegistryLoader ();
my $r = Apache::RegistryLoader->new;
$r->handler($uri, $filename);
$r->handler($uri, $filename, $virtual_hostname);
=head1 DESCRIPTION
This modules allows compilation of B<Apache::Registry> scripts at
server startup. The script's handler routine is compiled by the
parent server, of which children get a copy. The
B<Apache::RegistryLoader> C<handler> method takes arguments of C<uri>
and the C<filename>. URI to filename translation normally doesn't
happen until HTTP request time, so we're forced to roll our own
translation.
If filename is omitted and a C<trans> routine was not
defined, the loader will try using the B<uri> relative to
B<ServerRoot>. Example:
#in httpd.conf
ServerRoot /opt/www/apache
Alias /perl/ /opt/www/apache/perl
#in PerlScript
use Apache::RegistryLoader ();
#/opt/www/apache/perl/test.pl
#is the script loaded from disk here:
Apache::RegistryLoader->new->handler("/perl/test.pl");
To make the loader smarter about the uri->filename translation, you may
provide the C<new> method with a C<trans> function to translate the
uri to filename.
The following example will pre-load all files ending with C<.pl> in the
B<perl-scripts/> directory relative to B<ServerRoot>.
The example code assumes the Location URI C</perl> is an B<Alias> to
this directory.
{
use Cwd ();
use Apache::RegistryLoader ();
use DirHandle ();
use strict;
my $dir = Apache->server_root_relative("perl-scripts/");
my $rl = Apache::RegistryLoader->new(trans => sub {
my $uri = shift;
$uri =~ s:^/perl/:/perl-scripts/:;
return Apache->server_root_relative($uri);
});
my $dh = DirHandle->new($dir) or die $!;
for my $file ($dh->read) {
next unless $file =~ /\.pl$/;
$rl->handler("/perl/$file");
}
}
=head1 AUTHORS
Doug MacEachern
Stas Bekman (Rewrote the handler() to report and handle all the possible
erroneous conditions)
=head1 SEE ALSO
Apache::Registry(3), Apache(3), mod_perl(3)