Apache2-SSI
view release on metacpan or search on metacpan
lib/Apache2/SSI.pm view on Meta::CPAN
sub find_file
{
my( $self, $args ) = @_;
my $r = $self->apache_request;
my $req = '';
if( exists( $args->{file} ) )
{
$self->_interp_vars( $args->{file} );
$req = $self->lookup_file( $args->{file} );
}
elsif( exists( $args->{virtual} ) )
{
$self->_interp_vars( $args->{virtual} );
$req = $self->lookup_uri( $args->{virtual} );
}
elsif( $r )
{
$req = Apache2::SSI::File->new( $r->filename, apache_request => $r );
}
return( $req );
}
sub finfo
{
my $self = shift( @_ );
my $r = $self->apache_request;
my $newfile;
if( @_ )
{
$newfile = shift( @_ );
return( $self->error( "New file path specified but is an empty string." ) ) if( !defined( $newfile ) || !length( $newfile ) );
}
elsif( !$self->{finfo} )
{
$newfile = $self->filename;
return( $self->error( "No file path set. This should not happen." ) ) if( !$newfile );
}
if( defined( $newfile ) )
{
$self->{finfo} = Apache2::SSI::Finfo->new( $newfile, ( $r ? ( apache_request => $r ) : () ) );
}
return( $self->{finfo} );
}
sub html { return( shift->_set_get_scalar( 'html', @_ ) ); }
sub legacy { return( shift->_set_get_boolean( 'legacy', @_ ) ); }
sub lookup_file
{
my $self = shift( @_ );
my $file = shift( @_ ) || return( $self->error( "No file provided to look up." ) );
my $r = $self->apache_request;
my $f = Apache2::SSI::File->new(
$file,
( $r ? ( apache_request => $r ) : () ),
base_file => $self->uri->filename,
debug => $self->debug
) || return( $self->error( "Unable to instantiate an Apache2::SSI::File object: ", Apache2::SSI::File->error ) );
if( $f->code == 404 )
{
# Mimic the Apache error when the file does not exist
$self->error( "unable to lookup information about \"$file\" in parsed file \"", $self->uri, "\"." );
}
return( $f );
}
sub lookup_uri
{
my $self = shift( @_ );
my $uri = shift( @_ );
my $r = $self->apache_request;
my $u = Apache2::SSI::URI->new(
( $r ? ( apache_request => $r ) : () ),
base_uri => $self->uri,
document_uri => $uri,
document_root => ( $r ? $r->document_root : $self->document_root ),
debug => $self->debug
) || return( $self->error( "Unable to instantiate an Apache2::SSI::URI object: ", Apache2::SSI::URI->error ) );
if( $u->code == 404 )
{
# Mimic the Apache error when the file does not exist
$self->error( "unable to get information about uri \"$uri\" in parsed file ", $self->uri );
}
return( $u );
}
sub mod_perl { return( shift->_set_get_boolean( 'mod_perl', @_ ) ); }
sub new_uri
{
my $self = shift( @_ );
my $uri = shift( @_ );
return( $self->error( "No uri provided to create an Apache2::SSI::URI object." ) ) if( !defined( $uri ) || !length( $uri ) );
my $p =
{
document_uri => $uri,
document_root => $self->document_root,
base_uri => $self->uri,
debug => $self->debug,
};
$p->{apache_request} = $self->apache_request if( $self->apache_request );
my $o = Apache2::SSI::URI->new( $p ) ||
return( $self->error( "Unable to create an Apache2::SSI::URI: ", Apache2::SSI::URI->error ) );
return( $o );
}
# This makes use of Apache2::SSI::Notes which guarantees that notes are shared in and out of Apache framework
# Notes are cleaned up at server shutdown with an handler set in startup.pl
# See scripts/startup.pl and conf/extra.conf.in as an example
sub notes
{
my $self = shift( @_ );
my $notes = $self->{notes};
my $r = $self->apache_request;
unless( scalar( @_ ) )
{
if( $r )
{
return( $r->pnotes );
}
elsif( $notes )
{
return( $notes->get );
}
# We just return an empty hash to avoid error
else
{
return( {} );
}
}
my $var = shift( @_ );
my $new;
my $new_value_set = 0;
if( @_ )
{
$new = shift( @_ );
$new_value_set++;
if( $notes )
{
lib/Apache2/SSI.pm view on Meta::CPAN
{
$filename = $r->filename;
if( $r->allow_options & &Apache2::Const::OPT_INCNOEXEC )
{
$self->error( "httpd: exec used but not allowed in $filename" );
return( $self->errmsg );
}
}
# TODO Need to improve on this
if( exists( $args->{cmd} ) )
{
# https://metacpan.org/pod/Apache2::SubProcess
# Fails to work: <https://rt.cpan.org/Public/Bug/Display.html?id=54153>
# <https://rt.cpan.org/Public/Dist/Display.html?Status=Active;Name=mod_perl>
if( $r && MOD_PERL_SPAWN_PROC_PROG_WORKING )
{
my $data;
my $fh = $r->spawn_proc_prog( $args->{cmd} );
if( PERLIO_IS_ENABLED || IO::Select->new( $fh )->can_read(10) )
{
$data = <$fh>;
}
return( defined( $data ) ? $data : '' );
}
else
{
my $env = $self->env;
local %ENV = %$env;
# What a shame to fork exec. Too bad spawn_proc_prog() does not work.
return( scalar( qx( $args->{cmd} ) ) );
}
}
unless( exists( $args->{cgi} ) )
{
$self->error( "No 'cmd' or 'cgi' argument given to #exec" );
return( $self->errmsg );
}
# Get a new Apache2::SSI::URI object
my $cgi = $self->new_uri( $args->{cgi} ) || do
{
return( $self->errmsg );
};
my $doc_root = $self->document_root || do
{
$self->error( "No document root set." );
return( $self->errmsg );
};
if( $cgi->code != 200 )
{
$self->error( "Error including cgi: subrequest returned status '" . $cgi->code . "', not 200" );
return( $self->errmsg );
}
my $finfo = $cgi->finfo;
if( !$finfo->exists )
{
$cgi->code( 404 );
$self->error( "Error including cgi \"$args->{cgi}\". File not found. CGI resolved to \"", $cgi->filename, "\"" );
return( $self->errmsg );
}
elsif( !$finfo->can_exec )
{
unless( $^O =~ /^(dos|mswin32|NetWare|symbian|win32)$/i && -T( "$finfo" ) )
{
# return( $self->error( "Error including cgi \"$args->{cgi}\". File is not executable by Apache user." ) );
$self->error( "Error including cgi \"$args->{cgi}\". File is not executable by Apache user." );
$cgi->code( 401 );
return( $self->errmsg );
}
}
if( $r )
{
my $rr = $cgi->apache_request;
# my $u = URI->new( $rr->uri . ( length( $cgi->path_info ) ? $cgi->path_info : length( $uri->path_info ) ? $uri->path_info : '' ) );
# $u->query( $uri->query_string ) if( !length( $cgi->query_string ) && length( $uri->query_string ) );
$cgi->path_info( $uri->path_info ) if( !length( $cgi->path_info ) && length( $uri->path_info ) );
$cgi->query_string( $uri->query_string ) if( !length( $cgi->query_string ) && length( $uri->query_string ) );
$rr->content_type( 'application/x-httpd-cgi' );
$cgi->env( GATEWAY_INTERFACE => 'CGI/1.1' );
$cgi->env( DOCUMENT_URI => "$cgi" );
my( $content, $headers ) = $rr->fetch_uri( "$cgi" );
return( $content );
}
else
{
my $buf;
{
local $ENV{DOCUMENT_URI} = $cgi->document_uri;
local $ENV{PATH_INFO} = $uri->path_info;
local $ENV{PATH_INFO} = $cgi->path_info if( length( $cgi->path_info ) );
local $ENV{QUERY_STRING} = $uri->query_string;
local $ENV{QUERY_STRING} = $cgi->query_string if( length( $cgi->query_string ) );
local $ENV{REMOTE_ADDR} = $self->remote_ip;
local $ENV{REQUEST_METHOD} = 'GET';
local $ENV{REQUEST_URI} = $cgi->document_uri;
my $file = $cgi->filename;
my $mime = $finfo->mime_type;
if( $^O =~ /^(dos|mswin32|NetWare|symbian|win32)$/i && $mime eq 'text/x-perl' )
{
$buf = `$^X $file`;
}
else
{
$buf = qx( "$file" );
}
};
# Failed to execute
if( $? == -1 )
{
$cgi->code( 500 );
return( $self->errmsg );
}
my( $key, $val );
my $headers = {};
while( $buf =~ s/([^\012]*)\012// )
( run in 0.898 second using v1.01-cache-2.11-cpan-39bf76dae61 )