diff --git a/framework-platform/framework-platform.gradle b/framework-platform/framework-platform.gradle index 2e55c644c27..69d2e920530 100644 --- a/framework-platform/framework-platform.gradle +++ b/framework-platform/framework-platform.gradle @@ -11,7 +11,7 @@ dependencies { api(platform("io.micrometer:micrometer-bom:1.14.0-M3")) api(platform("io.netty:netty-bom:4.1.113.Final")) api(platform("io.netty:netty5-bom:5.0.0.Alpha5")) - api(platform("io.projectreactor:reactor-bom:2024.0.0-M6")) + api(platform("io.projectreactor:reactor-bom:2024.0.0-SNAPSHOT")) api(platform("io.rsocket:rsocket-bom:1.1.3")) api(platform("org.apache.groovy:groovy-bom:4.0.23")) api(platform("org.apache.logging.log4j:log4j-bom:2.21.1")) @@ -50,6 +50,7 @@ dependencies { api("io.micrometer:context-propagation:1.1.1") api("io.mockk:mockk:1.13.4") api("io.projectreactor.netty:reactor-netty5-http:2.0.0-M3") + api("io.projectreactor.netty:reactor-netty-http") api("io.projectreactor.tools:blockhound:1.0.8.RELEASE") api("io.r2dbc:r2dbc-h2:1.0.0.RELEASE") api("io.r2dbc:r2dbc-spi-test:1.0.0.RELEASE") diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java index b939eee45ac..b136e9bbb7b 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorServerHttpRequest.java @@ -65,7 +65,8 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest { public ReactorServerHttpRequest(HttpServerRequest request, NettyDataBufferFactory bufferFactory) throws URISyntaxException { - super(HttpMethod.valueOf(request.method().name()), ReactorUriHelper.createUri(request), "", + super(HttpMethod.valueOf(request.method().name()), + ReactorUriHelper.createUri(request), request.forwardedPrefix(), new Netty4HeadersAdapter(request.requestHeaders())); Assert.notNull(bufferFactory, "DataBufferFactory must not be null"); this.request = request; diff --git a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorUriHelper.java b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorUriHelper.java index 2207f9e76cc..9f31f3db59b 100644 --- a/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorUriHelper.java +++ b/spring-web/src/main/java/org/springframework/http/server/reactive/ReactorUriHelper.java @@ -48,8 +48,12 @@ public static URI createUri(HttpServerRequest request) throws URISyntaxException builder.append(port); } - appendRequestUri(request, builder); + String prefix = request.forwardedPrefix(); + if (prefix != null && !prefix.isEmpty()) { + builder.append(prefix); + } + appendRequestUri(request, builder); return new URI(builder.toString()); } diff --git a/spring-web/src/test/java/org/springframework/http/server/reactive/ReactorUriHelperTests.java b/spring-web/src/test/java/org/springframework/http/server/reactive/ReactorUriHelperTests.java index 3f829808a68..b275c96ace7 100644 --- a/spring-web/src/test/java/org/springframework/http/server/reactive/ReactorUriHelperTests.java +++ b/spring-web/src/test/java/org/springframework/http/server/reactive/ReactorUriHelperTests.java @@ -20,6 +20,8 @@ import java.net.URISyntaxException; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.CsvSource; import reactor.netty.http.server.HttpServerRequest; import static org.assertj.core.api.Assertions.assertThat; @@ -49,4 +51,29 @@ void hostnameWithZoneId() throws URISyntaxException { } + @ParameterizedTest(name = "{displayName}({arguments})") + @CsvSource(delimiter='|', value = { + "/prefix | /prefix/", + "/prefix1/prefix2 | /prefix1/prefix2/", + " | /", + "'' | /", + }) + void forwardedPrefix(String prefixHeader, String expectedPath) throws URISyntaxException { + HttpServerRequest nettyRequest = mock(); + + given(nettyRequest.scheme()).willReturn("https"); + given(nettyRequest.hostName()).willReturn("localhost"); + given(nettyRequest.hostPort()).willReturn(443); + given(nettyRequest.uri()).willReturn("/"); + given(nettyRequest.forwardedPrefix()).willReturn(prefixHeader); + + URI uri = ReactorUriHelper.createUri(nettyRequest); + assertThat(uri).hasScheme("https") + .hasHost("localhost") + .hasPort(-1) + .hasPath(expectedPath) + .hasToString("https://localhost" + expectedPath); + } + + }