2

According to Tomcat7's documentation, setting maxPostSize in Connector to a value less than or equal to 0 may disable the limit of the size of a post request. But in fact, when I set it to 0, uploading a file in multipart/form-data enctype still got the error of exceeding the max size limit. When I set it to -1, no limit occurs, but other strange things happened.

Here is the HTML codes for uploading a file with a text input field:

<html>
    <head>
    </head>
    <body>
        test
        <form action="UploadFile" method="post" enctype="multipart/form-data">
            <input type="text" name="description" />
            <input type="file" name="file" />
            <input type="submit" />
        </form>
    </body>
</html>

The server side codes are using Servlet 3.0 api:

import javax.servlet.http.Part;
import javax.servlet.annotation.MultipartConfig;
import java.io.InputStream;
import java.io.FileOutputStream;
import java.io.PrintWriter;
import java.util.Collection;
import com.google.gson.JsonObject;
import com.google.gson.JsonArray;
import com.google.gson.JsonElement;


    @MultipartConfig(fileSizeThreshold=1024*1024*10,    // 10 MB
                     maxFileSize=1024*1024*50,          // 50 MB
                     maxRequestSize=1024*1024*100)      // 100 MB
    public class UploadFile extends HttpServlet
    {
        public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws Exception
        {
            // Retrieves <input type="text" name="description">
            String description = request.getParameter("description"); 

            JsonObject jsonRet = new JsonObject();
            JsonArray jsonArray = new JsonArray();
            jsonRet.add("files", jsonArray);
            try {
                Collection<Part> allParts = request.getParts(); // Retrieves all uploaded files
                for (Part filePart : allParts) {
                    String filename = null;
                    if (filePart == null || filePart.getContentType() == null) {
                        System.out.println("part is null");
                        continue;
                    } else {
                        filename = getFilename(filePart);
                    }
                    System.out.println(filename);
                    InputStream filecontent = filePart.getInputStream();
                    FileOutputStream fos = new FileOutputStream("/tmp/uploadfile/" + filename);
                    byte[] buffer = new byte[1024 * 4];
                    int c = 0;
                    while ((c = filecontent.read(buffer)) != -1) {
                        fos.write(buffer, 0, c);
                    }
                    JsonObject jsonObj = new JsonObject();
                    jsonObj.addProperty("name", filename);
                    jsonObj.addProperty("size", filePart.getSize());
                    jsonObj.addProperty("url", "the-url");
                    jsonObj.addProperty("thumbnail_url", "the-thumb");
                    jsonObj.addProperty("delete_url", "the-delete");
                    jsonObj.addProperty("delete_type", "DELETE");
                    jsonArray.add(jsonObj);
                }

                response.setCharacterEncoding("utf-8");
                response.setContentType("text/plain");
                PrintWriter writer = response.getWriter();
                writer.write(jsonRet.toString());
            } catch (Exception e) {
                throw e;
            }

        }

        private static String getFilename(Part part) 
        {
            for (String cd : part.getHeader("Content-Disposition").split(";")) {
                if (cd.trim().startsWith("filename")) {
                    String filename = cd.substring(cd.indexOf('=') + 1).trim().replace("\"", "");
                    return filename.substring(filename.lastIndexOf('/') + 1).substring(filename.lastIndexOf('\\') + 1); // MSIE fix.
                }
            }
            return null;
        }

If I set maxPostSize to -1, and leave the text field "description" to blank, it responses:

java.lang.String.<init>(String.java:481)
    org.apache.tomcat.util.http.fileupload.disk.DiskFileItem.getString(DiskFileItem.java:328)
    org.apache.catalina.connector.Request.parseParts(Request.java:2752)
    org.apache.catalina.connector.Request.parseParameters(Request.java:3083)
    org.apache.catalina.connector.Request.getParameter(Request.java:1151)
    org.apache.catalina.connector.RequestFacade.getParameter(RequestFacade.java:384)
    com.bluepyxis.servlet.HttpServletRequestWrapper.getParameter(HttpServletRequestWrapper.java:40)
    com.bluepyxis.actions.UploadFile.process(UploadFile.java:34)
......

If I set maxPostSize to a positive value or fill some texts in the description field, everything works fine.

So I wonder, why could this happen? And is there any way to set the post size unlimited while preventing the NullPointerException for an unfilled field?

Thanks in advance.

StackzOfZtuff
  • 2,534
  • 1
  • 28
  • 25
astonia
  • 528
  • 6
  • 9
  • The NPE looks like a bug. However, the stack trace isn't consistent with the source. I'd expect to see org.apache.catalina.core.ApplicationPart.getString() between the 2nd and 3rd lines. Exactly what version of Tomcat are you using and is that stack trace correct? – Mark Thomas Nov 12 '13 at 13:49
  • I'm sorry, the stack trace is not accurate. I tested with tomcat 7.0.47 and 8rc5, both got the same results. And I also tested with OpenJDK 1.7.0_45 and Oracle JDK 1.7.0_45, both of which are 64bit running on a 64bit CentOS 6. I modified the posted version of UploadFile.java since there is something might interfere reading. The last line of the stack trace of UploadFile indicates to request.getParameter(), and if it's changed to request.getParts(), the error still occurs. The rest of the stack trace is exactly the output generated by the runtime. – astonia Nov 13 '13 at 06:09
  • The posted stack trace is out from tomcat 7.0.47 and Oracle JDK 1.7.0_45. – astonia Nov 13 '13 at 06:17

1 Answers1

4

The docs aren't quite right. maxPostSize=0 results in a limit of zero. -1 is the correct value for no limit. I'll get that fixed shortly.

Mark Thomas
  • 16,339
  • 1
  • 39
  • 60