From e594b6e5f3f42fd37738dfd8ac066d255a271542 Mon Sep 17 00:00:00 2001 From: vladdenisov Date: Wed, 18 Apr 2018 20:58:22 +0300 Subject: [PATCH] Fix of exception "Attempted read from closed stream." which occurred after HttpEntity consuming --- .../httpclient/AllureHttpClientResponse.java | 38 +++++++++++++++---- .../httpclient/AllureHttpClientTest.java | 9 ++++- 2 files changed, 39 insertions(+), 8 deletions(-) diff --git a/allure-httpclient/src/main/java/io/qameta/allure/httpclient/AllureHttpClientResponse.java b/allure-httpclient/src/main/java/io/qameta/allure/httpclient/AllureHttpClientResponse.java index 561706a22..dc2e8dbb1 100644 --- a/allure-httpclient/src/main/java/io/qameta/allure/httpclient/AllureHttpClientResponse.java +++ b/allure-httpclient/src/main/java/io/qameta/allure/httpclient/AllureHttpClientResponse.java @@ -6,13 +6,16 @@ import io.qameta.allure.attachment.DefaultAttachmentProcessor; import io.qameta.allure.attachment.FreemarkerAttachmentRenderer; import io.qameta.allure.attachment.http.HttpResponseAttachment; -import org.apache.http.HttpException; +import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.HttpResponseInterceptor; +import org.apache.http.entity.HttpEntityWrapper; import org.apache.http.protocol.HttpContext; +import org.apache.http.util.EntityUtils; -import java.io.ByteArrayOutputStream; +import java.io.ByteArrayInputStream; import java.io.IOException; +import java.io.InputStream; import java.nio.charset.StandardCharsets; import java.util.stream.Stream; @@ -40,7 +43,7 @@ public AllureHttpClientResponse(final AttachmentRenderer rendere @Override public void process(final HttpResponse response, - final HttpContext context) throws HttpException, IOException { + final HttpContext context) throws IOException { final HttpResponseAttachment.Builder builder = create("Response") .withResponseCode(response.getStatusLine().getStatusCode()); @@ -48,13 +51,34 @@ public void process(final HttpResponse response, Stream.of(response.getAllHeaders()) .forEach(header -> builder.withHeader(header.getName(), header.getValue())); - final ByteArrayOutputStream os = new ByteArrayOutputStream(); - response.getEntity().writeTo(os); + final LoggableEntity loggableEntity = new LoggableEntity(response.getEntity()); + response.setEntity(loggableEntity); - final String body = new String(os.toByteArray(), StandardCharsets.UTF_8); - builder.withBody(body); + builder.withBody(loggableEntity.getBody()); final HttpResponseAttachment responseAttachment = builder.build(); processor.addAttachment(responseAttachment, renderer); } + + /** + * Required to allow consume httpEntity twice. + */ + private static class LoggableEntity extends HttpEntityWrapper { + + private final byte[] rawContent; + + LoggableEntity(final HttpEntity wrappedEntity) throws IOException { + super(wrappedEntity); + rawContent = EntityUtils.toByteArray(wrappedEntity); + } + + public String getBody() { + return new String(rawContent, StandardCharsets.UTF_8); + } + + @Override + public InputStream getContent() { + return new ByteArrayInputStream(rawContent); + } + } } diff --git a/allure-httpclient/src/test/java/io/qameta/allure/httpclient/AllureHttpClientTest.java b/allure-httpclient/src/test/java/io/qameta/allure/httpclient/AllureHttpClientTest.java index 5c6126222..948258bec 100644 --- a/allure-httpclient/src/test/java/io/qameta/allure/httpclient/AllureHttpClientTest.java +++ b/allure-httpclient/src/test/java/io/qameta/allure/httpclient/AllureHttpClientTest.java @@ -8,6 +8,7 @@ import org.apache.http.client.methods.HttpGet; import org.apache.http.impl.client.CloseableHttpClient; import org.apache.http.impl.client.HttpClientBuilder; +import org.apache.http.util.EntityUtils; import org.junit.After; import org.junit.Before; import org.junit.Test; @@ -32,6 +33,8 @@ */ public class AllureHttpClientTest { + private static final String BODY_STRING = "Hello world!"; + private WireMockServer server; @Before @@ -42,7 +45,7 @@ public void setUp() { stubFor(get(urlEqualTo("/hello")) .willReturn(aResponse() - .withBody("Hello world!"))); + .withBody(BODY_STRING))); } @SuppressWarnings("unchecked") @@ -58,6 +61,8 @@ public void shouldCreateRequestAttachment() throws Exception { final HttpGet httpGet = new HttpGet(String.format("http://localhost:%d/hello", server.port())); try (CloseableHttpResponse response = httpClient.execute(httpGet)) { response.getStatusLine().getStatusCode(); + assertThat(EntityUtils.toString(response.getEntity())) + .isEqualTo(BODY_STRING); } } @@ -84,6 +89,8 @@ public void shouldCreateResponseAttachment() throws Exception { final HttpGet httpGet = new HttpGet(String.format("http://localhost:%d/hello", server.port())); try (CloseableHttpResponse response = httpClient.execute(httpGet)) { response.getStatusLine().getStatusCode(); + assertThat(EntityUtils.toString(response.getEntity())) + .isEqualTo(BODY_STRING); } }