From 55fe0fb13982b316b32a364c9747cf511517af5b Mon Sep 17 00:00:00 2001 From: Karl Wright Date: Thu, 22 Jun 2017 09:51:27 -0400 Subject: [PATCH] HTTPCLIENT-1859: Encode header name, filename appropriately --- .../http/entity/mime/FormBodyPartBuilder.java | 19 ++++++++++++++-- .../entity/mime/TestFormBodyPartBuilder.java | 22 +++++++++++++++++++ 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/FormBodyPartBuilder.java b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/FormBodyPartBuilder.java index 25bf4f2eb..5195cc627 100644 --- a/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/FormBodyPartBuilder.java +++ b/httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/FormBodyPartBuilder.java @@ -101,11 +101,11 @@ public FormBodyPart build() { if (headerCopy.getField(MIME.CONTENT_DISPOSITION) == null) { final StringBuilder buffer = new StringBuilder(); buffer.append("form-data; name=\""); - buffer.append(this.name); + buffer.append(encodeForHeader(this.name)); buffer.append("\""); if (this.body.getFilename() != null) { buffer.append("; filename=\""); - buffer.append(this.body.getFilename()); + buffer.append(encodeForHeader(this.body.getFilename())); buffer.append("\""); } headerCopy.addField(new MinimalField(MIME.CONTENT_DISPOSITION, buffer.toString())); @@ -136,4 +136,19 @@ public FormBodyPart build() { return new FormBodyPart(this.name, this.body, headerCopy); } + private static String encodeForHeader(final String headerName) { + if (headerName == null) { + return null; + } + final StringBuilder sb = new StringBuilder(); + for (int i = 0; i < headerName.length(); i++) { + final char x = headerName.charAt(i); + if (x == '"' || x == '\\' || x == '\r') { + sb.append("\\"); + } + sb.append(x); + } + return sb.toString(); + } + } diff --git a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestFormBodyPartBuilder.java b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestFormBodyPartBuilder.java index e333b5f3e..741865f53 100644 --- a/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestFormBodyPartBuilder.java +++ b/httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestFormBodyPartBuilder.java @@ -28,6 +28,7 @@ package org.apache.hc.client5.http.entity.mime; import java.io.File; +import java.io.ByteArrayInputStream; import java.util.Arrays; import java.util.List; @@ -56,6 +57,27 @@ public void testBuildBodyPartBasics() throws Exception { header.getFields()); } + @Test + public void testCharacterStuffing() throws Exception { + final FormBodyPartBuilder builder = FormBodyPartBuilder.create(); + final InputStreamBody fileBody = new InputStreamBody(new ByteArrayInputStream("hello world".getBytes("UTF-8")), "stuff_with \"quotes\" and \\slashes\\.bin"); + final FormBodyPart bodyPart2 = builder + .setName("yada_with \"quotes\" and \\slashes\\") + .setBody(fileBody) + .build(); + + Assert.assertNotNull(bodyPart2); + Assert.assertEquals("yada_with \"quotes\" and \\slashes\\", bodyPart2.getName()); + Assert.assertEquals(fileBody, bodyPart2.getBody()); + final Header header2 = bodyPart2.getHeader(); + Assert.assertNotNull(header2); + assertFields(Arrays.asList( + new MinimalField("Content-Disposition", "form-data; name=\"yada_with \\\"quotes\\\" and \\\\slashes\\\\\"; filename=\"stuff_with \\\"quotes\\\" and \\\\slashes\\\\.bin\""), + new MinimalField("Content-Type", "application/octet-stream"), + new MinimalField("Content-Transfer-Encoding", "binary")), + header2.getFields()); + } + @Test public void testBuildBodyPartMultipleBuilds() throws Exception { final StringBody stringBody = new StringBody("stuff", ContentType.TEXT_PLAIN);