You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hc.apache.org by ol...@apache.org on 2023/12/11 11:24:40 UTC

(httpcomponents-client) 01/01: Fix Response Body Truncation Issue in ContentResponseHandler (#521)

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

olegk pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/httpcomponents-client.git

commit 7d853d521e8741aa1967b216fe4dfbe425a21efa
Author: Arturo Bernal <ab...@apache.org>
AuthorDate: Mon Dec 11 12:08:27 2023 +0100

    Fix Response Body Truncation Issue in ContentResponseHandler (#521)
    
    Resolved a bug where the response body was truncated to 256 bytes in all cases, including successful responses.
---
 .../http/fluent/ContentResponseHandler.java        |  6 +--
 .../hc/client5/testing/fluent/TestFluent.java      | 50 ++++++++++++++++++++++
 2 files changed, 52 insertions(+), 4 deletions(-)

diff --git a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
index faa221f0a..102c6454b 100644
--- a/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
+++ b/httpclient5-fluent/src/main/java/org/apache/hc/client5/http/fluent/ContentResponseHandler.java
@@ -72,12 +72,10 @@ public class ContentResponseHandler extends AbstractHttpClientResponseHandler<Co
     public Content handleResponse(final ClassicHttpResponse response) throws IOException {
         final int statusCode = response.getCode();
         final HttpEntity entity = response.getEntity();
-        final byte[] contentBytes = (entity != null) ? EntityUtils.toByteArray(entity, MAX_MESSAGE_LENGTH) : new byte[0];
         final ContentType contentType = (entity != null && entity.getContentType() != null) ? ContentType.parse(entity.getContentType()) : ContentType.DEFAULT_BINARY;
-        final Content content = new Content(contentBytes, contentType);
         if (statusCode >= 300) {
-            throw new HttpResponseException(statusCode, response.getReasonPhrase(), contentBytes, contentType);
+            throw new HttpResponseException(statusCode, response.getReasonPhrase(), entity != null ? EntityUtils.toByteArray(entity, MAX_MESSAGE_LENGTH) : null, contentType);
         }
-        return content;
+        return new Content(entity != null ? EntityUtils.toByteArray(entity) : new byte[] {}, contentType);
     }
 }
diff --git a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
index 35e3ae464..cb3378f41 100644
--- a/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
+++ b/httpclient5-testing/src/test/java/org/apache/hc/client5/testing/fluent/TestFluent.java
@@ -31,12 +31,14 @@ import java.net.URI;
 import java.nio.charset.StandardCharsets;
 
 import org.apache.hc.client5.http.ClientProtocolException;
+import org.apache.hc.client5.http.HttpResponseException;
 import org.apache.hc.client5.http.fluent.Content;
 import org.apache.hc.client5.http.fluent.Request;
 import org.apache.hc.client5.testing.sync.extension.TestClientResources;
 import org.apache.hc.core5.http.ContentType;
 import org.apache.hc.core5.http.HttpEntity;
 import org.apache.hc.core5.http.HttpHost;
+import org.apache.hc.core5.http.HttpStatus;
 import org.apache.hc.core5.http.URIScheme;
 import org.apache.hc.core5.http.io.entity.EntityUtils;
 import org.apache.hc.core5.http.io.entity.StringEntity;
@@ -79,6 +81,20 @@ public class TestFluent {
             }
             response.setEntity(responseEntity);
         });
+
+        // Handler for large content large message
+        server.registerHandler("/large-message", (request, response, context) -> {
+            final String largeContent = generateLargeString(10000); // Large content string
+            response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
+        });
+
+        // Handler for large content large message with error
+        server.registerHandler("/large-message-error", (request, response, context) -> {
+            final String largeContent = generateLargeString(10000); // Large content string
+            response.setCode(HttpStatus.SC_REDIRECTION);
+            response.setEntity(new StringEntity(largeContent, ContentType.TEXT_PLAIN));
+        });
+
     }
 
     @Test
@@ -156,4 +172,38 @@ public class TestFluent {
         }
     }
 
+    private String generateLargeString(final int size) {
+        final StringBuilder sb = new StringBuilder(size);
+        for (int i = 0; i < size; i++) {
+            sb.append("x");
+        }
+        return sb.toString();
+    }
+
+    @Test
+    public void testLargeResponse() throws Exception {
+
+        final HttpHost target = targetHost();
+        final String baseURL = "http://localhost:" + target.getPort();
+
+        final Content content = Request.get(baseURL + "/large-message").execute().returnContent();
+        Assertions.assertEquals(10000, content.asBytes().length);
+    }
+
+    @Test
+    public void testLargeResponseError() throws Exception {
+        final HttpHost target = targetHost();
+        final String baseURL = "http://localhost:" + target.getPort();
+
+        try {
+            Request.get(baseURL + "/large-message-error").execute().returnContent();
+            Assertions.fail("Expected an HttpResponseException to be thrown");
+        } catch (final HttpResponseException e) {
+            // Check if the content of the exception is less than or equal to 256 bytes
+            final byte[] contentBytes = e.getContentBytes();
+            Assertions.assertNotNull(contentBytes, "Content bytes should not be null");
+            Assertions.assertTrue(contentBytes.length <= 256, "Content length should be less or equal to 256 bytes");
+        }
+    }
+
 }