diff --git a/core/src/main/java/feign/Logger.java b/core/src/main/java/feign/Logger.java index 13e3bf394..6e190530a 100644 --- a/core/src/main/java/feign/Logger.java +++ b/core/src/main/java/feign/Logger.java @@ -1,5 +1,5 @@ /* - * Copyright 2012-2023 The Feign Authors + * Copyright 2012-2024 The Feign Authors * * Licensed 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 @@ -15,6 +15,7 @@ import static feign.Util.UTF_8; import static feign.Util.decodeOrDefault; +import static feign.Util.ensureClosed; import static feign.Util.valuesOrEmpty; import static java.util.Objects.nonNull; import java.io.IOException; @@ -126,6 +127,7 @@ protected Response logAndRebufferResponse(String configKey, log(configKey, ""); // CRLF } byte[] bodyData = Util.toByteArray(response.body().asInputStream()); + ensureClosed(response.body()); bodyLength = bodyData.length; if (logLevel.ordinal() >= Level.FULL.ordinal() && bodyLength > 0) { log(configKey, "%s", decodeOrDefault(bodyData, UTF_8, "Binary data")); diff --git a/core/src/test/java/feign/LoggerMethodsTest.java b/core/src/test/java/feign/LoggerMethodsTest.java new file mode 100644 index 000000000..7a9c382cc --- /dev/null +++ b/core/src/test/java/feign/LoggerMethodsTest.java @@ -0,0 +1,52 @@ +/* + * Copyright 2012-2024 The Feign Authors + * + * Licensed 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 feign; + +import feign.Logger.Level; +import org.junit.jupiter.api.Test; +import java.io.IOException; +import java.util.Collections; +import static feign.Util.UTF_8; +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.spy; +import static org.mockito.Mockito.verify; + +public class LoggerMethodsTest { + + Logger logger = new Logger() { + @Override + protected void log(String configKey, String format, Object... args) {} + }; + + @Test + void responseIsClosedAfterRebuffer() throws IOException { + Request request = + Request.create(Request.HttpMethod.GET, "/api", Collections.emptyMap(), null, UTF_8, null); + Response response = Response.builder() + .status(200) + .reason("OK") + .request(request) + .headers(Collections.emptyMap()) + .body("some text", UTF_8) + .build(); + Response.Body spyBody = spy(response.body()); + response = response.toBuilder().body(spyBody).build(); + + Response rebufferedResponse = + logger.logAndRebufferResponse("someMethod()", Level.FULL, response, 100); + + verify(spyBody).close(); + assertThat(rebufferedResponse.body()).isNotSameAs(spyBody); + } +}