Switch order of multipart Content-Type directives
Since SPR-15205, the `FormHttpMessageConverter` is adding a `charset` directive to the `Content-Type` request header in order to help servers understand which charset is being used to encode headers of each part. As reported in SPR-17030 and others, some servers are not parsing properly such header values and assume that `boundary` is the last directive in the `Content-Type` header. This commit reorders the charset information right before the boundary declaration to get around those issues. Issue: SPR-17030
This commit is contained in:
@@ -25,7 +25,7 @@ import java.nio.charset.Charset;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.mail.internet.MimeUtility;
|
||||
@@ -351,11 +351,11 @@ public class FormHttpMessageConverter implements HttpMessageConverter<MultiValue
|
||||
HttpOutputMessage outputMessage) throws IOException {
|
||||
|
||||
final byte[] boundary = generateMultipartBoundary();
|
||||
Map<String, String> parameters = new HashMap<>(2);
|
||||
parameters.put("boundary", new String(boundary, "US-ASCII"));
|
||||
Map<String, String> parameters = new LinkedHashMap<>(2);
|
||||
if (!isFilenameCharsetSet()) {
|
||||
parameters.put("charset", this.charset.name());
|
||||
}
|
||||
parameters.put("boundary", new String(boundary, "US-ASCII"));
|
||||
|
||||
MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters);
|
||||
HttpHeaders headers = outputMessage.getHeaders();
|
||||
|
||||
@@ -30,6 +30,8 @@ import org.apache.commons.fileupload.FileItemFactory;
|
||||
import org.apache.commons.fileupload.FileUpload;
|
||||
import org.apache.commons.fileupload.RequestContext;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.hamcrest.CoreMatchers;
|
||||
import org.hamcrest.Matchers;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
@@ -148,7 +150,8 @@ public class FormHttpMessageConverterTests {
|
||||
this.converter.write(parts, new MediaType("multipart", "form-data", StandardCharsets.UTF_8), outputMessage);
|
||||
|
||||
final MediaType contentType = outputMessage.getHeaders().getContentType();
|
||||
assertNotNull("No boundary found", contentType.getParameter("boundary"));
|
||||
// SPR-17030
|
||||
assertThat(contentType.getParameters().keySet(), Matchers.contains("charset", "boundary"));
|
||||
|
||||
// see if Commons FileUpload can read what we wrote
|
||||
FileItemFactory fileItemFactory = new DiskFileItemFactory();
|
||||
|
||||
Reference in New Issue
Block a user