File Coverage

blib/lib/WebDyne/Request/Fake.pm
Criterion Covered Total %
statement 118 187 63.1
branch 30 64 46.8
condition 17 49 34.6
subroutine 26 48 54.1
pod 0 35 0.0
total 191 383 49.8


line stmt bran cond sub pod time code
1             #
2             # This file is part of WebDyne.
3             #
4             # This software is copyright (c) 2026 by Andrew Speer .
5             #
6             # This is free software; you can redistribute it and/or modify it under
7             # the same terms as the Perl 5 programming language system itself.
8             #
9             # Full license text is available at:
10             #
11             #
12             #
13              
14              
15             package WebDyne::Request::Fake;
16              
17              
18             # Compiler Pragma
19             #
20 7     7   506942 use strict qw(vars);
  7         16  
  7         424  
21 7     7   44 use vars qw($VERSION $AUTOLOAD);
  7         14  
  7         455  
22 7     7   40 use warnings;
  7         14  
  7         481  
23 7     7   38 no warnings qw(uninitialized);
  7         26  
  7         366  
24              
25              
26             # External modules
27             #
28 7     7   44 use Cwd qw(fastcwd);
  7         10  
  7         551  
29 7     7   776 use Data::Dumper;
  7         11811  
  7         505  
30 7     7   1159 use HTTP::Status (RC_OK);
  7         12547  
  7         605  
31 7     7   1149 use WebDyne::Util;
  7         18  
  7         100  
32 7     7   1544 use WebDyne::Constant;
  7         19  
  7         74  
33              
34              
35             # Var to hold package wide hash, for data shared across package
36             #
37             my %Package;
38              
39              
40             # Snapshot environment for Dir_config
41             #
42             #my %Dir_config_env;
43              
44              
45             # Version information
46             #
47             $VERSION='2.075';
48              
49              
50             # Debug load
51             #
52             0 && debug("Loading %s version $VERSION", __PACKAGE__);
53              
54              
55             # Run init code for utility accessors unless already done
56             #
57             &_init unless defined(&method);
58              
59              
60             # All done. Positive return
61             #
62             1;
63              
64              
65             #==================================================================================================
66              
67             sub _init {
68              
69             # Load quick and dirty mod_perl equivalent handler accessors that get info from
70             # environment vars if they exist
71             #
72 7     7   108 my %handler=(
73             method => 'REQUEST_METHOD',
74             protocol => 'SERVER_PROTOCOL',
75             args => 'QUERY_STRING',
76             path_info => 'PATH_INFO',
77             content_length => 'CONTENT_LENGTH',
78             hostname => 'SERVER_NAME',
79             get_server_name => 'SERVER_NAME',
80             get_server_port => 'SERVER_PORT',
81             get_remote_host => 'REMOTE_ADDR',
82             user => 'REMOTE_USER',
83             ap_auth_type => 'AUTH_TYPE',
84             unparsed_uri => 'REQUEST_URI',
85             );
86 7         43 while (my ($k, $v)=each %handler) {
87 84 100   0   130 *{$k}=sub { return $ENV{$v} } unless defined &{$k}
  77         332  
  0         0  
  84         380  
88             }
89              
90             }
91              
92              
93             sub dir_config0 {
94              
95             # Old very simplistic dir_config
96             #
97 0     0 0 0 my ($r, $key)=@_;
98 0         0 return $ENV{$key};
99              
100             }
101              
102              
103             sub dir_config {
104              
105            
106             # Newer more comprehensive dir_config that pulls from WEBDYNE_CONF
107             #
108 49     49 0 185 my ($r, $key)=@_;
109 49         72 0 && debug("r: $r, caller: %s", Dumper([caller(0)]));
110            
111              
112             # Get hash ref from config file
113             #
114 49         115 my $constant_hr=$WEBDYNE_DIR_CONFIG;
115 49         89 0 && debug('using constant_hr: %s', Dumper($constant_hr));
116              
117              
118             # Optionally load WEBDYNE_DIR_CONFIG from current dir
119             #
120 49 50       169 if ($WEBDYNE_DIR_CONFIG_CWD_LOAD) {
121            
122              
123             # Yes, wanted. Get cwd, skip if already processed
124             #
125 49         198 my $cwd_dn=$r->cwd();
126 49   50     235 my $dir_config_hr=($Package{'_dir_config'}{$cwd_dn} ||= do {
      66        
127             my $webdyne_conf_fn=File::Spec->catfile($cwd_dn, sprintf('.%s', $WEBDYNE_CONF_FN));
128             0 && debug("fn: $webdyne_conf_fn");
129             if (-f $webdyne_conf_fn) {
130             0 && debug("found: $webdyne_conf_fn, reading");
131             my $webdyne_conf_hr=do($webdyne_conf_fn) ||
132             warn "unable to read document root dir_config constant file, $!";
133             0 && debug('webdyne_conf_hr: %s', Dumper($webdyne_conf_hr));
134             $webdyne_conf_hr->{'WebDyne::Constant'}{'WEBDYNE_DIR_CONFIG'};
135             }} || {}
136             );
137 49 50       79 if (keys %{$dir_config_hr}) {
  49         198  
138             $constant_hr={
139 0         0 %{$constant_hr},
140 0         0 %{$dir_config_hr}
  0         0  
141             }
142             }
143             }
144              
145              
146             # OK - heirarchy is this:
147             #
148             # If WEBDYNE_PSGI_DIR_CONFIG=$hr order of return
149             #
150             # $ENV{$key} # Wins everything
151             # $hr->{$servername}{$location}{$key}
152             # $hr->{$servername}{''}{$key}
153             # $hr->{$servername}{$key}
154             # $hr->{$location}{$key}
155             # $hr->{''}{$key}
156             # $hr->{$key}
157             #
158              
159 49 100       140 if ($key) {
160            
161             # Key specified, returning just that value
162             #
163             #if (exists $Dir_config_env{$key}) {
164 48 50       185 if (exists $ENV{$key}) {
165            
166             # $ENV{$key} # Wins everything
167             #
168             #debug('found $ENV{%s}, returning %s', $key, $Dir_config_env{$key});
169 0         0 0 && debug('found $ENV{%s}, returning %s', $key, $ENV{$key});
170             #return $Dir_config_env{$key};
171 0         0 return $ENV{$key};
172            
173             }
174             else {
175            
176              
177             # Get location we are operating in
178             #
179 48         177 my $location=$r->location();
180 48         79 0 && debug("in dir_config looking for key $key at location $location");
181            
182            
183             # Array of hashes we may need to look through
184             #
185 48         126 my @constant_hr=($constant_hr);
186              
187              
188             # Do we have $hr->{$servername}{$location} ?
189             #
190 48 50 33     419 if (my $server=($ENV{'WebDyneServer'} || $ENV{'HOSTNAME'} || $ENV{'SERVER_NAME'})) {
191              
192             # Have $servername
193             #
194 48         94 0 && debug("using server: $server");
195 48 100       175 if (exists $constant_hr->{$server}) {
196            
197             # Add to array of hashes we have to look at
198             #
199 1         4 unshift @constant_hr, (my $constant_server_hr=$constant_hr->{$server});
200 1         3 0 && debug("pushing $constant_server_hr onto dir_config review stack: %s", Dumper($constant_server_hr));
201            
202             }
203            
204             }
205            
206            
207             # Now iterate across array, return on first match
208             #
209 48         118 foreach my $hr (@constant_hr) {
210 48         107 foreach my $hr_key ($location, '') {
211 94         124 0 && debug("looking at hr: $hr, k: $hr_key");
212             # Maybe $hr->{$location}{$key} or $hr->{''}{$key} ?
213             #
214 94 100       237 if (exists $constant_hr->{$hr_key}) {
215 2         5 0 && debug('found $hr->{%s}', $hr_key);
216 2 50       21 return $hr->{$hr_key}{$key} if exists($hr->{$hr_key}{$key});
217             }
218             else {
219 92         160 0 && debug('no match on hr:$hr {%s}', $hr_key);
220             }
221             }
222             # No - $hr->{$key} is last chance
223             #
224 46 50       119 if (exists $hr->{$key}) {
225 0         0 0 && debug('found $hr->{%s}', $key);
226 0         0 return $hr->{$key}
227             }
228             else {
229 46         88 0 && debug("no match on $hr {%s}", $key);
230             }
231             }
232            
233             # Nothing found
234             #
235 46         68 0 && debug("no key found for location: $location or any other match, %s");
236 46         302 return undef;
237            
238             }
239            
240             }
241             else {
242              
243             # Return dump of whole thing with ENV vars taking precendence at top level. Scrub mixing in ENV at moment, exposes
244             # too many non WebDyne vars if called with dir_config(). Do properly with Plack::Middleware::AddEnv or similar later
245             #
246             #my %dir_config=(%{$constant_hr}, %Dir_config_env);
247             my %dir_config=(
248 1         13 %{$constant_hr},
249 1         5 (map { $_=>$ENV{$_} } grep {/^WebDyne/i} keys %ENV),
  28         59  
250 1         3 (map { $_=>$ENV{$_} } grep {exists $ENV{$_} } keys %{$constant_hr})
  0         0  
  4         10  
  1         4  
251             #(map { $_=>$ENV{$_} } @{$WEBDYNE_PSGI_ENV_KEEP},
252             #%{$WEBDYNE_PSGI_ENV_SET}
253             );
254 1         11 return \%dir_config;
255             }
256              
257             }
258              
259              
260             sub filename {
261              
262 47     47 0 91 my $r=shift();
263              
264             # Store cwd as takes a fair bit of processing time.
265 47   66     1570 File::Spec->rel2abs($r->{'filename'}, ($Package{'_cwd'} ||= fastcwd()));
266              
267             }
268              
269              
270             sub headers {
271              
272             # Set/get header. r=request, d=direction(in/out), k=key, v=value
273             #
274 20     20 0 73 my ($r, $d, $k, $v)=@_;
275            
276 20 100       94 if (@_ == 4) {
    50          
    50          
277 1         4 return $r->{$d}{$k}=$v
278             }
279             elsif (@_ == 3) {
280 0         0 return $r->{$d}{$k}
281             }
282             elsif (@_ == 2) {
283 19   50     97 return ($r->{$d} ||= {});
284             }
285             else {
286 0         0 return err("incorrect usage of %s $d object, r->$d(%s)", ref($r), join(',', @_[1..$#_]));
287             }
288              
289             }
290              
291              
292             sub headers_out {
293              
294 18     18 0 34 my $r=shift();
295 18         62 return $r->headers('headers_out', @_);
296            
297             }
298              
299              
300             sub headers_in {
301              
302 2     2 0 5 my $r=shift();
303 2         10 return $r->headers('headers_in', @_);
304            
305             }
306              
307              
308             sub is_main {
309              
310 0     0 0 0 my $r=shift();
311 0 0       0 $r->{'main'} ? 0 : 1;
312              
313             }
314              
315              
316             sub log_error {
317              
318 0     0 0 0 my $r=shift();
319 0 0       0 warn(@_) unless !$r->{'warn'};
320              
321             }
322              
323              
324             sub lookup_file0 {
325              
326             # Old, simplistic version
327             #
328 0     0 0 0 my ($r, $fn)=@_;
329 0   0     0 my $r_child=ref($r)->new(filename => $fn, main=>$r) || return err();
330              
331             }
332              
333              
334             sub lookup_file {
335              
336 0     0 0 0 my ($r, $fn)=@_;
337 0         0 my $r_child;
338 0 0       0 if ($fn!~WEBDYNE_PSP_EXT_RE) { # fastest
339              
340              
341             # Static file. Should migrate to this module but OK is PSGI for moment
342             #
343 0         0 require WebDyne::Request::PSGI::Static;
344 0   0     0 $r_child=WebDyne::Request::PSGI::Static->new(filename => $fn, prev => $r) ||
345             return err();
346              
347             }
348             else {
349              
350              
351             # Subrequest
352             #
353 0   0     0 $r_child=ref($r)->new(filename => $fn, prev => $r) || return err();
354              
355             }
356              
357             # Return child
358             #
359 0         0 return $r_child;
360              
361             }
362              
363              
364             sub lookup_uri {
365              
366 0     0 0 0 my ($r, $uri)=@_;
367 0         0 my $fn=File::Spec::Unix->catfile((File::Spec->splitpath($r->filename()))[1], $uri);
368 0         0 return $r->lookup_file($fn);
369              
370             }
371              
372              
373             sub main {
374              
375 18     18 0 33 my $r=shift();
376             #@_ ? $r->{'main'}=shift() : $r->{'main'} || $r;
377 18 50       221 @_ ? $r->{'main'}=shift() : $r->{'main'};
378              
379             }
380              
381              
382             sub new {
383              
384 23     23 0 288764 my ($class, %r)=@_;
385 23         48 0 && debug("$class, r:%s", Dumper(\%r));
386 23         147 return bless \%r, $class;
387              
388             }
389              
390              
391             sub notes {
392              
393 0     0 0 0 my ($r, $k, $v)=@_;
394 0 0       0 if (@_ == 3) {
    0          
    0          
395 0         0 return $r->{'_notes'}{$k}=$v
396             }
397             elsif (@_ == 2) {
398 0         0 return $r->{'_notes'}{$k}
399             }
400             elsif (@_ == 1) {
401 0   0     0 return ($r->{'_notes'} ||= {});
402             }
403             else {
404 0         0 return err('incorrect usage of %s notes object, r->notes(%s)', +__PACKAGE__, join(',', @_[1..$#_]));
405             }
406              
407             }
408              
409              
410             sub parsed_uri {
411              
412 0     0 0 0 my $r=shift();
413 0         0 require URI;
414 0         0 URI->new($r->uri());
415              
416             }
417              
418              
419             sub prev {
420              
421 0     0 0 0 my $r=shift();
422 0 0       0 @_ ? $r->{'prev'}=shift() : $r->{'prev'};
423              
424             }
425              
426              
427             sub print {
428              
429 18     18 0 34 my $r=shift();
430 18   100     61 my $fh=$r->{'select'} || \*STDOUT;
431 18         30 0 && debug("print fh: $fh");
432 18 100       102 CORE::print $fh ((ref($_[0]) eq 'SCALAR') ? ${$_[0]} : @_);
  16         97  
433              
434             }
435              
436              
437             sub register_cleanup {
438              
439             #my $r=shift();
440 14     14 0 35 my ($r, $cr)=@_;
441 14   50     41 push @{$r->{'register_cleanup'} ||= []}, $cr;
  14         99  
442              
443             #my $ar=$r->{'register_cleanup'} ||= [];
444             #push @
445              
446             }
447              
448              
449             sub cleanup_register {
450              
451 0     0 0 0 ®ister_cleanup(@_);
452              
453             }
454              
455              
456             sub pool {
457              
458             # Used by mod_perl2, usually for cleanup_register in the form of $r->pool->cleanup_register(), so just
459             # return $r and let the code then call cleanup_register
460             #
461 0     0 0 0 my $r=shift();
462              
463             }
464              
465              
466             sub run {
467              
468 0     0 0 0 my ($r, $self)=@_;
469 0         0 0 && debug("r: $r, self: $self");
470 0   0     0 (ref($self) || $self)->handler($r);
471             #(ref($self) ? $self : $self)->handler($r);
472              
473             }
474              
475              
476             sub status {
477              
478 18     18 0 33 my $r=shift();
479 18 100 50     130 @_ ? $r->{'status'}=shift() : $r->{'status'} || RC_OK;
480              
481             }
482              
483              
484             sub uri {
485              
486 0     0 0 0 shift()->{'filename'}
487              
488             }
489              
490              
491             sub document_root {
492              
493 0     0 0 0 my $r=shift();
494 0 0 0     0 @_ ? $r->{'document_root'}=shift() : $r->{'document_root'} || ($ENV{'DOCUMENT_ROOT'} || fastcwd());
495            
496             }
497              
498              
499       0 0   sub output_filters {
500              
501             # Stub
502             }
503              
504              
505             sub location {
506              
507             # Get/set location
508 67     67 0 564 my ($self, $location)=@_;
509 67 50       157 if ($location) {
510 0         0 return $self->{'location'}=$location;
511             }
512             else {
513 67   100     547 return $self->{'location'} || $ENV{'WebDyneLocation'}
514             }
515              
516             }
517              
518              
519       18 0   sub header_only {
520              
521             # Stub
522             }
523              
524              
525       0 0   sub set_handlers {
526              
527             # Stub
528             }
529              
530              
531             sub noheader {
532              
533 0     0 0 0 my $r=shift();
534 0 0       0 @_ ? $r->{'header'}=shift() : $r->{'header'};
535              
536             }
537              
538              
539             sub send_http_header {
540              
541 18     18 0 39 my $r=shift();
542 18 50       88 return unless $r->{'header'};
543 0   0     0 my $fh=$r->{'select'} || \*STDOUT;
544 0         0 CORE::printf $fh ("Status: %s\n", $r->status());
545 0         0 while (my ($header, $value)=each(%{$r->{'headers_out'}})) {
  0         0  
546 0         0 CORE::print $fh ("$header: $value\n");
547             }
548 0         0 CORE::print $fh "\n";
549              
550             }
551              
552              
553             sub content_type {
554              
555 20     20 0 48 my ($r, $content_type)=@_;
556 20 50       147 return ($content_type ? $r->{'headers_out'}{'Content-Type'}=$content_type : $ENV{'CONTENT_TYPE'});
557             #CORE::print("Content-Type: $content_type\n");
558              
559             }
560              
561              
562             sub handler {
563              
564             # Replicate mod_perl handler function
565             #
566 0     0 0 0 my ($r, $handler)=@_;
567 0 0 0     0 return ($handler ? $r->{'handler'}=$handler : $r->{'handler'} ||= 'default-handler');
568              
569             }
570              
571              
572             sub custom_response {
573              
574 0     0 0 0 my ($r, $status)=(shift, shift);
575 0         0 $r->status($status);
576 0         0 $r->send_http_header();
577 0         0 $r->print(@_);
578              
579             }
580              
581              
582             sub args {
583              
584 0     0 0 0 return $ENV{'QUERY_STRING'};
585            
586             }
587              
588              
589             sub cwd {
590              
591             # Return cwd of current psp file
592             #
593 49     49 0 89 my $r=shift();
594 49   66     226 return $r->{'_cwd'} ||= do {
595 22         41 0 && debug("$r, fn: %s", $r->filename());
596 22         87 my $fn=$r->filename();
597 22         58 my $dn;
598 22 100       747 unless (-d ($dn=File::Spec->rel2abs($fn))) {
599             # Not a directory, must be file
600             #
601 20   33     400 $dn=(File::Spec->splitpath($fn))[1] || fastcwd();
602 20         52 0 && debug("return calculated dn: $dn");
603 20         99 $dn;
604             }
605             else {
606 2         4 0 && debug("return existing dn: $dn");
607 2         12 $dn;
608             }
609            
610             }
611              
612             }
613              
614              
615             sub AUTOLOAD {
616              
617 0     0   0 my ($r, $v)=@_;
618 0         0 0 && debug("$r AUTOLOAD: $AUTOLOAD, v: $v");
619 0   0     0 my $k=($AUTOLOAD=~/([^:]+)$/) && $1;
620 0         0 warn(sprintf("Unhandled '%s' method, using AUTOLOAD. Caller:%s", $k, Dumper([caller(0)])));
621 0 0       0 $v ? $r->{$k}=$v : $r->{$k};
622              
623              
624             }
625              
626              
627             sub DESTROY {
628              
629 39     39   3202 my $r=shift();
630 39         63 0 && debug("$r DESTROY");
631 39 100       472 if (my $cr_ar=delete $r->{'register_cleanup'}) {
632 14         30 foreach my $cr (@{$cr_ar}) {
  14         37  
633 14         44 $cr->($r);
634             }
635             }
636              
637             }