sub read_multipart {
my($self,$boundary,$length,$filehandle) = @_;
my($buffer) = $self->new_MultipartBuffer($boundary,$length,$filehandle);
return unless $buffer;
my(%header,$body);
my $filenumber = 0;
while (!$buffer->eof) {
%header = $buffer->readHeader;
unless (%header) {
$self->cgi_error("400 Bad request (malformed multipart POST)");
return;
}
my($param)= $header{'Content-Disposition'}=~/ name="?([^\";]*)"?/;
# Bug: Netscape doesn't escape quotation marks in file names!!!
my($filename) = $header{'Content-Disposition'}=~/ filename="?([^\"]*)"?/
;
# add this parameter to our list
$self->add_parameter($param);
# If no filename specified, then just read the data and assign it
# to our parameter list.
if ( !defined($filename) || $filename eq '' ) {
my($value) = $buffer->readBody;
push(@{$self->{$param}},$value);
next;
}
my ($tmpfile,$tmp,$filehandle);
UPLOADS: {
# If we get here, then we are dealing with a potentially large
# uploaded form. Save the data to a temporary file, then open
# the file for reading.
# skip the file if uploads disabled
if ($DISABLE_UPLOADS) {
while (defined($data = $buffer->read)) { }
last UPLOADS;
}
# choose a relatively unpredictable tmpfile sequence number
my $seqno = unpack("%16C*",join('',localtime,values %ENV));
for (my $cnt=10;$cnt>0;$cnt--) {
next unless $tmpfile = new CGITempFile($seqno);
$tmp = $tmpfile->as_string;
last if defined($filehandle = Fh->new($filename,$tmp,$PRIVATE_TEMPFI
LES));
$seqno += int rand(100);
}
die "CGI open of tmpfile: $!\n" unless defined $filehandle;
$CGI::DefaultClass->binmode($filehandle) if $CGI::needs_binmode;
my ($data);
local($\) = '';
while (defined($data = $buffer->read)) {
print $filehandle $data;
}
# back up to beginning of file
seek($filehandle,0,0);
$CGI::DefaultClass->binmode($filehandle) if $CGI::needs_binmode;
# Save some information about the uploaded file where we can get
# at it later.
$self->{'.tmpfiles'}->{fileno($filehandle)}= {
name => $tmpfile,
info => {%header},
};
push(@{$self->{$param}},$filehandle);
}
}
}