• Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 248
  • Last Modified:

Uploading


While uploading a file from a form (using "file" type) can I get the size of the file ? Or perhaps the size that has been uploaded so far?
0
leoleo
Asked:
leoleo
  • 4
  • 3
  • 3
1 Solution
 
maneshrCommented:
yes you can..

try this...


=============upload.html==============

<form ENCTYPE="multipart/form-data" action="/cgi-bin/upload.pl" Method=POST>
Attach:<input name="doc" type="file">
<INPUT TYPE=SUBMIT>
</form>

==================upload.pl
#!/usr/local/bin/perl

use CGI;

$query=new CGI;

$DocLocation=$query->param('doc');


$WebFileName = "UpdateGroupFile.htm";
print "Content-type: text/html\n\n";

`rm /tmp/$WebFileName`;
open(MYFILE,"> /tmp/$WebFileName") || die $!;
binmode MYFILE;
while($bytesread=read($DocLocation,$data,1024)){
  $size+=$bytesread; ## Keep track of file size
  print MYFILE $data;
}
close(MYFILE);
close($DocLocation);

`chmod 777 /tmp/$WebFileName`;

print "<B>$DocLocation has been uploaded</B><br>\n";
print "<B>Size = ",$size," byte(s)</B><BR>\n";
0
 
alien_life_formCommented:
Grretings.

Maneshr, your code is correct, but, what you get is actually the size *after* the file has already been uploaded (by CGI.pm) and saved to temporary file.

So, you can get at the size of the file
with:

$size=(stat($query->tmpFileName($query->param('doc')))[7];

OTOH, getting to know the size *before* uploading it, and limiting the upload, requires rummaging through the internals of CGI.pm, which goes out of its way to hide this kind of details. Gaining more control probably leads to overrriding CGI.pm's methods, and specifically the read_multipart sub (look for the UPLOADS: label).
Now that sorta breaks the incapsulation and code privacy stuff...;-)

Failing this, and if coarse grained control is sufficient, one can set the $CGI::POST_MAX variable  to some maximum byte value, and be assured that the *total* post size will not exceed that value.

As a final note, some clients make it possible to know the file size in the header of the multipart document (I.e., they set Content-Length on the single part). But that is client dependent and, last time I looked, netscape was not doing it, so it cannot really be relied upon.

Because of this, the only sure way to know if a file exceeds some specified length is to read that many bytes from stdin.

HTH & cheers,
   alf

0
 
leoleoAuthor Commented:

Thanks, it worked.

One more thing: Is there absolutely no way of getting the total file size just as upload starts? So that I can specify what % has been uploaded so far?
0
Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

 
leoleoAuthor Commented:

Thanks, it worked.

One more thing: Is there absolutely no way of getting the total file size just as upload starts? So that I can specify what % has been uploaded so far?
0
 
alien_life_formCommented:
See my comment above.
0
 
maneshrCommented:
alf,

you are not totally accurate when you say "...what you get is actually the size *after* the file has already been uploaded".

you get the size of the file even as it is being read and not after the file has been uploaded. so if you want to abort the download after reaching a particular limit you can still do that and not have the entire file.

However, in this case i think leoleo would be better off using the solution you have provided.
0
 
alien_life_formCommented:
Greeting.

Well, the way CGI.pm does uploads reads, in part:

[...]
$tmpfile = new TempFile;
$tmp = $tmpfile->as_string;

$filehandle = Fh->new($filename,$tmp,$PRIVATE_TEMPFILES);

$CGI::DefaultClass->binmode($filehandle) if $CGI::needs_binmode;
chmod 0600,$tmp;    # only the owner can tamper with it

my ($data);
local($\) = '';
while (defined($data = $buffer->read)) {
    print $filehandle $data;
}
[...]

here, $buffer is an instance of MultipartBuffer which deep inside is little more than a filehandle. I can see no good way to get into the while (but I'll be glad to be shown one), except by perhaps overriding the read method in  MultipartBuffer - which may be preferable than overriding the whole shebang, anyway.

Looks to me that, by the time that the sub returns, the upload is over. Now it would be nice to have the possibility to supply a callback function to oversee the process, but Lincoln (Stein) will have to take care of that... :-)

Cheers,
  alf
0
 
maneshrCommented:
leoleo, was your problem solved by the answers you got?

Pl. let  the forum know.
0
 
leoleoAuthor Commented:

 I think so, I am still exploring the CGI module which I have not used much.

Thanks indeed.
0
 
maneshrCommented:
Glad to know that you have your solution :). Please go ahead & award thte points to the right answer

Thanks
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

Join & Write a Comment

Featured Post

Get your problem seen by more experts

Be seen. Boost your question’s priority for more expert views and faster solutions

  • 4
  • 3
  • 3
Tackle projects and never again get stuck behind a technical roadblock.
Join Now