From 0274752fe941f5cc260dc4df7024c93afa9cf44a Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 15 May 2019 16:02:28 -0400 Subject: [PATCH 1/3] Use singleOrEmpty to avoid upstream cancel Closes gh-22952 --- .../http/codec/EncoderHttpMessageWriter.java | 3 ++- .../codec/EncoderHttpMessageWriterTests.java | 17 ++++++++++++----- 2 files changed, 14 insertions(+), 6 deletions(-) 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 ce4d481429..ce8049a178 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 @@ -120,7 +120,8 @@ public class EncoderHttpMessageWriter implements HttpMessageWriter { if (inputStream instanceof Mono) { HttpHeaders headers = message.getHeaders(); - return Mono.from(body) + return body + .singleOrEmpty() .switchIfEmpty(Mono.defer(() -> { headers.setContentLength(0); return message.setComplete().then(Mono.empty()); diff --git a/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java b/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java index 6405ea7088..8d54ea7157 100644 --- a/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java +++ b/spring-web/src/test/java/org/springframework/http/codec/EncoderHttpMessageWriterTests.java @@ -33,6 +33,7 @@ import reactor.core.publisher.Flux; import reactor.core.publisher.Mono; import reactor.test.StepVerifier; +import org.springframework.core.codec.CharSequenceEncoder; import org.springframework.core.io.buffer.DataBuffer; import org.springframework.core.io.buffer.DefaultDataBufferFactory; import org.springframework.http.MediaType; @@ -131,9 +132,7 @@ public class EncoderHttpMessageWriterTests { @Test public void useNegotiatedMediaTypeCharset() { - MediaType negotiatedMediaType = new MediaType("text", "html", ISO_8859_1); - HttpMessageWriter writer = getWriter(TEXT_PLAIN_UTF_8, TEXT_HTML); writer.write(Mono.just("body"), forClass(String.class), negotiatedMediaType, this.response, NO_HINTS); @@ -143,7 +142,6 @@ public class EncoderHttpMessageWriterTests { @Test public void useHttpOutputMessageMediaType() { - MediaType outputMessageMediaType = MediaType.TEXT_HTML; this.response.getHeaders().setContentType(outputMessageMediaType); @@ -156,16 +154,25 @@ public class EncoderHttpMessageWriterTests { @Test public void setContentLengthForMonoBody() { - DefaultDataBufferFactory factory = new DefaultDataBufferFactory(); DataBuffer buffer = factory.wrap("body".getBytes(StandardCharsets.UTF_8)); HttpMessageWriter writer = getWriter(Flux.just(buffer), MimeTypeUtils.TEXT_PLAIN); - writer.write(Mono.just("body"), forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS).block(); assertEquals(4, this.response.getHeaders().getContentLength()); } + @Test // gh-22952 + public void monoBodyDoesNotCancelEncodedFlux() { + Mono inputStream = Mono.just("body") + .doOnCancel(() -> { + throw new AssertionError("Cancel signal not expected"); + }); + new EncoderHttpMessageWriter<>(CharSequenceEncoder.allMimeTypes()) + .write(inputStream, forClass(String.class), TEXT_PLAIN, this.response, NO_HINTS) + .block(); + } + @Test // SPR-17220 public void emptyBodyWritten() { HttpMessageWriter writer = getWriter(MimeTypeUtils.TEXT_PLAIN); From e0b9ed6d72f36dc9c5fbc9ee11f67abc0c898fa6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 15 May 2019 16:13:02 -0400 Subject: [PATCH 2/3] Fix typo in reference Closes gh-22975 --- src/docs/asciidoc/web/webmvc.adoc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/docs/asciidoc/web/webmvc.adoc b/src/docs/asciidoc/web/webmvc.adoc index 16761003ed..8fa5923f9b 100644 --- a/src/docs/asciidoc/web/webmvc.adoc +++ b/src/docs/asciidoc/web/webmvc.adoc @@ -4735,8 +4735,7 @@ The following example shows how to achieve the same configuration in XML: [subs="verbatim"] ---- - - + @@ -4754,7 +4753,7 @@ bean so that it can be injected into others. You can also make the rewrite trans rely on `HttpServletResponse#encodeURL`. Note that, when using both `EncodedResourceResolver` (for example, for serving gzipped or -brotli-encoded resources) and `VersionedResourceResolver`, you must register them in this order. +brotli-encoded resources) and `VersionResourceResolver`, you must register them in this order. That ensures content-based versions are always computed reliably, based on the unencoded file. https://www.webjars.org/documentation[WebJars] are also supported through the From ffd7cffa1403259b78e657c338e30e580e1a4cd6 Mon Sep 17 00:00:00 2001 From: Rossen Stoyanchev Date: Wed, 15 May 2019 16:42:07 -0400 Subject: [PATCH 3/3] Fix typo in HttpHeaders Closes gh-22976 --- .../src/main/java/org/springframework/http/HttpHeaders.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java index 1d3f6924bc..527da5e4b6 100644 --- a/spring-web/src/main/java/org/springframework/http/HttpHeaders.java +++ b/spring-web/src/main/java/org/springframework/http/HttpHeaders.java @@ -869,7 +869,7 @@ public class HttpHeaders implements MultiValueMap, Serializable /** * Set the {@link Locale} of the content language, * as specified by the {@literal Content-Language} header. - *

Use {@code set(CONTENT_LANGUAGE, ...)} if you need + *

Use {@code set(CONTENT_LANGUAGE, list)} if you need * to set multiple content languages.

* @since 5.0 */