user1432882
user1432882

Reputation: 1152

Failure to upload file to servlet with https enabled

I am having a weird issue in my application.

Application Details: - Spring 4, Java 8, Tomcat 8

When I enable https (in web.xml), and try to upload a multi-part file, I get the following error:

Caused by: org.apache.commons.fileupload.MultipartStream$MalformedStreamException: Stream ended unexpectedly
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.makeAvailable(MultipartStream.java:1005)
    at org.apache.commons.fileupload.MultipartStream$ItemInputStream.read(MultipartStream.java:903)
    at java.io.InputStream.read(InputStream.java:101)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:100)
    at org.apache.commons.fileupload.util.Streams.copy(Streams.java:70)
    at org.apache.commons.fileupload.FileUploadBase.parseRequest(FileUploadBase.java:347)

However, when I turn off https and make the request via http everything works correctly. Any ideas?

I am just testing with a very simple upload form right now:

<form action="../upload/TestUpload"
enctype="multipart/form-data" method="post">
<p>
Please specify a file, or a set of files:<br>
<input type="file" name="datafile" size="40">
</p>
<div>
<input type="submit" value="Send">
</div>
</form>

The spring class is very simple right now - just printing out the file names without doing anything. However, the code doesn't even reach this action because fileupload fails to parse the stream.

@RestController
public class Upload {
    private static final Logger LOG = LogManager.getLogger(Upload.class);
    @RequestMapping(value="/TestUpload", method=RequestMethod.POST)
    public List<FileResult> handleFileUpload(MultipartHttpServletRequest request){
        //List<File> tempFiles = new LinkedList<File>();
        List<FileResult> files = new LinkedList<FileResult>();
        Iterator<String> itr = request.getFileNames();
            while (itr.hasNext()) {
                MultipartFile multipartFile = request.getFile(itr.next()); 
                LOG.info(multipartFile.getName());
            }
          return files;

    }

web.xml https snippet

  <security-constraint>
    <web-resource-collection>
        <web-resource-name>securedapp</web-resource-name>
        <url-pattern>/*</url-pattern>
        <http-method>GET</http-method>
        <http-method>POST</http-method>
        <http-method>PUT</http-method>
    </web-resource-collection>
    <user-data-constraint>
        <transport-guarantee>CONFIDENTIAL</transport-guarantee>
    </user-data-constraint>
</security-constraint> 

Upvotes: 2

Views: 1374

Answers (2)

Etienne Tonnelier
Etienne Tonnelier

Reputation: 2229


I have had this error with the application details: Spring 4.3.1, Java 7, Tomcat 8.5.4.
I found out that the Tomcat connector org.apache.coyote.http11.Http11Nio2Protocol does not work over the internet for uploaded files bigger than 20KB, though it works fine in localhost.
I ended up using the Tomcat connector org.apache.coyote.http11.Http11NioProtocol, which works fine.
I assume it has to do with the blocking vs. non-blocking I/O connector's characteristic.

Upvotes: 1

user1432882
user1432882

Reputation: 1152

I fixed this by installing the latest version of tomcat 8 and latest version of jdk 8. Not sure what the issue was before, but might have been some rare bug or configuration error causing this issue.

Upvotes: 2

Related Questions