diff --git a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java index 8499476861..a6130387d8 100644 --- a/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java +++ b/spring-test/src/main/java/org/springframework/mock/web/reactive/function/server/MockServerRequest.java @@ -88,11 +88,15 @@ public class MockServerRequest implements ServerRequest { @Nullable private Principal principal; + @Nullable + private final InetSocketAddress remoteAddress; + private MockServerRequest(HttpMethod method, URI uri, String contextPath, MockHeaders headers, MultiValueMap cookies, @Nullable Object body, Map attributes, MultiValueMap queryParams, - Map pathVariables, @Nullable WebSession session, @Nullable Principal principal) { + Map pathVariables, @Nullable WebSession session, @Nullable Principal principal, + @Nullable InetSocketAddress remoteAddress) { this.method = method; this.uri = uri; @@ -105,6 +109,7 @@ public class MockServerRequest implements ServerRequest { this.pathVariables = pathVariables; this.session = session; this.principal = principal; + this.remoteAddress = remoteAddress; } @@ -143,6 +148,11 @@ public class MockServerRequest implements ServerRequest { return this.cookies; } + @Override + public Optional remoteAddress() { + return Optional.ofNullable(this.remoteAddress); + } + @Override @SuppressWarnings("unchecked") public S body(BodyExtractor extractor) { @@ -262,8 +272,16 @@ public class MockServerRequest implements ServerRequest { Builder session(WebSession session); + /** + * @deprecated in favor of {@link #principal(Principal)} + */ + @Deprecated Builder session(Principal principal); + Builder principal(Principal principal); + + Builder remoteAddress(InetSocketAddress remoteAddress); + MockServerRequest body(Object body); MockServerRequest build(); @@ -297,6 +315,9 @@ public class MockServerRequest implements ServerRequest { @Nullable private Principal principal; + @Nullable + private InetSocketAddress remoteAddress; + @Override public Builder method(HttpMethod method) { Assert.notNull(method, "'method' must not be null"); @@ -401,24 +422,36 @@ public class MockServerRequest implements ServerRequest { @Override public Builder session(Principal principal) { + return principal(principal); + } + + @Override + public Builder principal(Principal principal) { Assert.notNull(principal, "'principal' must not be null"); this.principal = principal; return this; } + @Override + public Builder remoteAddress(InetSocketAddress remoteAddress) { + Assert.notNull(remoteAddress, "'remoteAddress' must not be null"); + this.remoteAddress = remoteAddress; + return this; + } + @Override public MockServerRequest body(Object body) { this.body = body; return new MockServerRequest(this.method, this.uri, this.contextPath, this.headers, this.cookies, this.body, this.attributes, this.queryParams, this.pathVariables, - this.session, this.principal); + this.session, this.principal, this.remoteAddress); } @Override public MockServerRequest build() { return new MockServerRequest(this.method, this.uri, this.contextPath, this.headers, this.cookies, null, this.attributes, this.queryParams, this.pathVariables, - this.session, this.principal); + this.session, this.principal, this.remoteAddress); } } diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java index a8c115b4fb..6ff81115e3 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/DefaultServerRequest.java @@ -116,6 +116,11 @@ class DefaultServerRequest implements ServerRequest { return request().getCookies(); } + @Override + public Optional remoteAddress() { + return Optional.ofNullable(request().getRemoteAddress()); + } + @Override public T body(BodyExtractor extractor) { return body(extractor, Collections.emptyMap()); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java index 654990265a..49a22fcacb 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/RequestPredicates.java @@ -16,6 +16,7 @@ package org.springframework.web.reactive.function.server; +import java.net.InetSocketAddress; import java.net.URI; import java.security.Principal; import java.util.ArrayList; @@ -513,6 +514,11 @@ public abstract class RequestPredicates { return this.request.cookies(); } + @Override + public Optional remoteAddress() { + return this.request.remoteAddress(); + } + @Override public T body(BodyExtractor extractor) { return this.request.body(extractor); diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java index 9ee7d8cb2d..bc19f197c6 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/ServerRequest.java @@ -114,6 +114,12 @@ public interface ServerRequest { */ MultiValueMap cookies(); + /** + * Return the remote address where this request is connected to, if available. + * @since 5.1 + */ + Optional remoteAddress(); + /** * Extract the body with the given {@code BodyExtractor}. * @param extractor the {@code BodyExtractor} that reads from the request diff --git a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java index dde16b7dd1..ee3538ee3a 100644 --- a/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java +++ b/spring-webflux/src/main/java/org/springframework/web/reactive/function/server/support/ServerRequestWrapper.java @@ -116,6 +116,11 @@ public class ServerRequestWrapper implements ServerRequest { return this.delegate.cookies(); } + @Override + public Optional remoteAddress() { + return this.delegate.remoteAddress(); + } + @Override public T body(BodyExtractor extractor) { return this.delegate.body(extractor); diff --git a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java index ccdd2db180..d7bf19a8e6 100644 --- a/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java +++ b/spring-webflux/src/test/java/org/springframework/web/reactive/function/server/MockServerRequest.java @@ -87,11 +87,15 @@ public class MockServerRequest implements ServerRequest { @Nullable private Principal principal; + @Nullable + private final InetSocketAddress remoteAddress; + private MockServerRequest(HttpMethod method, URI uri, String contextPath, MockHeaders headers, MultiValueMap cookies, @Nullable Object body, Map attributes, MultiValueMap queryParams, - Map pathVariables, @Nullable WebSession session, @Nullable Principal principal) { + Map pathVariables, @Nullable WebSession session, @Nullable Principal principal, + @Nullable InetSocketAddress remoteAddress) { this.method = method; this.uri = uri; @@ -104,6 +108,7 @@ public class MockServerRequest implements ServerRequest { this.pathVariables = pathVariables; this.session = session; this.principal = principal; + this.remoteAddress = remoteAddress; } @@ -142,6 +147,11 @@ public class MockServerRequest implements ServerRequest { return this.cookies; } + @Override + public Optional remoteAddress() { + return Optional.ofNullable(this.remoteAddress); + } + @Override @SuppressWarnings("unchecked") public S body(BodyExtractor extractor) { @@ -260,8 +270,16 @@ public class MockServerRequest implements ServerRequest { Builder session(WebSession session); + /** + * @deprecated in favor of {@link #principal(Principal)} + */ + @Deprecated Builder session(Principal principal); + Builder principal(Principal principal); + + Builder remoteAddress(InetSocketAddress remoteAddress); + MockServerRequest body(Object body); MockServerRequest build(); @@ -295,6 +313,9 @@ public class MockServerRequest implements ServerRequest { @Nullable private Principal principal; + @Nullable + private InetSocketAddress remoteAddress; + @Override public Builder method(HttpMethod method) { Assert.notNull(method, "'method' must not be null"); @@ -399,24 +420,36 @@ public class MockServerRequest implements ServerRequest { @Override public Builder session(Principal principal) { + return principal(principal); + } + + @Override + public Builder principal(Principal principal) { Assert.notNull(principal, "'principal' must not be null"); this.principal = principal; return this; } + @Override + public Builder remoteAddress(InetSocketAddress remoteAddress) { + Assert.notNull(remoteAddress, "'remoteAddress' must not be null"); + this.remoteAddress = remoteAddress; + return this; + } + @Override public MockServerRequest body(Object body) { this.body = body; return new MockServerRequest(this.method, this.uri, this.contextPath, this.headers, this.cookies, this.body, this.attributes, this.queryParams, this.pathVariables, - this.session, this.principal); + this.session, this.principal, this.remoteAddress); } @Override public MockServerRequest build() { return new MockServerRequest(this.method, this.uri, this.contextPath, this.headers, this.cookies, null, this.attributes, this.queryParams, this.pathVariables, - this.session, this.principal); + this.session, this.principal, this.remoteAddress); } }