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

ffang pushed a commit to branch 4.1.x-fixes
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/4.1.x-fixes by this push:
     new cd12f3012e5 fix Invocation.Builder.property() not visible to HTTP 
transport (#3375)
cd12f3012e5 is described below

commit cd12f3012e5bd42d32fffd1b5c1239ba3f76327f
Author: Neena P Jacob <[email protected]>
AuthorDate: Tue Aug 18 19:55:41 2026 +0530

    fix Invocation.Builder.property() not visible to HTTP transport (#3375)
    
    (cherry picked from commit 4fdf9fe2ea7329df785bc9a4c8d1e2e555414eb5)
---
 .../jaxrs/client/spec/InvocationBuilderImpl.java   |  4 ++
 .../client/spec/InvocationBuilderImplTest.java     | 61 ++++++++++++++++++++++
 2 files changed, 65 insertions(+)

diff --git 
a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImpl.java
 
b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImpl.java
index 25c85abd825..5b062151f88 100644
--- 
a/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImpl.java
+++ 
b/rt/rs/client/src/main/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImpl.java
@@ -288,8 +288,12 @@ public class InvocationBuilderImpl implements 
Invocation.Builder {
         }
         if (value == null) {
             filterProps.remove(name);
+            contextProps.remove(name);
         } else {
             filterProps.put(name, value);
+            // CXF-9235: also write to the top-level context so that the 
transport layer
+            // can find the property via Message.getContextualProperty()
+            contextProps.put(name, value);
         }
         return this;
     }
diff --git 
a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImplTest.java
 
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImplTest.java
index 9569bfeddf1..6dcba9a8371 100644
--- 
a/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImplTest.java
+++ 
b/rt/rs/client/src/test/java/org/apache/cxf/jaxrs/client/spec/InvocationBuilderImplTest.java
@@ -19,6 +19,7 @@
 package org.apache.cxf.jaxrs.client.spec;
 
 import java.io.IOException;
+import java.util.Map;
 
 import jakarta.ws.rs.client.Client;
 import jakarta.ws.rs.client.ClientBuilder;
@@ -28,15 +29,21 @@ import jakarta.ws.rs.client.Invocation.Builder;
 import jakarta.ws.rs.core.MultivaluedHashMap;
 import jakarta.ws.rs.core.MultivaluedMap;
 import jakarta.ws.rs.core.Response;
+import org.apache.cxf.helpers.CastUtils;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.transport.http.Headers;
 
 import org.junit.Test;
 
 import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNull;
 import static org.junit.Assert.assertTrue;
 
 public class InvocationBuilderImplTest {
 
+    private static final String FILTER_PROPS_KEY = "jaxrs.filter.properties";
+
     public static class TestFilter implements ClientRequestFilter {
 
         /** {@inheritDoc}*/
@@ -83,4 +90,58 @@ public class InvocationBuilderImplTest {
         response = builder.get();
         assertEquals("", response.readEntity(String.class));
     }
+
+    /**
+     * CXF-9235: Invocation.Builder.property() must write the property value 
into BOTH:
+     *
+     * (a) the nested "jaxrs.filter.properties" sub-map inside the 
ClientConfiguration
+     *     request context — this is what context.getProperty() reads inside a
+     *     ClientRequestFilter (via MessagePropertyHolder / 
Exchange.get(PROPERTY_KEY)).
+     *
+     * (b) the flat top-level ClientConfiguration request context — this is 
what the
+     *     HTTP transport reads via Message.getContextualProperty() in
+     *     Headers.setProtocolHeadersInConnection().
+     *
+     * Before the fix only (a) was written.  The transport (b) path was 
silently missing,
+     * meaning a property like "set.content.type.for.empty.request" set on the
+     * Invocation.Builder had no effect on the conduit.
+     */
+    @Test
+    public void testPropertyWrittenToBothFilterPropsAndFlatContext() {
+        Client client = ClientBuilder.newClient().register(TestFilter.class);
+        Builder builder = 
client.target("http://localhost:8080/notReal";).request();
+
+        // ---- set ----
+        builder.property(Headers.SET_EMPTY_REQUEST_CT_PROPERTY, Boolean.FALSE);
+
+        InvocationBuilderImpl builderImpl = (InvocationBuilderImpl) builder;
+        Map<String, Object> requestContext =
+                
WebClient.getConfig(builderImpl.getWebClient()).getRequestContext();
+
+        // (a) Must be in the nested filterProps sub-map that a 
ClientRequestFilter reads.
+        //     This path was already written before the fix; we guard it stays 
working.
+        Map<String, Object> filterProps =
+                CastUtils.cast((Map<?, ?>) 
requestContext.get(FILTER_PROPS_KEY));
+        assertTrue("jaxrs.filter.properties sub-map must exist after 
Builder.property()",
+                filterProps != null && 
filterProps.containsKey(Headers.SET_EMPTY_REQUEST_CT_PROPERTY));
+        assertEquals("Value in filterProps must match what was set",
+                Boolean.FALSE, 
filterProps.get(Headers.SET_EMPTY_REQUEST_CT_PROPERTY));
+
+        // (b) Must also be present flat in the top-level context — the path 
the HTTP
+        //     transport reads via Message.getContextualProperty().  This was 
the bug in
+        //     CXF-9235: only (a) was written, so the transport never saw the 
property.
+        assertEquals("Flat request context must contain the property for the 
transport layer (CXF-9235)",
+                Boolean.FALSE, 
requestContext.get(Headers.SET_EMPTY_REQUEST_CT_PROPERTY));
+
+        // ---- remove (null value) ----
+        builder.property(Headers.SET_EMPTY_REQUEST_CT_PROPERTY, null);
+
+        // (a) removed from filterProps
+        assertNull("Null value must remove property from filterProps sub-map",
+                filterProps.get(Headers.SET_EMPTY_REQUEST_CT_PROPERTY));
+
+        // (b) removed from flat context
+        assertFalse("Null value must remove property from the flat transport 
context (CXF-9235)",
+                
requestContext.containsKey(Headers.SET_EMPTY_REQUEST_CT_PROPERTY));
+    }
 }

Reply via email to