ultranerds has asked for the wisdom of the Perl Monks concerning the following question:

Hi,

I've got a really annoying thing going on here with CGI.pm :/

At first - I thought it was just cos I was tired, and was missing something stupid... but I really can't see it (even now, the morning after)

The code in question is:

use CGI; my $cgi = new CGI; my $fh = $cgi->upload('client_local_offer_image_url'); print $IN->header; print STDERR "HERE ... \n"; while (< $fh >) { print STDERR $_ ; } print "HERE"; exit;


...and the HTML (I've cut some of it out, as its about 800 lines long, and I'm sure you don't wanna see all of it <G>)

<form name="offerForm" id="offerForm" action="/form.cgi" method="post" + enctype="multipart/form-data"> <input type="hidden" name="action" value="catalog_online" /> <input type="hidden" name="do" value="client_manage" /> <input type="hidden" name="func" value="add_do" /> <input type="hidden" name="user_client_id" value="1" /> <table width="100%" border="0" cellspacing="0" cellpadding="4" bgcolor +="#DDE8F4"> <tr bgcolor="#6699CC"> <td colspan="2" height="1" width="100%" class="background_bleu +_fonce_top"><img src="http://images.site.org/images/v2/clear_shim.gif +" width="10" height="1" border="0"><br></td> </tr> <tr> <td width="43%" align="right"><font face="Verdana,Arial,Helvet +ica" size=2 color="#191C1F">Title:</td> <td><font face="Verdana,Arial,Helvetica" size=2 color="#191C1F +"><input type="text" class="button required" name="client_local_offer +_title" size="40" value=""> *</td> </tr> ... more HTML and options <tr> <td width="43%" align="right"><font face="Verdana,Arial,Helvet +ica" size=2 color="#191C1F">Image:</td> <td><font face="Verdana,Arial,Helvetica" size=2 color="#191C1F +"><input type="file" class="button" name="client_local_offer_image_ur +l" size="40"> *</td> </tr> ... more HTML and options </table> </form>


When submitting the form, it submits, BUT nothing ever comes through in the image field that was submitted!

At first, I thought it was a problem with the enctype, but that all appears to be there fine

Can anyone have a look with a fresh pair of eyes, and see if they can spot the boo-boo? I've spent over 3 hours trying to work it out, and I'm still no closer :( (I've done file uploads a ton of times before - which is why I can't work out why this wont work :/)

TIA!

Andy

Replies are listed 'Best First'.
Re: File upload is refusing to work
by 7stud (Deacon) on Nov 16, 2010 at 18:27 UTC

    According to the CGI.pm documentation, section PROCESSING A FILE UPLOAD FIELD, your code should look something like this:

    use CGI; my $cgi = CGI->new(); my $lightweight_fh = $cgi->upload('client_local_offer_image_url'); # undef may be returned if it's not a valid file handle if (defined $lightweight_fh) { # Upgrade the handle to one compatible with IO::Handle: my $fh = $lightweight_fh->handle(); open (my $OUTFILE, '>', 'some_file_path') or die "Couldn't open output file: $!"; while (my $bytes_read = $fh->read($my chunk_of_data, 1024) ) { print {$OUTFILE} $chunk_of_data; } }

    Also this from Programming Perl:

    CGI does not designate how web servers should handle output to STDERR, and servers implement this in different ways, but they almost always produces a 500 Internal Server Error reply. Some web servers, like Apache, append STDERR output to the web server's error log, which includes other errors such as authorization failures and requests for documents not on the server. This is very helpful for debugging errors in CGI scripts.

    Other servers, such as those by iPlanet, do not distinguish between STDOUT and STDERR; they capture both as output from the script and return them to the client. Nevertheless, outputting data to STDERR will typically produce a server error because Perl does not buffer STDERR, so data printed to STDERR often arrives at the web server before data printed to STDOUT. The web server will then report an error because it expects the output to start with a valid header, not the error message. On iPlanet, only the server's error message, and not the complete contents of STDERR, is then logged.

    Note that if you are doing line oriented input, perl will automatically convert any newlines(\n) it reads to \r\n on Windows, which will corrupt the data in an image file if there are any \n characters in the image file.

    Also, you might want to read the following sitepoint article on sanitizing the file name for file uploads:

    http://articles.sitepoint.com/article/uploading-files-cgi-perl
Re: File upload is refusing to work
by Anonymous Monk on Nov 16, 2010 at 12:52 UTC
      Hi,

      Thanks for the reply. However, I'm not trying to "disable" the uploads - in fact, I WANT to upload files =)

      I did find this in your post interesting though:

      print STDERR " CGI dump: " . Dumper(CGI->new);

      ..which prints out:

      CGI dump: $VAR1 = bless( { '.parameters' => [], 'use_tempfile' => 1, '.charset' => 'ISO-8859-1', '.fieldnames' => {}, 'param' => {}, '.cgi_error' => '400 Bad request (malformed multipart + POST)', 'escape' => 1 }, 'CGI' );


      I've never seen that error before - any ideas what i means?

      TIA

      Andy
        Ok weird... it works now.

        However, $IN is actually a variable from GT::CGI (not CGI.pm):

        my $fh = $IN->param('client_local_offer_image_url'); while (<$fh>) { print STDERR $_; }


        Not sure why CGI.pm wasn't working though - as I've used almost idential code in other projects!

        Thanks for the reply anyway

        Cheers

        Andy
        Thanks for the reply. However, I'm not trying to "disable" the uploads - in fact, I WANT to upload files =)

        you were supposed to check those settings to make sure file uploads weren't disabled