From cfef9b1c15955c4de577c1ed469bf0270c4287db Mon Sep 17 00:00:00 2001 From: Vladimir Sitnikov Date: Mon, 18 Mar 2024 13:43:46 +0300 Subject: [PATCH] HTTPCLIENT-2325 Avoid adding "; charset=" for multipart/form-data requests --- .../http/entity/mime/MultipartEntityBuilder.java | 13 +++++++------ .../entity/mime/TestMultipartEntityBuilder.java | 8 ++++---- .../entity/mime/TestMultipartFormHttpEntity.java | 5 +++-- 3 files changed, 14 insertions(+), 12 deletions(-) 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 8234123ee..1eee64629 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 @@ -253,12 +253,13 @@ MultipartFormEntity buildEntity() { if (charsetCopy == null && contentType != null) { charsetCopy = contentType.getCharset(); } - final List paramsList = new ArrayList<>(2); - paramsList.add(new BasicNameValuePair("boundary", boundaryCopy)); - if (charsetCopy != null) { - paramsList.add(new BasicNameValuePair("charset", charsetCopy.name())); - } - final NameValuePair[] params = paramsList.toArray(EMPTY_NAME_VALUE_ARRAY); + // Previusly, "charset" parameter was added to the Content-Type header, however adding "charset=..." + // is not specified in RFC 7578, and it causes issues with (flawed?) HTTP servers. + // For instance: + // https://github.com/owasp-modsecurity/ModSecurity/commit/6e56950cdf258c9b39f12cf6eb014cb59797cfd3 + // https://github.com/akka/akka-http/issues/338 + // https://bz.apache.org/bugzilla/show_bug.cgi?id=61384 + final NameValuePair[] params = new NameValuePair[]{new BasicNameValuePair("boundary", boundaryCopy)}; final ContentType contentTypeCopy; if (contentType != null) { 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 6a55a821e..731d7ece6 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 @@ -88,7 +88,7 @@ public void testMultipartCustomContentType() throws Exception { .setLaxMode() .buildEntity(); Assertions.assertNotNull(entity); - Assertions.assertEquals("application/xml; boundary=blah-blah; charset=UTF-8", entity.getContentType()); + Assertions.assertEquals("application/xml; charset=UTF-8; boundary=blah-blah", entity.getContentType()); } @Test @@ -99,7 +99,7 @@ public void testMultipartContentTypeParameter() throws Exception { new BasicNameValuePair("charset", "ascii"))) .buildEntity(); Assertions.assertNotNull(entity); - Assertions.assertEquals("multipart/form-data; boundary=yada-yada; charset=US-ASCII", entity.getContentType()); + Assertions.assertEquals("multipart/form-data; boundary=yada-yada; charset=ascii", entity.getContentType()); Assertions.assertEquals("yada-yada", entity.getMultipart().boundary); Assertions.assertEquals(StandardCharsets.US_ASCII, entity.getMultipart().charset); } @@ -116,7 +116,7 @@ public void testMultipartCustomContentTypeParameterOverrides() throws Exception .setLaxMode() .buildEntity(); Assertions.assertNotNull(entity); - Assertions.assertEquals("multipart/form-data; boundary=blah-blah; charset=UTF-8; my=stuff", + Assertions.assertEquals("multipart/form-data; boundary=blah-blah; charset=ascii; my=stuff", entity.getContentType()); } @@ -130,7 +130,7 @@ public void testMultipartCustomContentTypeUsingAddParameter() { eb.buildEntity(); final MultipartFormEntity entity = eb.buildEntity(); Assertions.assertNotNull(entity); - Assertions.assertEquals("multipart/related; boundary=yada-yada; charset=US-ASCII; my=stuff", + Assertions.assertEquals("multipart/related; boundary=yada-yada; charset=ascii; my=stuff", entity.getContentType()); } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartFormHttpEntity.java b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartFormHttpEntity.java index 210d0c0da..3ff515ada 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartFormHttpEntity.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartFormHttpEntity.java @@ -59,8 +59,9 @@ public void testExplictContractorParams() throws Exception { Assertions.assertNotNull(p1); Assertions.assertEquals("whatever", p1.getValue()); final NameValuePair p2 = elem.getParameterByName("charset"); - Assertions.assertNotNull(p2); - Assertions.assertEquals("UTF-8", p2.getValue()); + Assertions.assertNull(p2, + "RFC7578 does not mention charset parameter for Content-Type, " + + "so no charset should be present for MultipartEntity.getContentType()"); } @Test