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

davsclaus pushed a commit to branch fix/CAMEL-25188
in repository https://gitbox.apache.org/repos/asf/camel.git

commit 9b52046ca7343c5b6d61b6bb5d91673c6698a891
Author: Claus Ibsen <[email protected]>
AuthorDate: Wed Sep 30 15:32:47 2026 +0200

    CAMEL-25188: camel-util - URISupport.normalizeUri writes a space in a query 
value as + in the fast path too
    
    Since CAMEL-24524 the fast path wrote a space as %20 while the complex path
    writes +, so normalizing a normalized uri changed it, and the same endpoint
    written as a+b or a%20b got two endpoint keys.
    
    Co-Authored-By: Claude Opus 5.5 (1M context) <[email protected]>
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../java/org/apache/camel/util/URISupport.java     |  3 ++
 .../java/org/apache/camel/util/URISupportTest.java | 34 ++++++++++++++++++++++
 2 files changed, 37 insertions(+)

diff --git 
a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java 
b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
index 25250ff857b6..0f97643e11e6 100644
--- a/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
+++ b/core/camel-util/src/main/java/org/apache/camel/util/URISupport.java
@@ -955,6 +955,9 @@ public final class URISupport {
             // characters in a URI query per RFC 3986 - 
UnsafeUriCharactersEncoder does not escape them
             // as it is also used outside of this query-value context
             String encoded = 
UnsafeUriCharactersEncoder.encode(value).replace("&", "%26").replace("=", 
"%3D");
+            // a space as +, as the complex normalizer (createQueryString) 
writes it, so normalizing a normalized
+            // uri gives the same uri; the fast parser only takes uris without 
%, so %20 here is always a space
+            encoded = encoded.replace("%20", "+");
             sb.append(encoded);
         }
     }
diff --git 
a/core/camel-util/src/test/java/org/apache/camel/util/URISupportTest.java 
b/core/camel-util/src/test/java/org/apache/camel/util/URISupportTest.java
index 4cd22a9b2bf0..a6e32cc42fe3 100644
--- a/core/camel-util/src/test/java/org/apache/camel/util/URISupportTest.java
+++ b/core/camel-util/src/test/java/org/apache/camel/util/URISupportTest.java
@@ -148,6 +148,40 @@ public class URISupportTest {
         assertEquals("http://www.google.com?q=S%C3%B8ren+Hansen";, out);
     }
 
+    @Test
+    public void testNormalizeSpaceTheSameInEverySpelling() throws Exception {
+        // CAMEL-25188: the fast and the complex normalizer both write a space 
in a value as +
+        
assertThat(URISupport.normalizeUri("log:foo?marker=a+b")).isEqualTo("log://foo?marker=a+b");
+        
assertThat(URISupport.normalizeUri("log:foo?marker=a%20b")).isEqualTo("log://foo?marker=a+b");
+        assertThat(URISupport.normalizeUri("log:foo?marker=a 
b")).isEqualTo("log://foo?marker=a+b");
+        assertThat(URISupport.normalizeUri("log:foo?showAll=true&marker=a+b"))
+                .isEqualTo("log://foo?marker=a+b&showAll=true");
+        
assertThat(URISupport.normalizeUri("log:foo?marker=a++b")).isEqualTo("log://foo?marker=a++b");
+    }
+
+    @Test
+    public void testNormalizeTwiceGivesTheSameUri() throws Exception {
+        // CAMEL-25188: a normalized uri normalizes to itself, so endpoint 
keys and lookups agree
+        String[] uris = {
+                "http://localhost:8080/foo?a=1&b=2";,
+                "http://localhost:8080/foo?b=hello world&a=1",
+                "http://localhost:8080/foo?q=a+b";,
+                "http://localhost:8080/foo?q=a%20b";,
+                "http://localhost:8080/foo?q=a+b&x=1";,
+                "ftp://[email protected]:21/dir?password=se+cret&binary=true";,
+                "ftp://[email protected]:21/dir?password=RAW(se+cret)&binary=true",
+                "log:foo?level=INFO&showAll=true",
+                "timer:tick?period=1s&delay=2s",
+                "direct:start?b=\u00f8&a=1",
+                "file:target/in?include=.*\\.txt&noop=true",
+                "http://h/p?x=a&x=b&y=1";,
+                "mock:a?b=x+y+z&a=1" };
+        for (String uri : uris) {
+            String once = URISupport.normalizeUri(uri);
+            assertThat(URISupport.normalizeUri(once)).as("normalizing %s 
twice", uri).isEqualTo(once);
+        }
+    }
+
     @Test
     public void testParseParametersURLEncodedValue() throws Exception {
         String out = 
URISupport.normalizeUri("http://www.google.com?q=S%C3%B8ren%20Hansen";);

Reply via email to