2
###################################################################################
4
# Embperl - Copyright (c) 1997-2004 Gerald Richter / ECOS
6
# You may distribute under the terms of either the GNU General Public
7
# License or the Artistic License, as specified in the Perl README file.
9
# THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
10
# IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
11
# WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13
# $Id: SSI.pm,v 1.3 2004/01/23 06:50:57 richter Exp $
15
###################################################################################
17
package Embperl::Syntax::SSI ;
19
use Embperl::Syntax qw{:types} ;
20
use Embperl::Syntax::HTML ;
27
eval "use Apache::Constants qw(:common OPT_INCNOEXEC);" ;
33
@ISA = qw(Embperl::Syntax::HTML) ;
36
###################################################################################
40
###################################################################################
42
# ---------------------------------------------------------------------------------
44
# Create new Syntax Object
46
# ---------------------------------------------------------------------------------
54
my $self = Embperl::Syntax::HTML::new ($class) ;
56
if (!$self -> {-ssiInit})
58
$self -> {-ssiInit} = 1 ;
67
###################################################################################
69
# Definitions for SSI HTML tags
71
###################################################################################
78
$self -> AddInitCode (undef, 'Embperl::Syntax::SSI::InitSSI($_[0], $req_rec);', undef) ;
80
$self -> AddComment ('#echo', ['var', 'encoding'], undef, undef, { perlcode => '_ep_rp(%$x%, $ENV{%&*\'var%}) ;' } ) ;
81
$self -> AddComment ('#printenv', undef, undef, undef, { perlcode => '_ep_rp(%$x%, join ("\\\\<br\\\\>\n", map { "$_ = $ENV{$_}" } keys %ENV)) ;' } ) ;
82
$self -> AddComment ('#config', ['errmsg', 'sizefmt', 'timefmt'], undef, undef,
84
'$_ep_ssi_errmsg = %&*\'errmsg% ;',
85
'$_ep_ssi_sizefmt = %&*\'sizefmt% ;',
86
'$_ep_ssi_timefmt = %&*\'timefmt% ;',
91
$self -> AddComment ('#exec', ['cgi', 'cmd'], undef, undef,
93
'_ep_rp(%$x%, Embperl::Syntax::SSI::exec (%&\'cmd%, %&\'cgi%)) ;',
96
$self -> AddComment ('#fsize', ['file', 'virtual'], undef, undef,
98
'_ep_rp(%$x%, Embperl::Syntax::SSI::fsize ($_ep_ssi_sizefmt, %&\'file%, %&\'virtual%)) ;',
100
$self -> AddComment ('#flastmod', ['file', 'virtual'], undef, undef,
102
'_ep_rp(%$x%, Embperl::Syntax::SSI::flastmod ($_ep_ssi_timefmt, %&\'file%, %&\'virtual%)) ;',
105
$self -> AddComment ('#include', ['file', 'virtual'], undef, undef,
107
'_ep_rp(%$x%, Embperl::Syntax::SSI::include (%&\'file%, %&\'virtual%)) ;',
109
$self -> AddComment ('#set', ['var', 'value'], undef, undef,
110
{ perlcode => '%&value%',
111
compiletimeperlcode => '$Embperl::req -> component -> code (q{$ENV{%&*\'var%} = "} . Embperl::Syntax::SSI::InterpretVars (%&\'value%) . \'";\') ;',
114
$self -> AddComment ('#if', ['expr'], undef, undef,
115
{ perlcode => '%&\'expr%',
116
compiletimeperlcode => '$Embperl::req -> component -> code (q{if (} . Embperl::Syntax::SSI::InterpretVars (%&\'expr%) . \') {\') ;',
119
stackname => 'ssicmd',
122
$self -> AddComment ('#elif', ['expr'], undef, undef,
123
{ perlcode => '%&\'expr%',
124
compiletimeperlcode => '$Embperl::req -> component -> code (\'} elsif (\' . Embperl::Syntax::SSI::InterpretVars (%&\'expr%) . \') {\') ;',
127
stackname => 'ssicmd',
131
$self -> AddComment ('#else', undef, undef, undef,
132
{ perlcode => '} else {',
135
stackname => 'ssicmd',
139
$self -> AddComment ('#endif', undef, undef, undef,
143
stackname => 'ssicmd',
146
my $tag = $self -> AddComment ('#syntax', ['type'], undef, undef,
148
compiletimeperlcode => '$Embperl::req -> component -> syntax (Embperl::Syntax::GetSyntax(%&\'type%, $Embperl::req -> component -> syntax -> name));',
152
my $ptcode = '$Embperl::req -> component -> syntax (Embperl::Syntax::GetSyntax(\'%%\', $Embperl::req -> component -> syntax -> name)) ;' ;
154
if (!$self -> {-ssiAssignAttrType})
156
$self -> {-ssiAssignAttrType} = $self -> CloneHash ($self -> {-htmlAssignAttr}) ;
158
$tag -> {inside}{type}{'follow'} = $self -> {-ssiAssignAttrType} ;
159
$self -> {-ssiAssignAttrType}{Assign}{follow}{'Attribut ""'}{parsetimeperlcode} = $ptcode ;
160
$self -> {-ssiAssignAttrType}{Assign}{follow}{'Attribut \'\''}{parsetimeperlcode} = $ptcode ;
161
$self -> {-ssiAssignAttrType}{Assign}{follow}{'Attribut alphanum'}{parsetimeperlcode} = $ptcode ;
167
###################################################################################
171
###################################################################################
173
# ---------------------------------------------------------------------------------
177
# ---------------------------------------------------------------------------------
183
$ENV{DATE_GMT} = gmtime ;
184
$ENV{DATE_LOCAL} = localtime ;
185
$ENV{DOCUMENT_NAME} = basename ($fn = $Embperl::req -> component -> sourcefile) ;
186
$ENV{DOCUMENT_URI} = $Embperl::req -> apache_req?$Embperl::req -> apache_req -> uri:'' ;
187
$ENV{LAST_MODIFIED} = format_time('', (stat ($fn))[9]) ;
191
# ---------------------------------------------------------------------------------
193
# Interpolate vars inside string
195
# ---------------------------------------------------------------------------------
203
$val =~ s/\$(\w)([a-zA-Z0-9_]*)/\$ENV{'$1$2'}/g ;
204
$val =~ s/\$\{(\w)([a-zA-Z0-9_]*?)\}/\$ENV{'$1$2'}/g ;
205
$val =~ s/\'/\\\'/g if ($esc) ;
209
# ---------------------------------------------------------------------------------
213
# ---------------------------------------------------------------------------------
217
my ($fn, $virt) = @_;
220
if (!defined ($Embperl::req -> apache_req))
226
return $Embperl::req -> component -> cwd . '/' . $fn ;
233
return $Embperl::req -> component -> sourcefile if (!$virt) ;
235
my $filename = $virt;
237
#die "Cannot use 'virtual' without mod_perl" if ($virt) ;
239
if ($filename && ($filename =~ /^\//)) {
240
$filename = $ENV{DOCUMENT_ROOT} . $filename;
247
my $req = $Embperl::req -> apache_req -> lookup_file (InterpretVars ($fn)) ;
248
return $req -> filename ;
252
my $req = $Embperl::req -> apache_req -> lookup_uri (InterpretVars ($virt)) ;
253
return $req -> filename ;
257
return $Embperl::req -> component -> sourcefile ;
262
# ---------------------------------------------------------------------------------
266
# ---------------------------------------------------------------------------------
271
# This routine must respect the caller's wantarray() context.
272
my ($time, $zone) = @_;
273
return $zone =~ /GMT/ ? gmtime($time) : localtime($time);
279
my ($format, $time, $tzone) = @_;
281
POSIX::strftime($format, time_args($time, $tzone)) :
282
scalar time_args($time, $tzone));
288
# ---------------------------------------------------------------------------------
292
# ---------------------------------------------------------------------------------
299
my ($fmt, $fn, $virt) = @_;
301
my $size = -s find_file($fn, $virt) ;
309
elsif ($fmt eq 'abbrev')
311
return " 0k" unless $size;
312
return " 1k" if $size < 1024;
313
return sprintf("%4dk", ($size + 512)/1024) if $size < 1048576;
314
return sprintf("%4.1fM", $size/1048576.0) if $size < 103809024;
315
return sprintf("%4dM", ($size + 524288)/1048576);
319
die "Unrecognized size format '$fmt'" ;
323
# ---------------------------------------------------------------------------------
327
# ---------------------------------------------------------------------------------
331
my($fmt, $fn, $virt) = @_;
333
return format_time($fmt, (stat (find_file($fn, $virt)))[9])
336
# ---------------------------------------------------------------------------------
340
# ---------------------------------------------------------------------------------
347
my $type = "SSI"; # adding Embperl to syntax results in errors I can't figure out...
348
my $filename = $virt;
355
if ($filename && ($filename =~ /^\//)) {
356
$filename = $ENV{DOCUMENT_ROOT} . "/$filename";
360
warn "Nothing to #include... need file or virtual";
365
Embperl::Req::ExecuteComponent({inputfile=>$filename, output=>\$output, syntax=>$type});
367
local $Embperl::escmode = 0 ;
371
# ---------------------------------------------------------------------------------
375
# ---------------------------------------------------------------------------------
382
if (!defined (&Apache::request))
384
return scalar `$cmd` if ($cmd) ;
385
die "Cannot use 'cgi' without mod_perl" ;
388
my $r = $Embperl::req -> apache_req ;
389
my $filename = $r->filename;
391
die ("httpd: exec used but not allowed in $filename") if ($r->allow_options & &OPT_INCNOEXEC) ;
393
return scalar `$cmd` if ($cmd) ;
395
die ("No 'cmd' or 'cgi' argument given to #exec") if (!$cgi) ;
397
die ("'cgi' as argument to #exec not implemented yet") ;
399
# Okay, we're doing <!--#exec cgi=...>
400
my $rr = $r->lookup_uri($cgi);
401
die("Error including cgi: subrequest returned status '" . $rr->status . "', not 200") if ($rr->status != 200);
403
# Pass through our own path_info and query_string (does this work?)
404
$rr->path_info( $r->path_info );
405
$rr->args( scalar $r->args );
406
$rr->content_type("application/x-httpd-cgi");
407
&_set_VAR($rr, 'DOCUMENT_URI', $r->uri);
409
my $status = $rr->run;
422
SSI syntax module for Embperl
428
DATE_GMT: <!-- #echo var='DATE_GMT' -->
429
DATE_LOCAL: <!-- #echo var='DATE_LOCAL' -->
430
DOCUMENT_NAME: <!-- #echo var='DOCUMENT_NAME' -->
431
DOCUMENT_URI: <!-- #echo var='DOCUMENT_URI' -->
432
LAST_MODIFIED: <!-- #echo var='LAST_MODIFIED' -->
437
The module make Embperl understand the following SSI tags. See
438
Apaches mod_include (or Apache::SSI) for a description, what they
469
The syntax SSI is non standard and is used to change the syntax once you are
470
in SSI syntax. It looks like
472
<!--#syntax type="Embperl" -->
479
Gerald Richter <richter@dev.ecos.de>
481
Some ideas and parts of the code are taken from Apache::SSI by Ken Williams.
485
Embperl::Syntax, Embperl::Syntax::HTML
491
# ---------------------------------------------------------------------------------
495
# ---------------------------------------------------------------------------------
501
my($self, $args, $margs) = @_;
503
my ($pass_r, @arg1, @arg2, $sub) = (1);
506
while (@a = splice(@$margs, 0, 2)) {
507
$a[1] =~ s/\\(.)/$1/gs;
508
if (lc $a[0] eq 'sub') {
510
} elsif (lc $a[0] eq 'arg') {
512
} elsif (lc $a[0] eq 'args') {
513
push @arg1, split(/,/, $a[1]);
514
} elsif (lc $a[0] eq 'pass_request') {
515
$pass_r = 0 if lc $a[1] eq 'no';
516
} elsif ($a[0] =~ s/^-//) {
518
} else { # Any unknown get passed as key-value pairs
524
warn "sub is $sub, args are @arg1 & @arg2" if $debug;
526
if ( $sub =~ /^\s*sub\s/ ) { # for <!--#perl sub="sub {print ++$Access::Cnt }" -->
527
$subref = eval($sub);
529
$self->error("Perl eval of '$sub' failed: $@") if $self->{_r};
530
warn("Perl eval of '$sub' failed: $@") unless $self->{_r}; # For offline mode
532
return $self->error("sub=\"sub ...\" didn't return a reference") unless ref $subref;
533
} else { # for <!--#perl sub="package::subr" -->
535
$subref = (defined &{$sub} ? \&{$sub} :
536
defined &{"${sub}::handler"} ? \&{"${sub}::handler"} :
540
$pass_r = 0 if $self->{_r} and lc $self->{_r}->dir_config('SSIPerlPass_Request') eq 'no';
541
unshift @arg1, $self->{_r} if $pass_r;
542
warn "sub is $subref, args are @arg1 & @arg2" if $debug;
543
return scalar &{ $subref }(@arg1, @arg2);