From d14de7857684d691224a520ac995de35da2b7437 Mon Sep 17 00:00:00 2001 From: artur-ciocanu Date: Tue, 29 Apr 2025 20:06:05 +0300 Subject: [PATCH] Fix URL building logic (#1320) * Fix URL building logic Signed-off-by: Artur Ciocanu * Add test for query params Signed-off-by: Artur Ciocanu * Fix the assertion in the test Signed-off-by: Artur Ciocanu * Adjust the tests Signed-off-by: Artur Ciocanu * Remove uneeded changes from IT test Signed-off-by: Artur Ciocanu * Revert some unintended changes Signed-off-by: Artur Ciocanu * Simplify the testing a little bit Signed-off-by: Artur Ciocanu * Adjust the test to use ServerRequest Signed-off-by: Artur Ciocanu * Test removing things from method invoke controller Signed-off-by: Artur Ciocanu * Add query param encoding test Signed-off-by: Artur Ciocanu * Revert some unintended changes Signed-off-by: Artur Ciocanu * Some tiny styles Signed-off-by: Artur Ciocanu --------- Signed-off-by: Artur Ciocanu Co-authored-by: Artur Ciocanu Signed-off-by: Cassandra Coyle --- .../http/MethodInvokeController.java | 6 +++++ .../it/methodinvoke/http/MethodInvokeIT.java | 23 ++++++++++++++++++- .../main/java/io/dapr/client/DaprHttp.java | 21 ++++++++++++++--- 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java index 8ff77985b7..d381e2ac69 100644 --- a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java +++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeController.java @@ -6,6 +6,7 @@ import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.PutMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.ArrayList; @@ -88,6 +89,11 @@ public void sleep(@RequestBody int seconds) throws InterruptedException { Thread.sleep(seconds * 1000); } + @GetMapping(path = "/query") + public Map getQuery(@RequestParam("uri") String uri) { + return Map.of("uri", uri); + } + @GetMapping(path = "/health") public void health() { } diff --git a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java index ba7b485ca6..9d9ac02f8b 100644 --- a/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java +++ b/sdk-tests/src/test/java/io/dapr/it/methodinvoke/http/MethodInvokeIT.java @@ -1,7 +1,8 @@ package io.dapr.it.methodinvoke.http; +import com.fasterxml.jackson.databind.JsonNode; import io.dapr.client.DaprClient; -import io.dapr.client.DaprClientBuilder; +import io.dapr.client.DaprHttp; import io.dapr.client.domain.HttpExtension; import io.dapr.exceptions.DaprException; import io.dapr.it.BaseIT; @@ -140,4 +141,24 @@ public void testInvokeException() throws Exception { assertTrue(new String(exception.getPayload()).contains("Internal Server Error")); } } + + @Test + public void testInvokeQueryParamEncoding() throws Exception { + try (DaprClient client = daprRun.newDaprClientBuilder().build()) { + client.waitForSidecar(10000).block(); + + String uri = "abc/pqr"; + Map> queryParams = Map.of("uri", List.of(uri)); + HttpExtension httpExtension = new HttpExtension(DaprHttp.HttpMethods.GET, queryParams, Map.of()); + JsonNode result = client.invokeMethod( + daprRun.getAppName(), + "/query", + null, + httpExtension, + JsonNode.class + ).block(); + + assertEquals(uri, result.get("uri").asText()); + } + } } diff --git a/sdk/src/main/java/io/dapr/client/DaprHttp.java b/sdk/src/main/java/io/dapr/client/DaprHttp.java index 5b23d733ec..489fd40491 100644 --- a/sdk/src/main/java/io/dapr/client/DaprHttp.java +++ b/sdk/src/main/java/io/dapr/client/DaprHttp.java @@ -24,7 +24,6 @@ import java.io.IOException; import java.net.URI; -import java.net.URISyntaxException; import java.net.URLEncoder; import java.net.http.HttpClient; import java.net.http.HttpRequest; @@ -324,10 +323,17 @@ private static String getContentType(Map headers) { private static URI createUri(URI uri, String[] pathSegments, Map> urlParameters) { String path = createPath(uri, pathSegments); String query = createQuery(urlParameters); + StringBuilder result = new StringBuilder(); + + result.append(uri.getScheme()).append("://").append(uri.getAuthority()).append(path); + + if (query != null) { + result.append("?").append(query); + } try { - return new URI(uri.getScheme(), uri.getAuthority(), path, query, null); - } catch (URISyntaxException exception) { + return URI.create(result.toString()); + } catch (IllegalArgumentException exception) { throw new DaprException(exception); } } @@ -346,6 +352,10 @@ private static String createPath(URI uri, String[] pathSegments) { } for (String segment : pathSegments) { + if (segment == null || segment.isEmpty()) { + continue; // Skip empty segments + } + pathBuilder.append(encodePathSegment(segment)).append("/"); // Encode each segment } @@ -363,6 +373,11 @@ private static String createQuery(Map> urlParameters) { for (Map.Entry> entry : urlParameters.entrySet()) { String key = entry.getKey(); + + if (key == null || key.isEmpty()) { + continue; // Skip empty keys + } + List values = entry.getValue(); for (String value : values) {