Description
Affects Version(s): 5.1.3
Bug
The multipart/form-data RFC states:
multiple files MUST be sent
by supplying each file in a separate part but all with the same
"name" parameter
However, when I send a multipart message with three parts named data
, only one makes it into the message.
Sample request (with Intellij's http client)
### Send a form with the text and file fields
POST http://localhost:8091/conversion
Content-Type: multipart/form-data; boundary=WebAppBoundary
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data.tiff"
Content-Type: image/tiff
< ../resources/inputSamples/data.tiff
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data2.tiff"
Content-Type: image/tiff
< ../resources/inputSamples/data2.tiff
--WebAppBoundary
Content-Disposition: form-data; name="data"; filename="data3.tiff"
Content-Type: image/tiff
< ../resources/inputSamples/data3.tiff
--WebAppBoundary--
The reason is that MultipartAwareFormHttpMessageConverter#readMultipart
uses multipartRequest.getFileMap()
to access the files:
private MultiValueMap<String, ?> readMultipart(MultipartHttpInputMessage multipartRequest) throws IOException {
MultiValueMap<String, Object> resultMap = new LinkedMultiValueMap<String, Object>();
Map<?, ?> parameterMap = multipartRequest.getParameterMap();
for (Entry<?, ?> entry : parameterMap.entrySet()) {
resultMap.add((String) entry.getKey(), entry.getValue());
}
for (Map.Entry<String, MultipartFile> entry : multipartRequest
.getFileMap().entrySet()) { // <== problematic
MultipartFile multipartFile = entry.getValue();
if (multipartFile.isEmpty()) {
continue;
}
resultMap.add(entry.getKey(), this.multipartFileReader.readMultipartFile(multipartFile));
}
return resultMap;
}
which ultimately comes to AbstractMutlipartHttpServletRequest
:
public Map<String, MultipartFile> getFileMap() {
return getMultipartFiles().toSingleValueMap();
}
Here it loses all but the first files.
Possible solution: Use MultipartHttpInputMessage#getMultiFileMap
instead of getFileMap
. I suggest to treat this as a bug because it really seems that getFileMap
was used inadvertently.
Workaround: use different names for all multipart files (pretty ugly, though).