| 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__ |