Forum Moderators: coopster & phranque

Message Too Old, No Replies

Still Trying to Parse Multi-Part Form Data

Help please!

         

WriterSP

3:30 am on Jun 20, 2005 (gmt 0)

10+ Year Member



Okay,

I've tried the CGI.PM route and can't get it to work.
Please look at the following code and let me know where I've gone wrong.

(Note, I've tried the suggested code line that uses "upload", but get an error about it being an invalid subroutine;
also, the resulting web page that displays shows no values parsed from my data. )

(Partial Form Page input shown below)----------------

<FORM METHOD="post" ENCTYPE="multipart/form-data" NAME="Newsletter" ACTION="NewsLtr-01F.pl">

<INPUT TYPE='file' NAME="Image-Story1" SIZE=35>

etcetera...

(The parsing portion of my called page)--------------

require CGI;

use CGI qw/:standard/;
$query = new CGI;

$upload_dir = "/images";

$NewsTitle = $query->param( 'NewsTitle' ) ¦¦ '';
$Date = $query->param( 'Date' ) ¦¦ '';
$Lead = $query->param( 'Lead' ) ¦¦ '';

$PicFile = $query->param('Image-Story1') ¦¦ '';

open UPLOADFILE, ">>$upload_dir/$PicFile";
binmode UPLOADFILE;
while ($bytesread=read($PicFile,$buffer,1024)) {
print UPLOADFILE $buffer;
}
close UPLOADFILE;

rename "images/$buffer", "images/$PicFile";
-------------------------------------------------
I've check the CGI documentation (CPAN) and several tutorials/articles, but none give me a complete chunk of code that works. I know this should be simple, but it's driving me nuts. Aaaargh!

Thanks in advance.

Moby_Dim

4:47 am on Jun 20, 2005 (gmt 0)

10+ Year Member



If you have not a solution yet, describe the task in plain words, please (I can not understand the initial problem - do you have a form which has a 'file' field to upload an image and a field containing a description?)

bennymack

2:01 pm on Jun 20, 2005 (gmt 0)

10+ Year Member



Hello, a quick look at the CGI.pm file reveals that if you want to use the upload functionality you need to

use CGI qw/:cgi/;

Because (from source)
':cgi'=>[qw/param upload ...

Whereas :standard only has:
':standard' => [qw/:html2 :html3 :html4 :form :cgi/],

Unless there's some sort cascading that I'm not aware of. See what that gets you.

WriterSP

2:58 pm on Jun 20, 2005 (gmt 0)

10+ Year Member



Thanks.

bennymack, when I replace my line with "use CGI qw/:cgi/;" (below), and put in "$PicFile = $query->upload('Image-Story1');", I still get "undefined subroutine CGI upload...." in my resulting page.

And Moby_Dim, I have an html form which includes several INPUT fields (most are 'text' and one is a 'file' input field to upload a picture). I'm using the correct FORM format for multi-part forms, and my ACTION calls the perl html page where the input information is displayed. The problem I'm having is that my form information isn't getting processed, so therefore the info I'm trying to pass to display isn't showing. The problem is in this CGI portion that parses the passed info--either the wrong procedure or calls or something.

Also guys, I'm using the Tripod webserver for my site. There cgi-bin directory does have CGI.PM, as well as their own TripodCGI.PM (for which there is scant documentation).

Thanks guys.

Moby_Dim

3:21 pm on Jun 20, 2005 (gmt 0)

10+ Year Member



Well, I can find my own script in archives (100% working), but the last paragraph about Tripod server bumped me in a thought... hmmm - can you guarantee that certain services have not been disallowed on the server?

rocknbil

4:57 pm on Jun 20, 2005 (gmt 0)

WebmasterWorld Senior Member 10+ Year Member



Uploading can be a B.. . . ugger. :-)

OK writer there are a couple things you will find HELPFUL.

First, write an error sub:

sub error (
my $error = shift(@_);
print "content-type: text/html\n\n";
print "$error";
exit 0;
}

Chant this 100 times: ALWAYS TRAP ERRORS. :-)

Now,

open (UPLOADFILE, ">$upload_dir/$PicFile")¦¦ (&error("Cannot open file $upload_dir/$PicFile $!");
binmode UPLOADFILE;
while ($bytesread=read($PicFile,$buffer,1024)) {
$totalbytes += $bytesread;
print UPLOADFILE $buffer;
}
close UPLOADFILE;

if (! ($totalbytes > 0)) { &error("ACK! File size is is zero!"); }

Note that >> means append, > means overwrite. You don't want to append.

I don't know if you've ever used $!, see end error statement (no I'm not excited! about not being able to write my file.) $! is an awesome little helper. It holds some errors returned by the system, things like "No such file or directory." Which is what I think you'll see. So USE IT! :-)

Second, you might want to get in the habit of keeping a method of seeing what's actually reaching your program from the form, something like:

@allVars = $query->param;
foreach $k (@allVars) { $debug .= "$k $query->param{$k} <br>"; }
... and print $debug somewhere.

One of the interesting things you'll find is

$PicFile = $query->param('Image-Story1')? '';

$picFile is likely to contain "C:\My Computer\OMG\this_is_now_the_filename"

So when you go to write, you're writing
$upload_dir/C:\My Computer\OMG\this_is_now_the_filename"

As the file name.
That could certainly change things. :-)

You'll want to either pick a random name, or a name that matches the article, or split off the last item in $picFile as the FILENAME:

@path = split (/\/¦\\¦\:/,$picFile); ## / or \ or :, Mac
$filename = $path[$#path]; ## Last item

$filename is now what you write to, as in $upload_dir/$filename.

Third, for the previous reasons, the rename command might be troublesome. This is on a Windblows box? Try getting it to work WITHOUT the rename.

Whether Windblows or linux, make sure the permissions on the upload directory are world-writeable, or at least owned by Apache and writeable by Apache.