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

reta pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/cxf.git


The following commit(s) were added to refs/heads/main by this push:
     new d0ac9fb5d4 CXF-8962: HttpClientHTTPConduit sets Content-Type Header 
for DELETE requests with empty body (#1699)
d0ac9fb5d4 is described below

commit d0ac9fb5d4717c77134764cf45eb72292f3e7f5f
Author: Andriy Redko <[email protected]>
AuthorDate: Mon Mar 4 20:10:56 2024 -0500

    CXF-8962: HttpClientHTTPConduit sets Content-Type Header for DELETE 
requests with empty body (#1699)
---
 .../org/apache/cxf/transport/http/Headers.java     |  2 +-
 .../cxf/transport/http/HttpClientHTTPConduit.java  | 21 +++++++-
 .../apache/cxf/systest/jaxrs/EmptyBookServer.java  | 46 ++++++++++++++++
 .../apache/cxf/systest/jaxrs/EmptyBookStore.java   | 46 ++++++++++++++++
 .../jaxrs/JAXRSClientServerEmptyBookTest.java      | 63 ++++++++++++++++++++++
 5 files changed, 175 insertions(+), 3 deletions(-)

diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
index 5df6f727d1..012e9f9b49 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/Headers.java
@@ -66,7 +66,7 @@ public class Headers {
     public static final String HTTP_HEADERS_LINK = "Link";
     public static final String EMPTY_REQUEST_PROPERTY = 
"org.apache.cxf.empty.request";
     public static final String USER_AGENT = initUserAgent();
-    private static final String SET_EMPTY_REQUEST_CT_PROPERTY = 
"set.content.type.for.empty.request";
+    public static final String SET_EMPTY_REQUEST_CT_PROPERTY = 
"set.content.type.for.empty.request";
     private static final TimeZone TIME_ZONE_GMT = TimeZone.getTimeZone("GMT");
     private static final Logger LOG = LogUtils.getL7dLogger(Headers.class);
 
diff --git 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
index e5d26d2c60..5f4d4653d4 100644
--- 
a/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
+++ 
b/rt/transports/http/src/main/java/org/apache/cxf/transport/http/HttpClientHTTPConduit.java
@@ -567,9 +567,26 @@ public class HttpClientHTTPConduit extends 
URLConnectionHTTPConduit {
             }
             if (!h.headerMap().containsKey("User-Agent")) {
                 rb.header("User-Agent", Headers.USER_AGENT);
-            }   
+            }
+
             if (hasCT || 
!KNOWN_HTTP_VERBS_WITH_NO_CONTENT.contains(outMessage.get(Message.HTTP_REQUEST_METHOD)))
 {
-                rb.header(HttpHeaderHelper.CONTENT_TYPE, 
h.determineContentType());
+                boolean dropContentType = false;
+                boolean emptyRequest = 
PropertyUtils.isTrue(outMessage.get(Headers.EMPTY_REQUEST_PROPERTY));
+
+                // If it is an empty request (without a request body) then 
check further if CT still needs be set
+                if (emptyRequest) {
+                    final Object setCtForEmptyRequestProp = outMessage
+                        
.getContextualProperty(Headers.SET_EMPTY_REQUEST_CT_PROPERTY);
+                    if (setCtForEmptyRequestProp != null) {
+                        // If SET_EMPTY_REQUEST_CT_PROPERTY is set then do as 
a user prefers.
+                        // CT will be dropped if setting CT for empty requests 
was explicitly disabled
+                        dropContentType = 
PropertyUtils.isFalse(setCtForEmptyRequestProp);
+                    }
+                }
+
+                if (!dropContentType) {
+                    rb.header(HttpHeaderHelper.CONTENT_TYPE, 
h.determineContentType());
+                }
             }            
         }
         
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookServer.java
 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookServer.java
new file mode 100644
index 0000000000..e22b8ff883
--- /dev/null
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookServer.java
@@ -0,0 +1,46 @@
+/**
+ * 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.cxf.systest.jaxrs;
+
+import org.apache.cxf.Bus;
+import org.apache.cxf.endpoint.Server;
+import org.apache.cxf.jaxrs.JAXRSServerFactoryBean;
+import org.apache.cxf.jaxrs.lifecycle.SingletonResourceProvider;
+import org.apache.cxf.testutil.common.AbstractServerTestServerBase;
+
+public class EmptyBookServer extends AbstractServerTestServerBase {
+    public static final String PORT = allocatePort(EmptyBookServer.class);
+
+    @Override
+    protected Server createServer(Bus bus) throws Exception {
+        final JAXRSServerFactoryBean sf = new JAXRSServerFactoryBean();
+        sf.setResourceClasses(EmptyBookStore.class);
+        sf.setResourceProvider(EmptyBookStore.class,
+            new SingletonResourceProvider(new EmptyBookStore(), true));
+        sf.setAddress("http://localhost:"; + PORT + "/");
+        sf.setBus(bus);
+        return sf.create();
+    }
+
+    public static void main(String[] args) throws Exception {
+        new EmptyBookServer().start();
+    }
+
+}
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookStore.java 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookStore.java
new file mode 100644
index 0000000000..e0131aa855
--- /dev/null
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/EmptyBookStore.java
@@ -0,0 +1,46 @@
+/**
+ * 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.cxf.systest.jaxrs;
+
+import jakarta.ws.rs.DELETE;
+import jakarta.ws.rs.GET;
+import jakarta.ws.rs.Path;
+import jakarta.ws.rs.core.Context;
+import jakarta.ws.rs.core.HttpHeaders;
+
+@Path("/bookstore")
+public class EmptyBookStore {
+    @GET
+    public void get(@Context HttpHeaders headers) {
+        if (headers.getHeaderString("Content-Type") != null) {
+            throw new IllegalStateException("'Content-Type' header is not 
expected");
+        }
+    }
+
+    @DELETE
+    public void delete(@Context HttpHeaders headers) {
+        if (headers.getHeaderString("Content-Type") != null) {
+            throw new IllegalStateException("'Content-Type' header is not 
expected");
+        }
+    }
+
+}
+
+
diff --git 
a/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerEmptyBookTest.java
 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerEmptyBookTest.java
new file mode 100644
index 0000000000..04859f4351
--- /dev/null
+++ 
b/systests/jaxrs/src/test/java/org/apache/cxf/systest/jaxrs/JAXRSClientServerEmptyBookTest.java
@@ -0,0 +1,63 @@
+/**
+ * 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.cxf.systest.jaxrs;
+
+import jakarta.ws.rs.core.Response;
+import org.apache.cxf.Bus;
+import org.apache.cxf.jaxrs.client.WebClient;
+import org.apache.cxf.jaxrs.model.AbstractResourceInfo;
+import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase;
+import org.apache.cxf.transport.http.Headers;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import static org.hamcrest.CoreMatchers.equalTo;
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public class JAXRSClientServerEmptyBookTest extends 
AbstractBusClientServerTestBase {
+    public static final String PORT = EmptyBookServer.PORT;
+    
+    @BeforeClass
+    public static void startServers() throws Exception {
+        AbstractResourceInfo.clearAllMaps();
+        assertTrue("server did not launch correctly", 
launchServer(EmptyBookServer.class, true));
+
+        final Bus bus = createStaticBus();
+        bus.setProperty(Headers.SET_EMPTY_REQUEST_CT_PROPERTY, false);
+    }
+
+    @Test
+    public void testContentTypeEmptyGet() throws Exception {
+        String address = "http://localhost:"; + PORT + "/bookstore/";
+        WebClient wc = WebClient.create(address);
+        final Response r = wc.get();
+        assertThat(r.getStatus(), equalTo(204));
+    }
+    
+    @Test
+    public void testContentTypeEmptyDelete() throws Exception {
+        String address = "http://localhost:"; + PORT + "/bookstore/";
+        WebClient wc = WebClient.create(address);
+        final Response r = wc.delete();
+        assertThat(r.getStatus(), equalTo(204));
+    }
+}

Reply via email to