[Buffalo-pm] CGI.pm uploadinfo filesize

joshj@linuxmail.org joshj at linuxmail.org
Fri Mar 3 08:16:56 PST 2006


Thanks Jim and Dan for the replies. Since I originally posted I've run
into another problem. The first problem was getting the orginal file
size. Which, just like Jim said, I can get after I've got the file
handle. but I can't track progress that way. But I figured I could do
without that, I could just show how many bytes (or Kbytes or whatever)
have been uploaded so far. so the user would have some idea that
something is actually happening. Well, I noticed that when I uploaded a
larger file (~10M) my "buffer" file wouldn't change size until it was
almost finished, then it would grow really fast in size and be done way
sooner than a 10M file should take to upload. A bit of research into
this showed that CGI.pm actually creates its own temp file. Then when
you do that loop with the "buffer" file, you are actually chunking it
from CGI.pm's temp file into your custom filename. Any "file uploader"
I've seen online (filechucker, xupload) has this same draw back. It
won't indicate any progress until the upload is almost finished, then it
will shoot up. And even then it is a 'fake' status because it only knows
the filesize after it has the file. On my system the CGItemp files are
stored at /var/tmp/CGItemp[0-9]{5} . So I've been working out a system
with lockfiles and whatnot to track the progress of the file that I
want. Not the most graceful but...  I looked into hacking up CGI.pm or
accessing the raw POST without CGI.pm but thats just too messy. Too
error prone.

Dan: I dumped the %ENV on upload and there was no FILE or anything
closely related. However, CONTENT_LENGTH was suspiciously close in size
to the file I uploaded. Just a little bigger. I guess it accounts for
all bytes transfered. Which, of course, the file makes up the bulk of. I
thought I could use this but I can't really (in fact, it might not be
created until CGI.pm's temp file is done). Because the script won't do
anything until it is done buffering the file. Even with buffering turned
off. So for example:

use strict;
$|=1;
print "starting upload...\n";
# upload code here
print "done with upload\n";


won't print anything until the upload is complete. I thought that it
would print a start message to indicate some goings-on. but thats not
the case.

Either way, I'll let you guys know what I come with. Its an interesting
problem that seems to have not really been tackeled before. Its not a
big deal for files less than 2M (on broadband). but over that the
browser just sits there spinning without any indication of progress
unless you have a monitor on your network interface. Any more
ideas (and don't say "applet")?

-Josh J

Thus spake Jim Brandt on Fri, 3 Mar 2006

> Check out the code for the valid_file_max_bytes method in this module:
>
> http://search.cpan.org/src/MARKSTOS/Data-FormValidator-4.14/lib/Data/FormValidator/Constraints/Upload.pm
>
> If you trace it through, you'll see they use CGI.pm 'upload' method to get a 
> filehandle to the uploaded file. Then they just stat the file.
>
> 	 my $fh = _get_upload_fh($self);
> 	 if (!$fh) { warn "Failed to load filehandle for $field" && return
> 	 undef; }
>
> 	 ## retrieve size
>   	 my $file_size = (stat ($fh))[7];
>
> I don't think this will really solve your problem, though. To display 
> progress, you need to know the size of the file ahead of time. But you can't 
> know this until you've already got the file on your file system.
>
> If you want a progress indicator, you just need to make a fake one.
>
>
>
> DANIEL MAGNUSZEWSKI wrote:
>>  This page may help a little - check out the bottom of the last example
>>  (http://perlmeme.org/tutorials/cgi_upload.html):
>>
>>
>>          while ($bytesread = read($filename, $buffer, $num_bytes)) {
>>              $totalbytes += $bytesread;
>>              print OUTFILE $buffer;
>>          }
>>
>>  I can't find anything on it right now, but I was told that there is a
>>  "FILE" (or something similar) entry in the %ENV (environment variable)
>>  hash. It should contain a whole bunch of information on the file (name,
>>  size, etc). If this is the case, then you can simply grab the filesize
>>  and use the above while loop and compare the bytes read with whatever
>>  the total number of bytes is.
>>  I'm not a "web guy" so I'm not too familar with using %ENV beyond its
>>  basic uses. Does anyone else know if the filesize is in %ENV?
>>
>>  -Dan
>>
>> 
>> > > >  <joshj at linuxmail.org> 03/01/06 6:20 PM >>>
>>  How exactly do you get the filesize of an uploaded file? I'd like to
>>  use
>>  it so I could display progress to the user. Everything seems to say to
>>  use uploadInfo from CGI.pm or upload_info from CGI::Simple. The only
>>  one
>>  that even returns anything useful is CGI.pm. It gives me content-type,
>>  content-disposition, name, and filename. But no file size. So I'm
>>  thinking that maybe there is something more I should specify in the
>>  html
>>  to tell the client that I want that information. Here is my html form:
>>
>>  <form method="post" action="oldup.cgi" enctype="multipart/form-data">
>>  <input type="file" name="upfile" /><input type="submit" /></form>
>>
>>  and the cgi:
>>
>>  use strict;
>>  use CGI qw(:standard uploadInfo);
>>  use Data::Dumper;
>>
>>  my $q = new CGI;
>>  my $fname = param('upfile');
>>  my $fsize = $q->uploadInfo($fname);
>>  print <<"html";
>>  Content-type: text/html
>>
>>  <h1>UpLoad File</h1>
>>
>>  file: $fname<br />
>>
>>  <b>Done $fsize</b>
>>  html
>>  print Dumper($fsize);
>>
>>  ------------------------------
>>  Any ideas how to get this information?
>>
>>  -Josh J
>>  _______________________________________________
>>  Buffalo-pm mailing list
>>  Buffalo-pm at pm.org http://mail.pm.org/mailman/listinfo/buffalo-pm
>>
>>  _______________________________________________
>>  Buffalo-pm mailing list
>>  Buffalo-pm at pm.org
>>  http://mail.pm.org/mailman/listinfo/buffalo-pm
>
> -- 
> Jim Brandt
> Administrative Computing Services
> University at Buffalo
>
>


More information about the Buffalo-pm mailing list