HTTPCLIENT-2100: incorrect handling of EXTENDED mode by MultipartEntityBuilder
diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java index 54135c1..8ed0b44 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/MultipartEntityBuilder.java
@@ -232,7 +232,7 @@ MultipartFormEntity buildEntity() { form = new LegacyMultipart(charsetCopy, boundaryCopy, multipartPartsCopy); break; case EXTENDED: - if (ContentType.MULTIPART_FORM_DATA.isSameMimeType(ContentType.MULTIPART_FORM_DATA)) { + if (contentTypeCopy.isSameMimeType(ContentType.MULTIPART_FORM_DATA)) { if (charsetCopy == null) { charsetCopy = StandardCharsets.UTF_8; }
diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartEntityBuilder.java b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartEntityBuilder.java index 5b588c1..abaedb2 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartEntityBuilder.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartEntityBuilder.java
@@ -120,9 +120,10 @@ public void testMultipartCustomContentTypeParameterOverrides() throws Exception @Test public void testMultipartWriteTo() throws Exception { + final String helloWorld = "hello world"; final List<NameValuePair> parameters = new ArrayList<>(); parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_NAME, "test")); - parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_FILENAME, "hello world")); + parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_FILENAME, helloWorld)); final MultipartFormEntity entity = MultipartEntityBuilder.create() .setStrictMode() .setBoundary("xxxxxxxxxxxxxxxxxxxxxxxx") @@ -141,21 +142,23 @@ public void testMultipartWriteTo() throws Exception { "Content-Disposition: multipart/form-data; name=\"test\"; filename=\"hello world\"\r\n" + "Content-Type: text/plain; charset=ISO-8859-1\r\n" + "\r\n" + - "hello world\r\n" + + helloWorld + "\r\n" + "--xxxxxxxxxxxxxxxxxxxxxxxx--\r\n", out.toString(StandardCharsets.US_ASCII.name())); } + @Test public void testMultipartWriteToRFC7578Mode() throws Exception { + final String helloWorld = "hello \u03BA\u03CC\u03C3\u03BC\u03B5!%"; final List<NameValuePair> parameters = new ArrayList<>(); parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_NAME, "test")); - parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_FILENAME, "hello \u03BA\u03CC\u03C3\u03BC\u03B5!%")); + parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_FILENAME, helloWorld)); final MultipartFormEntity entity = MultipartEntityBuilder.create() .setMode(HttpMultipartMode.EXTENDED) .setBoundary("xxxxxxxxxxxxxxxxxxxxxxxx") .addPart(new FormBodyPartBuilder() .setName("test") - .setBody(new StringBody("hello world", ContentType.TEXT_PLAIN)) + .setBody(new StringBody(helloWorld, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))) .addField("Content-Disposition", "multipart/form-data", parameters) .build()) .buildEntity(); @@ -165,10 +168,40 @@ public void testMultipartWriteToRFC7578Mode() throws Exception { out.close(); Assert.assertEquals("--xxxxxxxxxxxxxxxxxxxxxxxx\r\n" + "Content-Disposition: multipart/form-data; name=\"test\"; filename=\"hello%20%CE%BA%CF%8C%CF%83%CE%BC%CE%B5!%25\"\r\n" + - "Content-Type: text/plain; charset=ISO-8859-1\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + "\r\n" + - "hello world\r\n" + - "--xxxxxxxxxxxxxxxxxxxxxxxx--\r\n", out.toString(StandardCharsets.US_ASCII.name())); + "hello \u00ce\u00ba\u00cf\u008c\u00cf\u0083\u00ce\u00bc\u00ce\u00b5!%\r\n" + + "--xxxxxxxxxxxxxxxxxxxxxxxx--\r\n", out.toString(StandardCharsets.ISO_8859_1.name())); + } + + @Test + public void testMultipartWriteToRFC6532Mode() throws Exception { + final String helloWorld = "hello \u03BA\u03CC\u03C3\u03BC\u03B5!%"; + final List<NameValuePair> parameters = new ArrayList<>(); + parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_NAME, "test")); + parameters.add(new BasicNameValuePair(MimeConsts.FIELD_PARAM_FILENAME, helloWorld)); + + final MultipartFormEntity entity = MultipartEntityBuilder.create() + .setMode(HttpMultipartMode.EXTENDED) + .setContentType(ContentType.create("multipart/other")) + .setBoundary("xxxxxxxxxxxxxxxxxxxxxxxx") + .addPart(new FormBodyPartBuilder() + .setName("test") + .setBody(new StringBody(helloWorld, ContentType.TEXT_PLAIN.withCharset(StandardCharsets.UTF_8))) + .addField("Content-Disposition", "multipart/form-data", parameters) + .build()) + .buildEntity(); + + final ByteArrayOutputStream out = new ByteArrayOutputStream(); + entity.writeTo(out); + out.close(); + Assert.assertEquals("--xxxxxxxxxxxxxxxxxxxxxxxx\r\n" + + "Content-Disposition: multipart/form-data; name=\"test\"; " + + "filename=\"hello \u00ce\u00ba\u00cf\u008c\u00cf\u0083\u00ce\u00bc\u00ce\u00b5!%\"\r\n" + + "Content-Type: text/plain; charset=UTF-8\r\n" + + "\r\n" + + "hello \u00ce\u00ba\u00cf\u008c\u00cf\u0083\u00ce\u00bc\u00ce\u00b5!%\r\n" + + "--xxxxxxxxxxxxxxxxxxxxxxxx--\r\n", out.toString(StandardCharsets.ISO_8859_1.name())); } }