When updating Spring Boot to version 2.2.0 I get an error when trying to upload a file.
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed
Error code
@RestController
public class FileController {
@PostMapping("/api/file")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) {
//...
}
}
This code worked for me on versions less than 2.2.0
Thanks for the report. I would guess from the exception that something is closing the network connection before the upload has completed. That could, perhaps, be due to a timeout or a problem with the client. If you would like us to spend some time investigating, can you please take the time to provide a complete and minimal example that reproduces the problem in the form of a zipped project attached to this issue.
The problem did not reproduce on the new empty project. Perhaps in the new version of the framework the mechanism for working with request inputStream has changed in the case of multipart/form-data content ... and this is not fixed in the project where a MultipartException occurs. I propose to close this issue.
Ok, thanks for letting us know. If you encounter the problem again in a reproducible manner, please comment here with a sample and we'll gladly take another look.
I ran into the same issue.
org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.FileUploadException: Stream closed
Worked fine on Spring Boot 2.1.12, failed after upgrade to 2.2.4 (both versions run the same embedded Tomcat 9.0.30).
The root cause was that we were using logback-access filter that logs requests and responses.
The filter wrapped HttpServletRequest
with a caching wrapper and closed the input stream before passing the request along the filter chain.
This caused an issue when javax.servlet.http.HttpServletRequest#getParts
was called, as that call is delegated to the original Tomcat's request (with a now-closed input stream), which then results in the "stream closed" exception.
The Spring change that triggered this issue is hiddenHttpMethodFilter
no longer being present in the filter chain.
Previously this filter would be one of the first filters to be called, and it would call HttpServletRequest#getParameter
, which in turn would make Tomcat's request implementation parse multipart content and store the parts in the object (so that later calls to #getParts
would use that and not try to parse them again).
I reported this to Logback: https://jira.qos.ch/browse/LOGBACK-1503
Workaround - call HttpServletRequest#getParameter
before passing the request to logback's filter (see LOGBACK-1503 for code), to force Tomcat to parse and store request parts while input stream is still open.
I encounter the same error with SpringBoot 2.2+. When I change SpringBoot version to 2.1.13.RELEASE , everything works well .
@knight0707 if you share a small sample (a zip or a link to a github repo) that shows it work with 2.1x and fail with 2.2x (by just changing the version) we can reopen this issue.
I also encountered this problem in the 2.2.6 version. I built a repeatable request.getInputStream()
. It is convenient for me to verify the security problem, but after upgrading to it, it will stream closed. Do you have any solutions?
@snicoll @wilkinsona Here's a sample that works on 2.1.x but fails on 2.2.x: https://github.com/grimsa/spring-boot-18644-sample
spring:
mvc:
hiddenmethod:
filter:
enabled: true
Open this filter and the problem will be solved
spring: mvc: hiddenmethod: filter: enabled: true
Open this filter and the problem will be solved
Works for me.
@snicoll @wilkinsona Here's a sample that works on 2.1.x but fails on 2.2.x: https://github.com/grimsa/spring-boot-18644-sample
how about spring boot 2.3.x ? is it okay?
@umanking 2.3 is likely to have the same issue but I don't think there's anything that we can do about this in Spring Boot. Someone needs to probably get involved with a fix for LOGBACK-1503.
mark
Working with spring boot version: 2.3.0.RELEASE
groupId: org.springframework.boot
artifactId: spring-boot-starter-parent
version: 2.3.0.RELEASE
when i try to upload 1 GB file then i am facing an error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet request; nested exception is java.io.IOException: org.apache.tomcat.util.http.fileupload.impl.IOFileUploadException: Processing of multipart/form-data request failed. java.io.EOFException: Unexpected EOF read on the socket] with root cause
java.io.EOFException: Unexpected EOF read on the socket
ERROR CODE:
@RestController
public class FileController {
@PostMapping("/api/file")
public ResponseEntity<String> upload(@RequestParam("file") MultipartFile multipartFile) {
//...
}
}
@San500 Without knowing more about your problem (which web container you are using, if the problem only occurs with large (1GB files) or also with smaller files, whether you're using Logback's TeeFilter, etc), it's difficult to help you. If you'd like some help please come and chat on Gitter or ask a question on Stack Overflow.
Change request method from PUT to post, the problem will be solved.
Most helpful comment
Open this filter and the problem will be solved