File Coverage

blib/lib/Apache/EmbeddedPerl/Lite.pm
Criterion Covered Total %
statement 43 48 89.5
branch 9 12 75.0
condition 2 3 66.6
subroutine 5 7 71.4
pod 2 2 100.0
total 61 72 84.7


line stmt bran cond sub pod time code
1             #!/usr/bin/perl
2             package Apache::EmbeddedPerl::Lite;
3             #use strict;
4             #use diagnostics;
5              
6 7     7   6834 use vars qw($VERSION @ISA @EXPORT_OK);
  7         15  
  7         5806  
7             require Exporter;
8             @ISA = qw(Exporter);
9              
10             $VERSION = do { my @r = (q$Revision: 0.06 $ =~ /\d+/g); sprintf "%d."."%02d" x $#r, @r };
11              
12             @EXPORT_OK = qw(
13             embedded
14             );
15              
16             if (eval { require Apache2::RequestRec }) {
17             require Apache2::RequestUtil;
18             require Apache2::RequestIO;
19             }
20              
21             =head1 NAME
22              
23             Apache::EmbeddedPerl::Lite - light weight embedded perl parser
24              
25             =head1 SYNOPSIS
26              
27             PerlModule Apache::EmbeddedPerl::Lite
28              
29            
30             SetHandler perl-script
31             PerlHandler Apache::EmbeddedPerl::Lite
32             PerlSetVar ContentType text/html
33            
34              
35             or
36              
37             use Apache::EmbeddedPerl::Lite qw(
38             embedded
39             };
40              
41             $response = embedded($class,$r,$filename,@args)
42              
43             =head1 DESCRIPTION
44              
45             This modules is a light weight perl parser designed to be used in
46             conjunction wit mod_perl and Apache 1 or Apache 2. It may be used as a
47             handler for files containing embedded perl or it may be called as a
48             subroutine to conditionally parse files of your choosing.
49              
50             Perl code may be embedded in a file parsed by this module as described
51             below. Each section of perl code is collected and eval'd as a subroutine that
52             is passed the two arguments ($classnam,$r) in its input array @_;
53              
54             Embedded perl should have the following format:
55              
56             On a line by itself:
57              
58             {optional whitespace}
64              
65             The beginning and terminating brackets may optionally be followed by a white
66             space and comments, which will be ignored.
67              
68             i.e.
69              
70            
78              
79             =item * $http_response = handler($classname,$r);
80              
81             The function "handler" has the prototype:
82              
83             handler ($$) : method {
84              
85             which receives the arguments $class, $r from Apache mod_perl.
86              
87             input: class name, (a scalar, not a ref)
88             request handle
89              
90             return: Apache response code or undef
91              
92             handler is not exported.
93              
94             Expected Codes:
95              
96             0 OK
97             404 File Not Found
98             500 Server Error
99              
100             404 could not find, open, etc... file
101             500 missing closing embedded perl bracket
102             embedded perl has an error
103              
104             When a 500 error is returned, a warning will be issued to STDERR providing
105             details about the error.
106            
107             A ContentType header will not be sent unless the type is specified as
108             follows:
109              
110             PerlSetVar ContentType text/html
111              
112             mod_perl configuration is as follows:
113              
114             PerlModule Apache::EmbeddedPerl::Lite
115              
116            
117             SetHandler perl-script
118             PerlHandler Apache::EmbeddedPerl::Lite
119             PerlSetVar ContentType text/html
120            
121              
122             =item * $http_response = embedded($classname,$r,$file,@args);
123              
124             The function "embedded" is similar to "handler" above except that it does not send any headers.
125             Headers are the responsibility of the application "handler", or the embedded
126             code.
127              
128             @args are optional arguments that may be passed from your handler to embedded.
129              
130             input: class name, (a scalar, not a ref)
131             request handle,
132             file name
133             @args [optional] appication specific
134              
135             return: Apache response code or undef
136              
137             ... at startup or .httaccess ...
138              
139             use Apache::EmbeddedPerl::Lite qw(embedded);
140              
141             ... in the application handler ...
142              
143             if ($r->filename =~ /\.ebhtml$/) {
144             ... set content type, etc...
145              
146             $response = embedded(__PACKAGE__,$r,$r->filename);
147             } else {
148             $response = embedded(__PACKAGE__,$r,$someotherfile);
149             }
150             return $response if $response; # contains error
151              
152             ... do something else
153              
154             =cut
155              
156             sub handler ($$) : method {
157 0     0 1 0 my($class,$r) = @_;
158 0         0 my $ct = $r->dir_config('ContentType');
159 0 0       0 $r->content_type($ct) if $ct;
160 0         0 embedded($class,$r,$r->filename);
161             }
162              
163             # execute in an environment with no lexical variables
164             sub _ex_eval {
165 4     4   11 local $_ = shift;
166             # eval sees our global @_
167              
168 4     0   8 { local $SIG{__WARN__} = sub {};
  4         48  
  0         0  
169 4     4   33 eval;
  4     4   8  
  4         148  
  4         67  
  4         19  
  4         297  
  4         423  
170             }
171             }
172              
173             sub embedded {
174 7     7 1 2538 my ($class,$r,$file,@args) = @_;
175 7         16 my $lineno = 0;
176 7         25 local *F;
177 7         14 my $line;
178 7 100 66     431 (-e $file && open(F,$file)) or return 404;
179             READLINE:
180 6         171 while (defined ($line = )) {
181 66         402 $lineno++;
182 66 100       174 if ($line =~ /^\s*\<\!--\s+perl\s*/) {
183 5         26 (my $perl = $0) =~ s/::/_/g;
184 5         38 $perl =~ s/([^a-zA-Z0-9_])/sprintf("%02X",ord($1))/seg;
  10         103  
185 5         22 $perl = 'package '. __PACKAGE__ .'::anon::'. $perl .";\nno strict;\n";
186 5 50       25 $perl .= "use diagnostics;\n" if exists $INC{'diagnostics.pm'};
187 5         22 my $start = $lineno;
188 5         26 while (defined ($line = )) {
189 42         43 $lineno++;
190 42 100       113 if ($line =~ /^\s*-->/) {
191 4         26 _ex_eval($perl,@_);
192 4 100       77 if ($@) {
193 1         14 close F;
194 1         12 warn "$class embedded: failed $file line $start\n$@";
195 1         10 return 500;
196             }
197 3         19 next READLINE;
198             }
199 38         107 $perl .= $line;
200             }
201 1         10 close F;
202 1         22 warn "$class embedded: $file line $start\nno closing '-->'\n";
203 1         11 return 500;
204             }
205 61         144 $r->print($line);
206             }
207 4         94 close F;
208 4         20 return 0; # Apache::Constant::OK
209             }
210            
211             =head1 PREREQUISITES
212              
213             Apache
214             or
215             Apache2
216             Apache2::RequestRec
217             Apache2::RequestUtil;
218             Apache2::RequestIO;
219            
220             =head1 EXPORT_OK
221              
222             embedded
223              
224             =head1 AUTHOR
225              
226             Michael Robinton, michael@bizsystems.com
227              
228             =head1 COPYRIGHT
229              
230             Copyright 2013-2014, Michael Robinton & BizSystems
231             This program is free software; you can redistribute it and/or modify
232             it under the same terms of the Apache Software License, a copy of which is
233             included in this distribution.
234              
235             This program is distributed in the hope that it will be useful,
236             but WITHOUT ANY WARRANTY; without even the implied warranty of
237             MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
238              
239             =cut
240              
241             1;