diff --git a/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java b/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java index 15e6325f721..031fe10a7db 100644 --- a/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java +++ b/spring-core/src/main/java/org/springframework/core/codec/StringDecoder.java @@ -143,13 +143,14 @@ public final class StringDecoder extends AbstractDataBufferDecoder { private Collection processDataBuffer( DataBuffer buffer, DataBufferUtils.Matcher matcher, LimitedDataBufferList chunks) { + boolean release = true; try { List result = null; do { int endIndex = matcher.match(buffer); if (endIndex == -1) { chunks.add(buffer); - DataBufferUtils.retain(buffer); // retain after add (may raise DataBufferLimitException) + release = false; break; } DataBuffer split = buffer.split(endIndex + 1); @@ -177,7 +178,9 @@ public final class StringDecoder extends AbstractDataBufferDecoder { return (result != null ? result : Collections.emptyList()); } finally { - DataBufferUtils.release(buffer); + if (release) { + DataBufferUtils.release(buffer); + } } } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java index 8be90ef25b3..07c5adaa05a 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientIntegrationTests.java @@ -1258,6 +1258,26 @@ class WebClientIntegrationTests { .verify(); } + @ParameterizedWebClientTest + void retrieveTextDecodedToFlux(ClientHttpConnector connector) { + startServer(connector); + + prepareResponse(response -> response + .setHeader("Content-Type", "text/plain") + .setBody("Hey now")); + + Flux result = this.webClient.get() + .uri("/") + .accept(MediaType.TEXT_PLAIN) + .retrieve() + .bodyToFlux(String.class); + + StepVerifier.create(result) + .expectNext("Hey now") + .expectComplete() + .verify(Duration.ofSeconds(3)); + } + private Mono doMalformedChunkedResponseTest( ClientHttpConnector connector, Function> handler) {