Skip to content

Commit 390bb87

Browse files
committed
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
1 parent 9a43d2e commit 390bb87

File tree

2 files changed

+7
-4
lines changed

2 files changed

+7
-4
lines changed

spring-web/src/main/java/org/springframework/http/converter/FormHttpMessageConverter.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
import java.nio.charset.StandardCharsets;
2626
import java.util.ArrayList;
2727
import java.util.Collections;
28-
import java.util.HashMap;
28+
import java.util.LinkedHashMap;
2929
import java.util.List;
3030
import java.util.Map;
3131
import javax.mail.internet.MimeUtility;
@@ -351,11 +351,11 @@ private void writeMultipart(final MultiValueMap<String, Object> parts,
351351
HttpOutputMessage outputMessage) throws IOException {
352352

353353
final byte[] boundary = generateMultipartBoundary();
354-
Map<String, String> parameters = new HashMap<>(2);
355-
parameters.put("boundary", new String(boundary, "US-ASCII"));
354+
Map<String, String> parameters = new LinkedHashMap<>(2);
356355
if (!isFilenameCharsetSet()) {
357356
parameters.put("charset", this.charset.name());
358357
}
358+
parameters.put("boundary", new String(boundary, "US-ASCII"));
359359

360360
MediaType contentType = new MediaType(MediaType.MULTIPART_FORM_DATA, parameters);
361361
HttpHeaders headers = outputMessage.getHeaders();

spring-web/src/test/java/org/springframework/http/converter/FormHttpMessageConverterTests.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030
import org.apache.commons.fileupload.FileUpload;
3131
import org.apache.commons.fileupload.RequestContext;
3232
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
33+
import org.hamcrest.CoreMatchers;
34+
import org.hamcrest.Matchers;
3335
import org.junit.Test;
3436

3537
import org.springframework.core.io.ClassPathResource;
@@ -148,7 +150,8 @@ public String getFilename() {
148150
this.converter.write(parts, new MediaType("multipart", "form-data", StandardCharsets.UTF_8), outputMessage);
149151

150152
final MediaType contentType = outputMessage.getHeaders().getContentType();
151-
assertNotNull("No boundary found", contentType.getParameter("boundary"));
153+
// SPR-17030
154+
assertThat(contentType.getParameters().keySet(), Matchers.contains("charset", "boundary"));
152155

153156
// see if Commons FileUpload can read what we wrote
154157
FileItemFactory fileItemFactory = new DiskFileItemFactory();

0 commit comments

Comments
 (0)