package Apache::PerlRunFilter; use strict; use Apache::PerlRun; use Apache::Constants qw(:common); use Symbol; use vars qw($Debug @ISA); @ISA = qw(Apache::PerlRun); sub readscript { my $pr = shift; my $fh = $pr->{'fh'}; local $/; return $pr->{'code'} = \(scalar <$fh>); } sub handler { my ($package, $r) = @_; ($package, $r) = (__PACKAGE__, $package) unless $r; my $pr = $package->new($r); my $rc = $pr->can_compile; return $rc unless $rc == OK; # Get a filehandle to the Perl code if (lc $r->dir_config('Filter') eq 'on') { $r = $r->filter_register; my ($fh, $status) = $r->filter_input(); return $status unless $status == OK; $pr->{'fh'} = $fh; } else { $pr->{'fh'} = gensym; open $pr->{'fh'}, $r->filename or die $!; } # After here is the same as PerlRun.pm... my $package = $pr->namespace; my $code = $pr->readscript; $pr->parse_cmdline($code); $pr->set_script_name; $pr->chdir_file; my $line = $pr->mark_line; my %orig_inc = %INC; my $eval = join '', 'package ', $package, ';use Apache qw(exit);', $line, $$code, "\n"; $rc = $pr->compile(\$eval); $pr->chdir_file("$Apache::Server::CWD/"); #in case .pl files do not declare package ...; for (keys %INC) { next if $orig_inc{$_}; next if /\.pm$/; delete $INC{$_}; } if(my $opt = $r->dir_config("PerlRunOnce")) { $r->child_terminate if lc($opt) eq "on"; } { #flush the namespace no strict; my $tab = \%{$package.'::'}; foreach (keys %$tab) { if(defined &{$tab->{$_}}) { undef_cv_if_owner($package, \&{$tab->{$_}}); } } %$tab = (); } return $rc; } sub undef_cv_if_owner { return unless $INC{'B.pm'}; my($package, $cv) = @_; my $obj = B::svref_2object($cv); my $stash = $obj->GV->STASH->NAME; return unless $package eq $stash; undef &$cv; } 1; __END__ =head1 NAME Apache::PerlRunFilter - run Perl scripts in an Apache::Filter chain =head1 SYNOPSIS #in httpd.conf PerlModule Apache::PerlRunFilter # Run the output of scripts through Apache::SSI SetHandler perl-script PerlHandler Apache::PerlRunFilter Apache::SSI PerlSetVar Filter on # Generate some Perl code using templates, then execute it SetHandler perl-script PerlHandler YourModule::GenCode Apache::PerlRunFilter PerlSetVar Filter on =head1 DESCRIPTION This module is a subclass of Apache::PerlRun, and contains all of its functionality. The only difference between the two is that this module can be used in conjunction with the Apache::Filter module, whereas Apache::PerlRun cannot. It only takes a tiny little bit of code to make the filtering stuff work, so perhaps it would be more appropriate for the code to be integrated right into Apache::PerlRun. As it stands, I've had to duplicate a bunch of PerlRun's code here (in the handler routine), so bug fixes & feature changes must be made both places. =head1 CAVEATS Note that this is not an exact replacement for Apache::Registry - it doesn't do any of the code-caching stuff that Registry does. It shouldn't be too hard a task, but for now Registry is still based on old code, and Doug's plan is to make future versions of Registry by subclassing PerlRun (see Apache::RegistryNG). Since this is the case, I figured I'd hold off on doing any Registry work until things have moved forward a bit. =head1 SEE ALSO perl(1), mod_perl(3), Apache::PerlRun(3) =head1 AUTHOR Ken Williams =cut