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

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


The following commit(s) were added to refs/heads/3.3.x-fixes by this push:
     new 1ffa6ae  [CXF-8565] Add support for requests with no body to the netty 
client transport There were several issues with the netty client transport:
1ffa6ae is described below

commit 1ffa6ae57f09675e8cce2b7fd669d1f7eda15e84
Author: Tim Ward <[email protected]>
AuthorDate: Wed Jul 21 14:47:59 2021 +0100

    [CXF-8565] Add support for requests with no body to the netty client 
transport
    There were several issues with the netty client transport:
    
    * Several NPE locations due to setting or removing null headers
    * No call to connect when there is no OutputStream to write a body
    * No call to write the request when there is no OutputStream to close
    
    Signed-off-by: Tim Ward <[email protected]>
    (cherry picked from commit fc5b8fd8689815ee3bff284b89ac8d9cb897e83b)
---
 .../http/netty/client/NettyHttpConduit.java        | 62 +++++++++++++++++++---
 1 file changed, 54 insertions(+), 8 deletions(-)

diff --git 
a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
 
b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
index f5d4e7a..cd358d4 100644
--- 
a/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
+++ 
b/rt/transports/http-netty/netty-client/src/main/java/org/apache/cxf/transport/http/netty/client/NettyHttpConduit.java
@@ -32,6 +32,8 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.security.Principal;
 import java.security.cert.Certificate;
+import java.util.Arrays;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -78,6 +80,9 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
     public static final String MAX_RESPONSE_CONTENT_LENGTH =
         "org.apache.cxf.transport.http.netty.maxResponseContentLength";
     static final Integer DEFAULT_MAX_RESPONSE_CONTENT_LENGTH = 1048576;
+    private static final Set<String> KNOWN_HTTP_VERBS_WITH_NO_CONTENT =
+            new HashSet<>(Arrays.asList(new String[]{"GET", "HEAD", "OPTIONS", 
"TRACE"}));
+    
     final NettyHttpConduitFactory factory;
     private Bootstrap bootstrap;
 
@@ -197,7 +202,10 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
             entity.createRequest(out.getOutBuffer());
             // TODO need to check how to set the Chunked feature
             //request.getRequest().setChunked(true);
-            entity.getRequest().headers().set(Message.CONTENT_TYPE, 
message.get(Message.CONTENT_TYPE));
+            Object contentType = message.get(Message.CONTENT_TYPE);
+            if (contentType != null) {
+                entity.getRequest().headers().set(Message.CONTENT_TYPE, 
contentType);
+            }
             return out;
         }
         return super.createOutputStream(message, needToCacheRequest, 
isChunking, chunkThreshold);
@@ -314,7 +322,7 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
                     
                     synchronized (entity) {
                         Channel syncChannel = getChannel();
-                        ChannelFuture channelFuture = 
syncChannel.write(entity);
+                        ChannelFuture channelFuture = 
syncChannel.writeAndFlush(entity);
                         channelFuture.addListener(listener);
                         outputStream.close();
                     }
@@ -328,6 +336,11 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
                 wrappedStream = cachedStream;
             }
         }
+        
+        @Override
+        protected void handleNoOutput() throws IOException {
+            connect(false);
+        }
 
         protected TLSClientParameters findTLSClientParameters() {
             TLSClientParameters clientParameters = 
outMessage.get(TLSClientParameters.class);
@@ -378,11 +391,6 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
 
             connFuture.addListener(listener);
 
-            if (!output) {
-                entity.getRequest().headers().remove("Transfer-Encoding");
-                entity.getRequest().headers().remove("Content-Type");
-                entity.getRequest().headers().remove(null);
-            }
 
             // setup the CxfResponseCallBack
             CxfResponseCallBack callBack = new CxfResponseCallBack() {
@@ -398,6 +406,29 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
             };
             entity.setCxfResponseCallback(callBack);
 
+            if (!output) {
+                entity.getRequest().headers().remove("Transfer-Encoding");
+                entity.getRequest().headers().remove("Content-Type");
+                
+                ChannelFutureListener writeFailureListener = new 
ChannelFutureListener() {
+                    @Override
+                    public void operationComplete(ChannelFuture future) throws 
Exception {
+                        if (!future.isSuccess()) {
+                            setException(future.cause());
+                        }
+                    }
+                };
+                
+                connFuture.addListener(new ChannelFutureListener() {
+                        @Override
+                        public void operationComplete(ChannelFuture future) 
throws Exception {
+                            if (future.isSuccess()) {
+                                ChannelFuture channelFuture = 
future.channel().writeAndFlush(entity);
+                                
channelFuture.addListener(writeFailureListener);
+                            }
+                        }
+                    });
+            }
         }
 
         @Override
@@ -434,7 +465,7 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
         @Override
         protected void setProtocolHeaders() throws IOException {
             Headers h = new Headers(outMessage);
-            entity.getRequest().headers().set(Message.CONTENT_TYPE, 
h.determineContentType());
+            setContentTypeHeader(h);
             boolean addHeaders = MessageUtils.getContextualBoolean(outMessage, 
Headers.ADD_HEADERS_PROPERTY, false);
 
             for (Map.Entry<String, List<String>> header : 
h.headerMap().entrySet()) {
@@ -460,6 +491,21 @@ public class NettyHttpConduit extends 
URLConnectionHTTPConduit implements BusLif
                 }
             }
         }
+        
+        private void setContentTypeHeader(Headers headers) {
+            if (outMessage.get(Message.CONTENT_TYPE) == null) {
+                // if no content type is set then check for a request body
+                Object requestMethod = 
outMessage.get(Message.HTTP_REQUEST_METHOD);
+                boolean emptyRequest = 
KNOWN_HTTP_VERBS_WITH_NO_CONTENT.contains(requestMethod) 
+                        || 
PropertyUtils.isTrue(outMessage.get(Headers.EMPTY_REQUEST_PROPERTY));
+                // If it is not an empty request then add a content type
+                if (!emptyRequest) {
+                    entity.getRequest().headers().set(Message.CONTENT_TYPE, 
headers.determineContentType());
+                }
+            } else {
+                entity.getRequest().headers().set(Message.CONTENT_TYPE, 
headers.determineContentType());
+            }
+        }
 
         @Override
         protected void setFixedLengthStreamingMode(int i) {

Reply via email to