File Coverage

blib/lib/CGI/Upload.pm
Criterion Covered Total %
statement 80 82 97.5
branch 20 28 71.4
condition 6 9 66.6
subroutine 13 14 92.8
pod 3 3 100.0
total 122 136 89.7


line stmt bran cond sub pod time code
1             package CGI::Upload;
2 9     9   81974 use strict;
  9         72  
  9         285  
3 9     9   42 use warnings;
  9         20  
  9         213  
4              
5 9     9   43 use Carp;
  9         17  
  9         796  
6 9     9   57 use File::Basename;
  9         18  
  9         1280  
7 9     9   6797 use File::MMagic;
  9         148328  
  9         341  
8 9     9   8191 use HTTP::BrowserDetect;
  9         191041  
  9         359  
9 9     9   77 use IO::File;
  9         15  
  9         1196  
10              
11 9     9   57 use vars qw/ $AUTOLOAD $VERSION @ISA @EXPORT_OK /;
  9         17  
  9         8266  
12              
13             require Exporter;
14              
15             @ISA = qw/ Exporter /;
16             @EXPORT_OK = qw/ file_handle file_name file_type mime_magic mime_type query /;
17              
18             $VERSION = '1.13';
19              
20              
21             sub AUTOLOAD {
22 19     19   3437 my ( $self, $param ) = @_;
23              
24             # Parse method name from $AUTOLOAD variable
25              
26 19         34 my $property = $AUTOLOAD;
27 19         124 $property =~ s/.*:://;
28              
29 19         60 my @properties = qw/ file_handle file_name file_type mime_type /;
30              
31 19 100       42 unless ( grep { $property eq $_ } @properties ) {
  76         170  
32 4         850 croak( __PACKAGE__, '->AUTOLOAD : Unsupported object method within module - ', $property );
33             }
34              
35             # Return undef if the requested parameter does not exist within
36             # CGI object
37              
38 15         56 my $cgi = $self->query;
39 15 100       55 return unless defined $cgi->param( $param );
40              
41             # The determination of all information about the uploaded file is
42             # performed by a private subroutine called _handle_file - This subroutine
43             # returns a hash of all information determined about the uploaded file
44             # which is be cached for subsequent requests.
45              
46 10 100       324 $self->{'_CACHE'}->{$param} = $self->_handle_file( $param ) unless exists $self->{'_CACHE'};
47              
48             # Return the requested property of the uploaded file
49              
50 10         90 return $self->{'_CACHE'}->{$param}->{$property};
51             }
52              
53              
54       0     sub DESTROY {}
55              
56              
57             sub _handle_file {
58 5     5   21 my ( $self, $param ) = @_;
59 5         12 my $cgi = $self->query;
60              
61             # Determine and set the appropriate file system parsing routines for the
62             # uploaded path name based upon the HTTP client header information.
63              
64 5         15 my $client_os = $^O;
65 5         42 my $browser = HTTP::BrowserDetect->new;
66 5 100       1545 $client_os = 'MSWin32' if $browser->windows;
67 5 50       332 $client_os = 'MacOS' if $browser->mac;
68 5         409 fileparse_set_fstype($client_os);
69 5         36 my @file = fileparse( scalar($cgi->param( $param )), '\.[^.]*' );
70              
71             # Return an undefined value if the file name cannot be parsed from the
72             # file field form parameter.
73              
74 5 50       733 return unless $file[0];
75              
76             # Determine whether binary mode is required in the handling of uploaded
77             # files -
78             # Binary mode is deemed to be required when we (the server) are running one one
79             # of these platforms: for Windows, OS/2 and VMS
80              
81 5         36 my $binmode = $^O =~ /OS2|VMS|Win|DOS|Cygwin/i;
82              
83             # Pass uploaded file into temporary file handle - This is somewhat
84             # redundant given the temporary file generation within CGI.pm, however is
85             # included to reduce dependence upon the CGI.pm module.
86              
87 5         8 my $buffer;
88 5         795 my $fh = IO::File->new_tmpfile;
89 5 50       35 binmode( $fh ) if $binmode;
90              
91              
92             # it seems that in CGI::Simple for every call to ->upload it somehow resets
93             # the file handle. or I don't really know what is the problem with this code:
94             # while ( read( $cgi->upload( $param ) , $buffer, 1024 ) ) {
95 5         29 my $ourfh = $cgi->upload( $param );
96 5         354 while ( read( $ourfh , $buffer, 1024 ) ) {
97 5         118 $fh->write( $buffer, length( $buffer ) );
98             }
99              
100             # Hold temporary file open, move file pointer to start - As the temporary
101             # file handle returned by the IO::File::new_tmpfile method is only
102             # accessible via this handle, the file handle must be held open for all
103             # operations.
104              
105 5         293 $fh->seek( 0, 0 );
106              
107             # Retrieve the MIME magic file, if this has been defined, and construct
108             # the File::MMagic object for the identification of the MIME type of the
109             # uploaded file.
110              
111 5         221 my $mime_magic = $self->mime_magic;
112 5 50       51 my $magic = length $mime_magic ? File::MMagic->new( $mime_magic ) : File::MMagic->new;
113              
114 5         3192 my $properties = {
115             'file_handle' => $fh,
116             'file_name' => $file[0] . $file[2],
117             'file_type' => lc substr( $file[2], 1 ),
118             'mime_type' => $magic->checktype_filehandle($fh)
119             };
120              
121             # Hold temporary file open, move file pointer to start - As the temporary
122             # file handle returned by the IO::File::new_tmpfile method is only
123             # accessible via this handle, the file handle must be held open for all
124             # operations.
125             #
126             # The importance of this operation here is due to the MIME type
127             # identification routine of File::MMagic on the open file handle
128             # (File::MMagic->checktype_filehandle), which may or may not reset the
129             # file pointer following its operation.
130              
131 5         140458 $fh->seek( 0, 0 );
132            
133 5         401 return $properties;
134             }
135              
136              
137             sub mime_magic {
138 5     5 1 19 my ( $self, $magic ) = @_;
139              
140             # If a filename is passed to this subroutine as an argument, this filename
141             # is taken to be the file containing file MIME types and magic numbers
142             # which File::MMagic uses for determining file MIME types.
143            
144 5 50       32 $self->{'_MIME'} = $magic if defined $magic;
145 5         18 return $self->{'_MIME'};
146             }
147              
148              
149             sub new {
150 8     8 1 50929 my ( $class, $args ) = @_;
151              
152 8 100 100     67 if ($args and 'HASH' ne ref $args) {
153 1         194 croak( __PACKAGE__, 'Argument to new should be a HASH reference');
154             }
155 7         14 my $query;
156 7         18 my $module = "CGI"; # default module is CGI.pm if for nothing else for backword compatibility
157            
158 7 50 66     38 if ($args and $args->{query}) {
159 3         7 $module = $args->{query};
160             }
161              
162 7 100       37 if (ref $module) { # an object was passed to us
163 1         1 $query = $module;
164 1         9 $module = ref $module;
165             } else { # assuming a name of a module was passed to us
166            
167             # load the requested module
168 6         47 (my $file = $module) =~ s{::}{/}g;
169 6         52 $file .= ".pm";
170 6         5178 require $file;
171              
172              
173 5 50       161161 if ("CGI::Simple" eq $module) {
174 0         0 $CGI::Simple::DISABLE_UPLOADS = 0;
175             }
176 5         29 $query = new $module;
177             }
178            
179 6 50 33     55733 if ($module eq "CGI::Simple" and $CGI::Simple::VERSION < '0.075') {
180 0         0 die "CGI::Simple must be at least version 0.075\n";
181             }
182              
183 6         39 my $self = bless {
184             # '_CACHE' => {},
185             '_CGI' => $query,
186             '_MIME' => ''
187             }, $class;
188 6         22 return $self;
189             }
190              
191              
192             sub query {
193 20     20 1 36 my ( $self ) = @_;
194 20         56 return $self->{'_CGI'};
195             }
196              
197              
198             1;
199              
200              
201             __END__