From 71f9a84d22a85884c29f1b4823aba8a55a026a65 Mon Sep 17 00:00:00 2001 From: Arjen Poutsma Date: Tue, 13 Sep 2022 11:24:32 +0200 Subject: [PATCH] Fix releasing bug in StringDecoder This commit fixes an issue in StringDecoder, where, if the buffer did not contain any delimiters, it was released before it was relayed to any subscribers. Closes gh-29119 --- .../core/codec/StringDecoder.java | 7 +++++-- .../client/WebClientIntegrationTests.java | 20 +++++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) 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 15e6325f72..031fe10a7d 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 8be90ef25b..07c5adaa05 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) {