PDA

View Full Version : Reading-in Multi-Part forms


mlseim
02-13-2007, 07:27 PM
I had a photo upload script that worked well a week ago, but suddenly
it does not work. My webhost claims nothing has changed.

The HTML form has a spot for up to 5 photos and some text boxes.

I narrowed down the script to the part shown below, with a few
print lines to see what the variables are from the form. The
variable are now coming up null (blank).

I'm just stumped as to why this quit working. Perhaps there's a better
way to bring in multiple files with text boxes mixed together on a form?

#!/usr/bin/perl

binmode(STDIN);
&Parse_Multi;

foreach $item (keys %CGI) {
$var="$item";
$val="$CGI{$item}";
if ($var =~ /\_val/is) {
if ($val eq "") {$var=~ s#\_val##is;$var=~ s#^(.*?)\_##is;error("$var cannot be empty!");}
}
}

## I put this part in to test it out ... the variables are blank.

$direct = $CGI{direct};
$redirect_link = $CGI{'redirect_link'};
print "Content-type:text/html \n\n";
print "direct: ".$direct;
print "<br>";
print "redirect: ".$redirect_link;
print "<br>";

exit;

sub Parse_Multi {
local($boundary,@pairs,$position);
local($raw_data,$value,$name,$part);

$raw_data = &Parse_Method;
($boundary = $ENV{CONTENT_TYPE}) =~ s/^.*boundary=(.*)$/\1/;
@pairs = split(/--$boundary/, $raw_data);
@pairs = splice(@pairs,1,$#pairs-1);

for $part (@pairs) {
$part =~ s/[\r]\n$//g;
($dump, $firstline, $datas) = split(/[\r]\n/, $part, 3);
next if $firstline =~ /filename=\"\"/;
$firstline =~ s/^Content-Disposition: form-data; //;
(@columns) = split(/;\s+/, $firstline);
($name = $columns[0]) =~ s/^name="([^"]+)"$/\1/g;
if ($#columns > 0) {
if ($datas =~ /^Content-Type:/) {
($CGI{"$name"}->{'Content-Type'}, $blankline, $datas) = split(/[\r]\n/, $datas, 3);
$CGI{"$name"}->{'Content-Type'} =~ s/^Content-Type: ([^\s]+)$/\1/g;
}
else {
($blankline, $datas) = split(/[\r]\n/, $datas, 2);
$CGI{"$name"}->{'Content-Type'} = "application/octet-stream";
}
}
else {
($blankline, $datas) = split(/[\r]\n/, $datas, 2);
if (grep(/^$name$/, keys(%CGI))) {
if (@{$CGI{$name}} > 0) {
push(@{$CGI{$name}}, $datas);
}
else {
$arrvalue = $CGI{$name};
undef $CGI{$name};
$CGI{$name}[0] = $arrvalue;
push(@{$CGI{$name}}, $datas);
}
}
else {
next if $datas =~ /^\s*$/;
$CGI{"$name"} = $datas;
}
next;
}
for $currentColumn (@columns) {
($currentHeader, $currentValue) = $currentColumn =~ /^([^=]+)="([^"]+)"$/;
$CGI{"$name"}->{"$currentHeader"} = $currentValue;
}
$CGI{"$name"}->{'Contents'} = $datas;
}
}

KevinADC
02-13-2007, 07:59 PM
use the CGI module and uploading multiple part/mixed data is simple enough.

mlseim
02-13-2007, 08:38 PM
Kevin ...

Do you know of any examples that would be like
a form with 5 photos to upload and a couple of
text boxes all at the same time? Where the script
can capture the form variables as well as the files?

KevinADC
02-13-2007, 10:57 PM
there are lots and lots of file uploader scripts already written. I'm sure you could locate some scripts/examples using a google search or searching script archives.

But if not I will try and locate some later.

mlseim
02-14-2007, 01:01 AM
Kevin ...

I found what I was looking for ... use CGI

An example that works great.... and like you said, very easy.

Thanks for the hint.

mlseim
02-14-2007, 02:55 PM
Kevin ...

I have a footnote to add to this ....

I altered a Perl script that puts a photo into a temporary
directory and uses Imagemagick to resize it. It then adds
a line to a text file (the name of the photo).

I accidently created an endless loop in my script.

Well, I ran the script and realized my mistake and closed my
browser ... too late.

Now, even after 10 hours, the script is still running on my
webhost's server (www.cleverdot.com). It's still appending
lines into the text file. I can't stop it, and my emails to the
webhost are not answered.

So I thought I would be clever and delete the text file, but the
script is smart enough to create it again if it doesn't exist.

Why wouldn't a webhost have a "time-out" for Perl scripts?

Why wouldn't they protect an endless-loop situation?

This puzzles me ... I wonder how many other scripts they have
running like this?

I just checked my directory again, and the text file keeps growing ...
damnit!

FishMonger
02-14-2007, 05:38 PM
Do you have shell access to your account? If so, use the ps command to get the pocess ID of the running script, then use the kill command to stop it.

FishMonger
02-14-2007, 06:47 PM
If you dont have shell access, you can kill it with a quick-n-dirty web script. This can be improved, but should get the job done.

#!/usr/bin/perl

use strict;
use CGI qw/:standard/;

my $runaway_process = 'name_of_script';

print header(), start_html('kill a runaway process');

my $pid = `ps -C $runaway_process -o pid=`;
print "killing runaway $runaway_process : process ID $pid";
system "kill -9 $pid";

print end_html;

KevinADC
02-14-2007, 07:14 PM
trying to answer why a specific webhost does anything is like contemplating your navel. Many are run by people that simply do not have a clue. If I were you I wouldn't report this though. You can write scripts that will run forever! Sounds like a bonus to me... ;)

mlseim
02-14-2007, 08:39 PM
Fishmonger ...

I don't have shell access.

I did notice that they have stopped the script.

But I am saving your "kill" script just in case.

All of my problems started on Saturday. I noticed my website
was not loading (server not found). They now have admitted that
they were down on Saturday. Since then, my previously working
Perl photo upload script worked fine ... after Saturday, it no longer
worked. That's when I used Kevin's idea of "use CGI" ... instead of
the older script I had in place. I got it working great and then
used a "for loop" but made a typo that sent it off endlessly.

Thanks again both of you guys ...