From 91cd439302fa9b2e4053922516236803a025e741 Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 9 Jun 2022 11:08:18 +0300 Subject: [PATCH] Ensure that File is properly handled in native mode in RESTEasy Reactive Fixes: #25973 --- .../deployment/ResteasyReactiveProcessor.java | 6 ++++++ .../rest/client/multipart/MultipartClient.java | 6 ++++++ .../client/multipart/MultipartResource.java | 17 +++++++++++++++++ .../client/multipart/MultipartResourceTest.java | 12 ++++++++++++ 4 files changed, 41 insertions(+) diff --git a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java index be9da31998cac..478f45e3e653e 100644 --- a/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java +++ b/extensions/resteasy-reactive/quarkus-resteasy-reactive/deployment/src/main/java/io/quarkus/resteasy/reactive/server/deployment/ResteasyReactiveProcessor.java @@ -6,6 +6,7 @@ import static java.util.stream.Collectors.toList; import static org.jboss.resteasy.reactive.common.processor.ResteasyReactiveDotNames.DATE_FORMAT; +import java.io.File; import java.util.ArrayDeque; import java.util.ArrayList; import java.util.Collection; @@ -182,6 +183,7 @@ public class ResteasyReactiveProcessor { DotName.createSimple(HttpServerRequest.class.getName()), DotName.createSimple(HttpServerResponse.class.getName()), DotName.createSimple(RoutingContext.class.getName())); + private static final DotName FILE = DotName.createSimple(File.class.getName()); private static final int SECURITY_EXCEPTION_MAPPERS_PRIORITY = Priorities.USER + 1; @@ -501,6 +503,10 @@ public void accept(EndpointIndexer.ResourceMethodCallbackData entry) { .source(source) .build()); } + if (parameterType.name().equals(FILE)) { + reflectiveClass.produce(new ReflectiveClassBuildItem(false, true, false, + entry.getActualEndpointInfo().name().toString())); + } } } diff --git a/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartClient.java b/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartClient.java index 08542f443a73e..d6342ca92a280 100644 --- a/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartClient.java +++ b/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartClient.java @@ -20,6 +20,12 @@ @RegisterRestClient(configKey = "multipart-client") public interface MultipartClient { + @POST + @Path("/octet-stream") + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + @Produces(MediaType.TEXT_PLAIN) + String octetStreamFile(File body); + @POST @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_PLAIN) diff --git a/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartResource.java b/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartResource.java index 92b7ea3d63464..6569aa1cd9839 100644 --- a/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartResource.java +++ b/integration-tests/rest-client-reactive-multipart/src/main/java/io/quarkus/it/rest/client/multipart/MultipartResource.java @@ -52,6 +52,16 @@ public class MultipartResource { @RestClient MultipartClient client; + @GET + @Path("/client/octet-stream") + @Produces(MediaType.TEXT_PLAIN) + @Blocking + public String sendOctetStreamFile() throws IOException { + java.nio.file.Path tempFile = Files.createTempFile("dummy", ".txt"); + Files.write(tempFile, "test".getBytes(UTF_8)); + return client.octetStreamFile(tempFile.toFile()); + } + @GET @Path("/client/byte-array-as-binary-file-with-pojo") @Consumes(MediaType.TEXT_PLAIN) @@ -228,6 +238,13 @@ public String sendPathAsText() throws IOException { return client.sendPathAsTextFile(data); } + @POST + @Path("/echo/octet-stream") + @Consumes(MediaType.APPLICATION_OCTET_STREAM) + public String consumeOctetStream(File file) throws IOException { + return Files.readString(file.toPath()); + } + @POST @Path("/echo/binary") @Consumes(MediaType.MULTIPART_FORM_DATA) diff --git a/integration-tests/rest-client-reactive-multipart/src/test/java/io/quarkus/it/rest/client/multipart/MultipartResourceTest.java b/integration-tests/rest-client-reactive-multipart/src/test/java/io/quarkus/it/rest/client/multipart/MultipartResourceTest.java index 7e9e339baa449..8c8d995b56b08 100644 --- a/integration-tests/rest-client-reactive-multipart/src/test/java/io/quarkus/it/rest/client/multipart/MultipartResourceTest.java +++ b/integration-tests/rest-client-reactive-multipart/src/test/java/io/quarkus/it/rest/client/multipart/MultipartResourceTest.java @@ -217,6 +217,18 @@ public void shouldProducesMultipartForm() { assertMultipartResponseContains(response, "file", MediaType.TEXT_PLAIN, HELLO_WORLD); } + @Test + public void shouldProperlyHandleOctetStreamFile() { + // @formatter:off + given() + .header("Content-Type", "text/plain") + .when().get("/client/octet-stream") + .then() + .statusCode(200) + .body(equalTo("test")); + // @formatter:on + } + private void assertMultipartResponseContains(String response, String name, String contentType, Object value) { String[] lines = response.split("--"); assertThat(lines).anyMatch(line -> line.contains(String.format(EXPECTED_CONTENT_DISPOSITION_PART, name))