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

I'm currently working on a CGI file upload script, and, as a new programmer, am running into a problem I can't seem to fix. Really, the problem may or may not be perl related, but I figure someone here may know the answer. The problem is that when I select a file to upload on my file upload HTML page, and click "submit" to send the file to my CGI, the browser sits for a few minutes, and then crashes (IE = "DNS error"). I put the following lines in the beginning of my code for debugging purposes:
if ($query->param("Submit")){ die; }
When I submit a file, the program never reaches these lines (the program never dies). However if I goto the url "newimage.cgi?Submit=test", the program promptly dies. I'm using HTML templates, but the same problem occurs when I use static HTML. Below is the HTML code:
<form name="upload" method="post" action="newimage.cgi" enctype="mult +ipart/form-data"> <table border="0" cellpadding="0" cellspacing="0"> <tr><td height="50">&nbsp; </td></tr> <tr> <td colspan="2"> File: <input type="file" name="file" size="40"> </td> </tr> <tr><td colspan="2"> <input type="submit" name="Submit" value="Add Image"> <input type="reset" name="Reset" value="Reset"> </td></tr> <tr><td colspan="2"> <font color="#CC0000" size="-1"></font> </td></tr> </table> </form>
I didn't include my CGI program because I don't feel that the code is the problem. Thanks for any help you can provide.

Replies are listed 'Best First'.
Re: CGI file upload - endless loop??
by Abstraction (Friar) on Jul 17, 2002 at 19:28 UTC
    It may be that your not posting to your script. Try...
    <form name="upload" method="post" action="http://www.your_domain.com/ +cgi-bin/newimage.cgi" enctype="multipart/form-data">


    Also, posting some more of the relevant code may help.

Re: CGI file upload - endless loop??
by sedhed (Scribe) on Jul 18, 2002 at 01:26 UTC

    It may very well be just a timeout problem like joealba said, but your perl code could be the problem. (Your HTML form looks fine.) To elaborate:

    When you submit a multipart form, your browser packages up the file you specified in the file field and sends it along in the HTTP request to the server. So the initial request is when the actual transfer takes place, which can make it appear that it's hung, when it's really just still sending. CGI.pm reads in the file, and places it in a temp file. Only then is your program really able to spit headers and content back to the browser. So if it's a big file and you're on a modem, it will appear to hang, and may even time out.

    (You don't have to process the file, it will just be deleted if you don't.) Try a simple CGI response like:

    #!/usr/bin/perl -w use strict; use CGI; my $q = new CGI; print $q->header(); if ($q->param()) { print $q->ul( 'Got Something:', $q->li( [map {"$_: ".$q->param($_)} $q->param()] ) ); } else { print 'Got squat, sorry'; }

    Anyway, go ahead and post your code, someone will be able to spot the breaking point if there is one.

    PS, I have noticed that in particular IE 5.5 on MacOS seems to have trouble sometimes with all of my CGI.pm-based upload scripts. If that's your OS, you might try debugging from another machine to be sure it's not a client-specific problem.

      First, thanks for your response sedhed. I tried your script and using the form I posted earlier on this thread, came up with some confusing results. Note that I added a text field on the form to make sure that it was sending something in the post. When I uploaded a small text file, the CGI responded with "Got squat" (even though the text field had text in it). When I uploaded a larger (90kb) image file, Netscape responded (client side)"A network error occurred while Netscape was sending data. (Network error: Connection Aborted). Try Connecting again." IE responded with "Cannot find server or DNS error". I added the line $cgi_lib::maxdata = 2000000; to make sure that size limitations wern't the problem. This code did not fix the problem. I can upload a 70kb file (getting "got squat" as the answer), but not a 90kb (or larger) file. The script is running on a PII 400Mhz server, which is on the same LAN as my machine, so bandwidth is not an issue (100BaseT ethernet). Any ideas? Thanks for your help.

        Well first things first... The syntax for setting upload limits is:

        $CGI::POST_MAX=1024 * 200; # max 200k posts # also, though it's already a default... $CGI::DISABLE_UPLOADS = 0;

        I don't know where your got the $cgi_lib::maxdata line, but it's not going to to anything. Note that CGI.pm is entirely different from cgi-lib.pl, and CGI.pm is the generally recommended tool. Sounds like you might be looking at docs or code that were written for cgi-lib.pl.

        To narrow the problem, you could try a simple form with no file fields, just a text box or two, and see how the simple test script responds.

        I've posted a copy of the test script at http://lmsg.net/cgi-bin/lc1/formtest.cgi, feel free to point your form at it for testing. (Max 200k posts is set.)

        Update, typo: changed from /cgi/ to /cgi-bin/

        If the test script works on my server, but not yours, I suspect you might have networking and/or server problems. On the other hand, if it doesn't work for you on my server, I suspect you have client/browser problems, since your sample form works nicely for me when pointed at the above URL. I get...


          Got Something:
        • file: C:\temp\test.jpg
        • Submit: Add Image

        What OSes are involved, and what web server software are you using? Also, be sure to clear your browser cache when doing testing like this, I tell ya the wierdest stuff can happen with IE's caching :)

        Good luck....

Re: CGI file upload - endless loop??
by joealba (Hermit) on Jul 17, 2002 at 20:40 UTC
    2 questions: How big is the image you are uploading? How fast is your connection to the server?

    When uploading a file through HTTP to a CGI script, the entire file is uploaded in the POST request before the script can do its thing. It sounds like the upload is taking so long, your browser (or the web server) is timing out the connection.
Re: CGI file upload - endless loop??
by lpoht (Sexton) on Jul 18, 2002 at 18:01 UTC
    Here is the important part of the code:
    my $query = new CGI; if ($query->param("Submit")){ die; my ($buff, $size, $bytes_read, $title, $description); my $data = 0; my $TOTAL_BYTES = 0; my $file = $query->upload('file'); my $type = $query->uploadInfo($file)->{'Content-Type'}; if (!$file && $query->cgi_error) { $err_msg .= $query->header(-status=>$query->cgi_error); &printhtml; } unless ($type =~ /image/){ $err_msg.="You may only upload image files to this server. +<BR>"; &printhtml; } if ($query->param("title")){$title=$query->param("title");} if ($query->param("description")){$description=$query->param(" +description");} if (!$title or !$description or !$file){ $err_msg.="Missing title or description.<BR>"; &printhtml; } binmode STDIN; binmode STDOUT; open (SAVE, ">C:\temp\upload.jpg"); binmode SAVE; while (read($file,$data,1024)) { #$TOTAL_BYTES += $Bytes; #if (($TOTAL_BYTES > $MAXIMUM_UPLOAD) && ($MAXIMUM_UPLOAD +> 0)) { # $i1 = 1; # last; #} print SAVE $data; } close SAVE;
    the third line (die;) never executes. I'm quite new to perl, so I've been trying all sorts of different file upload methods and don't know if this one even works in theory, let alone reality. Thanks for all of your help.