File Coverage

blib/lib/WWW/Mechanize/CGI.pm
Criterion Covered Total %
statement 90 95 94.7
branch 34 42 80.9
condition n/a
subroutine 15 15 100.0
pod 4 4 100.0
total 143 156 91.6


line stmt bran cond sub pod time code
1             package WWW::Mechanize::CGI;
2              
3 6     6   359467 use strict;
  6         18  
  6         890  
4 6     6   41 use warnings;
  6         11  
  6         222  
5 6     6   52 use base 'WWW::Mechanize';
  6         14  
  6         26889  
6              
7 6     6   2452196 use Carp;
  6         22  
  6         667  
8 6     6   35 use File::Spec;
  6         509  
  6         219  
9 6     6   34 use HTTP::Request;
  6         18  
  6         137  
10 6     6   10232 use HTTP::Request::AsCGI;
  6         72732  
  6         73  
11 6     6   304 use HTTP::Response;
  6         13  
  6         197  
12 6     6   8444 use IO::Pipe;
  6         15307  
  6         64154  
13              
14             our $VERSION = 0.3;
15              
16             sub cgi {
17 14     14 1 175023 my $self = shift;
18              
19 14 100       124 if ( @_ ) {
20 8         25 $self->{cgi} = shift;
21             }
22              
23 14         139 return $self->{cgi};
24             }
25              
26             sub cgi_application {
27 1     1 1 7 my ( $self, $application ) = @_;
28              
29 1 50       16 unless ( File::Spec->file_name_is_absolute($application) ) {
30 1         45 $application = File::Spec->rel2abs($application);
31             }
32              
33 1         4 $self->env( SCRIPT_FILENAME => $application, $self->env );
34              
35 1 50       36 unless ( -e $application ) {
36 0         0 croak( qq/Path to application '$application' does not exist./ );
37             }
38              
39 1 50       4 unless ( -f _ ) {
40 0         0 croak( qq/Path to application '$application' is not a file./ );
41             }
42              
43 1 50       7 unless ( -x _ ) {
44 0         0 croak( qq/Application '$application' is not executable./ );
45             }
46              
47             my $cgi = sub {
48              
49 2     2   75232 my $status = system($application);
50 2         42 my $value = $status >> 8;
51              
52 2 50       26 if ( $status == -1 ) {
53 0         0 croak( qq/Failed to execute application '$application'. Reason: '$!'/ );
54             }
55              
56 2 100       55 if ( $value > 0 ) {
57 1         755 croak( qq/Application '$application' exited with value: $value/ );
58             }
59 1         7 };
60              
61 1         5 $self->cgi($cgi);
62             }
63              
64             sub fork {
65 25     25 1 72091 my $self = shift;
66              
67 25 100       170 if ( @_ ) {
68 3         12 $self->{fork} = shift;
69             }
70              
71 25         230 return $self->{fork};
72             }
73              
74             sub env {
75 15     15 1 95488 my $self = shift;
76              
77 15 100       76 if ( @_ ) {
78 4         21 $self->{env} = { @_ };
79             }
80              
81 15 100       31 return %{ $self->{env} || {} };
  15         451  
82             }
83              
84             sub _make_request {
85 9     9   79518 my ( $self, $request ) = @_;
86              
87 9 50       60 if ( $self->cookie_jar ) {
88 9         146 $self->cookie_jar->add_cookie_header($request);
89             }
90              
91 9         2642 my $c = HTTP::Request::AsCGI->new( $request, $self->env );
92              
93 9         11781 my ( $error, $kid, $pipe, $response );
94              
95 9 100       44 if ( $self->fork ) {
96              
97 5         58 $pipe = IO::Pipe->new;
98 5         9123 $kid = CORE::fork();
99              
100 5 50       346 unless ( defined $kid ) {
101 0         0 croak("Can't fork() kid: $!");
102             }
103             }
104              
105 9 100       155 unless ( $kid ) {
106              
107 6         306 $c->setup;
108              
109 6         5348 eval { $self->cgi->() };
  6         69  
110              
111 6         664 $c->restore;
112              
113 6 100       1361 if ( $self->fork ) {
114              
115 2         39 $pipe->writer;
116 2 100       364 $pipe->write($@) if $@;
117              
118 2 100       273 exit(1) if $@;
119 1         65 exit(0);
120             }
121             }
122              
123 7         61 $error = $@;
124              
125 7 100       205 if ( $self->fork ) {
126              
127 3         2310553 waitpid( $kid, 0 );
128              
129 3         100 $pipe->reader;
130 3 100       611 $pipe->read( $error, 4096 ) if ( $? >> 8 ) > 0;
131             }
132              
133 7 100       115 if ( $error ) {
134 3         101 $response = HTTP::Response->new( 500, 'Internal Server Error' );
135 3         405 $response->date( time() );
136 3         469 $response->header( 'X-Error' => $error );
137 3         308 $response->content( $response->error_as_HTML );
138 3         233 $response->content_type('text/html');
139             }
140             else {
141 4         58 $response = $c->response;
142             }
143              
144 7         5385 $response->header( 'Content-Base' => $request->uri );
145 7         517 $response->request($request);
146              
147 7 50       779 if ( $self->cookie_jar ) {
148 7         93 $self->cookie_jar->extract_cookies($response);
149             }
150              
151 7         1055 return $response;
152             }
153              
154             1;
155              
156             __END__