Skip to content

Commit 55e4353

Browse files
committed
Allow usage of other multipart types in Reactive REST Client
Fixes: #28026
1 parent 9c3141f commit 55e4353

File tree

2 files changed

+42
-0
lines changed
  • extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/multipart
  • independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers

2 files changed

+42
-0
lines changed

extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/multipart/MultiByteFileTest.java

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import jakarta.inject.Inject;
1616
import jakarta.ws.rs.Consumes;
1717
import jakarta.ws.rs.FormParam;
18+
import jakarta.ws.rs.HeaderParam;
1819
import jakarta.ws.rs.POST;
1920
import jakarta.ws.rs.Path;
2021
import jakarta.ws.rs.core.MediaType;
@@ -139,6 +140,17 @@ void shouldSendFromMultiEmittingOutsideEventLoop() {
139140
assertThat(result).isEqualTo("myFile");
140141
}
141142

143+
@Test
144+
public void shouldPropertySetContentType() {
145+
Client client = RestClientBuilder.newBuilder().baseUri(baseUri).build(Client.class);
146+
147+
ClientForm form = new ClientForm();
148+
form.file = Multi.createBy().repeating().supplier(() -> (byte) 4).atMost(100);
149+
150+
assertThat(client.postMultipartToType(form)).startsWith("multipart/form-data");
151+
assertThat(client.postMultipartMixedToType(form)).startsWith("multipart/mixed");
152+
}
153+
142154
private void delayedEmit(AtomicLong i, MultiEmitter<? super Byte> em) {
143155
vertx.setTimer(100, id -> {
144156
long index = i.getAndIncrement();
@@ -190,6 +202,12 @@ public String uploadEmpty(@MultipartForm FormWithTwoFiles form) {
190202
+ verifyFile(form.file2, 100, position -> (byte) 7);
191203
}
192204

205+
@Path("type")
206+
@POST
207+
public String contentType(@HeaderParam("Content-Type") String contentType) {
208+
return contentType;
209+
}
210+
193211
private String verifyFile(FileUpload upload, int expectedSize, Function<Integer, Byte> expectedByte) {
194212
var uploadedFile = upload.uploadedFile();
195213
int size;
@@ -270,6 +288,16 @@ public interface Client {
270288
@POST
271289
@Consumes(MediaType.MULTIPART_FORM_DATA)
272290
String postEmpty(@MultipartForm ClientForm form);
291+
292+
@Path("/type")
293+
@POST
294+
@Consumes(MediaType.MULTIPART_FORM_DATA)
295+
String postMultipartToType(@MultipartForm ClientForm clientForm);
296+
297+
@Path("/type")
298+
@POST
299+
@Consumes("multipart/mixed")
300+
String postMultipartMixedToType(@MultipartForm ClientForm clientForm);
273301
}
274302

275303
public static class ClientForm {

independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/handlers/ClientSendRequestHandler.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
import org.jboss.resteasy.reactive.common.core.Serialisers;
4040
import org.jboss.resteasy.reactive.common.util.MultivaluedTreeMap;
4141

42+
import io.netty.handler.codec.http.HttpHeaderValues;
4243
import io.netty.handler.codec.http.LastHttpContent;
4344
import io.netty.handler.codec.http.multipart.InterfaceHttpData;
4445
import io.smallrye.mutiny.Multi;
@@ -484,6 +485,19 @@ private QuarkusMultipartFormUpload setMultipartHeadersAndPrepareBody(HttpClientR
484485
headerMap.put(multipartHeader, multipartHeaders.getAll(multipartHeader));
485486
}
486487

488+
if (state.getEntity().getVariant() != null) {
489+
Variant v = state.getEntity().getVariant();
490+
String variantContentType = v.getMediaType().toString();
491+
String multipartContentType = headerMap.getFirst(HttpHeaders.CONTENT_TYPE);
492+
if (multipartContentType.startsWith(HttpHeaderValues.MULTIPART_FORM_DATA.toString())
493+
&& !variantContentType.startsWith(HttpHeaderValues.MULTIPART_FORM_DATA.toString())) {
494+
// this is a total hack whose purpose is to allow the @Consumes annotation to override the media type
495+
int semicolonIndex = multipartContentType.indexOf(';');
496+
headerMap.put(HttpHeaders.CONTENT_TYPE,
497+
List.of(variantContentType + multipartContentType.substring(semicolonIndex)));
498+
}
499+
}
500+
487501
setVertxHeaders(httpClientRequest, headerMap);
488502
return multipartFormUpload;
489503
}

0 commit comments

Comments
 (0)