File Coverage

blib/lib/Embperl/Object.pm
Criterion Covered Total %
statement 48 230 20.8
branch 1 134 0.7
condition 0 58 0.0
subroutine 16 21 76.1
pod 0 5 0.0
total 65 448 14.5


line stmt bran cond sub pod time code
1              
2             ###################################################################################
3             #
4             # Embperl - Copyright (c) 1997-2008 Gerald Richter / ecos gmbh www.ecos.de
5             # Embperl - Copyright (c) 2008-2014 Gerald Richter
6             #
7             # You may distribute under the terms of either the GNU General Public
8             # License or the Artistic License, as specified in the Perl README file.
9             #
10             # THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
11             # IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
12             # WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
13             #
14             # $Id: Object.pm 1578075 2014-03-16 14:01:14Z richter $
15             #
16             ###################################################################################
17              
18              
19             package Embperl::Object ;
20              
21             require Cwd ;
22             require File::Basename ;
23              
24             require Exporter;
25             require DynaLoader;
26              
27 1     1   2306 use Embperl ;
  1         3  
  1         61  
28 1     1   7 use Embperl::Constant ;
  1         2  
  1         25  
29              
30 1     1   5 use constant OK => 0 ;
  1         3  
  1         78  
31 1     1   5 use constant NOT_FOUND => 404 ;
  1         2  
  1         38  
32 1     1   14 use constant FORBIDDEN => 403 ;
  1         2  
  1         68  
33 1 50   1   5 use constant DECLINED => $ENV{MOD_PERL}?-1:403 ;
  1         1  
  1         39  
34              
35              
36 1     1   4 use File::Spec ;
  1         2  
  1         18  
37 1     1   4 use File::Basename ;
  1         12  
  1         77  
38              
39 1     1   6 use strict ;
  1         1  
  1         39  
40 1         1704 use vars qw(
41             @ISA
42             $VERSION
43             $volume
44             $fsignorecase
45             %packages
46 1     1   5 ) ;
  1         6  
47              
48              
49             @ISA = qw(Exporter DynaLoader);
50              
51              
52             $VERSION = '2.4.0';
53              
54              
55             $volume = (File::Spec -> splitpath ($Embperl::cwd))[0] ;
56             $fsignorecase = File::Spec->case_tolerant ;
57              
58             1 ;
59              
60             #############################################################################
61             #
62             # Normalize path into filesystem
63             #
64             # in $path path to normalize
65             # ret normalized path
66             #
67              
68              
69             sub norm_path
70              
71             {
72 0     0 0   my $path = shift ;
73 0 0         return '' if (!$path) ;
74              
75             # remove spaces
76 0 0         $path = $1 if ($path =~ /^\s*(.*?)\s*$/) ;
77            
78 0 0         if (File::Spec->file_name_is_absolute ($path))
79             {
80 0           $path = File::Spec -> canonpath ($path) ;
81 0 0         if (!$_[0])
82             {
83 0           my ($volume, $dir, $file) = File::Spec -> splitpath ($path) ;
84 0           $_[0] = File::Spec -> catdir ($volume, $dir) ;
85             }
86             }
87             else
88             {
89 0   0       $_[0] ||= Cwd::fastcwd ;
90             # make absolute path
91 0           $path = File::Spec -> rel2abs ($path, $_[0]) ;
92             }
93             # Use always forward slashes
94 0           $path =~ s/\\/\//g ;
95             # Add volume (i.e. drive on Windows) if not exists
96 0 0         $path = $volume . $path if ($path =~ /^\//) ;
97             # Make lower case if filesystem doesn't cares about case
98 0 0         $path = lc ($path) if ($fsignorecase) ;
99              
100 0           return $path ;
101             }
102              
103              
104             #############################################################################
105              
106             sub handler_dmalloc
107             {
108 0     0 0   my %req ;
109              
110 0           $req{'req_rec'} = $_[0] ;
111            
112 0           my $n = Embperl::dmalloc_mark () ;
113 0           my $rc = Execute (\%req) ;
114 0           Embperl::dmalloc_check ($n, "Embperl::Object") ;
115 0           return $rc ;
116             }
117            
118             #############################################################################
119              
120             sub handler
121             {
122 0     0 0   my %req ;
123              
124 0           $req{'req_rec'} = $_[0] ;
125            
126 0           Execute (\%req) ;
127             }
128            
129            
130            
131             #############################################################################
132              
133             sub run
134             {
135 0     0 0   $_[0] -> run ;
136             }
137              
138             #############################################################################
139              
140             sub Execute
141              
142             {
143 0     0 0   my $req = shift ;
144            
145 0           local $SIG{__WARN__} = \&Embperl::Warn ;
146              
147 0           $Embperl::req_rec = $req -> {req_rec} ;
148 0           my ($rc, $r) = Embperl::Req::InitRequest ($req -> {req_rec}, $req) ;
149 0   0       my $debug = $r && ($r -> config -> debug & Embperl::Constant::dbgObjectSearch) ;
150            
151 0 0         if ($rc)
152             {
153 0 0         print Embperl::LOG "[$$]Embperl::Object InitRequest returns $rc\n" if ($debug);
154 0           return $rc ;
155             }
156              
157              
158 0 0 0       if (exists $req -> {fdat} && ref ($req -> {fdat}) eq 'HASH')
159             {
160 0           %Embperl::fdat = %{$req -> {fdat}} ;
  0            
161 0 0         if (ref $req -> {ffld} eq 'ARRAY')
162             {
163 0           @Embperl::ffld = @%{$req -> {ffld}};
164             }
165             else
166             {
167 0           @Embperl::ffld = keys %Embperl::fdat ;
168             }
169 0           delete $req -> {fdat};
170 0           delete $req -> {ffld} ;
171             }
172              
173              
174 0           my $app = $r -> app ;
175 0           my $appcfg = $app -> config;
176              
177 0           my $cwd ;
178 0           my $filename = norm_path ($r -> param -> filename, $cwd) ;
179 0           my $apr ;
180 0 0         $apr = $req -> {req_rec} if ($req -> {req_rec}) ;
181              
182 0   0       my $basename = $appcfg -> object_base || '_base.epl' ;
183             ##$basename =~ s/%modifier%/$req->{object_base_modifier}/ ;
184 0           my $addpath = $appcfg -> object_addpath ;
185 0           my $reqpath = $appcfg -> object_reqpath ;
186 0           my $directory ;
187 0 0         my $rootdir = $apr?norm_path ($apr -> document_root, $cwd):"$volume/" ;
188 0           my $stopdir = norm_path ($appcfg -> object_stopdir, $cwd) ;
189            
190 0 0         if (-d $filename)
191             {
192 0           $directory = $filename ;
193             }
194             else
195             {
196 0           $directory = dirname ($filename) ;
197             }
198            
199 0           my @searchpath ;
200            
201 0 0         print Embperl::LOG "[$$]Embperl::Object Request Filename: $filename\n" if ($debug);
202 0 0         print Embperl::LOG "[$$]Embperl::Object basename: $basename\n" if ($debug);
203            
204 0           my $fn ;
205             my $ap ;
206 0           my $ldir = '' ;
207 0           my $found = 0 ;
208 0           my $fallback = 0 ;
209            
210             do
211 0   0       {
      0        
      0        
      0        
      0        
212 0           $fn = "$directory/$basename" ;
213 0           push @searchpath, $directory ;
214 0 0         print Embperl::LOG "[$$]Embperl::Object Check for base: $fn\n" if ($debug);
215 0 0         if (-e $fn)
216             {
217 0 0         $apr -> filename ($fn) if ($apr) ;
218 0           $found = 1 ;
219             }
220             else
221             {
222 0           $ldir = $directory ;
223 0           $directory = dirname ($directory) ;
224             }
225             }
226             while (!$found && $ldir ne $rootdir && $ldir ne $stopdir && $directory ne '/' && $directory ne '.' && $directory ne $ldir) ;
227              
228 0   0       while ($found && $stopdir && $stopdir ne $directory && $directory ne '/' && $directory ne '.' && $directory ne $ldir)
      0        
      0        
      0        
      0        
229             {
230 0           $ldir = $directory ;
231 0           $directory = dirname ($directory) ;
232 0           push @searchpath, $directory ;
233             }
234              
235 0 0         push @searchpath, @$addpath if ($addpath) ;
236 0 0         if (!$found)
237             {
238 0           foreach $ap (@$addpath)
239             {
240 0 0         next if (!$ap) ;
241 0           $fn = "$ap/$basename" ;
242 0 0         print Embperl::LOG "[$$]Embperl::Object Check for base: $fn\n" if ($debug);
243 0 0         if (-e $fn)
244             {
245 0 0         $apr -> filename ($fn) if ($apr) ;
246 0           $found = 1 ;
247 0           last ;
248             }
249              
250             }
251             }
252              
253              
254 0 0         if ($found)
255             {
256 0 0         print Embperl::LOG "[$$]Embperl::Object Found Base: $fn\n" if ($debug);
257 0 0         print Embperl::LOG "[$$]Embperl::Object path: @searchpath\n" if ($debug);
258              
259            
260 0           my $basepackage = $packages{$fn} ;
261 0           my $package = $packages{$filename} ;
262              
263 0 0         if (!$basepackage)
264             {
265 0 0         print Embperl::LOG "[$$]Embperl::Object import new Base: $fn\n" if ($debug);
266 0           my $cparam = {%$req, inputfile => $fn, import => 0 } ;
267 0           my $c = $r -> setup_component ($cparam) ;
268 0           run($c) ;
269 0 0         $basepackage = $packages{$fn} = $c -> curr_package if (!$r -> error) ;
270 0           $c -> cleanup ;
271 0 0         print Embperl::LOG "[$$]Embperl::Object import base ", ($r -> error?'with ERRORS ':'') . "finished: $fn, " . ($basepackage?"package = $basepackage \n":"\n") if ($debug);
    0          
    0          
272              
273 0 0         if (!$r -> error)
274             {
275 0           local $^W = 0 ;
276 1     1   8 no strict ;
  1         2  
  1         138  
277 0           my $isa = \@{"$package\:\:ISA"} ;
  0            
278 0   0       my $class = $appcfg -> object_handler_class || 'Embperl::Req' ;
279 0 0         if (!grep /^\Q$class\E$/, @$isa)
280             {
281 0           push @{"$basepackage\:\:ISA"}, $class ;
  0            
282             }
283             }
284 1     1   8 use strict ;
  1         3  
  1         315  
285             }
286              
287 0           $r -> config -> path (\@searchpath) ;
288              
289 0 0 0       if ($appcfg -> object_app && !$r -> error)
290             {
291 0           my $appfn = $appcfg -> object_app ;
292              
293 0 0         print Embperl::LOG "[$$]Embperl::Object import new Application: $appfn\n" if ($debug);
294            
295 0           my $cparam = {object => $appfn, syntax => 'Perl', debug => $req -> {debug}} ;
296 0           my $c = $r -> setup_component ($cparam) ;
297 0           my $app = run($c) ;
298 0 0         my $package = $c -> curr_package if (!$r -> error) ;
299 0           $c -> cleanup ;
300 0 0         print Embperl::LOG "[$$]Embperl::Object import new Application ", ($r -> error?'with ERRORS ':'') . "finished: $appfn, " . ($package?"package = $package\n":"\n") if ($debug);
    0          
    0          
301              
302 0 0         if (!$r -> error)
303             {
304 1     1   7 no strict ;
  1         3  
  1         105  
305 0           my $isa = \@{"$package\:\:ISA"} ;
  0            
306 0 0         if (!grep /^Embperl::App$/, @$isa)
307             {
308 0           push @{"$package\:\:ISA"}, 'Embperl::App' ;
  0            
309             }
310 1     1   5 use strict ;
  1         2  
  1         744  
311            
312 0           $app = $r -> app ;
313 0           bless $app, $package ;
314              
315 0           my $status = eval { $app -> init ($r) ; } ;
  0            
316 0 0         if ($@)
    0          
317             {
318 0           $r -> logerror (Embperl::Constant::rcEvalErr, $@, $apr) ;
319             }
320             elsif ($status)
321             {
322 0           $r -> send_http_header ;
323 0           $r -> cleanup ;
324 0 0         print Embperl::LOG "[$$]Embperl::Object Application -> init had returned $status\n" if ($debug);
325 0           return $status ;
326             }
327 0           $filename = norm_path ($r -> param -> filename, $cwd) ;
328             }
329             }
330              
331              
332              
333 0           my $file_not_found = 0 ;
334 0 0         if (!-f $filename)
335             {
336 0           $file_not_found = 1 ;
337 0 0         if ($reqpath)
338             {
339 0           my $file = basename ($filename) ;
340 0           foreach my $path (@$reqpath)
341             {
342 0           my $testfn = "$path/$file" ;
343 0 0         print Embperl::LOG "[$$]Embperl::Object Search for request file $file in $path\n" if ($debug);
344 0 0         if (-f $testfn)
345             {
346 0           $filename = $testfn ;
347 0           $file_not_found = 0 ;
348 0           last ;
349             }
350             }
351             }
352             }
353              
354 0 0         if ($file_not_found)
355             {
356 0 0         if ($appcfg -> object_fallback)
357             {
358 0           $fallback = 1 ;
359 0           $filename = $appcfg -> object_fallback ;
360 0 0         print Embperl::LOG "[$$]Embperl::Object use fallback: $filename\n" if ($debug);
361             }
362             else
363             {
364 0 0         print Embperl::LOG "[$$]Embperl::Object $filename not found, no fallback\n" if ($debug);
365 0           return NOT_FOUND ;
366             }
367             }
368            
369 0 0         if ($fn eq $filename)
370             {
371 0           $r -> logerror (Embperl::Constant::rcForbidden, $filename, $apr) ;
372 0           $r -> cleanup ;
373 0           return FORBIDDEN ;
374             }
375              
376              
377 0 0 0       if ((!$package || $fallback) && !$r -> error)
      0        
378             {
379 0 0 0       print Embperl::LOG "[$$]Embperl::Object import new file: $filename\n" if ($debug && !$fallback);
380            
381 0           my $cparam = {%$req, inputfile => $filename, import => 0 } ;
382 0           my $c = $r -> setup_component ($cparam) ;
383 0           run($c) ;
384 0 0         $package = $packages{$filename} = $c -> curr_package if (!$r -> error);
385 0           $c -> cleanup ;
386 0 0         print Embperl::LOG "[$$]Embperl::Object import file ", ($r -> error?'with ERRORS ':'') , "finished: $filename, package = $package\n" if ($debug);
    0          
387              
388 0 0 0       if (!$r -> error && $package ne $basepackage)
389             {
390 1     1   7 no strict ;
  1         2  
  1         113  
391 0           my $isa = \@{"$package\:\:ISA"} ;
  0            
392 0 0         if (!grep /^\Q$basepackage\E$/, @$isa)
393             {
394 0           push @{"$package\:\:ISA"}, $basepackage ;
  0            
395             }
396             }
397 1     1   6 use strict ;
  1         2  
  1         405  
398              
399             }
400              
401 0 0         if (!$r -> error)
402             {
403 0 0         $r -> param -> filename ($filename) if ($filename ne $fn) ;
404 0           bless $r, $package ;
405             }
406              
407 0           my $cparam = {%$req, inputfile => $fn } ;
408 0           my $c = $r -> setup_component ($cparam) ;
409              
410 0           $rc = run($r) ;
411              
412 0           $r -> cleanup ;
413              
414 0           return $rc ;
415             }
416              
417            
418 0           $r -> logerror (Embperl::Constant::rcNotFound, $basename, $apr) ;
419 0 0         $apr -> log_error ("Embperl::Object base $basename not found. Searched '@searchpath'" . ($addpath?" and '@$addpath' ":'')) if ($apr) ;
    0          
420 0           $r -> cleanup ;
421              
422 0           return &NOT_FOUND ;
423             }
424              
425              
426             __END__