I've had to do a very similar thing before, the browser plugin we had to use for a project didn't quite send the data in a proper GET/POST request, therefore CGI.pm couldn't handle the data. For "commercial" reasons, I've had to extract that specific part of the file:
sub library_read_form {
# Reads the incoming data from the web browser
my ($buffer,$pair,$datasent,$name,$value,$mydata,$filename,$contentty
+pe)=("","","","","","","","");
if (length($ENV{'CONTENT_LENGTH'})>0) {
if ($ENV{'CONTENT_TYPE'}=~/^multipart\/form-data/i) {
binmode(STDIN); # cope with Win platforms }
read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
if (length($ENV{'QUERY_STRING'}>0)) { $buffer.="&".$ENV{'QUERY_STRIN
+G'};}
} else {
$buffer=$ENV{'QUERY_STRING'};
}
foreach $var (sort(keys(%ENV))) {
$val = $ENV{$var};$val =~ s|\n|\\n|g;$val =~ s|"|\\"|g;
}
if (($buffer=~/^\<doc /) && ($buffer=~/\<\/doc\>\n?$/)) {
### section removed.....
### don't ask what this did or why, I'm not allowed to say :(
} else {
if (!($ENV{'CONTENT_TYPE'}=~/^multipart\/form-data/i)) {
@pairs = split(/(&|;)/, $buffer);
foreach $pair (@pairs) {
($name, $value) = split(/=/, $pair);
$value =~ tr/+/ /;
$value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;
$datasent.=";$name=$value";
if (length($form{$name})>0) { $value=$form{$name}."\0".$value; }
$form{lc($name)} = $value;
}
} else {
$ENV{'CONTENT_TYPE'}=~/boundary=([^"]+)/i;
$boundary="--".$1;$section=0;
@lines=split(/(\n|\r)/,$buffer);
MULTIPART: foreach $line (@lines) {
if ($section==3) {
if ($line=~/content-type:\s?(.*)/i) {
$contenttype=$1;
} elsif (!($line=~/^(\n|\r|\n\r|\r\n)?$/)) {
$section=4;
}
} elsif ($section==2) {
if ($line=~/^content-type:\s?(.*)/i) {
$contenttype=$1;
} elsif ($line=~/^(\n|\r|\n\r|\r\n)?$/) {
$section=3; # data possibly starts next line
}
} elsif ($section==1) {
if ($line=~/^content-disposition:\s?form-data;\s?name="([^"]+)"
+(.*)$/i) {
$name=$1;if ($2=~/filename="([^"]+)"/) { $filename=$1; }
$section=2; # prepare for data
}
}
if ($line=~/^$boundary(--)?$/) {
$section=1;# found boundary
if ((length($name)>0) && (length($filename)<1)) {
chomp($mydata);chop($mydata); # munch munch
$datasent.=";$name=$mydata";
if (length($form{$name})>0) { $mydata=$form{$name}."\0".$mydata;
+ }
$form{lc($name)}=$mydata;
} elsif (length($name)>0) {
$form_filenames{$name}=$filename;$form_contenttype{$name}=$conte
+nttype;
$tempfile=$tempdir.(time())."_".int(rand(300000));
$tempfile.=".tmp";
open (DATA,">".$tempfile) || die("Unable to open temp dir for st
+orage\n");
binmode(DATA);print DATA $mydata;close DATA;
$form_data{$name}=$tempfile;
}
$name="";$mydata="";$filename="";$contenttype="";
}
if ($section==4) {
$mydata.=$line;
}
}
}
}
$datasent.=";";
}
Data is normally stored in the $form hash (for example
$form{'lastnode_id'}=160961), but if have an uploaded file (say from a
<input type="file" name="tester"> tag, you'll have
$form_data{'tester'} (which contains the name of the temporary file),
$form_filenames{'tester'} (which contains the 'user provided' upload path),
$form_contenttype{'tester'} (which contains the user provided MIME type).
Where it says '
code removed' will probably be the bit you need to hack away at.I put in the appropriate regexp to 'identify' the plugin supplied file, but you'll need to tweak it to recognise your uploaded files and store it either in an appropriate file or variable yourself.
Ok, ok, the code is neither neat, (probably not) secure or 'strict-safe' but it should give you an idea how to do what you are trying to achieve (and it's been happily running on a Windows2000 Server box with Apache for nearly 2 years now). Hope it helps!