jersey-netty-connector v2.47 : Connector is returning 200 OK when decoded result in HttpResponse contains TooLongHttpHeaderException #6045 (#6047)

Signed-off-by: Jorge Bescos Gascon <jorge.bescos.gascon@oracle.com>
diff --git a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
index da9cf83..968afcc 100644
--- a/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
+++ b/connectors/netty-connector/src/main/java/org/glassfish/jersey/netty/connector/JerseyClientHandler.java
@@ -27,6 +27,7 @@
 import java.util.function.Predicate;
 
 import javax.ws.rs.core.Response;
+import javax.ws.rs.client.ResponseProcessingException;
 
 import org.glassfish.jersey.client.ClientRequest;
 import org.glassfish.jersey.client.ClientResponse;
@@ -38,6 +39,7 @@
 import io.netty.buffer.ByteBuf;
 import io.netty.channel.ChannelHandlerContext;
 import io.netty.channel.SimpleChannelInboundHandler;
+import io.netty.handler.codec.DecoderResult;
 import io.netty.handler.codec.http.HttpContent;
 import io.netty.handler.codec.http.HttpObject;
 import io.netty.handler.codec.http.HttpResponse;
@@ -179,33 +181,40 @@
             return;
         }
         if (msg instanceof HttpResponse) {
-            final HttpResponse response = (HttpResponse) msg;
-            jerseyResponse = new ClientResponse(new Response.StatusType() {
-                @Override
-                public int getStatusCode() {
-                    return response.status().code();
+            if (msg.decoderResult().isFailure()) {
+                Throwable cause = msg.decoderResult().cause();
+                ResponseProcessingException ex = new ResponseProcessingException(null, cause);
+                responseAvailable.completeExceptionally(ex);
+                return;
+            } else {
+                final HttpResponse response = (HttpResponse) msg;
+                jerseyResponse = new ClientResponse(new Response.StatusType() {
+                    @Override
+                    public int getStatusCode() {
+                        return response.status().code();
+                    }
+
+                    @Override
+                    public Response.Status.Family getFamily() {
+                        return Response.Status.Family.familyOf(response.status().code());
+                    }
+
+                    @Override
+                    public String getReasonPhrase() {
+                        return response.status().reasonPhrase();
+                    }
+                }, jerseyRequest);
+
+                for (Map.Entry<String, String> entry : response.headers().entries()) {
+                    jerseyResponse.getHeaders().add(entry.getKey(), entry.getValue());
                 }
 
-                @Override
-                public Response.Status.Family getFamily() {
-                    return Response.Status.Family.familyOf(response.status().code());
-                }
+                // request entity handling.
+                nis = new NettyInputStream();
+                responseDone.whenComplete((_r, th) -> nis.complete(th));
 
-                @Override
-                public String getReasonPhrase() {
-                    return response.status().reasonPhrase();
-                }
-            }, jerseyRequest);
-
-            for (Map.Entry<String, String> entry : response.headers().entries()) {
-                jerseyResponse.getHeaders().add(entry.getKey(), entry.getValue());
+                jerseyResponse.setEntityStream(nis);
             }
-
-            // request entity handling.
-            nis = new NettyInputStream();
-            responseDone.whenComplete((_r, th) -> nis.complete(th));
-
-            jerseyResponse.setEntityStream(nis);
         }
         if (msg instanceof HttpContent) {
 
diff --git a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/HugeHeaderTest.java b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/HugeHeaderTest.java
index 6f2d433..39f5524 100644
--- a/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/HugeHeaderTest.java
+++ b/connectors/netty-connector/src/test/java/org/glassfish/jersey/netty/connector/HugeHeaderTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2024 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2024, 2025 Oracle and/or its affiliates. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v. 2.0, which is available at
@@ -28,6 +28,7 @@
 import javax.ws.rs.HeaderParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
+import javax.ws.rs.ProcessingException;
 import javax.ws.rs.core.Application;
 import javax.ws.rs.core.Response;
 
@@ -36,6 +37,7 @@
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertNull;
+import static org.junit.jupiter.api.Assertions.fail;
 
 public class HugeHeaderTest extends JerseyTest {
 
@@ -90,13 +92,14 @@
         for (int i = 1; i < 33; i++) {
             veryHugeHeader.append(hugeHeader);
         }
-        final Response response = target("test").request()
-                .header("X-HUGE-HEADER", veryHugeHeader.toString())
-                .post(null);
-
-        assertNull(response.getHeaderString("X-HUGE-HEADER-SIZE"));
-        assertNull(response.getHeaderString("X-HUGE-HEADER"));
-        response.close();
+        try {
+            target("test").request()
+                    .header("X-HUGE-HEADER", veryHugeHeader.toString())
+                    .post(null);
+            fail("Expected an exception");
+        } catch (ProcessingException ex) {
+            assertEquals("HTTP header is larger than 8192 bytes.", ex.getCause().getCause().getMessage());
+        }
     }
 
     @Test