Link to home
Start Free TrialLog in
Avatar of zaq
zaq

asked on

Java File Upload size Limitation

I am working on a servlet that will do file uploads, and all works fine.  However I want to add a size limitation to it.  I did this, and at first had it upload to the server, then check the size, and if it was too large, had it send back a message to the user saying it was too large.

Then I tried doing a check like this.

if (1048576 < req.getContentLength())
{
  throw custom error message;
}

meaning that if the file was larger then 1mb they would get a custom error.  This works, sort of.  For small files (under a couple mb) it only takes a few seconds, however when I attempted to upload a 1.6gb file (as one of my clients tried to do) the browser sits there and hangs.

Is there a way to force the error to occur and stop parsing the user request?  The first thing I have the service method do is that if statement.  I get the error in my logs instantly, but not to the browser.  Does the client browser get hung up on sending the file, even though I'm not doing anything with it?

I also tried instead of throwing a custom error, I threw an IOException, which didn't work.
I also tried to do a res.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE, "File is larger than the set limit");

Which also didn't work.  Is there any way to not have the clients browser choke on this?
Avatar of sudhakar_koundinya
sudhakar_koundinya

This works for IE browsers

<html>
<head>
<script language="JavaScript">
function A()
{
var oas = new ActiveXObject("Scripting.FileSystemObject");
var d = document.a.b.value;
var e = oas.getFile(d);
var f = e.size;
alert(f + " bytes");
}
</script>
</head>
<body>
<form name="a">
<input type="file" name="b">
<input type="button" name="c" value="SIZE" onClick="A();">
</form>
</body>
</html>


function a(str)
{
var myFile = new File(str);
     myFile.open("r");
     alert('myFile length: ' + myFile.getLength());

}
Avatar of zaq

ASKER

I can't use javascript to solve this problem.  Unfortunately the rules of the project do not allow us to do that.

And as for the function a(str), that creates a file, reading in the request content, which is what I'm trying to avoid.  If you read in the request content, when the content is a 1.6gb file, it takes forever.  I can do a req.getContentLength() and instantly know its to big, but I don't know how to stop the client from sending it at that point, if its even possible.
function a(str)
{
var myFile = new File(str);
     myFile.open("r");
     alert('myFile length: ' + myFile.getLength());

}
this is also client side javascript function only, so before uploading only u can get the size of file

Regards
Sudha
So you can't use JavaScript. OK. let me check other possibilities



Avatar of zaq

ASKER

I wanted to test the function you gave me, to see if it would work.  If it did, I could try to convince them to allow javascript for this.  But when I try to use it I get a "File" is undefined.

The activeX version listed before yours works, but ActiveX is definately not going to be allowed.
Avatar of CEHJ
If you're handling the upload at the server side, try closing the input stream
Avatar of zaq

ASKER

well the thing is, I haven't  even opened the input stream.

I do a req.getContentLength(), see its too large, and try to output to the browser, without ever touching the inputstream, but it sits there and hangs while it is aparently recieving/processing the request object, even though I'm not doing anything with it.
OK. Try getting it anyway and closing it
Avatar of zaq

ASKER

getting it, when the user is trying to upload a 1.6gb file, takes forever.  This time is what I'm trying to avoid.
>>getting it ... takes forever

What, getting the input stream?

As mentioned before, it's not possible on all Systems. It is possible on all Windows NT / 2K / XP machines with Internet Explorer. But to use that possibility won't be a good Idea cause it uses Active X and many Apps like Norton think that it's an "evil-script". But there's no other possibility (as far as I know)
Here's a working example:

<html>
<head>
<title>Check Size</title>
<SCRIPT LANGUAGE="VBScript">
<!--
   Function form1_onSubmit ()
          Set WSHShell = CreateObject("WScript.Shell")
          Set fso = CreateObject("Scripting.FileSystemObject")
          Set file = fso.GetFile(document.form1.file.value)
          filename = file.size
          if (file.size > 6291456) then
               MsgBox("The File is too big to upload")
               form1_onSubmit = False
          else
               form1_onSubmit = True
          end if
   End Function
-->
</SCRIPT>


</head>

<body>
<form name="form1" enctype="multipart/form-data" method="post" action="/cgi-bin/upload.cgi">
  <input type="file" name="file">
  <br>
  <input type="submit" name="Submit" value="Submit">
</form>
</body>
</html>
Avatar of zaq

ASKER

Here is my code.

int contentLength = req.getContentLength();
    if (maxSize < contentLength)
    {
      throw new IOException("This file is way too large");
    }

with a 1mb file, it takes about 3 seconds, but with a 1.6gb file, it takes upwards of 10 minutes for the browser to show the error.

if I modify it as follows.

int contentLength = req.getContentLength();
    if (maxSize < contentLength)
    {
      PushbackInputStream input = new PushbackInputStream(
          new BufferedInputStream(req.getInputStream()), 128);
     input.close();
      throw new IOException("This file is way too large");
    }

it still takes the 3 seconds, and 10 minutes respectively.

For both of these, the error log shows the error instantly, but the users browser is hung up for those times.  I don't want the users browser to hang up, even though the server already knows there is an error.
did u try like this??
int contentLength = req.getContentLength();
    if (maxSize < contentLength)
    {
       response.sendRedirect("YourUploadPage.jsp");
    }
Avatar of zaq

ASKER

yes.

Ive tried the following inside the IF.

response.sendRedirect()
response.sendError(HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE)
throw IOException
return
request = null (didn't figure it would work, but was worth a shot)

All of those had an instant error message in the log files, but the browser was still hung up for the times listed in my previous post.
If you use the O'Reilly MultipartRequest it should automatically throw an exception if the file > 1Mb
That would be in conjunction with this

>>
public MultipartParser(HttpServletRequest req, int maxSize) throws IOException
>>

This is the one you should use
Avatar of zaq

ASKER

Even the logic out of the multipartParser method causes the same wait/hanging of the users browser.  I will try to incorporate the entire oreilly multipart package tomorrow and use it.  See if that makes things any better or not.  But if useing the logic they use in the parser to send the exception doesn't work in my if statement.  I don't know why theirs would work.
>>Even the logic out of the multipartParser method causes the same wait/hanging of the users browser

You make it sound as though you've tried this - have you?
Avatar of zaq

ASKER

yes.  I cut out the logic from their method, and used it as the very first thing in the service method of my file.

caused the same hang up.
I see, you've got the source?
Avatar of zaq

ASKER

found it online.  had the jar file of the com.oreilly package, and the java files to go along with it.
I don't believe you can avoid what you are experiencing.
Avatar of zaq

ASKER

So no matter what I do, unless I use client side activeX objects, there is no way for the client to not experience a delay based on the file size they are trying to upload?
Have a look to see if there's a way this can be intercepted and disallowed by the web server (if there *is* a layer in front of the servlet engine)
Avatar of zaq

ASKER

There might be something internal to Tomcat, for a request size limitation, but I haven't looked into tomcat yet to find out.  That I guess will be the next step.
An applet might be helpfule. But you should sign that

import java.applet.*;
import java.awt.*;
import java.io.*;

public class FileSizeApplet extends Applet {
    public void init() {
        setSize(0,0);
    }
   
   
    public long getFileSize(String str)
    {
        File f=new File(str);
        return f.length();
    }
   
}



<HTML>

<script Language=JavaScript>
            function fileSize()
            {

                  alert(document.FileSize.getFileSize("c:\\a.txt"));
            }
            </script>
<HEAD>
   <TITLE>Applet HTML Page</TITLE>
</HEAD>
<BODY >
<APPLET CODE = "FileSizeApplet.class" WIDTH = 10 HEIGHT = 10 NAME = FileSize>
</APPLET>
<form name=filesize1>

<input type=button value='Get Size' onClick="fileSize();">
</form>
</BODY>
</HTML>
Avatar of zaq

ASKER

applets are yet another thing we aren't allowed to use.

It looks like I'll be able to protect the server from the large files being uploaded, but the client will have to wait to get the error until the upload of the request is complete.  Guess it serves the client right for doing something they know they aren't supposed to.

If anyone else has any ideas I'm all open, but it doesn't seem like there is.
>  there is no way for the client to not experience a delay based on the file size they are trying to upload?

I believe that is correct.
Avatar of zaq

ASKER

I have to say that the solutions here were good, if not for the limitations of my clients.

I have come to the conclusion that I will do the check in the java, and the client will have to live with the lag time due to uploading a file they should know is too large.

I'm not sure how to go about giving the points for this since I didn't actually get a final workable solution.  Anyone have any idea what I should do about setting this to closed, and giving someone credit for answering?
SOLUTION
Avatar of CEHJ
CEHJ
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
8-)
Avatar of zaq

ASKER

I thought splitting the points between the three of you, since you three tried as much as you could to help would be fair.

Thanks for all the help.  Now I just need to sit down with my clients and tell them that if they want the lag time to go away they must allow javascript.

Thanks again.
Thank You :-)