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

Oh pious ones. I gleaned great wisdom from this thread Uploading a File. However, it does not seem to work in IE on Windows. It works fine with other OS/browser combinations. In IE it creates a 0KB file. Any idea what the problem may be? Snippet below:
my ($Bytes, $Buffer, $BytesRead); open OUTFILE, ">$upload_dir/$filename" or die "Couldn't open o +utput file: $!\n"; binmode OUTFILE; while ($Bytes = read($filename,$Buffer,1024)) { $BytesRead += $Bytes; print OUTFILE $Buffer; } close OUTFILE;

Replies are listed 'Best First'.
Re: file upload
by Coruscate (Sexton) on Jul 11, 2003 at 06:11 UTC

    The other users have stated that grabbing the filehandle via CGI.pm's param() method is the best way. Please use the upload() method rather than param(). It's meant to be that way nowadays :) param() works but has a couple of small annoyances. From perldoc CGI:

    However, there are problems with the dual nature of the upload fields. If you "use strict", then Perl will complain when you try to use a string as a filehandle. You can get around this by placing the file reading code in a block containing the "no strict" pragma. More seri- ously, it is possible for the remote user to type garbage into the upload field, in which case what you get from param() is not a filehan- dle at all, but a string. To be safe, use the upload() function (new in version 2.47). When called with the name of an upload field, upload() returns a filehandle, or undef if the parameter is not a valid filehandle. $fh = $query->upload('uploaded_file'); while (<$fh>) { print; } In an array context, upload() will return an array of filehandles. This makes it possible to create forms that use the same name for mul- tiple upload fields. This is the recommended idiom.


    If the above content is missing any vital points or you feel that any of the information is misleading, incorrect or irrelevant, please feel free to downvote the post. At the same time, please reply to this node or /msg me to inform me as to what is wrong with the post, so that I may update the node to the best of my ability.

Re: file upload
by cbro (Pilgrim) on Jul 10, 2003 at 20:14 UTC
    I though that the first argument to read needed to be a file handle. I tested your code and it didn't work anywhere (via browser or manually on a LINUX box), but as soon as I added the following lines, all was well:
    open (IN, "$filename") || die ("$!"); # your code here # now change read to... while ($Bytes = read(IN, $Buffer, 1024)) { $BytesRead += $Bytes; print OUTFILE $Buffer; } close(OUTFILE); close(IN);
    Give that a try.

    HTH,
    Chris

      Try the following:

      my $file; open($file,"<test.txt") or die "urg: $!"; while ($bytes = read($file,$buffer,1024)) { $bytesread+=$bytes; print OUTFILE $buffer; } close(OUTFILE); close($file);

      Also, $filename is probably being set by calling $filename = CGI::param('upload_file_field'); which returns a variable that acts as both a string and a filehandle. As for why it doesn't work for IE, we would need to know the version of IE and platform (if it's Mac and IE4.x, there's a known issue with uploading files...but I don't recall much beyond that) before we begin beating ourselves in the head over this. Since it works with other browsers, the problem seems to be with the version of IE.

      antirice    
      The first rule of Perl club is - use Perl
      The
      ith rule of Perl club is - follow rule i - 1 for i > 1

        I am using CGI as you assumed. Sorry, I should have been more clear on that. The script does work on the Mac, althought I haven't tested it with IE4. It has successfully worked with MacOSX (Camino, IE, iCab, Safari), it also works fine on Linux (mozilla) and in Windows (Netscape). However, it is not working in Windows IE (XP/6.0) -- I'm trying to test on other Win/IE combos. So, it appears to be an IE issue.

        It does print the filename, but not the content (there's a 0K file), and the error log doesn't show anything.

        Also, this problem exists on two different servers:
        Apache/1.3.26 (Unix) PHP/4.2.3 mod_perl/1.27 on FreeBSD
        Perl 5.005_03

        Apache/1.3.27 (Unix) mod_ssl/2.8.11 OpenSSL/0.9.6b FrontPage/5.0.2.2510 PHP/4.3.0 mod_throttle/3.1.2 on Linux
        Perl 5.006

      In fact, if he uses the CGI module and he gets $filename from the param() method, then the string is also a filehandle. I also made the mistake in Re: Upload a file from a web form ;)
Re: file upload
by choocroot (Friar) on Jul 10, 2003 at 21:18 UTC
    Have you checked your http server logs for error messages ?

    Does it work if you write your file to a "static" filename ? for example:
    open OUTFILE, "> /tmp/test_upload" or die "error: $!";
    Using directly $filename, from the CGI param(), in open() is insecure as someone could overwrite your system files by uploading files named "../../../var/www/html/index.html" for example. It is wiser to use a temporary filename and never trust the filename from param().