Expose remoteAddress from ServerHttpRequest

Issue: SPR-15200
This commit is contained in:
Rossen Stoyanchev
2017-01-31 15:04:24 -05:00
parent 9142427c4d
commit 1fb0b0b786
10 changed files with 116 additions and 20 deletions

View File

@@ -19,6 +19,7 @@ package org.springframework.http.server.reactive;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;
import io.netty.handler.codec.http.cookie.Cookie;
import reactor.core.publisher.Flux;
@@ -57,7 +58,8 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
private static URI initUri(HttpServerRequest channel) {
Assert.notNull(channel, "'channel' must not be null");
InetSocketAddress address = channel.remoteAddress();
return (address == null ? URI.create(channel.uri()) : getBaseUrl(address).resolve(channel.uri()));
String requestUri = channel.uri();
return (address != null ? getBaseUrl(address).resolve(requestUri) : URI.create(requestUri));
}
private static URI getBaseUrl(InetSocketAddress address) {
@@ -100,6 +102,11 @@ public class ReactorServerHttpRequest extends AbstractServerHttpRequest {
return cookies;
}
@Override
public Optional<InetSocketAddress> getRemoteAddress() {
return Optional.ofNullable(this.request.remoteAddress());
}
@Override
public Flux<DataBuffer> getBody() {
return this.request.receive().retain().map(this.bufferFactory::wrap);

View File

@@ -16,10 +16,13 @@
package org.springframework.http.server.reactive;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
import java.util.Map;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.reactivex.netty.protocol.http.server.HttpServerRequest;
import io.reactivex.netty.protocol.http.server.HttpServerResponse;
@@ -54,10 +57,11 @@ public class RxNettyHttpHandlerAdapter extends HttpHandlerAdapterSupport
public Observable<Void> handle(HttpServerRequest<ByteBuf> nativeRequest,
HttpServerResponse<ByteBuf> nativeResponse) {
ByteBufAllocator allocator = nativeResponse.unsafeNettyChannel().alloc();
NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(allocator);
Channel channel = nativeResponse.unsafeNettyChannel();
NettyDataBufferFactory bufferFactory = new NettyDataBufferFactory(channel.alloc());
InetSocketAddress remoteAddress = (InetSocketAddress) channel.remoteAddress();
RxNettyServerHttpRequest request = new RxNettyServerHttpRequest(nativeRequest, bufferFactory);
RxNettyServerHttpRequest request = new RxNettyServerHttpRequest(nativeRequest, bufferFactory, remoteAddress);
RxNettyServerHttpResponse response = new RxNettyServerHttpResponse(nativeResponse, bufferFactory);
Publisher<Void> result = getHttpHandler().handle(request, response)

View File

@@ -19,6 +19,7 @@ package org.springframework.http.server.reactive;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.Optional;
import io.netty.buffer.ByteBuf;
import io.netty.handler.codec.http.cookie.Cookie;
@@ -35,7 +36,6 @@ import org.springframework.http.HttpMethod;
import org.springframework.util.Assert;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.util.StringUtils;
/**
* Adapt {@link ServerHttpRequest} to the RxNetty {@link HttpServerRequest}.
@@ -50,27 +50,27 @@ public class RxNettyServerHttpRequest extends AbstractServerHttpRequest {
private final NettyDataBufferFactory dataBufferFactory;
private final InetSocketAddress remoteAddress;
public RxNettyServerHttpRequest(HttpServerRequest<ByteBuf> request,
NettyDataBufferFactory dataBufferFactory) {
NettyDataBufferFactory dataBufferFactory, InetSocketAddress remoteAddress) {
super(initUri(request), initHeaders(request));
super(initUri(request, remoteAddress), initHeaders(request));
Assert.notNull(dataBufferFactory, "'dataBufferFactory' must not be null");
this.request = request;
this.dataBufferFactory = dataBufferFactory;
this.remoteAddress = remoteAddress;
}
private static URI initUri(HttpServerRequest<ByteBuf> request) {
private static URI initUri(HttpServerRequest<ByteBuf> request, InetSocketAddress remoteAddress) {
Assert.notNull(request, "'request' must not be null");
return StringUtils.isEmpty(request.getHostHeader()) ?
URI.create(request.getUri()) : getBaseUrl(request).resolve(request.getUri());
String requestUri = request.getUri();
return remoteAddress != null ? getBaseUrl(remoteAddress).resolve(requestUri) : URI.create(requestUri);
}
private static URI getBaseUrl(HttpServerRequest<ByteBuf> request) {
HttpHeaders headers = new HttpHeaders();
headers.add("Host", request.getHostHeader());
InetSocketAddress address = headers.getHost();
private static URI getBaseUrl(InetSocketAddress address) {
try {
return new URI(null, null, address.getHostString(), address.getPort(), null, null, null);
}
@@ -110,6 +110,11 @@ public class RxNettyServerHttpRequest extends AbstractServerHttpRequest {
return cookies;
}
@Override
public Optional<InetSocketAddress> getRemoteAddress() {
return Optional.ofNullable(this.remoteAddress);
}
@Override
public Flux<DataBuffer> getBody() {
Observable<DataBuffer> content = this.request.getContent().map(dataBufferFactory::wrap);

View File

@@ -16,6 +16,9 @@
package org.springframework.http.server.reactive;
import java.net.InetSocketAddress;
import java.util.Optional;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpMethod;
import org.springframework.http.HttpRequest;
@@ -53,6 +56,12 @@ public interface ServerHttpRequest extends HttpRequest, ReactiveHttpInputMessage
*/
MultiValueMap<String, HttpCookie> getCookies();
/**
* Returns the remote address where this request is connected to.
* @return remote address if available
*/
Optional<InetSocketAddress> getRemoteAddress();
/**
* Return a builder to mutate properties of this request by wrapping it

View File

@@ -15,7 +15,9 @@
*/
package org.springframework.http.server.reactive;
import java.net.InetSocketAddress;
import java.net.URI;
import java.util.Optional;
import reactor.core.publisher.Flux;
@@ -76,6 +78,11 @@ public class ServerHttpRequestDecorator implements ServerHttpRequest {
return getDelegate().getCookies();
}
@Override
public Optional<InetSocketAddress> getRemoteAddress() {
return getDelegate().getRemoteAddress();
}
@Override
public Flux<DataBuffer> getBody() {
return getDelegate().getBody();

View File

@@ -17,11 +17,13 @@
package org.springframework.http.server.reactive;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.charset.Charset;
import java.util.Enumeration;
import java.util.Map;
import java.util.Optional;
import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
@@ -175,6 +177,12 @@ public class ServletServerHttpRequest extends AbstractServerHttpRequest {
return httpCookies;
}
@Override
public Optional<InetSocketAddress> getRemoteAddress() {
return Optional.of(new InetSocketAddress(
this.request.getRemoteHost(), this.request.getRemotePort()));
}
@Override
public Flux<DataBuffer> getBody() {
return Flux.from(this.bodyPublisher);

View File

@@ -17,9 +17,11 @@
package org.springframework.http.server.reactive;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.Optional;
import io.undertow.connector.ByteBufferPool;
import io.undertow.connector.PooledByteBuffer;
@@ -111,6 +113,11 @@ public class UndertowServerHttpRequest extends AbstractServerHttpRequest {
return cookies;
}
@Override
public Optional<InetSocketAddress> getRemoteAddress() {
return Optional.ofNullable(this.exchange.getSourceAddress());
}
@Override
public Flux<DataBuffer> getBody() {
return Flux.from(this.body);