diff --git a/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java b/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java index 18361fceb75f..81f5930d3bf2 100644 --- a/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java +++ b/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfiguration.java @@ -64,10 +64,13 @@ static class AnnotationConfig { @Bean HttpHandler httpHandler(ObjectProvider propsProvider, ObjectProvider handlerBuilderCustomizers) { + WebFluxProperties properties = propsProvider.getIfAvailable(); WebHttpHandlerBuilder handlerBuilder = WebHttpHandlerBuilder.applicationContext(this.applicationContext); + if (properties != null) { + handlerBuilder.defaultHtmlEscape(properties.getDefaultHtmlEscape()); + } handlerBuilderCustomizers.orderedStream().forEach((customizer) -> customizer.customize(handlerBuilder)); HttpHandler httpHandler = handlerBuilder.build(); - WebFluxProperties properties = propsProvider.getIfAvailable(); if (properties != null && StringUtils.hasText(properties.getBasePath())) { Map handlersMap = Collections.singletonMap(properties.getBasePath(), httpHandler); return new ContextPathCompositeHandler(handlersMap); diff --git a/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java b/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java index 7a5d19329247..aadd36b79ac4 100644 --- a/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java +++ b/module/spring-boot-webflux/src/main/java/org/springframework/boot/webflux/autoconfigure/WebFluxProperties.java @@ -58,6 +58,11 @@ public class WebFluxProperties { */ private String webjarsPathPattern = "/webjars/**"; + /** + * Whether default HTML escaping is enabled for the web application. + */ + private @Nullable Boolean defaultHtmlEscape; + public @Nullable String getBasePath() { return this.basePath; } @@ -110,6 +115,14 @@ public void setWebjarsPathPattern(String webjarsPathPattern) { this.webjarsPathPattern = webjarsPathPattern; } + public @Nullable Boolean getDefaultHtmlEscape() { + return this.defaultHtmlEscape; + } + + public void setDefaultHtmlEscape(@Nullable Boolean defaultHtmlEscape) { + this.defaultHtmlEscape = defaultHtmlEscape; + } + public static class Format { /** diff --git a/module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java b/module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java index e2e4cb7d70ee..bcb6439fcb42 100644 --- a/module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java +++ b/module/spring-boot-webflux/src/test/java/org/springframework/boot/webflux/autoconfigure/HttpHandlerAutoConfigurationTests.java @@ -18,6 +18,8 @@ import org.assertj.core.api.InstanceOfAssertFactories; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.ValueSource; import reactor.core.publisher.Mono; import org.springframework.boot.autoconfigure.AutoConfigurations; @@ -35,6 +37,7 @@ import org.springframework.web.reactive.function.server.RouterFunction; import org.springframework.web.reactive.function.server.ServerResponse; import org.springframework.web.server.WebHandler; +import org.springframework.web.server.adapter.HttpWebHandlerAdapter; import static org.assertj.core.api.Assertions.assertThat; import static org.springframework.web.reactive.function.server.RequestPredicates.GET; @@ -100,6 +103,29 @@ void shouldConfigureBasePathCompositeHandler() { }); } + @ParameterizedTest + @ValueSource(booleans = { true, false }) + void shouldConfigureDefaultHtmlEscape(boolean enabled) { + this.contextRunner.withConfiguration(AutoConfigurations.of(WebFluxAutoConfiguration.class)) + .withPropertyValues("spring.webflux.default-html-escape=" + enabled) + .run((context) -> { + assertThat(context).hasSingleBean(HttpHandler.class); + assertThat(context.getBean(HttpHandler.class)).isInstanceOfSatisfying(HttpWebHandlerAdapter.class, + (adapter) -> assertThat(adapter.getDefaultHtmlEscape()).isEqualTo(enabled)); + }); + } + + @Test + void shouldNotConfigureDefaultHtmlEscaperWithoutWebFluxAutoConfiguration() { + this.contextRunner.withUserConfiguration(CustomWebHandler.class) + .withPropertyValues("spring.webflux.default-html-escape=true") + .run((context) -> { + assertThat(context).hasSingleBean(HttpHandler.class); + assertThat(context.getBean(HttpHandler.class)).isInstanceOfSatisfying(HttpWebHandlerAdapter.class, + (adapter) -> assertThat(adapter.getDefaultHtmlEscape()).isNull()); + }); + } + @Configuration(proxyBeanMethods = false) static class CustomHttpHandler {