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

davsclaus pushed a commit to branch backport/29731-to-camel-4-18-x
in repository https://gitbox.apache.org/repos/asf/camel.git

commit b19e1132c49c5c07d073b5dbf44b728bcc4d97f5
Author: Claus Ibsen <[email protected]>
AuthorDate: Thu Nov 12 20:44:06 2026 +0100

    [camel-4.18.x] CAMEL-26485: camel-netty-http - endpoint options are no 
longer sent to the server as query parameters
    
    The netty-http producer no longer sends its own endpoint options (such as
    cookieHandler, httpMethodRestrict) to the HTTP server as query parameters.
    NettyHttpComponent.createEndpoint built the address URI before setProperties
    bound and removed the endpoint options; it is now built after.
    
    Adapted: on this branch the CAMEL-26487 backport keeps the address as the
    endpoint URI and the full URI as the identity, so the endpoint is created
    with the full URI and its endpoint URI is set to the address once the
    options are bound (a package-private NettyHttpEndpoint.setAddressUri). The
    upgrade-guide note is on main.
    
    Co-Authored-By: Claude Opus 5.5 <[email protected]>
    (cherry picked from commit f70ca1171086)
    Signed-off-by: Claus Ibsen <[email protected]>
---
 .../component/netty/http/NettyHttpComponent.java   |  15 +--
 .../component/netty/http/NettyHttpEndpoint.java    |   8 ++
 .../NettyHttpEndpointOptionsNotInQueryTest.java    | 110 +++++++++++++++++++++
 3 files changed, 126 insertions(+), 7 deletions(-)

diff --git 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
index d1647ddb24a5..7c849c32f88b 100644
--- 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
+++ 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpComponent.java
@@ -175,18 +175,19 @@ public class NettyHttpComponent extends NettyComponent
         // validate config
         config.validateConfiguration();
 
-        // create the address uri which includes the remainder parameters 
(which
-        // is not configuration parameters for this component)
-        URI u = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(remaining));
-
-        String addressUri = URISupport.createRemainingURI(u, 
parameters).toString();
-
-        NettyHttpEndpoint answer = new NettyHttpEndpoint(addressUri, this, 
config);
+        // the endpoint uri is the http address to call: it is set below, once 
the endpoint options are bound
+        NettyHttpEndpoint answer = new NettyHttpEndpoint(uri, this, config);
         // endpoints that differ only in their options must not be equal, so 
the full uri is the identity
         answer.setIdentityUri(uri);
         answer.getConfiguration().setMuteException(muteException);
         setProperties(answer, parameters);
 
+        // create the address uri with the remainder parameters, after the 
endpoint options are bound
+        // (and removed), so only the query parameters that are not endpoint 
options are sent to the server
+        URI u = new URI(UnsafeUriCharactersEncoder.encodeHttpURI(remaining));
+        String addressUri = URISupport.createRemainingURI(u, 
parameters).toString();
+        answer.setAddressUri(addressUri);
+
         // must use a copy of the binding on the endpoint to avoid sharing same
         // instance that can cause side-effects
         if (answer.getNettyHttpBinding() == null) {
diff --git 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
index 4c706b025298..c2a3b9afffee 100644
--- 
a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
+++ 
b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java
@@ -262,6 +262,14 @@ public class NettyHttpEndpoint extends NettyEndpoint 
implements HeaderFilterStra
         this.identityUri = identityUri;
     }
 
+    /**
+     * The http address to call, which is the endpoint uri: the uri without 
the endpoint options, which are bound when
+     * the endpoint is created (CAMEL-26485).
+     */
+    void setAddressUri(String addressUri) {
+        setEndpointUri(addressUri);
+    }
+
     private String getIdentityUri() {
         return identityUri != null ? identityUri : getEndpointUri();
     }
diff --git 
a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointOptionsNotInQueryTest.java
 
b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointOptionsNotInQueryTest.java
new file mode 100644
index 000000000000..048f2a8cf483
--- /dev/null
+++ 
b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpEndpointOptionsNotInQueryTest.java
@@ -0,0 +1,110 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.camel.component.netty.http;
+
+import java.util.List;
+import java.util.Set;
+import java.util.stream.Collectors;
+
+import org.apache.camel.BindToRegistry;
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.camel.http.base.cookie.InstanceCookieHandler;
+import org.apache.camel.support.DefaultExchange;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertNotEquals;
+import static org.junit.jupiter.api.Assertions.assertSame;
+
+public class NettyHttpEndpointOptionsNotInQueryTest extends 
BaseNettyTestSupport {
+
+    @BindToRegistry("myCookieHandler")
+    private final InstanceCookieHandler cookieHandler = new 
InstanceCookieHandler();
+
+    @Test
+    public void testEndpointOptionsAreNotSentAsQueryParameters() {
+        String uri = 
"netty-http:http://localhost:{{port}}/echo?bar=1&cookieHandler=#myCookieHandler";
+                     + 
"&httpMethodRestrict=GET&traceEnabled=false&exchangePattern=InOut&lazyStartProducer=true"
+                     + "&throwExceptionOnFailure=true";
+
+        NettyHttpEndpoint endpoint = context.getEndpoint(uri, 
NettyHttpEndpoint.class);
+        // the options are bound to the endpoint
+        assertSame(cookieHandler, endpoint.getCookieHandler());
+        assertEquals("GET", endpoint.getHttpMethodRestrict());
+
+        // and only the query parameter that is not an endpoint option is in 
the address
+        assertEquals("http://localhost:"; + getPort() + "/echo?bar=1",
+                NettyHttpHelper.createURL(new DefaultExchange(context), 
endpoint));
+
+        String query = template.requestBody(uri, null, String.class);
+        assertEquals("bar=1", query);
+    }
+
+    @Test
+    public void testOnlyEndpointOptions() {
+        String query = template.requestBody(
+                
"netty-http:http://localhost:{{port}}/echo?cookieHandler=#myCookieHandler&httpMethodRestrict=GET";,
 null,
+                String.class);
+        // no query parameters at all
+        assertEquals("none", query);
+    }
+
+    @Test
+    public void testConsumersDifferingOnlyInHttpMethodRestrict() {
+        List<NettyHttpEndpoint> endpoints = context.getEndpoints().stream()
+                .filter(NettyHttpEndpoint.class::isInstance)
+                .map(NettyHttpEndpoint.class::cast)
+                .filter(e -> e.getConfiguration().getPath().equals("/orders"))
+                .toList();
+        // the rest consumers for GET and POST on the same path differ only in 
httpMethodRestrict
+        assertEquals(2, endpoints.size());
+        assertNotEquals(endpoints.get(0), endpoints.get(1));
+        assertEquals(Set.of("GET", "POST"),
+                
endpoints.stream().map(NettyHttpEndpoint::getHttpMethodRestrict).collect(Collectors.toSet()));
+
+        String out = 
template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/orders";, 
null,
+                Exchange.HTTP_METHOD, "GET", String.class);
+        assertEquals("get", out);
+        out = 
template.requestBodyAndHeader("netty-http:http://localhost:{{port}}/orders";, 
"Hello",
+                Exchange.HTTP_METHOD, "POST", String.class);
+        assertEquals("post", out);
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() {
+                from("netty-http:http://localhost:{{port}}/echo";)
+                        .process(e -> {
+                            String query = 
e.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
+                            e.getMessage().setBody(query != null ? query : 
"none");
+                        });
+
+                
restConfiguration().component("netty-http").host("localhost").port(getPort());
+
+                rest("/orders")
+                        .get().to("direct:get")
+                        .post().to("direct:post");
+
+                from("direct:get").transform().constant("get");
+                from("direct:post").transform().constant("post");
+            }
+        };
+    }
+}

Reply via email to