0

I have a servlet application that need to receive some files from some clients (in general not html\javascript based!) and I have to limit the filesize for each file. Thisi is a classical problem.

The streaming API of the apache fileUpload allow to stream a multi-part request to the server avoiding the need of saving the request content in temporary files before they are processed. Is this Correct?

Anyway with this approach I obviously can't know the actual filesize.
What I though was:

  1. The client knows the file size. So it will send a form-field containing the file size.
  2. The content-length http header contains the request size, so I can take it as an upperbound of the filesize
  3. I can count the bytes I'm saving

Now assuming that I want to make all the necessary validations server-side. This because I'm paranoic and I don't trust the clients, then:
a. options (1) and (2) are useful in case "good" clients make bad requests. So a first validation can be based on that. b. option (3) is the only completely server-side option I found. So it is needed.

So I though that I could count the bytes I read and if the file exceedes the size-limit I print errors, delete the file I was writing and then make the "return" in servlet doPost. Am I doing right or there are some other better way to go?

LJSilver
  • 583
  • 7
  • 20

1 Answers1

0

Try like this into your Servlet, also get all information about file from item

    //TODO Create and check tmpDir & destinationDir then do as below
    PrintWriter out = response.getWriter();
    response.setContentType("text/xml;charset=UTF-8");
    File file = null;
    DiskFileItemFactory fileItemFactory = new DiskFileItemFactory();
    fileItemFactory.setSizeThreshold(10 * 1024 * 1024);
    fileItemFactory.setRepository(tmpDir); /* Set the temporary directory for uploaded files of size above threshold. */
    ServletFileUpload uploadHandler = new ServletFileUpload(fileItemFactory);
    try {
        List items = uploadHandler.parseRequest(request);
        Iterator itr = items.iterator();
        while (itr.hasNext()) {
            FileItem item = (FileItem) itr.next();
            if (item.getSize() <######||item.getSize() > 0){ // Where you can control file size
                if (item.isFormField()) {
                    System.out.println("Field = " + item.getFieldName() + ", Value = " + item.getString());
                } else {
                    System.out.println("Field Name = " + item.getFieldName() + ", File Name = " + item.getName() + ", Content type = " + item.getContentType() + ", File Size = " + item.getSize());
                    file = new File(destinationDir, item.getName()); ///Destination for permanent save*/
                    item.write(file);
                }
                out.println("Upload success");
            }else{
                out.println("File Size is not be zero OR more than ####");
            }
        }
    } catch (FileUploadException ex) {
        out.println("Upload Failed" + ex.getMessage());
        log("Error while parsing the request", ex);
    } catch (Exception ex) {
        out.println("Upload Failed" + ex.getMessage());
        log("Error while uploading file", ex);
    }
    out.close();
Suzon
  • 749
  • 1
  • 8
  • 21
  • 1
    thanks for replying! But this uses the standard API not the streaming one right? – LJSilver Feb 23 '14 at 15:50
  • 1
    Please take a look first [ServletFileUpload](http://commons.apache.org/proper/commons-fileupload/apidocs/org/apache/commons/fileupload/servlet/ServletFileUpload.html). – Suzon Feb 23 '14 at 15:54
  • 1
    Ok my question is not about how to upload a file, but how to control the file size – LJSilver Feb 23 '14 at 16:08
  • 1
    in a streaming context – LJSilver Feb 23 '14 at 16:16
  • To control file size use `ServletFileUpload.setSizeMax(long sizeMax) & getFileSizeMax()' then check by condition .... and hope it will serve your problem ? – Suzon Feb 23 '14 at 16:19
  • What I know about setsizemax is that it limits the total request size, not the uploaded file one and it can be applied to standard API only because it needs files to be stored in temporary locations. Is that not correct? – LJSilver Feb 23 '14 at 16:32
  • Well! temp Location is used for some other purpose i.e: if the connection broken. Sets the maximum allowed size of a complete request, as opposed to setFileSizeMax(long) and Returns the maximum allowed size of a single uploaded file, as opposed to getSizeMax(). ... [setSizeMax(long)](http://commons.apache.org/proper/commons-fileupload/apidocs/org/apache/commons/fileupload/FileUploadBase.html#setSizeMax(long)) – Suzon Feb 23 '14 at 16:38
  • 1
    Ah ok, my doubt is about the fact that I prefer to use a streming approach in order to avoid temporary savings. In this case I can't use setSizeMax etc.. I must find another trick – LJSilver Feb 23 '14 at 16:44
  • Yes you may... [how to upload a file using commons file upload streaming api](http://stackoverflow.com/questions/15432024/how-to-upload-a-file-using-commons-file-upload-streaming-api). Best of Luck .. – Suzon Feb 23 '14 at 16:47
  • thanks Suzon for the comments and excuse my ignorance, but I still don't get the point. In the link you write there's the first answer that refers to standard API and the second to the streaming one. But in both no size control is mentioned. – LJSilver Feb 23 '14 at 17:32
  • Check the update post where your file size will control according to your need - Thanks – Suzon Feb 23 '14 at 17:49