From 1ffe66e9e98a59257477714cb7b7105aaa6bcb6c Mon Sep 17 00:00:00 2001 From: Ryan Bergman Date: Sun, 18 Feb 2024 11:10:14 -0600 Subject: [PATCH] allow consumers to set the value of the boundary param --- .../BehaviorTests/MultiPartFormPostingTest.java | 16 ++++++++++++++++ .../src/main/java/kong/unirest/core/Body.java | 4 ++++ .../kong/unirest/core/HttpRequestMultiPart.java | 15 +++++++++++++++ .../java/kong/unirest/core/MultipartBody.java | 8 ++++++++ .../java/kong/unirest/core/java/BodyBuilder.java | 2 +- .../core/java/MultipartBodyPublisher.java | 16 +++++++++------- 6 files changed, 53 insertions(+), 8 deletions(-) diff --git a/unirest-bdd-tests/src/test/java/BehaviorTests/MultiPartFormPostingTest.java b/unirest-bdd-tests/src/test/java/BehaviorTests/MultiPartFormPostingTest.java index c974d356..3fb0539f 100644 --- a/unirest-bdd-tests/src/test/java/BehaviorTests/MultiPartFormPostingTest.java +++ b/unirest-bdd-tests/src/test/java/BehaviorTests/MultiPartFormPostingTest.java @@ -476,4 +476,20 @@ void defaultMediaTypes() { }); } + + @Test + void settingTheBoundary() { + String boundary = "ABC-123-BOUNDARY"; + + Unirest.post(MockServer.POST) + .field("spidey", rezFile("/spidey.pdf")) + .field("something", "else") + .boundary(boundary) + .asObject(RequestCapture.class) + .getBody() + .assertHeader("Content-Type", h -> { + h.assertParam("boundary", boundary); + }); + + } } diff --git a/unirest/src/main/java/kong/unirest/core/Body.java b/unirest/src/main/java/kong/unirest/core/Body.java index bb8e744c..0e61c613 100644 --- a/unirest/src/main/java/kong/unirest/core/Body.java +++ b/unirest/src/main/java/kong/unirest/core/Body.java @@ -56,6 +56,10 @@ default ProgressMonitor getMonitor(){ return null; } + default String getBoundary() { + return null; + } + default BodyPart getField(String name){ return multiParts() .stream() diff --git a/unirest/src/main/java/kong/unirest/core/HttpRequestMultiPart.java b/unirest/src/main/java/kong/unirest/core/HttpRequestMultiPart.java index 06d36df1..bb70f2f7 100644 --- a/unirest/src/main/java/kong/unirest/core/HttpRequestMultiPart.java +++ b/unirest/src/main/java/kong/unirest/core/HttpRequestMultiPart.java @@ -37,6 +37,7 @@ class HttpRequestMultiPart extends BaseRequest implements Multipa private Charset charSet; private boolean forceMulti = false; private ProgressMonitor monitor; + private String boundary; HttpRequestMultiPart(HttpRequestBody httpRequest) { super(httpRequest); @@ -136,6 +137,20 @@ public MultipartBody uploadMonitor(ProgressMonitor uploadMonitor) { return this; } + @Override + public MultipartBody boundary(String boundaryIdentifier) { + this.boundary = boundaryIdentifier; + return this; + } + + @Override + public String getBoundary() { + if(boundary == null){ + boundary = UUID.randomUUID().toString(); + } + return boundary; + } + @Override public Charset getCharset() { return this.charSet; diff --git a/unirest/src/main/java/kong/unirest/core/MultipartBody.java b/unirest/src/main/java/kong/unirest/core/MultipartBody.java index e09ca2e2..49387b8d 100644 --- a/unirest/src/main/java/kong/unirest/core/MultipartBody.java +++ b/unirest/src/main/java/kong/unirest/core/MultipartBody.java @@ -160,4 +160,12 @@ public interface MultipartBody extends HttpRequest, Body { * @return The same MultipartBody * */ MultipartBody uploadMonitor(ProgressMonitor monitor); + + /** + * Sets the value to use as the boundary identifier. + * see https://datatracker.ietf.org/doc/html/rfc2046 + * @param boundaryIdentifier the value + * @return The same MultipartBody + */ + MultipartBody boundary(String boundaryIdentifier); } diff --git a/unirest/src/main/java/kong/unirest/core/java/BodyBuilder.java b/unirest/src/main/java/kong/unirest/core/java/BodyBuilder.java index 6965e517..04ae96d2 100644 --- a/unirest/src/main/java/kong/unirest/core/java/BodyBuilder.java +++ b/unirest/src/main/java/kong/unirest/core/java/BodyBuilder.java @@ -74,7 +74,7 @@ private java.net.http.HttpRequest.BodyPublisher mapToMultipart(Body o) { ); } - MultipartBodyPublisher.Builder builder = MultipartBodyPublisher.newBuilder(); + var builder = MultipartBodyPublisher.newBuilder(o.getBoundary()); o.multiParts().forEach(part -> { setMultiPart(o, builder, part); }); diff --git a/unirest/src/main/java/kong/unirest/core/java/MultipartBodyPublisher.java b/unirest/src/main/java/kong/unirest/core/java/MultipartBodyPublisher.java index 9f9b5412..8778f4f6 100644 --- a/unirest/src/main/java/kong/unirest/core/java/MultipartBodyPublisher.java +++ b/unirest/src/main/java/kong/unirest/core/java/MultipartBodyPublisher.java @@ -38,7 +38,6 @@ import java.nio.file.Path; import java.util.ArrayList; import java.util.List; -import java.util.UUID; import java.util.concurrent.Flow.Subscriber; import static java.nio.charset.StandardCharsets.UTF_8; @@ -56,12 +55,13 @@ final class MultipartBodyPublisher implements BodyPublisher { private final List parts; private final ProgressMonitor monitor; - private final String boundary = UUID.randomUUID().toString(); + private final String boundary; private long contentLength; - private MultipartBodyPublisher(List parts, ProgressMonitor monitor) { + private MultipartBodyPublisher(List parts, ProgressMonitor monitor, String boundary) { this.parts = parts; this.monitor = monitor; + this.boundary = boundary; contentLength = UNINITIALIZED_LENGTH; } @@ -119,15 +119,17 @@ private static void appendHeader(StringBuilder target, String name, String value } /** Returns a new {@code MultipartBodyPublisher.Builder}. */ - static MultipartBodyPublisher.Builder newBuilder() { - return new MultipartBodyPublisher.Builder(); + static MultipartBodyPublisher.Builder newBuilder(String boundary) { + return new MultipartBodyPublisher.Builder(boundary); } static final class Builder { private final List parts; + private final String boundary; - Builder() { + Builder(String boundary) { + this.boundary = boundary; parts = new ArrayList<>(); } @@ -220,7 +222,7 @@ MultipartBodyPublisher build(ProgressMonitor monitor) { if (!!addedParts.isEmpty()) { throw new UnirestException("at least one part should be added"); } - return new MultipartBodyPublisher(addedParts, monitor); + return new MultipartBodyPublisher(addedParts, monitor, boundary); } } } \ No newline at end of file