diff --git a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java index aa091045a86..03aab3dcb6c 100644 --- a/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java +++ b/spring-web/src/main/java/org/springframework/http/codec/EncoderHttpMessageWriter.java @@ -118,14 +118,12 @@ public class EncoderHttpMessageWriter implements HttpMessageWriter { if (inputStream instanceof Mono) { HttpHeaders headers = message.getHeaders(); - if (headers.getFirst(HttpHeaders.CONTENT_LENGTH) == null) { - return Mono.from(body) - .defaultIfEmpty(message.bufferFactory().wrap(new byte[0])) - .flatMap(buffer -> { - headers.setContentLength(buffer.readableByteCount()); - return message.writeWith(Mono.just(buffer)); - }); - } + return Mono.from(body) + .defaultIfEmpty(message.bufferFactory().wrap(new byte[0])) + .flatMap(buffer -> { + headers.setContentLength(buffer.readableByteCount()); + return message.writeWith(Mono.just(buffer)); + }); } return (isStreamingMediaType(contentType) ? diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java index ab396dc9209..8be6b1899bd 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/AbstractServerHttpResponse.java @@ -45,6 +45,7 @@ import org.springframework.util.MultiValueMap; * @author Rossen Stoyanchev * @author Juergen Hoeller * @author Sebastien Deleuze + * @author Brian Clozel * @since 5.0 */ public abstract class AbstractServerHttpResponse implements ServerHttpResponse { @@ -174,13 +175,21 @@ public abstract class AbstractServerHttpResponse implements ServerHttpResponse { @Override public final Mono writeWith(Publisher body) { return new ChannelSendOperator<>(body, - writePublisher -> doCommit(() -> writeWithInternal(writePublisher))); + writePublisher -> doCommit(() -> writeWithInternal(writePublisher))) + .doOnError(t -> removeContentLength()); } @Override public final Mono writeAndFlushWith(Publisher> body) { return new ChannelSendOperator<>(body, - writePublisher -> doCommit(() -> writeAndFlushWithInternal(writePublisher))); + writePublisher -> doCommit(() -> writeAndFlushWithInternal(writePublisher))) + .doOnError(t -> removeContentLength()); + } + + private void removeContentLength() { + if (!this.isCommitted()) { + this.getHeaders().remove(HttpHeaders.CONTENT_LENGTH); + } } @Override diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpResponseTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpResponseTests.java index 651e9c55bd8..55746952ca5 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpResponseTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ServerHttpResponseTests.java @@ -29,6 +29,7 @@ import reactor.core.publisher.Mono; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; +import org.springframework.http.HttpHeaders; import org.springframework.http.ResponseCookie; import static junit.framework.TestCase.assertTrue; @@ -75,12 +76,14 @@ public class ServerHttpResponseTests { @Test public void writeWithError() throws Exception { TestServerHttpResponse response = new TestServerHttpResponse(); + response.getHeaders().setContentLength(12); IllegalStateException error = new IllegalStateException("boo"); response.writeWith(Flux.error(error)).onErrorResume(ex -> Mono.empty()).block(); assertFalse(response.statusCodeWritten); assertFalse(response.headersWritten); assertFalse(response.cookiesWritten); + assertFalse(response.getHeaders().containsKey(HttpHeaders.CONTENT_LENGTH)); assertTrue(response.body.isEmpty()); }