This is an automated email from the ASF dual-hosted git repository.

gianm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/druid.git


The following commit(s) were added to refs/heads/master by this push:
     new e68dd496a2c fix: Encode queryId in DirectDruidClient cancelUrl. 
(#20308)
e68dd496a2c is described below

commit e68dd496a2c5e369cf9cb301a6b605d8e9bf09ea
Author: Gian Merlino <[email protected]>
AuthorDate: Tue Sep 29 00:32:51 2026 -0700

    fix: Encode queryId in DirectDruidClient cancelUrl. (#20308)
    
    queryId needs to be URI-encoded, or else queryIds containing path-unsafe
    characters will not be handled properly.
---
 .../org/apache/druid/client/DirectDruidClient.java   |  2 +-
 .../org/apache/druid/discovery/DataServerClient.java |  3 ++-
 .../apache/druid/client/DirectDruidClientTest.java   | 20 ++++++++++++++++++++
 3 files changed, 23 insertions(+), 2 deletions(-)

diff --git 
a/server/src/main/java/org/apache/druid/client/DirectDruidClient.java 
b/server/src/main/java/org/apache/druid/client/DirectDruidClient.java
index b222c9bcc9c..2f963e0b270 100644
--- a/server/src/main/java/org/apache/druid/client/DirectDruidClient.java
+++ b/server/src/main/java/org/apache/druid/client/DirectDruidClient.java
@@ -164,7 +164,7 @@ public class DirectDruidClient<T> implements QueryRunner<T>
 
     final ListenableFuture<InputStream> future;
     final String url = scheme + "://" + host + "/druid/v2/";
-    final String cancelUrl = url + query.getId();
+    final String cancelUrl = url + StringUtils.urlEncode(query.getId());
 
     try {
       log.debug("Querying queryId [%s] url [%s]", query.getId(), url);
diff --git 
a/server/src/main/java/org/apache/druid/discovery/DataServerClient.java 
b/server/src/main/java/org/apache/druid/discovery/DataServerClient.java
index d1b98c2189f..5cba3628c95 100644
--- a/server/src/main/java/org/apache/druid/discovery/DataServerClient.java
+++ b/server/src/main/java/org/apache/druid/discovery/DataServerClient.java
@@ -29,6 +29,7 @@ import io.netty.handler.codec.http.HttpMethod;
 import org.apache.druid.client.JsonParserIterator;
 import org.apache.druid.common.guava.FutureUtils;
 import org.apache.druid.error.DruidException;
+import org.apache.druid.java.util.common.StringUtils;
 import org.apache.druid.java.util.common.concurrent.Execs;
 import org.apache.druid.java.util.common.guava.BaseSequence;
 import org.apache.druid.java.util.common.guava.Sequence;
@@ -164,7 +165,7 @@ public class DataServerClient
       throw DruidException.defensive("Null queryId");
     }
 
-    final String cancelPath = BASE_PATH + queryId;
+    final String cancelPath = BASE_PATH + StringUtils.urlEncode(queryId);
 
     final ListenableFuture<Void> cancelFuture = serviceClient.asyncRequest(
         new RequestBuilder(HttpMethod.DELETE, 
cancelPath).timeout(CANCELLATION_TIMEOUT),
diff --git 
a/server/src/test/java/org/apache/druid/client/DirectDruidClientTest.java 
b/server/src/test/java/org/apache/druid/client/DirectDruidClientTest.java
index ca50b052ffd..b4d1e9e1b7b 100644
--- a/server/src/test/java/org/apache/druid/client/DirectDruidClientTest.java
+++ b/server/src/test/java/org/apache/druid/client/DirectDruidClientTest.java
@@ -221,6 +221,26 @@ public class DirectDruidClientTest
 
   }
 
+  @Test
+  public void testCancelUrlEncodesQueryId()
+  {
+    final QueryPlus queryPlus = 
QueryPlus.wrap(getQueryPlus().getQuery().withId("some 
query/id#needing?encoding"));
+    final QueuedTestHttpClient queuedHttpClient = new QueuedTestHttpClient();
+    queuedHttpClient.enqueue(Futures.immediateCancelledFuture());
+
+    // Canceled query future causes the client to submit a cancel task, which 
issues the DELETE request.
+    makeDirectDruidClient(queuedHttpClient).run(queryPlus, responseContext);
+    blockingExecutorService.finishNextPendingTask();
+
+    final List<Request> requests = queuedHttpClient.getRequests();
+    Assertions.assertEquals(2, requests.size());
+    Assertions.assertEquals(HttpMethod.DELETE, requests.get(1).getMethod());
+    Assertions.assertEquals(
+        "http://"; + hostName + 
"/druid/v2/some%20query%2Fid%23needing%3Fencoding",
+        requests.get(1).getUrl().toString()
+    );
+  }
+
   @Test
   public void testQueryInterruptionExceptionLogMessage()
   {


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to