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
This commit is contained in:
Arjen Poutsma 2022-09-13 11:24:32 +02:00
parent 2687de0fe8
commit 71f9a84d22
2 changed files with 25 additions and 2 deletions

View File

@ -143,13 +143,14 @@ public final class StringDecoder extends AbstractDataBufferDecoder<String> {
private Collection<DataBuffer> processDataBuffer(
DataBuffer buffer, DataBufferUtils.Matcher matcher, LimitedDataBufferList chunks) {
boolean release = true;
try {
List<DataBuffer> 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<String> {
return (result != null ? result : Collections.emptyList());
}
finally {
DataBufferUtils.release(buffer);
if (release) {
DataBufferUtils.release(buffer);
}
}
}

View File

@ -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<String> 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 <T> Mono<T> doMalformedChunkedResponseTest(
ClientHttpConnector connector, Function<ResponseSpec, Mono<T>> handler) {