Expose localAddress in WebFlux server

Closes gh-24174
This commit is contained in:
Rossen Stoyanchev 2019-12-10 15:10:13 +00:00
parent 2bd821c909
commit 1b172c1d20
14 changed files with 176 additions and 31 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -61,6 +61,9 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final InetSocketAddress localAddress;
@Nullable
private final SslInfo sslInfo;
@ -69,13 +72,14 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
private MockServerHttpRequest(HttpMethod httpMethod, URI uri, @Nullable String contextPath,
HttpHeaders headers, MultiValueMap<String, HttpCookie> cookies,
@Nullable InetSocketAddress remoteAddress, @Nullable SslInfo sslInfo,
Publisher<? extends DataBuffer> body) {
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress,
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
super(uri, contextPath, headers);
this.httpMethod = httpMethod;
this.cookies = cookies;
this.remoteAddress = remoteAddress;
this.localAddress = localAddress;
this.sslInfo = sslInfo;
this.body = Flux.from(body);
}
@ -97,6 +101,12 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
return this.remoteAddress;
}
@Nullable
@Override
public InetSocketAddress getLocalAddress() {
return this.localAddress;
}
@Nullable
@Override
protected SslInfo initSslInfo() {
@ -254,6 +264,12 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
*/
B remoteAddress(InetSocketAddress remoteAddress);
/**
* Set the local address to return.
* @since 5.2.3
*/
B localAddress(InetSocketAddress localAddress);
/**
* Set SSL session information and certificates.
*/
@ -408,6 +424,9 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable
private InetSocketAddress remoteAddress;
@Nullable
private InetSocketAddress localAddress;
@Nullable
private SslInfo sslInfo;
@ -441,6 +460,12 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
return this;
}
@Override
public BodyBuilder localAddress(InetSocketAddress localAddress) {
this.localAddress = localAddress;
return this;
}
@Override
public void sslInfo(SslInfo sslInfo) {
this.sslInfo = sslInfo;
@ -545,7 +570,7 @@ public final class MockServerHttpRequest extends AbstractServerHttpRequest {
public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) {
applyCookiesIfNecessary();
return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath,
this.headers, this.cookies, this.remoteAddress, this.sslInfo, body);
this.headers, this.cookies, this.remoteAddress, this.localAddress, this.sslInfo, body);
}
private void applyCookiesIfNecessary() {

View File

@ -93,6 +93,9 @@ public final class MockServerRequest implements ServerRequest {
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final InetSocketAddress localAddress;
private final List<HttpMessageReader<?>> messageReaders;
@Nullable
@ -103,8 +106,8 @@ public final class MockServerRequest implements ServerRequest {
MultiValueMap<String, HttpCookie> cookies, @Nullable Object body,
Map<String, Object> attributes, MultiValueMap<String, String> queryParams,
Map<String, String> pathVariables, @Nullable WebSession session, @Nullable Principal principal,
@Nullable InetSocketAddress remoteAddress, List<HttpMessageReader<?>> messageReaders,
@Nullable ServerWebExchange exchange) {
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress,
List<HttpMessageReader<?>> messageReaders, @Nullable ServerWebExchange exchange) {
this.method = method;
this.uri = uri;
@ -118,6 +121,7 @@ public final class MockServerRequest implements ServerRequest {
this.session = session;
this.principal = principal;
this.remoteAddress = remoteAddress;
this.localAddress = localAddress;
this.messageReaders = messageReaders;
this.exchange = exchange;
}
@ -163,6 +167,11 @@ public final class MockServerRequest implements ServerRequest {
return Optional.ofNullable(this.remoteAddress);
}
@Override
public Optional<InetSocketAddress> localAddress() {
return Optional.ofNullable(this.localAddress);
}
@Override
public List<HttpMessageReader<?>> messageReaders() {
return this.messageReaders;
@ -303,6 +312,8 @@ public final class MockServerRequest implements ServerRequest {
Builder remoteAddress(InetSocketAddress remoteAddress);
Builder localAddress(InetSocketAddress localAddress);
Builder messageReaders(List<HttpMessageReader<?>> messageReaders);
Builder exchange(ServerWebExchange exchange);
@ -343,6 +354,9 @@ public final class MockServerRequest implements ServerRequest {
@Nullable
private InetSocketAddress remoteAddress;
@Nullable
private InetSocketAddress localAddress;
private List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
@Nullable
@ -470,6 +484,13 @@ public final class MockServerRequest implements ServerRequest {
return this;
}
@Override
public Builder localAddress(InetSocketAddress localAddress) {
Assert.notNull(localAddress, "'localAddress' must not be null");
this.localAddress = localAddress;
return this;
}
@Override
public Builder messageReaders(List<HttpMessageReader<?>> messageReaders) {
Assert.notNull(messageReaders, "'messageReaders' must not be null");
@ -489,16 +510,16 @@ public final class MockServerRequest implements ServerRequest {
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.remoteAddress, this.messageReaders,
this.exchange);
this.session, this.principal, this.remoteAddress, this.localAddress,
this.messageReaders, this.exchange);
}
@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.remoteAddress, this.messageReaders,
this.exchange);
this.session, this.principal, this.remoteAddress, this.localAddress,
this.messageReaders, this.exchange);
}
}

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -181,9 +181,6 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
private final MultiValueMap<String, HttpCookie> cookies;
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final SslInfo sslInfo;
@ -199,7 +196,6 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
super(uri, contextPath, headers);
this.methodValue = methodValue;
this.cookies = cookies;
this.remoteAddress = originalRequest.getRemoteAddress();
this.sslInfo = sslInfo != null ? sslInfo : originalRequest.getSslInfo();
this.body = body;
this.originalRequest = originalRequest;
@ -218,7 +214,13 @@ class DefaultServerHttpRequestBuilder implements ServerHttpRequest.Builder {
@Nullable
@Override
public InetSocketAddress getRemoteAddress() {
return this.remoteAddress;
return this.originalRequest.getRemoteAddress();
}
@Nullable
@Override
public InetSocketAddress getLocalAddress() {
return this.originalRequest.getLocalAddress();
}
@Nullable

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -151,6 +151,11 @@ class ReactorServerHttpRequest extends AbstractServerHttpRequest {
return this.request.remoteAddress();
}
@Override
public InetSocketAddress getLocalAddress() {
return this.request.hostAddress();
}
@Override
@Nullable
protected SslInfo initSslInfo() {

View File

@ -72,6 +72,15 @@ public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage
return null;
}
/**
* Return the local address the request was accepted on, if available.
* 5.2.3
*/
@Nullable
default InetSocketAddress getLocalAddress() {
return null;
}
/**
* Return the SSL session information if the request has been transmitted
* over a secure protocol including SSL certificates, if available.

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -101,6 +101,11 @@ public class ServerHttpRequestDecorator implements ServerHttpRequest {
return getDelegate().getRemoteAddress();
}
@Override
public InetSocketAddress getLocalAddress() {
return getDelegate().getLocalAddress();
}
@Nullable
@Override
public SslInfo getSslInfo() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -178,6 +178,11 @@ class ServletServerHttpRequest extends AbstractServerHttpRequest {
return new InetSocketAddress(this.request.getRemoteHost(), this.request.getRemotePort());
}
@Override
public InetSocketAddress getLocalAddress() {
return new InetSocketAddress(this.request.getLocalAddr(), this.request.getLocalPort());
}
@Override
@Nullable
protected SslInfo initSslInfo() {

View File

@ -102,6 +102,11 @@ class UndertowServerHttpRequest extends AbstractServerHttpRequest {
return this.exchange.getSourceAddress();
}
@Override
public InetSocketAddress getLocalAddress() {
return this.exchange.getDestinationAddress();
}
@Nullable
@Override
protected SslInfo initSslInfo() {

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2018 the original author or authors.
* Copyright 2002-2019 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.
@ -52,7 +52,7 @@ import org.springframework.web.util.UriComponentsBuilder;
* @author Rossen Stoyanchev
* @since 5.0
*/
public class MockServerHttpRequest extends AbstractServerHttpRequest {
public final class MockServerHttpRequest extends AbstractServerHttpRequest {
private final HttpMethod httpMethod;
@ -61,6 +61,9 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final InetSocketAddress localAddress;
@Nullable
private final SslInfo sslInfo;
@ -69,13 +72,14 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
private MockServerHttpRequest(HttpMethod httpMethod, URI uri, @Nullable String contextPath,
HttpHeaders headers, MultiValueMap<String, HttpCookie> cookies,
@Nullable InetSocketAddress remoteAddress, @Nullable SslInfo sslInfo,
Publisher<? extends DataBuffer> body) {
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress,
@Nullable SslInfo sslInfo, Publisher<? extends DataBuffer> body) {
super(uri, contextPath, headers);
this.httpMethod = httpMethod;
this.cookies = cookies;
this.remoteAddress = remoteAddress;
this.localAddress = localAddress;
this.sslInfo = sslInfo;
this.body = Flux.from(body);
}
@ -97,6 +101,12 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
return this.remoteAddress;
}
@Nullable
@Override
public InetSocketAddress getLocalAddress() {
return this.localAddress;
}
@Nullable
@Override
protected SslInfo initSslInfo() {
@ -254,6 +264,12 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
*/
B remoteAddress(InetSocketAddress remoteAddress);
/**
* Set the local address to return.
* @since 5.2.3
*/
B localAddress(InetSocketAddress localAddress);
/**
* Set SSL session information and certificates.
*/
@ -408,6 +424,9 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
@Nullable
private InetSocketAddress remoteAddress;
@Nullable
private InetSocketAddress localAddress;
@Nullable
private SslInfo sslInfo;
@ -441,6 +460,12 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
return this;
}
@Override
public BodyBuilder localAddress(InetSocketAddress localAddress) {
this.localAddress = localAddress;
return this;
}
@Override
public void sslInfo(SslInfo sslInfo) {
this.sslInfo = sslInfo;
@ -545,7 +570,7 @@ public class MockServerHttpRequest extends AbstractServerHttpRequest {
public MockServerHttpRequest body(Publisher<? extends DataBuffer> body) {
applyCookiesIfNecessary();
return new MockServerHttpRequest(this.method, getUrlToUse(), this.contextPath,
this.headers, this.cookies, this.remoteAddress, this.sslInfo, body);
this.headers, this.cookies, this.remoteAddress, this.localAddress, this.sslInfo, body);
}
private void applyCookiesIfNecessary() {

View File

@ -122,6 +122,11 @@ class DefaultServerRequest implements ServerRequest {
return Optional.ofNullable(request().getRemoteAddress());
}
@Override
public Optional<InetSocketAddress> localAddress() {
return Optional.ofNullable(request().getLocalAddress());
}
@Override
public List<HttpMessageReader<?>> messageReaders() {
return this.messageReaders;

View File

@ -947,6 +947,11 @@ public abstract class RequestPredicates {
return this.request.remoteAddress();
}
@Override
public Optional<InetSocketAddress> localAddress() {
return this.request.localAddress();
}
@Override
public List<HttpMessageReader<?>> messageReaders() {
return this.request.messageReaders();

View File

@ -124,6 +124,12 @@ public interface ServerRequest {
*/
Optional<InetSocketAddress> remoteAddress();
/**
* Get the remote address to which this request is connected, if available.
* @since 5.2.3
*/
Optional<InetSocketAddress> localAddress();
/**
* Get the readers used to convert the body of this request.
* @since 5.1

View File

@ -123,6 +123,11 @@ public class ServerRequestWrapper implements ServerRequest {
return this.delegate.remoteAddress();
}
@Override
public Optional<InetSocketAddress> localAddress() {
return this.delegate.localAddress();
}
@Override
public List<HttpMessageReader<?>> messageReaders() {
return this.delegate.messageReaders();

View File

@ -61,7 +61,7 @@ import org.springframework.web.util.UriComponentsBuilder;
* @author Arjen Poutsma
* @since 5.0
*/
public class MockServerRequest implements ServerRequest {
public final class MockServerRequest implements ServerRequest {
private final HttpMethod method;
@ -91,6 +91,9 @@ public class MockServerRequest implements ServerRequest {
@Nullable
private final InetSocketAddress remoteAddress;
@Nullable
private final InetSocketAddress localAddress;
private final List<HttpMessageReader<?>> messageReaders;
@Nullable
@ -101,8 +104,8 @@ public class MockServerRequest implements ServerRequest {
MultiValueMap<String, HttpCookie> cookies, @Nullable Object body,
Map<String, Object> attributes, MultiValueMap<String, String> queryParams,
Map<String, String> pathVariables, @Nullable WebSession session, @Nullable Principal principal,
@Nullable InetSocketAddress remoteAddress, List<HttpMessageReader<?>> messageReaders,
@Nullable ServerWebExchange exchange) {
@Nullable InetSocketAddress remoteAddress, @Nullable InetSocketAddress localAddress,
List<HttpMessageReader<?>> messageReaders, @Nullable ServerWebExchange exchange) {
this.method = method;
this.uri = uri;
@ -116,6 +119,7 @@ public class MockServerRequest implements ServerRequest {
this.session = session;
this.principal = principal;
this.remoteAddress = remoteAddress;
this.localAddress = localAddress;
this.messageReaders = messageReaders;
this.exchange = exchange;
}
@ -161,6 +165,11 @@ public class MockServerRequest implements ServerRequest {
return Optional.ofNullable(this.remoteAddress);
}
@Override
public Optional<InetSocketAddress> localAddress() {
return Optional.ofNullable(this.localAddress);
}
@Override
public List<HttpMessageReader<?>> messageReaders() {
return this.messageReaders;
@ -291,6 +300,7 @@ public class MockServerRequest implements ServerRequest {
Builder session(WebSession session);
/**
* Sets the request {@link Principal}.
* @deprecated in favor of {@link #principal(Principal)}
*/
@Deprecated
@ -300,6 +310,8 @@ public class MockServerRequest implements ServerRequest {
Builder remoteAddress(InetSocketAddress remoteAddress);
Builder localAddress(InetSocketAddress localAddress);
Builder messageReaders(List<HttpMessageReader<?>> messageReaders);
Builder exchange(ServerWebExchange exchange);
@ -340,6 +352,9 @@ public class MockServerRequest implements ServerRequest {
@Nullable
private InetSocketAddress remoteAddress;
@Nullable
private InetSocketAddress localAddress;
private List<HttpMessageReader<?>> messageReaders = HandlerStrategies.withDefaults().messageReaders();
@Nullable
@ -467,6 +482,13 @@ public class MockServerRequest implements ServerRequest {
return this;
}
@Override
public Builder localAddress(InetSocketAddress localAddress) {
Assert.notNull(localAddress, "'localAddress' must not be null");
this.localAddress = localAddress;
return this;
}
@Override
public Builder messageReaders(List<HttpMessageReader<?>> messageReaders) {
Assert.notNull(messageReaders, "'messageReaders' must not be null");
@ -486,16 +508,16 @@ public class MockServerRequest implements ServerRequest {
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.remoteAddress, this.messageReaders,
this.exchange);
this.session, this.principal, this.remoteAddress, this.localAddress,
this.messageReaders, this.exchange);
}
@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.remoteAddress, this.messageReaders,
this.exchange);
this.session, this.principal, this.remoteAddress, this.localAddress,
this.messageReaders, this.exchange);
}
}