Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Apache commons fileupload timeout only with Firefox

I use the Apache commons fileupload 1.4 library in my java project. I have a html part with a classic form with a file input and some hidden fields.

I have a problem with uploading files of around >500ko only with Firefox >= 52

It works well with files of 10mo in Chrome or Internet Explorer. But with Firefox, I have a timeout after waiting several minutes after submitting the form.

After some debugging, I see that the code responsible of the timeout is :

List<FileItem> items = (new ServletFileUpload(new DiskFileItemFactory())).parseRequest(request);

The part with cause wait is "parseRequest".

I try to debug the content of request with debugger in IntelliJ, but there is no way to copy entire content value of this request object in raw format.

It's working in these cases : - Firefox : version <= 52 or file size < 500ko (around, it's not really precise) - Internet Explorer - Chrome

There is no file size limit, it seems that depends on the request size, because the parsing request part is taking too much time...

I get the HTTP request with a Firefox extension in two cases. One generating uploading a file of 3mo which doesn't works (the request file is huge, 3x the size of the uploaded file) : https://code.empreintesduweb.com/13561.html

One generated uploading a file of 200ko which works (the request file is small) : https://code.empreintesduweb.com/13560.html

In fact, the main difference is that in Chrome or IE, I don't have the raw content of the uploaded file in the request headers :

The part with : obj stream .... endstream endobj

Only appear with Firefox...

like image 246
user2178964 Avatar asked May 10 '19 11:05

user2178964


3 Answers

You can try setting the maximum file size, maybe the file size exceeds the maximum threshold .According to the documentation :

  • Uploaded items should be retained in memory as long as they are reasonably small.
  • Larger items should be written to a temporary file on disk.
  • Very large upload requests should not be permitted.
  • The built-in defaults for the maximum size of an item to be retained in memory, the maximum permitted size of an upload request, and the location of temporary files are acceptable.

Try the following :

 protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            // Set factory constraints
           DiskFileItemFactory factory = new DiskFileItemFactory();
           factory.setSizeThreshold(yourMaxMemorySize);
           ServletContext servletContext = this.getServletConfig().getServletContext();
           File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir");
           factory.setRepository(repository);
            List<FileItem> items = new ServletFileUpload(factory).parseRequest(request);
            for (FileItem item : items) {
                if (item.isFormField()) {
                    // Process regular form field (input type="text|radio|checkbox|etc", select, etc).
                    String fieldName = item.getFieldName();
                    String fieldValue = item.getString();
                    // ... (do your job here)
                } else {
                    // Process form file field (input type="file").
                    String fieldName = item.getFieldName();
                    String fileName = FilenameUtils.getName(item.getName());
                    InputStream fileContent = item.getInputStream();
                    // ... (do your job here)
                }
            }
        } catch (FileUploadException e) {
            throw new ServletException("Cannot parse multipart request.", e);
        }

        // ...
    }

Here, we are providing a temp location for the file since the file is large.

like image 100
Ananthapadmanabhan Avatar answered Oct 10 '22 12:10

Ananthapadmanabhan


A few things that are worth to try here:

  • Explicit the encoding: https://stackoverflow.com/a/10488411/4279120
  • Decompose your call and add iteration and try catch, ex. : https://www.programcreek.com/java-api-examples/?api=org.apache.commons.fileupload.FileItemIterator
  • Take a look at the MultipartConfig, it seems to provide such attributes as maxFileSize and maxRequestSize (see: https://www.codejava.net/java-ee/servlet/java-file-upload-example-with-servlet-30-api#maxFileSize%28%29)
  • Manually define the header of your Request if you can. It seems that adding "X-File-Name" and "X-File-Size", can also help, but this is a little old: AJAX File Upload with XMLHttpRequest

We may also help you better if you provide some more informations, like the versions of apache / java / servlet, and a few more code (especially the definition of request)

Some ressources that could be helpful:
XMLHttpRequest
Sending_files_using_a_FormData_object
How to set a header for a HTTP GET request, and trigger file download?

like image 20
olinox14 Avatar answered Oct 10 '22 13:10

olinox14


try this to set session timeout using setMaxInactiveInterval method

 request.getSession().setMaxInactiveInterval(1200);

parameter Specifies the time, in seconds, between client requests before the servlet container will invalidate this session. An interval value of zero or less indicates that thesession should never timeout.

like image 1
Niravdas Avatar answered Oct 10 '22 12:10

Niravdas