From a5339d71eae50e2cb6e572d52a823a26d1d103f1 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Fri, 9 Nov 2018 16:16:03 -0500 Subject: [PATCH] WebClient handles no Content-Type with data correctly Issue: SPR-17482 --- .../web/reactive/function/BodyExtractors.java | 11 +++++------ .../WebClientDataBufferAllocatingTests.java | 18 ++++++++++++++++++ 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java index b20cce8eaf..e0944fc92c 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/BodyExtractors.java @@ -224,16 +224,15 @@ public abstract class BodyExtractors { Flux result; if (message.getHeaders().getContentType() == null) { - // Maybe it's okay, if there is no content.. - result = message.getBody().map(o -> { + // Maybe it's okay there is no content type, if there is no content.. + result = message.getBody().map(buffer -> { + DataBufferUtils.release(buffer); throw ex; }); } else { - result = Flux.error(ex); - } - if (message instanceof ClientHttpResponse) { - result = consumeAndCancel(message).thenMany(result); + result = message instanceof ClientHttpResponse ? + consumeAndCancel(message).thenMany(Flux.error(ex)) : Flux.error(ex); } return result; } diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientDataBufferAllocatingTests.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientDataBufferAllocatingTests.java index ad7ec95030..919b635219 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientDataBufferAllocatingTests.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/client/WebClientDataBufferAllocatingTests.java @@ -16,6 +16,7 @@ package org.springframework.web.reactive.function.client; import java.time.Duration; +import java.util.Map; import java.util.function.Function; import io.netty.buffer.ByteBufAllocator; @@ -28,12 +29,14 @@ import org.junit.Test; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.core.io.buffer.AbstractDataBufferAllocatingTestCase; import org.springframework.core.io.buffer.NettyDataBufferFactory; import org.springframework.http.HttpStatus; import org.springframework.http.MediaType; import org.springframework.http.client.reactive.ReactorClientHttpConnector; import org.springframework.http.client.reactive.ReactorResourceFactory; +import org.springframework.web.reactive.function.UnsupportedMediaTypeException; import static org.junit.Assert.*; @@ -103,6 +106,21 @@ public class WebClientDataBufferAllocatingTests extends AbstractDataBufferAlloca assertEquals(1, this.server.getRequestCount()); } + @Test // SPR-17482 + public void bodyToMonoVoidWithoutContentType() { + + this.server.enqueue(new MockResponse() + .setResponseCode(HttpStatus.ACCEPTED.value()) + .setChunkedBody("{\"foo\" : \"123\", \"baz\" : \"456\", \"baz\" : \"456\"}", 5)); + + Mono> mono = this.webClient.get() + .uri("/sample").accept(MediaType.APPLICATION_JSON) + .retrieve() + .bodyToMono(new ParameterizedTypeReference>() {}); + + StepVerifier.create(mono).expectError(UnsupportedMediaTypeException.class).verify(Duration.ofSeconds(3)); + assertEquals(1, this.server.getRequestCount()); + } @Test public void onStatusWithBodyNotConsumed() {