File Coverage

blib/lib/Apache/ASP/CGI.pm
Criterion Covered Total %
statement 111 128 86.7
branch 20 32 62.5
condition 13 25 52.0
subroutine 17 22 77.2
pod 0 14 0.0
total 161 221 72.8


line stmt bran cond sub pod time code
1              
2             package Apache::ASP::CGI;
3              
4             # this package emulates an Apache request object with a CGI backend
5              
6 46     46   231791 use Apache::ASP;
  46         153  
  46         1950  
7 46     46   317 use Apache::ASP::Request;
  46         116  
  46         3624  
8 46     46   429370 use Class::Struct;
  46         145675  
  46         5444  
9 46     46   72623 use Apache::ASP::CGI::Table;
  46         135  
  46         1516  
10              
11 46     46   344 use strict;
  46         1545  
  46         1732  
12 46     46   244 no strict qw(refs);
  46         1502  
  46         2761  
13 46     46   2122 use vars qw($StructsDefined @END);
  46         93  
  46         120849  
14             $StructsDefined = 0;
15              
16             sub do_self {
17 39     39 0 184994 my $class = shift;
18              
19 39 100       210 if(defined($class)) {
20 35 100 66     454 if(ref $class or $class =~ /Apache::ASP::CGI/) {
21             # we called this OO style
22             } else {
23 32         114 unshift(@_, $class);
24 32         100 $class = undef;
25             }
26             }
27              
28 39         239 my %config = @_;
29 39   100     294 $class ||= 'Apache::ASP::CGI';
30              
31 39         711 my $r = $class->init($0, @ARGV);
32 39         948 $r->dir_config->set('CgiDoSelf', 1);
33 39         880 $r->dir_config->set('NoState', 0);
34              
35             # init passed in config
36 39         220 for(keys %config) {
37 91         2425 $r->dir_config->set($_, $config{$_});
38             }
39              
40 39         285 &Apache::ASP::handler($r);
41              
42 39         5283 $r;
43             }
44              
45             sub init {
46 51     51 0 517 my($class, $filename, @args) = @_;
47 51   33     250 $filename ||= $0;
48            
49             # for('Class/Struct.pm') {
50             # next if require $_;
51             # die("can't load the $_ library. please make sure you installed it");
52             # }
53            
54             # we define structs here so modperl users don't incur a runtime / memory
55 51 100       244 unless($StructsDefined) {
56 45         118 $StructsDefined = 1;
57 45         715 &Class::Struct::struct( 'Apache::ASP::CGI::connection' =>
58             {
59             'remote_ip' => "\$",
60             'auth_type' => "\$",
61             'user' => "\$",
62             'aborted' => "\$",
63             'fileno' => "\$",
64             }
65             );
66              
67 45         66066 &Class::Struct::struct( 'Apache::ASP::CGI' =>
68             {
69             'connection'=> 'Apache::ASP::CGI::connection',
70             'content_type' => "\$",
71             'current_callback' => "\$",
72             'dir_config'=> "Apache::ASP::CGI::Table",
73             'env' => "\%",
74             'filename' => "\$",
75             'get_basic_auth_pw' => "\$",
76             'headers_in' => "Apache::ASP::CGI::Table",
77             'headers_out'=> "Apache::ASP::CGI::Table",
78             'err_headers_out' => "Apache::ASP::CGI::Table",
79             'subprocess_env' => "Apache::ASP::CGI::Table",
80             'method' => "\$",
81             'sent_header' => "\$",
82             'OUT' => "\$",
83             }
84             );
85             }
86              
87             # create struct
88 51         147682 my $self = new();
89 51 50 33     4696 if(defined $ENV{GATEWAY_INTERFACE} and $ENV{GATEWAY_INTERFACE} =~ /^CGI/) {
90             # nothing, don't need CGI object anymore
91             } else {
92             # command line
93 51         160 my %args = @args;
94 51         1365 $ENV{QUERY_STRING} = join('&', map { "$_=$args{$_}" } keys %args);
  0         0  
95             }
96            
97 51         1762 $self->connection(Apache::ASP::CGI::connection->new);
98 51         9531 $self->dir_config(Apache::ASP::CGI::Table->new);
99 51         648 $self->err_headers_out(Apache::ASP::CGI::Table->new);
100 51         635 $self->headers_out(Apache::ASP::CGI::Table->new);
101 51         587 $self->headers_in(Apache::ASP::CGI::Table->new);
102 51         664 $self->subprocess_env(Apache::ASP::CGI::Table->new);
103              
104 51         1708 my $env = $self->subprocess_env;
105 51         3435 %$env = %ENV;
106              
107 51         1610 $self->filename($filename);
108 51   50     1414 $self->connection->remote_ip($ENV{REMOTE_HOST} || $ENV{REMOTE_ADDR} || '0.0.0.0');
109 51         4193 $self->connection->aborted(0);
110 51         2889 $self->current_callback('PerlHandler');
111              
112             # $self->headers_in->set('Cookie', $ENV{HTTP_COOKIE});
113 51         1338 for my $env_key ( sort keys %ENV ) {
114 1172 50 33     13182 if($env_key =~ /^HTTP_(.+)$/ or $env_key =~ /^(CONTENT_TYPE|CONTENT_LENGTH)$/) {
115 0         0 my $env_header_in = $1;
116 0         0 my $header_key = join('-', map { ucfirst(lc($_)) } split(/\_/, $env_header_in));
  0         0  
117 0         0 $self->headers_in->set($header_key, $ENV{$env_key});
118             }
119             }
120              
121             # we kill the state for now stuff for now, as it's just leaving .state
122             # directories everywhere you run this stuff
123 51 50       1865 defined($self->dir_config->get('NoState')) || $self->dir_config->set('NoState', 1);
124              
125 51   50     1812 $self->method($ENV{REQUEST_METHOD} || 'GET');
126              
127 51         609 for my $env_key ( keys %ENV ) {
128 1172         43222 $self->env($env_key, $ENV{$env_key});
129             }
130 51 50       1848 $self->env('SCRIPT_NAME') || $self->env('SCRIPT_NAME', $filename);
131              
132             # fix truncated output in standalone CGI mode under Win32
133 51         3261 binmode(STDOUT);
134              
135 51         389 bless $self, $class;
136             }
137              
138             sub init_dir_config {
139 6     6 0 80 my($self, %config) = @_;
140 6         329 my $dir_config = $self->dir_config;
141 6         73 %$dir_config = %config;
142 6         27 $dir_config;
143             }
144              
145             sub status {
146 6     6 0 10 my($self, $status) = @_;
147 6 50       16 if(defined($status)) {
148 6         138 $self->headers_out->set('status', $status);
149             } else {
150 0         0 $self->headers_out->get('status');
151             }
152             }
153              
154 0     0 0 0 sub cgi_env { %{$_[0]->env} ; }
  0         0  
155              
156             sub send_http_header {
157 47     47 0 180 my($self) = @_;
158 47         95 my($k, $v, $header);
159            
160 47         1185 $self->sent_header(1);
161 47         1406 $header = "Content-Type: " .$self->content_type()."\n";
162            
163 47         1360 for my $headers ($self->headers_out, $self->err_headers_out) {
164 94         1397 while(($k, $v) = each %$headers) {
165 106 50       1368 next if ($k =~ /^content\-type$/i);
166 106 100       302 if(ref $v) {
167             # if ref, then we have an array for cgi_header_out for cookies
168 1         3 for my $value (@$v) {
169 4   50     10 $value ||= '';
170 4         14 $header .= "$k: $value\n";
171             }
172             } else {
173 105   100     330 $v ||= '';
174 105         601 $header .= "$k: $v\n";
175             }
176             }
177             }
178              
179 47         204 $header .= "\n";
180            
181 47         1875 $self->print($header);
182             }
183              
184             sub send_cgi_header {
185 1     1 0 296 my($self, $header) = @_;
186              
187 1         43 $self->sent_header(1);
188 1         9 my(@left);
189 1         5 for(split(/\n/, $header)) {
190 1         6 my($name, $value) = split(/\:\s*/, $_, 2);
191 1 50       5 if($name =~ /content-type/i) {
192 0         0 $self->content_type($value);
193             } else {
194 1         4 push(@left, $_);
195             }
196             }
197              
198 1         8 $self->print(join("\n", @left, ''));
199 1         16 $self->send_http_header();
200             }
201              
202             sub print {
203 81     81 0 181 shift;
204 81         299 local $| = 1;
205 81 50       186 print STDOUT map { ref($_) =~ /SCALAR/ ? $$_ : $_; } @_;
  81         1188  
206             }
207              
208             sub args {
209 67     67 0 155 my $self = shift;
210              
211 67 50       238 if(wantarray) {
212 0         0 my $params = Apache::ASP::Request->ParseParams($ENV{QUERY_STRING});
213 0         0 %$params;
214             } else {
215 67         370 $ENV{QUERY_STRING};
216             }
217             }
218             *content = *args;
219              
220             sub log_error {
221 0     0 0 0 my($self, @args) = @_;
222 0         0 print STDERR @args, "\n";
223             }
224              
225 78     78 0 428 sub register_cleanup { push(@END, $_[1]); }
226              
227             # gets called when the $r get's garbage collected
228             sub END {
229 46     46   2475 for ( @END ) {
230 78 50       265 next unless $_;
231 78 50 33     793 if(ref($_) && /CODE/) {
232 78         146 my $rv = eval { &$_ };
  78         319  
233 78 50       110 if($@) {
234 0         0 Apache::ASP::CGI->log_error("[ERROR] error executing register_cleanup code $_: $@");
235             }
236             }
237             }
238             }
239              
240 0     0 0   sub soft_timeout { 1; };
241              
242             sub lookup_uri {
243 0     0 0   die('cannot call $Server->MapPath in CGI mode');
244             }
245              
246             sub custom_response {
247 0     0 0   die('$Response->ErrorDocument not implemented for CGI mode');
248             }
249              
250             1;