Skip to content

Commit c5a947b

Browse files
committed
Enhance FormBodyPartBuilder create methods for mode support
1 parent 7dd3ea2 commit c5a947b

File tree

2 files changed

+37
-31
lines changed

2 files changed

+37
-31
lines changed

httpclient5/src/main/java/org/apache/hc/client5/http/entity/mime/FormBodyPartBuilder.java

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
package org.apache.hc.client5.http.entity.mime;
2929

30+
import java.nio.charset.CharsetEncoder;
3031
import java.nio.charset.StandardCharsets;
3132
import java.util.ArrayList;
3233
import java.util.List;
@@ -48,24 +49,53 @@ public class FormBodyPartBuilder {
4849
private String name;
4950
private ContentBody body;
5051
private final Header header;
52+
53+
/**
54+
* The multipart mode determining how filenames are encoded in the {@code Content-Disposition}
55+
* header, defaults to {@link HttpMultipartMode#STRICT}.
56+
*
57+
* @since 5.5
58+
*/
5159
private HttpMultipartMode mode;
5260

61+
/**
62+
* Reusable encoder for ISO-8859-1 charset checks, improving performance by avoiding
63+
* repeated instance creation.
64+
*/
65+
private final CharsetEncoder iso8859_1Encoder = StandardCharsets.ISO_8859_1.newEncoder();
66+
67+
/**
68+
* Creates a new builder instance with the specified name, content body, and multipart mode.
69+
*
70+
* @param name the name of the form field
71+
* @param body the content body of the part
72+
* @param mode the {@link HttpMultipartMode} to use, determining filename encoding behavior;
73+
*
74+
* @return a new {@code FormBodyPartBuilder} instance
75+
* @since 5.5
76+
*/
77+
public static FormBodyPartBuilder create(final String name, final ContentBody body, final HttpMultipartMode mode) {
78+
return new FormBodyPartBuilder(name, body, mode);
79+
}
80+
5381
public static FormBodyPartBuilder create(final String name, final ContentBody body) {
54-
return new FormBodyPartBuilder(name, body);
82+
return new FormBodyPartBuilder(name, body, HttpMultipartMode.STRICT);
5583
}
5684

5785
public static FormBodyPartBuilder create() {
5886
return new FormBodyPartBuilder();
5987
}
6088

61-
FormBodyPartBuilder(final String name, final ContentBody body) {
89+
FormBodyPartBuilder(final String name, final ContentBody body, final HttpMultipartMode mode) {
6290
this();
6391
this.name = name;
6492
this.body = body;
93+
this.mode = mode != null ? mode : HttpMultipartMode.STRICT;
6594
}
6695

6796
FormBodyPartBuilder() {
6897
this.header = new Header();
98+
this.mode = HttpMultipartMode.STRICT;
6999
}
70100

71101
public FormBodyPartBuilder setName(final String name) {
@@ -99,29 +129,6 @@ public FormBodyPartBuilder setField(final String name, final String value) {
99129
return this;
100130
}
101131

102-
/**
103-
* Sets the multipart mode for this builder, determining how filenames are encoded in the
104-
* {@code Content-Disposition} header. The mode affects whether the {@code filename*} parameter
105-
* is included for non-ISO-8859-1 filenames.
106-
* <p>
107-
* In {@link HttpMultipartMode#LEGACY} mode, only the {@code filename} parameter is included
108-
* with the raw value, mimicking pre-RFC 7578 behavior. In {@link HttpMultipartMode#STRICT}
109-
* or {@link HttpMultipartMode#EXTENDED} modes, the {@code filename*} parameter is added
110-
* with RFC 5987 encoding for filenames containing non-ISO-8859-1 characters.
111-
* </p>
112-
* <p>
113-
* If {@code mode} is {@code null}, it defaults to {@link HttpMultipartMode#STRICT}.
114-
* </p>
115-
*
116-
* @param mode the {@link HttpMultipartMode} to use, or {@code null} for default behavior
117-
* @return this builder instance for method chaining
118-
* @since 5.5
119-
*/
120-
public FormBodyPartBuilder setMode(final HttpMultipartMode mode) {
121-
this.mode = mode != null ? mode : HttpMultipartMode.STRICT;
122-
return this;
123-
}
124-
125132
public FormBodyPartBuilder removeFields(final String name) {
126133
Args.notNull(name, "Field name");
127134
this.header.removeFields(name);
@@ -137,8 +144,8 @@ public FormBodyPartBuilder removeFields(final String name) {
137144
* @return {@code true} if the string can be encoded in ISO-8859-1, {@code false} otherwise
138145
* @since 5.5
139146
*/
140-
private static boolean canEncodeToISO8859_1(final String input) {
141-
return StandardCharsets.ISO_8859_1.newEncoder().canEncode(input);
147+
private boolean canEncodeToISO8859_1(final String input) {
148+
return iso8859_1Encoder.canEncode(input);
142149
}
143150

144151
/**
@@ -196,5 +203,4 @@ public FormBodyPart build() {
196203
}
197204
return new FormBodyPart(this.name, this.body, headerCopy);
198205
}
199-
200-
}
206+
}

httpclient5/src/test/java/org/apache/hc/client5/http/entity/mime/TestMultipartForm.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -295,11 +295,11 @@ void testMultipartFormBrowserCompatibleNonASCIIHeaders() throws Exception {
295295
@SuppressWarnings("resource")
296296
final FormBodyPart p1 = FormBodyPartBuilder.create(
297297
"field1",
298-
new InputStreamBody(new FileInputStream(tmpfile), s1 + ".tmp")).setMode(HttpMultipartMode.LEGACY).build();
298+
new InputStreamBody(new FileInputStream(tmpfile), s1 + ".tmp"), HttpMultipartMode.LEGACY).build();
299299
@SuppressWarnings("resource")
300300
final FormBodyPart p2 = FormBodyPartBuilder.create(
301301
"field2",
302-
new InputStreamBody(new FileInputStream(tmpfile), s2 + ".tmp")).setMode(HttpMultipartMode.LEGACY).build();
302+
new InputStreamBody(new FileInputStream(tmpfile), s2 + ".tmp"), HttpMultipartMode.LEGACY).build();
303303
final LegacyMultipart multipart = new LegacyMultipart(
304304
StandardCharsets.UTF_8, "foo",
305305
Arrays.asList(p1, p2));

0 commit comments

Comments
 (0)