Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.ws.rs.POST;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.MediaType;

import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;
Expand All @@ -23,4 +24,8 @@ public interface HelloClient {
@GET
@Path("/{name}")
public String helloWithPathParam(@PathParam("name") String name);

@GET
@Path("/query")
public String helloWithQueryParam(@QueryParam("foo") String foo);
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.Produces;
import jakarta.ws.rs.QueryParam;
import jakarta.ws.rs.core.Context;
import jakarta.ws.rs.core.MediaType;
import jakarta.ws.rs.core.Request;
Expand All @@ -26,6 +27,12 @@ public String invoke(@PathParam("name") String name) {
return "Hello, " + name;
}

@GET
@Path("/query")
public String helloWithQueryParam(@QueryParam("foo") String foo) {
return "Hello, this is your query parameter: " + foo;
}

@POST
public String echo(String name, @Context Request request) {
return "hello, " + name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
import jakarta.ws.rs.PathParam;
import jakarta.ws.rs.QueryParam;

import org.eclipse.microprofile.rest.client.RestClientBuilder;
import org.eclipse.microprofile.rest.client.inject.RestClient;
Expand All @@ -29,6 +30,12 @@ public String invokeClientWithPathParamContainingSlash(@PathParam("name") String
return client.helloWithPathParam(name + "/" + name);
}

@Path("/v2/query")
@GET
public String invokeClientWithQueryParam(@QueryParam("foo") String foo) {
return client.helloWithQueryParam(foo);
}

@Path("/{name}")
@GET
public String invokeClientWithPathParam(@PathParam("name") String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ void shouldSayHelloNameWithSlash() {

}

@Test
void shouldEncodeQueryCorrectly() {
when()
.get("/helper/v2/query?foo=cigüeña")
.then()
.statusCode(200)
.body(equalTo("Hello, this is your query parameter: cigüeña"));

}

@Test
void shouldSayHelloNameWithBlank() {
when()
Expand Down
5 changes: 5 additions & 0 deletions independent-projects/resteasy-reactive/client/runtime/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@
<artifactId>junit-jupiter</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<scope>test</scope>
</dependency>

<dependency>
<groupId>org.jboss.logging</groupId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ public void filter(ResteasyReactiveClientRequestContext requestContext) {
//To avoid the path double encoding we create uri with path=null and set the path after
URI newUri = new URI(scheme,
uri.getUserInfo(), host, port,
null, uri.getQuery(), uri.getFragment());
URI build = UriBuilder.fromUri(newUri).path(actualPath).build();
null, null, uri.getFragment());
URI build = UriBuilder.fromUri(newUri).path(actualPath).replaceQuery(uri.getRawQuery()).build();
requestContext.setUri(build);
if (measureTime && instance.gatherStatistics()) {
requestContext.setCallStatsCollector(instance);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.jboss.resteasy.reactive.client.impl;

import static org.mockito.Mockito.anyBoolean;
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.argThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.mockStatic;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import java.net.URI;

import jakarta.ws.rs.core.GenericType;

import org.jboss.resteasy.reactive.client.spi.ResteasyReactiveClientRequestContext;
import org.junit.jupiter.api.Test;
import org.mockito.MockedStatic;

import io.smallrye.mutiny.Multi;
import io.smallrye.mutiny.Uni;
import io.smallrye.stork.Stork;
import io.smallrye.stork.api.Service;
import io.smallrye.stork.api.ServiceInstance;

class StorkClientRequestFilterTest {
@Test
void testQueryEncoding() {
// Given
Stork mockStork = mock(Stork.class);
try (MockedStatic<Stork> storkStatic = mockStatic(Stork.class)) {
storkStatic.when(Stork::getInstance).thenReturn(mockStork);
Service mockedService = mock(Service.class);
ServiceInstance mockedServiceInstance = mock(ServiceInstance.class);
when(mockStork.getService(anyString())).thenReturn(mockedService);
when(mockedService.selectInstanceAndRecordStart(anyBoolean()))
.thenReturn(Uni.createFrom().item(mockedServiceInstance));
StorkClientRequestFilter filter = new StorkClientRequestFilter();
ResteasyReactiveClientRequestContext context = mock(ResteasyReactiveClientRequestContext.class);

URI originalUri = URI
.create("stork://my-service/some/path?foo=bar%20baz&special=%26%3D&ae=%C3%A4&oe=%C3%B6&ue=%C3%BC");
when(context.getUri()).thenReturn(originalUri);
when(context.getResponseType()).thenReturn(new GenericType<>(Multi.class));

// When
filter.filter(context);

// Then
verify(context).setUri(argThat(uri -> {
// Query should be preserved and properly encoded
return "http://localhost:80/some/path?foo=bar%20baz&special=%26%3D&ae=%C3%A4&oe=%C3%B6&ue=%C3%BC"
.equals(uri.toString());
}));
}
}
}
Loading