From 37d7af42ac401ae9a93c675af00ef7ad9b13fff2 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Tue, 18 Mar 2025 15:05:50 +0000 Subject: [PATCH 1/3] Allow setting ApplicationContext on MockServerWebExchange Closes gh-34601 --- .../web/server/MockServerWebExchange.java | 31 +++++++++++++++---- .../adapter/DefaultServerWebExchange.java | 4 +-- 2 files changed, 27 insertions(+), 8 deletions(-) diff --git a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java index e2cf0fae8f..bf5f0b37ba 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java +++ b/spring-test/src/main/java/org/springframework/mock/web/server/MockServerWebExchange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2018 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,6 +18,7 @@ package org.springframework.mock.web.server; import reactor.core.publisher.Mono; +import org.springframework.context.ApplicationContext; import org.springframework.http.codec.ServerCodecConfigurer; import org.springframework.lang.Nullable; import org.springframework.mock.http.server.reactive.MockServerHttpRequest; @@ -39,9 +40,15 @@ import org.springframework.web.server.session.WebSessionManager; */ public final class MockServerWebExchange extends DefaultServerWebExchange { - private MockServerWebExchange(MockServerHttpRequest request, WebSessionManager sessionManager) { - super(request, new MockServerHttpResponse(), sessionManager, - ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver()); + + private MockServerWebExchange( + MockServerHttpRequest request, @Nullable WebSessionManager sessionManager, + @Nullable ApplicationContext applicationContext) { + + super(request, new MockServerHttpResponse(), + sessionManager != null ? sessionManager : new DefaultWebSessionManager(), + ServerCodecConfigurer.create(), new AcceptHeaderLocaleContextResolver(), + applicationContext); } @@ -101,6 +108,9 @@ public final class MockServerWebExchange extends DefaultServerWebExchange { @Nullable private WebSessionManager sessionManager; + @Nullable + private ApplicationContext applicationContext; + public Builder(MockServerHttpRequest request) { this.request = request; } @@ -127,12 +137,21 @@ public final class MockServerWebExchange extends DefaultServerWebExchange { return this; } + /** + * Provide the {@code ApplicationContext} to expose through the exchange. + * @param applicationContext the context to use + * @since 6.2.5 + */ + public Builder applicationContext(ApplicationContext applicationContext) { + this.applicationContext = applicationContext; + return this; + } + /** * Build the {@code MockServerWebExchange} instance. */ public MockServerWebExchange build() { - return new MockServerWebExchange(this.request, - this.sessionManager != null ? this.sessionManager : new DefaultWebSessionManager()); + return new MockServerWebExchange(this.request, this.sessionManager, this.applicationContext); } } diff --git a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java index 0500180897..0c84ef9d00 100644 --- a/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java +++ b/spring-web/src/main/java/org/springframework/web/server/adapter/DefaultServerWebExchange.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -119,7 +119,7 @@ public class DefaultServerWebExchange implements ServerWebExchange { this(request, response, sessionManager, codecConfigurer, localeContextResolver, null); } - DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response, + protected DefaultServerWebExchange(ServerHttpRequest request, ServerHttpResponse response, WebSessionManager sessionManager, ServerCodecConfigurer codecConfigurer, LocaleContextResolver localeContextResolver, @Nullable ApplicationContext applicationContext) { From 34c69bfc6751ea2e0feccb64f3b3e430cb0c08b8 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Wed, 19 Mar 2025 12:14:37 +0000 Subject: [PATCH 2/3] Allow empty comment in ServerResponse.SseBuilder Closes gh-34608 --- .../servlet/function/SseServerResponse.java | 3 +-- .../function/SseServerResponseTests.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java index 38d5cc8ff0..fcf687a067 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/function/SseServerResponse.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,7 +173,6 @@ final class SseServerResponse extends AbstractServerResponse { @Override public SseBuilder comment(String comment) { - Assert.hasLength(comment, "Comment must not be empty"); String[] lines = comment.split("\n"); for (String line : lines) { field("", line); diff --git a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java index fc7ea6f9f1..2a2bf761e6 100644 --- a/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java +++ b/spring-webmvc/src/test/java/org/springframework/web/servlet/function/SseServerResponseTests.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -173,6 +173,26 @@ class SseServerResponseTests { assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected); } + @Test // gh-34608 + void sendHeartbeat() throws Exception { + ServerResponse response = ServerResponse.sse(sse -> { + try { + sse.comment("").send(); + } + catch (IOException ex) { + throw new UncheckedIOException(ex); + } + }); + + ServerResponse.Context context = Collections::emptyList; + + ModelAndView mav = response.writeTo(this.mockRequest, this.mockResponse, context); + assertThat(mav).isNull(); + + String expected = ":\n\n"; + assertThat(this.mockResponse.getContentAsString()).isEqualTo(expected); + } + private static final class Person { From 18c3b637e4040865ac7237239cc59176f7ccad18 Mon Sep 17 00:00:00 2001 From: rstoyanchev Date: Wed, 19 Mar 2025 12:33:01 +0000 Subject: [PATCH 3/3] Fix dated Javadoc in MvcUriComponentsBuilder related to forwarded headers Closes gh-34615 --- .../web/cors/CorsConfiguration.java | 15 ++++----------- .../annotation/MvcUriComponentsBuilder.java | 15 +++++++-------- 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java index bef29cf0e2..fced7fcba4 100644 --- a/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java +++ b/spring-web/src/main/java/org/springframework/web/cors/CorsConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -297,14 +297,7 @@ public class CorsConfiguration { * allowCredentials} is set to {@code true}, that combination is handled * by copying the method specified in the CORS preflight request. *

If not set, only {@code "GET"} and {@code "HEAD"} are allowed. - *

By default this is not set. - *

Note: CORS checks use values from "Forwarded" - * (RFC 7239), - * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, - * if present, in order to reflect the client-originated address. - * Consider using the {@code ForwardedHeaderFilter} in order to choose from a - * central place whether to extract and use, or to discard such headers. - * See the Spring Framework reference for more on this filter. + *

By default, this is not set. */ public void setAllowedMethods(@Nullable List allowedMethods) { this.allowedMethods = (allowedMethods != null ? new ArrayList<>(allowedMethods) : null); @@ -456,7 +449,7 @@ public class CorsConfiguration { * level of trust with the configured domains and also increases the surface * attack of the web application by exposing sensitive user-specific * information such as cookies and CSRF tokens. - *

By default this is not set (i.e. user credentials are not supported). + *

By default, this is not set (i.e. user credentials are not supported). */ public void setAllowCredentials(@Nullable Boolean allowCredentials) { this.allowCredentials = allowCredentials; @@ -480,7 +473,7 @@ public class CorsConfiguration { *

Setting this property has an impact on how {@link #setAllowedOrigins(List) * origins} and {@link #setAllowedOriginPatterns(List) originPatterns} are processed, * see related API documentation for more details. - *

By default this is not set (i.e. private network access is not supported). + *

By default, this is not set (i.e. private network access is not supported). * @since 5.3.32 * @see Private network access specifications */ diff --git a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java index c66bb0652e..64ad6f1db1 100644 --- a/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java +++ b/spring-webmvc/src/main/java/org/springframework/web/servlet/mvc/method/annotation/MvcUriComponentsBuilder.java @@ -1,5 +1,5 @@ /* - * Copyright 2002-2024 the original author or authors. + * Copyright 2002-2025 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -84,13 +84,12 @@ import org.springframework.web.util.pattern.PathPatternParser; * {@link #relativeTo(org.springframework.web.util.UriComponentsBuilder)}. * * - *

Note: This class uses values from "Forwarded" - * (RFC 7239), - * "X-Forwarded-Host", "X-Forwarded-Port", and "X-Forwarded-Proto" headers, - * if present, in order to reflect the client-originated protocol and address. - * Consider using the {@code ForwardedHeaderFilter} in order to choose from a - * central place whether to extract and use, or to discard such headers. - * See the Spring Framework reference for more on this filter. + *

Note: As of 5.1, methods in this class do not extract + * {@code "Forwarded"} and {@code "X-Forwarded-*"} headers that specify the + * client-originated address. Please, use + * {@link org.springframework.web.filter.ForwardedHeaderFilter + * ForwardedHeaderFilter}, or similar from the underlying server, to extract + * and use such headers, or to discard them. * * @author Oliver Gierke * @author Rossen Stoyanchev