File Coverage

blib/lib/Plack/App/PHPCGI.pm
Criterion Covered Total %
statement 27 75 36.0
branch 0 16 0.0
condition 0 3 0.0
subroutine 9 13 69.2
pod 2 3 66.6
total 38 110 34.5


line stmt bran cond sub pod time code
1             package Plack::App::PHPCGI;
2              
3 3     3   46063 use strict;
  3         8  
  3         112  
4 3     3   17 use warnings;
  3         9  
  3         91  
5 3     3   2377 use parent qw(Plack::Component);
  3         699  
  3         19  
6 3     3   42883 use Plack::Util::Accessor qw(script php_cgi _app);
  3         503  
  3         20  
7 3     3   2671 use CGI::Emulate::PSGI;
  3         199327  
  3         112  
8 3     3   3497 use File::Which;
  3         3115  
  3         168  
9 3     3   19 use File::Spec;
  3         6  
  3         69  
10 3     3   14 use Carp;
  3         5  
  3         159  
11 3     3   14 use POSIX ":sys_wait_h";
  3         5  
  3         14  
12              
13             our $VERSION = '0.04';
14              
15             sub wrap_php {
16 0     0 0   my ($php_cgi, $script) = @_;
17             my $app = sub {
18 0     0     my $env = shift;
19              
20 0           pipe( my $stdoutr, my $stdoutw );
21 0           pipe( my $stdinr, my $stdinw );
22              
23 0           my $pid = fork();
24 0 0         Carp::croak("fork failed: $!") unless defined $pid;
25              
26 0 0         if ($pid == 0) { # child
27             local $SIG{__DIE__} = sub {
28 0           print STDERR @_;
29 0           exit(1);
30 0           };
31              
32 0           close $stdoutr;
33 0           close $stdinw;
34            
35 0           local %ENV = (%ENV, CGI::Emulate::PSGI->emulate_environment($env));
36 0           local $ENV{REDIRECT_STATUS} = 1;
37 0           local $ENV{SCRIPT_FILENAME} = $script;
38              
39 0 0         open( STDOUT, ">&=" . fileno($stdoutw) ) ## no critic
40             or Carp::croak "Cannot dup STDOUT: $!";
41 0 0         open( STDIN, "<&=" . fileno($stdinr) ) ## no critic
42             or Carp::croak "Cannot dup STDIN: $!";
43              
44 0 0         exec($php_cgi,$script) or Carp::croak("cannot exec: $!");
45              
46 0           exit(2);
47             }
48              
49 0           close $stdoutw;
50 0           close $stdinr;
51            
52 0           syswrite($stdinw, do {
53 0           local $/;
54 0           my $fh = $env->{'psgi.input'};
55 0           <$fh>;
56             });
57             # close STDIN so child will stop waiting
58 0           close $stdinw;
59            
60 0           my $res = '';
61 0           while (waitpid($pid, WNOHANG) <= 0) {
62 0           $res .= do { local $/; <$stdoutr> };
  0            
  0            
63             }
64 0           $res .= do { local $/; <$stdoutr> };
  0            
  0            
65            
66 0 0         if (POSIX::WIFEXITED($?)) {
67 0           return CGI::Parse::PSGI::parse_cgi_output(\$res);
68             } else {
69 0           Carp::croak("Error at run_on_shell CGI: $!");
70             }
71 0           };
72 0           $app;
73             }
74              
75             sub prepare_app {
76 0     0 1   my $self = shift;
77 0 0         my $script = $self->script
78             or croak "'script' is not set";
79 0           $script = File::Spec->rel2abs($script);
80              
81 0           my $php_cgi = $self->php_cgi;
82 0   0       $php_cgi ||= which('php-cgi');
83 0 0         croak "cannot find 'php-cgi' command" unless -x $php_cgi;
84              
85 0           $self->_app(wrap_php($php_cgi,$script));
86             }
87              
88             sub call {
89 0     0 1   my($self, $env) = @_;
90 0           $self->_app->($env);
91             }
92              
93              
94             1;
95             __END__