From 5ce027b29cc88cc2da9491da9600139a18df48de Mon Sep 17 00:00:00 2001 From: Georgios Andrianakis Date: Thu, 1 Jun 2023 10:51:56 +0300 Subject: [PATCH] Properly implement ClientRequestContext#setEntity This method can be called by filters to override the entity being sent by the JAX-RS client and before this commit we were not properly handling the case where either the entity was set to null or only the body of the entity was being set (and not the media type). Fixes: #33738 --- .../EntitySettingRequestFilterTest.java | 74 +++++++++++++++++++ .../client/impl/ClientRequestContextImpl.java | 14 ++-- .../client/impl/RestClientRequestContext.java | 11 ++- 3 files changed, 91 insertions(+), 8 deletions(-) create mode 100644 extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/provider/EntitySettingRequestFilterTest.java diff --git a/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/provider/EntitySettingRequestFilterTest.java b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/provider/EntitySettingRequestFilterTest.java new file mode 100644 index 0000000000000..18fe86069f6c7 --- /dev/null +++ b/extensions/resteasy-reactive/rest-client-reactive/deployment/src/test/java/io/quarkus/rest/client/reactive/provider/EntitySettingRequestFilterTest.java @@ -0,0 +1,74 @@ +package io.quarkus.rest.client.reactive.provider; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.IOException; +import java.net.URI; + +import jakarta.ws.rs.POST; +import jakarta.ws.rs.Path; +import jakarta.ws.rs.client.ClientRequestContext; +import jakarta.ws.rs.client.ClientRequestFilter; + +import org.eclipse.microprofile.rest.client.RestClientBuilder; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; + +import io.quarkus.test.QuarkusUnitTest; +import io.quarkus.test.common.http.TestHTTPResource; + +public class EntitySettingRequestFilterTest { + + @RegisterExtension + static final QuarkusUnitTest config = new QuarkusUnitTest() + .withApplicationRoot((jar) -> jar.addClasses(Resource.class, Client.class, EntityRequestFilter.class)); + + @TestHTTPResource + URI baseUri; + + @Test + void testNullEntity() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).register(new EntityRequestFilter(null)) + .build(Client.class); + assertThat(client.call("ignored")).isEqualTo("null"); + } + + @Test + void testNonNullEntity() { + Client client = RestClientBuilder.newBuilder().baseUri(baseUri).register(new EntityRequestFilter("foo")) + .build(Client.class); + assertThat(client.call("ignored")).isEqualTo("foo"); + } + + @Path("/") + public static class Resource { + @POST + public String returnHeaders(String body) { + if ((body == null) || body.isEmpty()) { + return "null"; + } + return body; + } + } + + public interface Client { + + @Path("/") + @POST + String call(String body); + } + + public static class EntityRequestFilter implements ClientRequestFilter { + + private final String entity; + + public EntityRequestFilter(String entity) { + this.entity = entity; + } + + @Override + public void filter(ClientRequestContext context) throws IOException { + context.setEntity(entity); + } + } +} diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRequestContextImpl.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRequestContextImpl.java index eb653ee587544..f1b2017f27c82 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRequestContextImpl.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/ClientRequestContextImpl.java @@ -171,8 +171,12 @@ public Locale getLanguage() { @Override public MediaType getMediaType() { + if (restClientRequestContext.entity == null) { + return null; + } // those come from the entity - return restClientRequestContext.entity != null ? restClientRequestContext.entity.getMediaType() : null; + return restClientRequestContext.entity.getMediaType() == RestClientRequestContext.IGNORED_MEDIA_TYPE ? null + : restClientRequestContext.entity.getMediaType(); } @Override @@ -515,12 +519,8 @@ private boolean isContentType(Object key) { } private String mediaType() { - Entity entity = restClientRequestContext.entity; - return entity == null - ? null - : entity.getMediaType() == null - ? null - : entity.getMediaType().toString(); + MediaType mediaType = getMediaType(); + return mediaType == null ? null : mediaType.toString(); } } } diff --git a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/RestClientRequestContext.java b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/RestClientRequestContext.java index 59e89940f428c..3fb35e41152e7 100644 --- a/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/RestClientRequestContext.java +++ b/independent-projects/resteasy-reactive/client/runtime/src/main/java/org/jboss/resteasy/reactive/client/impl/RestClientRequestContext.java @@ -60,6 +60,8 @@ public class RestClientRequestContext extends AbstractResteasyReactiveContext entity, MultivaluedMap heade } public void setEntity(Object entity, Annotation[] annotations, MediaType mediaType) { - this.entity = Entity.entity(entity, mediaType, annotations); + if (entity == null) { + this.entity = null; + } else { + if (mediaType == null) { + mediaType = IGNORED_MEDIA_TYPE; // we need this in order to avoid getting IAE from Variant... + } + this.entity = Entity.entity(entity, mediaType, annotations); + } } public CompletableFuture getResult() {