3

I want to get file size I'm doing this:

my $filename=$query->param("upload_file");
my $filesize = (-s $filename);
print "Size: $filesize ";`

Yet it is not working. Note that I did not upload the file. I want to check its size before uploading it. So to limit it to max of 1 MB.

brian d foy
  • 129,424
  • 31
  • 207
  • 592
Luci
  • 3,174
  • 7
  • 31
  • 36
  • Are you uploading a file from the browser or the command line? – zaf Apr 26 '10 at 08:10
  • There seems to be some confusion in the answers. Do you want to check the file size before the client makes the HTTP request, or do you want to check an HTTP request before deciding to process it further? My feeling is that you'll at least have to do the latter in case a client doesn't do the former properly. – brian d foy Apr 26 '10 at 16:24
  • I want to know the size of the file on the server size before uploading it. There are other parameters that will be sent other than the file. If the user is going to upload a file of 1 MB and the POST_MAX is limited to 1MB, then the upload will fail, right? There must be a way to do that in a better way, can't we start reading the file without writing it, and check the size being read? Is that possible? Thank you all for your help. – Luci Apr 28 '10 at 06:47

8 Answers8

5

You can't know the size of something before uploading. But you can check the Content-Length request header sent by the browser, if there is one. Then, you can decide whether or not you want to believe it. Note that the Content-Length will be the length of the entire request stream, including other form fields, and not just the file upload itself. But it's sufficient to get you a ballpark figure for conformant clients.

Since you seem to be running under plain CGI, you should be able to get the request body length in $ENV{CONTENT_LENGTH}.

friedo
  • 65,762
  • 16
  • 114
  • 184
  • From `CGI.pm`: `if (($POST_MAX > 0) && ($content_length > $POST_MAX)) { $self->cgi_error("413 Request entity too large"); last METHOD; }` – Sinan Ünür Apr 26 '10 at 15:22
  • $ENV{CONTENT_LENGTH} seems to be reading the posted input size, yet it doesn't include file size. I tried it and it returned values less than the file size. – Luci Apr 29 '10 at 13:29
3

Also want to sanity check against possibly already having post max set (from perldoc CGI):

$CGI::POST_MAX

If set to a non-negative integer, this variable puts a ceiling on the size of POSTings, in bytes. If CGI.pm detects a POST that is greater than the ceiling, it will immediately exit with an error message. This value will affect both ordinary POSTs and multipart POSTs, meaning that it limits the maximum size of file uploads as well. You should set this to a reasonably high value, such as 1 megabyte.

Community
  • 1
  • 1
hpavc
  • 1,336
  • 7
  • 7
2

The uploaded file is stashed in a tmp location on the server when the form is submitted, check the file size there.

Supply the value for $field.

my $upload_filehandle = $query->upload($field);
my $tmpfilename = $query->tmpFileName($upload_filehandle);
my $file_size = (-s $tmpfilename);
Heinz
  • 471
  • 4
  • 4
1

This has nothing to do with Perl.

You are trying to read the filesize of a file on the user's computer using commands that read files on your server, what you want can't be done using Perl.

This is something that has to be done in the browser, and looking briefly at these questions it's either very hard or impossible.

Your best bet is to allow the user to start the upload and abort if the file is too big.

Community
  • 1
  • 1
Nifle
  • 11,745
  • 10
  • 75
  • 100
1

If you want to check before you process the request, you might be better off checking on the web page that triggers the request. I don't think the web browser can do it on it's own, but if you don't mind Flash, there are many Flash upload tools that can check things like size (as well as file types) and prevent uploading.

A good one to start with is the YUI Uploader. Lots more here: What is the best multiple file JavaScript / Flash file uploader?

Obviously you would want to check on the server side too, but by the time the user has started sending the request to the server, you are already using up your CPU cycles and bandwidth.

Community
  • 1
  • 1
Gavin Brock
  • 5,027
  • 1
  • 30
  • 33
1

Thanks everyone for your replies; I just found out why $filesize = (-s $filename); was not working before, it is due that I was checking file size while sending Ajax request and not while re submitting the page.That's why I was having size to be zero. I fixed that to submit the page and it worked. Thanks.

Luci
  • 3,174
  • 7
  • 31
  • 36
0

Just read this post but while checking the content-length is a good approximate pre-check you could also save the file to temporary folder and then perform any kind of check on it. If it doesn't meet your criteria just delete and don't send it to it's final destination.

-3

Look at the perl documentation for file stats -X - perldoc.perl.org and stat-perldoc.perl.org. Also, you can look at this upload script which is doing the similar thing what you are trying to do.

Space
  • 7,049
  • 6
  • 49
  • 68