File Coverage

blib/lib/ASP4/SimpleCGI.pm
Criterion Covered Total %
statement 64 86 74.4
branch 14 32 43.7
condition 1 2 50.0
subroutine 12 14 85.7
pod 5 7 71.4
total 96 141 68.0


line stmt bran cond sub pod time code
1              
2             package ASP4::SimpleCGI;
3            
4 6     6   365 use strict;
  6         9  
  6         150  
5 6     6   21 use warnings 'all';
  6         6  
  6         179  
6 6     6   2388 use HTTP::Body;
  6         150696  
  6         321  
7            
8            
9             sub new
10             {
11 5122     5122 1 10090 my ($s, %args) = @_;
12            
13 5122         5491 my %params = ();
14 5122         4671 my %upload_data = ();
15 6     6   39 no warnings 'uninitialized';
  6         7  
  6         2393  
16 5122 100       9416 if( length($args{querystring}) )
17             {
18 2         10 foreach my $part ( split /&/, $args{querystring} )
19             {
20 2         6 my ($k,$v) = map { $s->unescape($_) } split /\=/, $part;
  4         8  
21            
22 2 50       7 if( exists($params{$k}) )
23             {
24 0 0       0 if( ref($params{$k}) )
25             {
26 0         0 push @{$params{$k}}, $v;
  0         0  
27             }
28             else
29             {
30 0         0 $params{$k} = [ $params{$k}, $v ];
31             }# end if()
32             }
33             else
34             {
35 2         10 $params{$k} = $v;
36             }# end if()
37             }# end foreach()
38             }# end if()
39            
40 5122 100       8019 if( $args{body} )
41             {
42 5         54 my $body = HTTP::Body->new( $args{content_type}, $args{content_length} );
43 5         629 $body->add( $args{body} );
44            
45             # Parse form values:
46 5   50     3053 my $form_info = $body->param || { };
47 5 100       53 if( keys(%$form_info) )
48             {
49 3         11 foreach( keys(%$form_info) )
50             {
51 4         10 $params{$_} = $form_info->{$_};
52             }# end foreach()
53             }# end if()
54            
55             # Parse uploaded data:
56 5 50       18 if( my $uploads = $body->upload )
57             {
58 5         55 foreach my $name ( keys(%$uploads) )
59             {
60             open my $ifh, '<', $uploads->{$name}->{tempname}
61 2 50       76 or die "Cannot open '$uploads->{$name}->{tempname}' for reading: $!";
62             $upload_data{$name} = {
63 2         21 %{$uploads->{$name}},
64             'filehandle' => $ifh,
65             tempname => $uploads->{$name}->{tempname},
66 2         4 };
67 2         18 $params{$name} = $ifh;
68             }# end foreach()
69             }# end if()
70             }# end if()
71            
72 5122         5625 my $cookies = { };
73 5122 100       9279 if( my $cookie_str = $ENV{HTTP_COOKIE} )
74             {
75 5111         11190 foreach my $part ( split /;\s*/, $cookie_str )
76             {
77 5111         8206 my ($name,$val) = map { $s->unescape( $_ ) } split /\=/, $part;
  10222         13336  
78 5111         10869 $cookies->{$name} = $val;
79             }# end foreach()
80             }# end if()
81            
82 5122         27728 return bless {
83             params => \%params,
84             uploads => \%upload_data,
85             cookies => $cookies,
86             %args
87             }, $s;
88             }# end new()
89            
90            
91             sub upload
92             {
93 3     3 1 6 my ($s, $key) = @_;
94            
95 6     6   29 no warnings 'uninitialized';
  6         10  
  6         1302  
96 3 100       30 return exists( $s->{uploads}->{$key} ) ? $s->{uploads}->{$key}->{filehandle} : undef;
97             }# end upload()
98            
99            
100             sub param
101             {
102 0     0 1 0 my ($s, $key) = @_;
103            
104 0 0       0 if( defined($key) )
105             {
106 0 0       0 if( ref($s->{params}->{$key}) )
107             {
108 0 0       0 return wantarray ? @{ $s->{params}->{$key} } : $s->{params}->{$key};
  0         0  
109             }
110             else
111             {
112 0         0 return $s->{params}->{$key};
113             }# end if()
114             }
115             else
116             {
117 0         0 return keys(%{ $s->{params} });
  0         0  
118             }# end if()
119             }# end param()
120              
121              
122 5122     5122 0 19248 sub Vars { shift->{params} }
123              
124              
125             sub cookie
126             {
127 0     0 0 0 my $s = shift;
128            
129 0 0       0 if( @_ )
130             {
131 0         0 my $name = shift;
132 0 0       0 if( exists( $s->{cookies}->{ $name } ) )
133             {
134 0         0 return $s->{cookies}->{ $name };
135             }
136             else
137             {
138 0         0 return;
139             }# end if()
140             }
141             else
142             {
143 0         0 return %{ $s->{cookies} };
  0         0  
144             }# end if()
145             }# end cookies()
146            
147            
148             sub escape
149             {
150 20444     20444 1 15157 my $toencode = $_[1];
151 6     6   28 no warnings 'uninitialized';
  6         8  
  6         1375  
152 20444         25217 $toencode =~ s/([^a-zA-Z0-9_\-.])/uc sprintf("%%%02x",ord($1))/esg;
  0         0  
153 20444         108804 $toencode;
154             }# end escape()
155            
156            
157             sub unescape
158             {
159 10236     10236 1 8816 my ($s, $todecode) = @_;
160 10236 50       14232 return unless defined($todecode);
161 10236         10116 $todecode =~ tr/+/ /; # pluses become spaces
162 10236         8861 $todecode =~ s/%(?:([0-9a-fA-F]{2})|u([0-9a-fA-F]{4}))/
163 0 0       0 defined($1)? chr hex($1) : utf8_chr(hex($2))/ge;
164 10236         15041 return $todecode;
165             }# end unescape()
166              
167              
168             sub DESTROY
169             {
170 5116     5116   3648 my $s = shift;
171            
172             map {
173 2         8 close($s->{uploads}->{$_}->{filehandle});
174 2         133 unlink($s->{uploads}->{$_}->{tempname});
175 5116         3577 } keys(%{$s->{uploads}});
  5116         10289  
176 5116         14461 undef(%$s);
177             }# end DESTROY()
178            
179            
180             1;# return true:
181              
182             =pod
183              
184             =head1 NAME
185              
186             ASP4::SimpleCGI - Basic CGI functionality
187              
188             =head1 SYNOPSIS
189              
190             use ASP4::SimpleCGI;
191            
192             my $cgi = ASP4::SimpleCGI->new(
193             content_type => 'multipart/form-data',
194             content_length => 1200,
195             querystring => 'mode=create&uploadID=234234',
196             body => ...
197             );
198            
199             my $val = $cgi->param('mode');
200             foreach my $key ( $cgi->param )
201             {
202             print $key . ' --> ' . $cgi->param( $key ) . "\n";
203             }# end foreach()
204            
205             my $escaped = $cgi->escape( 'Hello world' );
206             my $unescaped = $cgi->unescape( 'Hello+world' );
207            
208             my $upload = $cgi->upload('filename');
209            
210             my $filehandle = $cgi->upload_info('filename', 'filehandle' );
211              
212             =head1 DESCRIPTION
213              
214             This package provides basic CGI functionality and is also used for testing and
215             in the API enironment.
216              
217             C uses L under the hood.
218              
219             =head1 PUBLIC METHODS
220              
221             =head2 new( %args )
222              
223             Returns a new C object.
224              
225             C<%args> can contain C, C, C and C.
226              
227             =head2 param( [$key] )
228              
229             If C<$key> is given, returns the value of the form or querystring parameter by that name.
230              
231             If C<$key> is not given, returns a list of all parameter names.
232              
233             =head2 escape( $str )
234              
235             Returns a URL-encoded version of C<$str>.
236              
237             =head2 unescape( $str )
238              
239             Returns a URL-decoded version of C<$str>.
240              
241             =head2 upload( $field_name )
242              
243             Returns all of the information we have about a file upload named C<$field_name>.
244              
245             =head2 upload_info( $field_name, $item_name )
246              
247             Returns just that part of C<$field_name>'s upload info.
248            
249             =head1 BUGS
250            
251             It's possible that some bugs have found their way into this release.
252            
253             Use RT L to submit bug reports.
254            
255             =head1 HOMEPAGE
256            
257             Please visit the ASP4 homepage at L to see examples
258             of ASP4 in action.
259            
260             =head1 AUTHOR
261            
262             John Drago L
263            
264             =head1 COPYRIGHT AND LICENSE
265            
266             Copyright 2007 John Drago, All rights reserved.
267            
268             This software is free software. It may be used and distributed under the
269             same terms as Perl itself.
270            
271             =cut