line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Data::FormValidator::Constraints::Upload; |
2
|
1
|
|
|
1
|
|
640
|
use Exporter 'import'; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
54
|
|
3
|
1
|
|
|
1
|
|
5
|
use strict; |
|
1
|
|
|
|
|
1
|
|
|
1
|
|
|
|
|
519
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
# Items to export into callers namespace by default. Note: do not export |
6
|
|
|
|
|
|
|
# names by default without a very good reason. Use EXPORT_OK instead. |
7
|
|
|
|
|
|
|
# Do not simply export all your public functions/methods/constants. |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# This allows declaration use Data::FormValidator::Constraints::Upload ':all'; |
10
|
|
|
|
|
|
|
# If you do not need this, moving things directly into @EXPORT or @EXPORT_OK |
11
|
|
|
|
|
|
|
# will save memory. |
12
|
|
|
|
|
|
|
|
13
|
|
|
|
|
|
|
our @EXPORT = qw( |
14
|
|
|
|
|
|
|
valid_file_format |
15
|
|
|
|
|
|
|
valid_image_max_dimensions |
16
|
|
|
|
|
|
|
valid_file_max_bytes |
17
|
|
|
|
|
|
|
valid_image_min_dimensions |
18
|
|
|
|
|
|
|
); |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our @EXPORT_OK = qw( |
21
|
|
|
|
|
|
|
file_format |
22
|
|
|
|
|
|
|
image_max_dimensions |
23
|
|
|
|
|
|
|
file_max_bytes |
24
|
|
|
|
|
|
|
image_min_dimensions |
25
|
|
|
|
|
|
|
); |
26
|
|
|
|
|
|
|
|
27
|
|
|
|
|
|
|
our $VERSION = 4.85; |
28
|
|
|
|
|
|
|
|
29
|
|
|
|
|
|
|
sub file_format { |
30
|
0
|
|
|
0
|
1
|
0
|
my %params = @_; |
31
|
|
|
|
|
|
|
return sub { |
32
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
33
|
0
|
|
|
|
|
0
|
$self->set_current_constraint_name('file_format'); |
34
|
0
|
|
|
|
|
0
|
valid_file_format($self,\%params); |
35
|
|
|
|
|
|
|
} |
36
|
0
|
|
|
|
|
0
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub image_max_dimensions { |
39
|
0
|
|
0
|
0
|
1
|
0
|
my $w = shift || die 'image_max_dimensions: missing maximum width value'; |
40
|
0
|
|
0
|
|
|
0
|
my $h = shift || die 'image_max_dimensions: missing maximum height value'; |
41
|
|
|
|
|
|
|
return sub { |
42
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
43
|
0
|
|
|
|
|
0
|
$self->set_current_constraint_name('image_max_dimensions'); |
44
|
0
|
|
|
|
|
0
|
valid_image_max_dimensions($self,\$w,\$h); |
45
|
|
|
|
|
|
|
} |
46
|
0
|
|
|
|
|
0
|
} |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
sub file_max_bytes { |
49
|
0
|
|
|
0
|
1
|
0
|
my ($max_bytes) = @_; |
50
|
|
|
|
|
|
|
return sub { |
51
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
52
|
0
|
|
|
|
|
0
|
$self->set_current_constraint_name('file_max_bytes'); |
53
|
0
|
|
|
|
|
0
|
valid_file_max_bytes($self,\$max_bytes); |
54
|
|
|
|
|
|
|
} |
55
|
0
|
|
|
|
|
0
|
} |
56
|
|
|
|
|
|
|
|
57
|
|
|
|
|
|
|
sub image_min_dimensions { |
58
|
0
|
|
0
|
0
|
1
|
0
|
my $w = shift || die 'image_min_dimensions: missing minimum width value'; |
59
|
0
|
|
0
|
|
|
0
|
my $h = shift || die 'image_min_dimensions: missing minimum height value'; |
60
|
|
|
|
|
|
|
return sub { |
61
|
0
|
|
|
0
|
|
0
|
my $self = shift; |
62
|
0
|
|
|
|
|
0
|
$self->set_current_constraint_name('image_min_dimensions'); |
63
|
0
|
|
|
|
|
0
|
valid_image_min_dimensions($self,\$w,\$h); |
64
|
|
|
|
|
|
|
} |
65
|
0
|
|
|
|
|
0
|
} |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
sub valid_file_format { |
68
|
0
|
|
|
0
|
0
|
0
|
my $self = shift; |
69
|
0
|
0
|
|
|
|
0
|
$self->isa('Data::FormValidator::Results') || |
70
|
|
|
|
|
|
|
die "file_format: first argument is not a Data::FormValidator::Results object. "; |
71
|
0
|
|
0
|
|
|
0
|
my $params = shift || {}; |
72
|
|
|
|
|
|
|
# if (ref $params ne 'HASH' ) { |
73
|
|
|
|
|
|
|
# die "format: hash reference expected. Make sure you have |
74
|
|
|
|
|
|
|
# included 'params => []' in your constraint definition, even if there |
75
|
|
|
|
|
|
|
# are no additional arguments"; |
76
|
|
|
|
|
|
|
# } |
77
|
0
|
|
|
|
|
0
|
my $q = $self->get_filtered_data; |
78
|
|
|
|
|
|
|
|
79
|
0
|
|
|
|
|
0
|
my $field = $self->get_current_constraint_field; |
80
|
0
|
|
|
|
|
0
|
my $fh = _get_upload_fh($self); |
81
|
|
|
|
|
|
|
|
82
|
|
|
|
|
|
|
## load filehandle |
83
|
0
|
0
|
|
|
|
0
|
if (!$fh) { |
84
|
0
|
0
|
|
|
|
0
|
warn "$0: can't get filehandle for field named $field" and return undef; |
85
|
|
|
|
|
|
|
} |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
## load file magic stuff |
88
|
0
|
|
|
|
|
0
|
require File::MMagic; |
89
|
0
|
|
|
|
|
0
|
my $mm = File::MMagic->new; |
90
|
0
|
|
|
|
|
0
|
my $fm_mt; |
91
|
|
|
|
|
|
|
|
92
|
|
|
|
|
|
|
## only use filehandle bits for magic data |
93
|
0
|
|
0
|
|
|
0
|
$fm_mt = $mm->checktype_filehandle($fh) || |
94
|
|
|
|
|
|
|
(warn "$0: can't get filehandle for field named $field" and return undef); |
95
|
|
|
|
|
|
|
# Work around a bug in File::MMagic (RT#12074) |
96
|
0
|
|
|
|
|
0
|
seek($fh,0,0); |
97
|
|
|
|
|
|
|
|
98
|
|
|
|
|
|
|
# File::MMagic returns 'application/octet-stream" as a punt |
99
|
|
|
|
|
|
|
# for "I don't know, here's a generic binary MIME type. |
100
|
|
|
|
|
|
|
# In some cases that is has indicated a bug in File::MMagic, |
101
|
|
|
|
|
|
|
# but it's a generally worthless response for identifying the file type. |
102
|
|
|
|
|
|
|
# so, we throw away the response in that case. The uploaded MIME type |
103
|
|
|
|
|
|
|
# will be used instead later, if present |
104
|
0
|
0
|
|
|
|
0
|
$fm_mt = undef if ($fm_mt eq 'application/octet-stream'); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
## fetch mime type universally (or close) |
108
|
0
|
|
|
|
|
0
|
my $uploaded_mt = _get_upload_mime_type($self); |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# try the File::MMagic, then the uploaded field, then return undef we find neither |
111
|
0
|
0
|
0
|
|
|
0
|
my $mt = ($fm_mt || $uploaded_mt) or return undef; |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
# figure out an extension |
114
|
1
|
|
|
1
|
|
444
|
use MIME::Types; |
|
1
|
|
|
|
|
3571
|
|
|
1
|
|
|
|
|
656
|
|
115
|
0
|
|
|
|
|
0
|
my $mimetypes = MIME::Types->new; |
116
|
0
|
|
|
|
|
0
|
my MIME::Type $t = $mimetypes->type($mt); |
117
|
0
|
0
|
|
|
|
0
|
my @mt_exts = $t ? $t->extensions : (); |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
## setup filename to retrieve extension |
120
|
0
|
|
|
|
|
0
|
my $fn = $self->get_input_data->param($field); |
121
|
0
|
|
|
|
|
0
|
my ($uploaded_ext) = ($fn =~ m/\.([\w\d]*)?$/); |
122
|
0
|
|
|
|
|
0
|
my $ext; |
123
|
|
|
|
|
|
|
|
124
|
0
|
0
|
|
|
|
0
|
if (scalar @mt_exts) { |
125
|
|
|
|
|
|
|
# If the upload extension is one recognized by MIME::Type, use it. |
126
|
0
|
0
|
|
|
|
0
|
if (grep {/^$uploaded_ext$/} @mt_exts) { |
|
0
|
|
|
|
|
0
|
|
127
|
0
|
|
|
|
|
0
|
$ext = $uploaded_ext; |
128
|
|
|
|
|
|
|
} |
129
|
|
|
|
|
|
|
# otherwise, use one from MIME::Type, just to be safe |
130
|
|
|
|
|
|
|
else { |
131
|
0
|
|
|
|
|
0
|
$ext = $mt_exts[0]; |
132
|
|
|
|
|
|
|
} |
133
|
|
|
|
|
|
|
} |
134
|
|
|
|
|
|
|
else { |
135
|
|
|
|
|
|
|
# If is a provided extension but no MIME::Type extension, use that. |
136
|
|
|
|
|
|
|
# It's possible that there no extension uploaded or found) |
137
|
0
|
|
|
|
|
0
|
$ext = $uploaded_ext; |
138
|
|
|
|
|
|
|
} |
139
|
|
|
|
|
|
|
|
140
|
|
|
|
|
|
|
# Add the mime_type and extension to the valid data set |
141
|
0
|
|
0
|
|
|
0
|
my $info = $self->meta($field) || {}; |
142
|
0
|
|
|
|
|
0
|
$info = { %$info, mime_type => $mt, extension => ".$ext" }; |
143
|
0
|
|
|
|
|
0
|
$self->meta($field,$info); |
144
|
|
|
|
|
|
|
|
145
|
0
|
|
|
|
|
0
|
return _is_allowed_type($mt, $params); |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
## Returns true if the passed-in mime-type matches our allowed types |
149
|
|
|
|
|
|
|
sub _is_allowed_type { |
150
|
4
|
|
|
4
|
|
351
|
my $mt = shift; |
151
|
4
|
|
|
|
|
30
|
my $params = shift; |
152
|
|
|
|
|
|
|
|
153
|
|
|
|
|
|
|
# XXX perhaps this should be in a global variable so it's easier |
154
|
|
|
|
|
|
|
# for other apps to change the defaults; |
155
|
4
|
|
50
|
|
|
25
|
$params->{mime_types} ||= [qw!image/jpeg image/pjpeg image/gif image/png!]; |
156
|
4
|
|
|
|
|
5
|
my %allowed_types = map { $_ => 1 } @{ $params->{mime_types} }; |
|
16
|
|
|
|
|
23
|
|
|
4
|
|
|
|
|
8
|
|
157
|
|
|
|
|
|
|
|
158
|
4
|
|
|
|
|
24
|
return $allowed_types{lc $mt}; |
159
|
|
|
|
|
|
|
} |
160
|
|
|
|
|
|
|
|
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
sub valid_image_max_dimensions { |
163
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
164
|
0
|
0
|
|
|
|
|
$self->isa('Data::FormValidator::Results') || |
165
|
|
|
|
|
|
|
die "image_max_dimensions: first argument is not a Data::FormValidator::Results object. "; |
166
|
0
|
|
0
|
|
|
|
my $max_width_ref = shift || die 'image_max_dimensions: missing maximum width value'; |
167
|
0
|
|
0
|
|
|
|
my $max_height_ref = shift || die 'image_max_dimensions: missing maximum height value'; |
168
|
0
|
|
|
|
|
|
my $max_width = $$max_width_ref; |
169
|
0
|
|
|
|
|
|
my $max_height = $$max_height_ref; |
170
|
0
|
0
|
|
|
|
|
($max_width > 0) || die 'image_max_dimensions: maximum width must be > 0'; |
171
|
0
|
0
|
|
|
|
|
($max_height > 0) || die 'image_max_dimensions: maximum height must be > 0'; |
172
|
|
|
|
|
|
|
|
173
|
0
|
|
|
|
|
|
my $q = $self->get_filtered_data; |
174
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
175
|
0
|
|
|
|
|
|
my ($width,$height) = _get_img_size($self); |
176
|
|
|
|
|
|
|
|
177
|
0
|
0
|
|
|
|
|
unless ($width) { |
178
|
0
|
|
|
|
|
|
warn "$0: imgsize test failed"; |
179
|
0
|
|
|
|
|
|
return undef; |
180
|
|
|
|
|
|
|
} |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
# Add the dimensions to the valid hash |
183
|
0
|
|
0
|
|
|
|
my $info = $self->meta($field) || {}; |
184
|
0
|
|
|
|
|
|
$info = { %$info, width => $width, height => $height }; |
185
|
0
|
|
|
|
|
|
$self->meta($field,$info); |
186
|
|
|
|
|
|
|
|
187
|
0
|
|
0
|
|
|
|
return (($width <= $$max_width_ref) and ($height <= $$max_height_ref)); |
188
|
|
|
|
|
|
|
} |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
sub valid_file_max_bytes { |
191
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
192
|
|
|
|
|
|
|
|
193
|
0
|
0
|
|
|
|
|
$self->isa('Data::FormValidator::Results') || |
194
|
|
|
|
|
|
|
die "first argument is not a Data::FormValidator::Results object."; |
195
|
|
|
|
|
|
|
|
196
|
0
|
|
|
|
|
|
my $max_bytes_ref = shift; |
197
|
0
|
|
|
|
|
|
my $max_bytes; |
198
|
|
|
|
|
|
|
|
199
|
0
|
0
|
0
|
|
|
|
if ((ref $max_bytes_ref) and defined $$max_bytes_ref) { |
200
|
0
|
|
|
|
|
|
$max_bytes = $$max_bytes_ref; |
201
|
|
|
|
|
|
|
} |
202
|
|
|
|
|
|
|
else { |
203
|
0
|
|
|
|
|
|
$max_bytes = 1024*1024; # default to 1 Meg |
204
|
|
|
|
|
|
|
} |
205
|
|
|
|
|
|
|
|
206
|
0
|
|
|
|
|
|
my $q = $self->get_filtered_data; |
207
|
|
|
|
|
|
|
|
208
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
209
|
|
|
|
|
|
|
|
210
|
|
|
|
|
|
|
## retrieve upload fh for field |
211
|
0
|
|
|
|
|
|
my $fh = _get_upload_fh($self); |
212
|
0
|
0
|
0
|
|
|
|
if (!$fh) { warn "Failed to load filehandle for $field" && return undef; } |
|
0
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
## retrieve size |
215
|
0
|
|
|
|
|
|
my $file_size = (stat ($fh))[7]; |
216
|
|
|
|
|
|
|
|
217
|
|
|
|
|
|
|
# Add the size to the valid hash |
218
|
0
|
|
0
|
|
|
|
my $info = $self->meta($field) || {}; |
219
|
0
|
|
|
|
|
|
$info = { %$info, bytes => $file_size }; |
220
|
0
|
|
|
|
|
|
$self->meta($field,$info); |
221
|
|
|
|
|
|
|
|
222
|
0
|
|
|
|
|
|
return ($file_size <= $max_bytes); |
223
|
|
|
|
|
|
|
} |
224
|
|
|
|
|
|
|
|
225
|
|
|
|
|
|
|
sub valid_image_min_dimensions { |
226
|
0
|
|
|
0
|
0
|
|
my $self = shift; |
227
|
0
|
0
|
|
|
|
|
$self->isa('Data::FormValidator::Results') || |
228
|
|
|
|
|
|
|
die "image_min_dimensions: first argument is not a Data::FormValidator::Results object. "; |
229
|
0
|
|
0
|
|
|
|
my $min_width_ref = shift || |
230
|
|
|
|
|
|
|
die 'image_min_dimensions: missing minimum width value'; |
231
|
0
|
|
0
|
|
|
|
my $min_height_ref = shift || |
232
|
|
|
|
|
|
|
die 'image_min_dimensions: missing minimum height value'; |
233
|
0
|
|
|
|
|
|
my $min_width = $$min_width_ref; |
234
|
0
|
|
|
|
|
|
my $min_height = $$min_height_ref; |
235
|
|
|
|
|
|
|
|
236
|
|
|
|
|
|
|
## do these matter? |
237
|
0
|
0
|
|
|
|
|
($min_width > 0) || die 'image_min_dimensions: minimum width must be > 0'; |
238
|
0
|
0
|
|
|
|
|
($min_height > 0) || die 'image_min_dimensions: minimum height must be > 0'; |
239
|
|
|
|
|
|
|
|
240
|
0
|
|
|
|
|
|
my $q = $self->get_filtered_data; |
241
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
242
|
0
|
|
|
|
|
|
my ($width, $height) = _get_img_size($self); |
243
|
|
|
|
|
|
|
|
244
|
0
|
0
|
|
|
|
|
unless ($width) { |
245
|
0
|
|
|
|
|
|
warn "image failed processing"; |
246
|
0
|
|
|
|
|
|
return undef; |
247
|
|
|
|
|
|
|
} |
248
|
|
|
|
|
|
|
|
249
|
|
|
|
|
|
|
# Add the dimensions to the valid hash |
250
|
0
|
|
0
|
|
|
|
my $info = $self->meta($field) || {}; |
251
|
0
|
|
|
|
|
|
$info = { %$info, width => $width, height => $height }; |
252
|
0
|
|
|
|
|
|
$self->meta($field,$info); |
253
|
|
|
|
|
|
|
|
254
|
0
|
|
0
|
|
|
|
return (($width >= $min_width) and ($height >= $min_height)); |
255
|
|
|
|
|
|
|
} |
256
|
|
|
|
|
|
|
|
257
|
|
|
|
|
|
|
sub _get_img_size |
258
|
|
|
|
|
|
|
{ |
259
|
0
|
|
|
0
|
|
|
my $self = shift; |
260
|
0
|
|
|
|
|
|
my $q = $self->get_filtered_data; |
261
|
|
|
|
|
|
|
|
262
|
|
|
|
|
|
|
## setup caller to make can errors more useful |
263
|
0
|
|
|
|
|
|
my $caller = (caller(1))[3]; |
264
|
0
|
|
|
|
|
|
my $pkg = __PACKAGE__ . "::"; |
265
|
0
|
|
|
|
|
|
$caller =~ s/$pkg//g; |
266
|
|
|
|
|
|
|
|
267
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
268
|
|
|
|
|
|
|
|
269
|
|
|
|
|
|
|
## retrieve filehandle from query object. |
270
|
0
|
|
|
|
|
|
my $fh = _get_upload_fh($self); |
271
|
|
|
|
|
|
|
|
272
|
|
|
|
|
|
|
## check error |
273
|
0
|
0
|
|
|
|
|
if (not $fh) { |
274
|
0
|
|
|
|
|
|
warn "Unable to load filehandle"; |
275
|
0
|
|
|
|
|
|
return undef; |
276
|
|
|
|
|
|
|
} |
277
|
|
|
|
|
|
|
|
278
|
0
|
|
|
|
|
|
require Image::Size; |
279
|
0
|
|
|
|
|
|
import Image::Size; |
280
|
|
|
|
|
|
|
|
281
|
|
|
|
|
|
|
## check size |
282
|
0
|
|
|
|
|
|
my ($width, $height, $err) = imgsize($fh); |
283
|
|
|
|
|
|
|
|
284
|
0
|
0
|
|
|
|
|
unless ($width) { |
285
|
0
|
|
|
|
|
|
warn "$caller: imgsize test failed: $err"; |
286
|
0
|
|
|
|
|
|
return undef; |
287
|
|
|
|
|
|
|
} |
288
|
|
|
|
|
|
|
|
289
|
0
|
|
|
|
|
|
return ($width, $height); |
290
|
|
|
|
|
|
|
} |
291
|
|
|
|
|
|
|
|
292
|
|
|
|
|
|
|
## fetch filehandle for use with various file type checking |
293
|
|
|
|
|
|
|
## call it with (_get_upload_fh($self)) since kind of mock object |
294
|
|
|
|
|
|
|
sub _get_upload_fh |
295
|
|
|
|
|
|
|
{ |
296
|
0
|
|
|
0
|
|
|
my $self = shift; |
297
|
0
|
|
|
|
|
|
my $q = $self->get_filtered_data; |
298
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
299
|
|
|
|
|
|
|
|
300
|
|
|
|
|
|
|
# convert the FH for the filtered data into a -seekable- handle; |
301
|
|
|
|
|
|
|
# depending on whether we're using CGI::Simple, CGI, or Apache::Request |
302
|
|
|
|
|
|
|
# we might not have something -seekable-. |
303
|
1
|
|
|
1
|
|
430
|
use IO::File; |
|
1
|
|
|
|
|
6115
|
|
|
1
|
|
|
|
|
260
|
|
304
|
|
|
|
|
|
|
|
305
|
0
|
0
|
|
|
|
|
if (ref $q->{$field} eq 'IO::File') { |
306
|
0
|
|
|
|
|
|
return $q->{$field}; |
307
|
|
|
|
|
|
|
} |
308
|
|
|
|
|
|
|
else { |
309
|
0
|
|
|
|
|
|
return IO::File->new_from_fd(fileno($q->{$field}), 'r'); |
310
|
|
|
|
|
|
|
} |
311
|
|
|
|
|
|
|
} |
312
|
|
|
|
|
|
|
|
313
|
|
|
|
|
|
|
## returns mime type if included as part of the send |
314
|
|
|
|
|
|
|
## |
315
|
|
|
|
|
|
|
## NOTE: retrieves from original uploaded, -UNFILTERED- data |
316
|
|
|
|
|
|
|
sub _get_upload_mime_type |
317
|
|
|
|
|
|
|
{ |
318
|
0
|
|
|
0
|
|
|
my $self = shift; |
319
|
0
|
|
|
|
|
|
my $q = $self->get_input_data; |
320
|
0
|
|
|
|
|
|
my $field = $self->get_current_constraint_field; |
321
|
|
|
|
|
|
|
|
322
|
0
|
0
|
|
|
|
|
if ($q->isa('CGI')) { |
323
|
0
|
|
|
|
|
|
my $fn = $q->param($field); |
324
|
|
|
|
|
|
|
|
325
|
|
|
|
|
|
|
## nicely check for info |
326
|
0
|
0
|
|
|
|
|
if ($q->uploadInfo($fn)) { |
327
|
0
|
|
|
|
|
|
return $q->uploadInfo($fn)->{'Content-Type'} |
328
|
|
|
|
|
|
|
} |
329
|
|
|
|
|
|
|
|
330
|
0
|
|
|
|
|
|
return undef; |
331
|
|
|
|
|
|
|
} |
332
|
|
|
|
|
|
|
|
333
|
0
|
0
|
|
|
|
|
if ($q->isa('CGI::Simple')) { |
334
|
0
|
|
|
|
|
|
my $fn = $q->param($field); |
335
|
0
|
|
|
|
|
|
return $q->upload_info($fn, 'mime'); |
336
|
|
|
|
|
|
|
} |
337
|
|
|
|
|
|
|
|
338
|
0
|
0
|
|
|
|
|
if ($q->isa('Apache::Request')) { |
339
|
0
|
|
|
|
|
|
my $upload = $q->upload($field); |
340
|
0
|
|
|
|
|
|
return $upload->info('Content-type'); |
341
|
|
|
|
|
|
|
} |
342
|
|
|
|
|
|
|
|
343
|
0
|
|
|
|
|
|
return undef; |
344
|
|
|
|
|
|
|
} |
345
|
|
|
|
|
|
|
|
346
|
|
|
|
|
|
|
|
347
|
|
|
|
|
|
|
1; |
348
|
|
|
|
|
|
|
__END__ |