renaming getPublishURL() to getContextURL(), enabling multi domain context path resolving of requests
This commit is contained in:
parent
e329bfff46
commit
4fc61db40d
11 changed files with 242 additions and 75 deletions
|
@ -1,6 +1,6 @@
|
||||||
group = org.xbib
|
group = org.xbib
|
||||||
name = netty-http
|
name = netty-http
|
||||||
version = 4.1.51.0
|
version = 4.1.51.1
|
||||||
|
|
||||||
gradle.wrapper.version = 6.4.1
|
gradle.wrapper.version = 6.4.1
|
||||||
netty.version = 4.1.51.Final
|
netty.version = 4.1.51.Final
|
||||||
|
|
|
@ -35,6 +35,7 @@ import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.LinkedHashSet;
|
import java.util.LinkedHashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
@ -48,6 +49,8 @@ public class Domain {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(Domain.class.getName());
|
private static final Logger logger = Logger.getLogger(Domain.class.getName());
|
||||||
|
|
||||||
|
private static final String EMPTY = "";
|
||||||
|
|
||||||
private final String name;
|
private final String name;
|
||||||
|
|
||||||
private final Set<String> aliases;
|
private final Set<String> aliases;
|
||||||
|
@ -75,16 +78,12 @@ public class Domain {
|
||||||
List<HttpEndpointResolver> httpEndpointResolvers,
|
List<HttpEndpointResolver> httpEndpointResolvers,
|
||||||
SslContext sslContext,
|
SslContext sslContext,
|
||||||
Collection<? extends X509Certificate> certificates) {
|
Collection<? extends X509Certificate> certificates) {
|
||||||
this.httpAddress = httpAddress;
|
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.aliases = aliases;
|
this.aliases = aliases;
|
||||||
|
this.httpAddress = httpAddress;
|
||||||
this.httpEndpointResolvers = httpEndpointResolvers;
|
this.httpEndpointResolvers = httpEndpointResolvers;
|
||||||
this.sslContext = sslContext;
|
this.sslContext = sslContext;
|
||||||
this.certificates = certificates;
|
this.certificates = certificates;
|
||||||
Objects.requireNonNull(httpEndpointResolvers);
|
|
||||||
if (httpEndpointResolvers.isEmpty()) {
|
|
||||||
throw new IllegalArgumentException("domain must have at least one endpoint resolver");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Builder builder(HttpAddress httpAddress) {
|
public static Builder builder(HttpAddress httpAddress) {
|
||||||
|
@ -143,26 +142,54 @@ public class Domain {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle server requests.
|
* Evaluate the context path of a given request.
|
||||||
|
* The request is not dispatched.
|
||||||
|
* URI request parameters are evaluated.
|
||||||
|
* @param serverRequest the server request
|
||||||
|
* @return the context path
|
||||||
|
* @throws IOException if handling fails
|
||||||
|
*/
|
||||||
|
public String findContextOf(ServerRequest serverRequest) throws IOException {
|
||||||
|
if (serverRequest == null) {
|
||||||
|
return EMPTY;
|
||||||
|
}
|
||||||
|
Map.Entry<HttpEndpointResolver, List<HttpEndpoint>> resolved = resolve(serverRequest);
|
||||||
|
if (resolved != null) {
|
||||||
|
resolved.getKey().handle(resolved.getValue(), serverRequest, null, false);
|
||||||
|
return serverRequest.getContextPath();
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle server requests by resolving and handling a server request.
|
||||||
* @param serverRequest the server request
|
* @param serverRequest the server request
|
||||||
* @param serverResponse the server response
|
* @param serverResponse the server response
|
||||||
* @throws IOException if handling server request fails
|
* @throws IOException if handling server request fails
|
||||||
*/
|
*/
|
||||||
public void handle(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
public void handle(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
||||||
boolean found = false;
|
Map.Entry<HttpEndpointResolver, List<HttpEndpoint>> resolved = resolve(serverRequest);
|
||||||
|
if (resolved != null) {
|
||||||
|
resolved.getKey().handle(resolved.getValue(), serverRequest, serverResponse, true);
|
||||||
|
} else {
|
||||||
|
ServerResponse.write(serverResponse, HttpResponseStatus.NOT_IMPLEMENTED,
|
||||||
|
"text/plain", "No endpoint match for request " + serverRequest);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Just resolve a server request to a matching endpoint resolver with endpoints matched.
|
||||||
|
* @param serverRequest the server request
|
||||||
|
* @return the endpoint resolver together with the matching endpoints
|
||||||
|
*/
|
||||||
|
public Map.Entry<HttpEndpointResolver, List<HttpEndpoint>> resolve(ServerRequest serverRequest) {
|
||||||
for (HttpEndpointResolver httpEndpointResolver : httpEndpointResolvers) {
|
for (HttpEndpointResolver httpEndpointResolver : httpEndpointResolvers) {
|
||||||
List<HttpEndpoint> matchingEndpoints = httpEndpointResolver.matchingEndpointsFor(serverRequest);
|
List<HttpEndpoint> matchingEndpoints = httpEndpointResolver.matchingEndpointsFor(serverRequest);
|
||||||
if (matchingEndpoints != null && !matchingEndpoints.isEmpty()) {
|
if (!matchingEndpoints.isEmpty()) {
|
||||||
httpEndpointResolver.handle(matchingEndpoints, serverRequest, serverResponse);
|
return Map.entry(httpEndpointResolver, matchingEndpoints);
|
||||||
found = true;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!found) {
|
return null;
|
||||||
ServerResponse.write(serverResponse, HttpResponseStatus.NOT_IMPLEMENTED,
|
|
||||||
"text/plain", "No endpoint match for request " + serverRequest +
|
|
||||||
" endpoints = " + httpEndpointResolvers);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -373,6 +400,9 @@ public class Domain {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Domain build() {
|
public Domain build() {
|
||||||
|
if (httpEndpointResolvers.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("domain must have at least one endpoint resolver");
|
||||||
|
}
|
||||||
if (httpAddress.isSecure() ) {
|
if (httpAddress.isSecure() ) {
|
||||||
try {
|
try {
|
||||||
if (sslContext == null && privateKey != null && keyCertChain != null) {
|
if (sslContext == null && privateKey != null && keyCertChain != null) {
|
||||||
|
|
|
@ -194,27 +194,44 @@ public final class Server implements AutoCloseable {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the domain with the given host name.
|
* Returns the domain for the given server request.
|
||||||
*
|
*
|
||||||
* @param dnsName the name of the virtual host with optional port to return or null for the
|
* @param serverRequest the server request
|
||||||
|
* @return the domain
|
||||||
|
*/
|
||||||
|
public Domain getDomain(ServerRequest serverRequest) {
|
||||||
|
return getDomain(getBaseURL(serverRequest));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the domain of the given URL.
|
||||||
|
* @param url the URL
|
||||||
|
* @return the domain
|
||||||
|
*/
|
||||||
|
public Domain getDomain(URL url) {
|
||||||
|
return getDomain(hostAndPort(url));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the domain for the given host name.
|
||||||
|
*
|
||||||
|
* @param name the name of the virtual host with optional port, or null for the
|
||||||
* default domain
|
* default domain
|
||||||
* @return the virtual host with the given name or the default domain
|
* @return the virtual host with the given name or the default domain
|
||||||
*/
|
*/
|
||||||
public Domain getDomain(String dnsName) {
|
public Domain getDomain(String name) {
|
||||||
return serverConfig.getDomain(dnsName);
|
return serverConfig.getDomain(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Domain getDomain(URL url) {
|
/**
|
||||||
return getDomain(url.getHost());
|
* Return the base URL regarding to a server request.
|
||||||
}
|
* The base URL depends on the host and port defined in a reqeust,
|
||||||
|
* if no request is defined, the bind URL is taken.
|
||||||
public URL getPublishURL() {
|
* @param serverRequest the server request
|
||||||
return getPublishURL(null);
|
* @return the URL
|
||||||
}
|
*/
|
||||||
|
public URL getBaseURL(ServerRequest serverRequest) {
|
||||||
public URL getPublishURL(ServerRequest serverRequest) {
|
URL bindURL = serverConfig.getDefaultDomain().getHttpAddress().base();
|
||||||
Domain domain = serverRequest != null ? getDomain(serverRequest.getURL()) : serverConfig.getDefaultDomain();
|
|
||||||
URL bindURL = domain.getHttpAddress().base();
|
|
||||||
String scheme = serverRequest != null ? serverRequest.getHeaders().get("x-forwarded-proto") : null;
|
String scheme = serverRequest != null ? serverRequest.getHeaders().get("x-forwarded-proto") : null;
|
||||||
if (scheme == null) {
|
if (scheme == null) {
|
||||||
scheme = bindURL.getScheme();
|
scheme = bindURL.getScheme();
|
||||||
|
@ -234,24 +251,40 @@ public final class Server implements AutoCloseable {
|
||||||
port = bindURL.getPort() != null ? Integer.toString(bindURL.getPort()) : null;
|
port = bindURL.getPort() != null ? Integer.toString(bindURL.getPort()) : null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
String path = serverRequest != null ? serverRequest.getHeaders().get("x-forwarded-path") : null;
|
|
||||||
URL.Builder builder = URL.builder().scheme(scheme).host(host);
|
URL.Builder builder = URL.builder().scheme(scheme).host(host);
|
||||||
if (port != null) {
|
if (port != null) {
|
||||||
if (path != null) {
|
builder.port(Integer.parseInt(port));
|
||||||
return builder.port(Integer.parseInt(port)).path(path).build();
|
|
||||||
} else {
|
|
||||||
return builder.port(Integer.parseInt(port)).build();
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if (path != null) {
|
|
||||||
return builder.path(path).build();
|
|
||||||
} else {
|
|
||||||
return builder.build();
|
return builder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the context URL of this server. This is equivalent to the bindURL
|
||||||
|
* @return the context URL
|
||||||
|
* @throws IOException should not happen
|
||||||
|
*/
|
||||||
|
public URL getContextURL() throws IOException {
|
||||||
|
return getContextURL(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get context URL of this server regarding to a given request.
|
||||||
|
* The context URL is the base URL with the path given in the matching
|
||||||
|
* domain prefix setting of the endpoint resolver.
|
||||||
|
* @param serverRequest the server request
|
||||||
|
* @return the context URL
|
||||||
|
* @throws IOException if context path finding fails
|
||||||
|
*/
|
||||||
|
public URL getContextURL(ServerRequest serverRequest) throws IOException {
|
||||||
|
URL baseURL = getBaseURL(serverRequest);
|
||||||
|
Domain domain = getDomain(baseURL);
|
||||||
|
String context = domain.findContextOf(serverRequest);
|
||||||
|
return baseURL.resolve(context);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(HttpServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
public void handle(HttpServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
||||||
Domain domain = getDomain(serverRequest.getURL());
|
Domain domain = getDomain(serverRequest);
|
||||||
|
logger.log(Level.FINEST, () -> "found domain " + domain + " for " + serverRequest);
|
||||||
if (executor != null) {
|
if (executor != null) {
|
||||||
executor.submit(() -> {
|
executor.submit(() -> {
|
||||||
try {
|
try {
|
||||||
|
@ -339,6 +372,10 @@ public final class Server implements AutoCloseable {
|
||||||
return i >= 0 ? hostMaybePort.substring(i + 1) : null;
|
return i >= 0 ? hostMaybePort.substring(i + 1) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static String hostAndPort(URL url) {
|
||||||
|
return url == null ? null : url.getPort() != -1 ? url.getHost() + ":" + url.getPort() : url.getHost();
|
||||||
|
}
|
||||||
|
|
||||||
private HttpChannelInitializer findChannelInitializer(int majorVersion,
|
private HttpChannelInitializer findChannelInitializer(int majorVersion,
|
||||||
HttpAddress httpAddress,
|
HttpAddress httpAddress,
|
||||||
Mapping<String, SslContext> domainNameMapping) {
|
Mapping<String, SslContext> domainNameMapping) {
|
||||||
|
|
|
@ -96,18 +96,22 @@ public class HttpEndpoint implements Endpoint<HttpEndpointDescriptor> {
|
||||||
@Override
|
@Override
|
||||||
public void before(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
public void before(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
||||||
serverRequest.setContext(pathMatcher.tokenizePath(getPrefix()));
|
serverRequest.setContext(pathMatcher.tokenizePath(getPrefix()));
|
||||||
|
if (serverResponse != null) {
|
||||||
for (Filter filter : beforeFilters) {
|
for (Filter filter : beforeFilters) {
|
||||||
filter.handle(serverRequest, serverResponse);
|
filter.handle(serverRequest, serverResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void after(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
public void after(ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
||||||
serverRequest.setContext(pathMatcher.tokenizePath(getPrefix()));
|
serverRequest.setContext(pathMatcher.tokenizePath(getPrefix()));
|
||||||
|
if (serverResponse != null) {
|
||||||
for (Filter filter : afterFilters) {
|
for (Filter filter : afterFilters) {
|
||||||
filter.handle(serverRequest, serverResponse);
|
filter.handle(serverRequest, serverResponse);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
|
|
|
@ -50,35 +50,37 @@ public class HttpEndpointResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(List<HttpEndpoint> matchingEndpoints,
|
public void handle(List<HttpEndpoint> matchingEndpoints,
|
||||||
ServerRequest serverRequest, ServerResponse serverResponse) throws IOException {
|
ServerRequest serverRequest,
|
||||||
|
ServerResponse serverResponse,
|
||||||
|
boolean dispatch) throws IOException {
|
||||||
Objects.requireNonNull(matchingEndpoints);
|
Objects.requireNonNull(matchingEndpoints);
|
||||||
for (HttpEndpoint endpoint : matchingEndpoints) {
|
for (HttpEndpoint endpoint : matchingEndpoints) {
|
||||||
endpoint.resolveUriTemplate(serverRequest);
|
endpoint.resolveUriTemplate(serverRequest);
|
||||||
endpoint.before(serverRequest, serverResponse);
|
endpoint.before(serverRequest, serverResponse);
|
||||||
|
if (dispatch) {
|
||||||
endpointDispatcher.dispatch(endpoint, serverRequest, serverResponse);
|
endpointDispatcher.dispatch(endpoint, serverRequest, serverResponse);
|
||||||
endpoint.after(serverRequest, serverResponse);
|
endpoint.after(serverRequest, serverResponse);
|
||||||
if (serverResponse.getStatus() != null) {
|
if (serverResponse != null && serverResponse.getStatus() != null) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<HttpEndpointDescriptor, List<HttpEndpoint>> getEndpointDescriptors() {
|
|
||||||
return endpointDescriptors;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Builder builder() {
|
public static Builder builder() {
|
||||||
return new Builder();
|
return new Builder();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class Builder {
|
public static class Builder {
|
||||||
|
|
||||||
|
private final List<HttpEndpoint> endpoints;
|
||||||
|
|
||||||
private int limit;
|
private int limit;
|
||||||
|
|
||||||
private String prefix;
|
private String prefix;
|
||||||
|
|
||||||
private final List<HttpEndpoint> endpoints;
|
|
||||||
|
|
||||||
private EndpointDispatcher<HttpEndpoint> endpointDispatcher;
|
private EndpointDispatcher<HttpEndpoint> endpointDispatcher;
|
||||||
|
|
||||||
Builder() {
|
Builder() {
|
||||||
|
@ -149,6 +151,9 @@ public class HttpEndpointResolver {
|
||||||
}
|
}
|
||||||
|
|
||||||
public HttpEndpointResolver build() {
|
public HttpEndpointResolver build() {
|
||||||
|
if (endpoints.isEmpty()) {
|
||||||
|
throw new IllegalArgumentException("no endpoints configured");
|
||||||
|
}
|
||||||
return new HttpEndpointResolver(endpoints, endpointDispatcher, limit);
|
return new HttpEndpointResolver(endpoints, endpointDispatcher, limit);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import io.netty.handler.ssl.SslHandler;
|
||||||
import org.xbib.netty.http.server.Server;
|
import org.xbib.netty.http.server.Server;
|
||||||
import org.xbib.netty.http.server.api.ServerResponse;
|
import org.xbib.netty.http.server.api.ServerResponse;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
public class Http1Transport extends BaseTransport {
|
public class Http1Transport extends BaseTransport {
|
||||||
|
|
||||||
|
@ -17,7 +18,9 @@ public class Http1Transport extends BaseTransport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestReceived(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, Integer sequenceId) throws IOException {
|
public void requestReceived(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, Integer sequenceId) throws IOException {
|
||||||
HttpServerRequest serverRequest = new HttpServerRequest(server, fullHttpRequest, ctx);
|
HttpServerRequest serverRequest = new HttpServerRequest(fullHttpRequest,
|
||||||
|
(InetSocketAddress) ctx.channel().localAddress(),
|
||||||
|
(InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
serverRequest.setSequenceId(sequenceId);
|
serverRequest.setSequenceId(sequenceId);
|
||||||
serverRequest.setRequestId(server.getRequestCounter().incrementAndGet());
|
serverRequest.setRequestId(server.getRequestCounter().incrementAndGet());
|
||||||
SslHandler sslHandler = ctx.channel().pipeline().get(SslHandler.class);
|
SslHandler sslHandler = ctx.channel().pipeline().get(SslHandler.class);
|
||||||
|
|
|
@ -9,6 +9,7 @@ import org.xbib.netty.http.server.Server;
|
||||||
import org.xbib.netty.http.server.api.ServerResponse;
|
import org.xbib.netty.http.server.api.ServerResponse;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
@ -22,7 +23,9 @@ public class Http2Transport extends BaseTransport {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void requestReceived(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, Integer sequenceId) throws IOException {
|
public void requestReceived(ChannelHandlerContext ctx, FullHttpRequest fullHttpRequest, Integer sequenceId) throws IOException {
|
||||||
HttpServerRequest serverRequest = new HttpServerRequest(server, fullHttpRequest, ctx);
|
HttpServerRequest serverRequest = new HttpServerRequest(fullHttpRequest,
|
||||||
|
(InetSocketAddress) ctx.channel().localAddress(),
|
||||||
|
(InetSocketAddress) ctx.channel().remoteAddress());
|
||||||
serverRequest.setSequenceId(sequenceId);
|
serverRequest.setSequenceId(sequenceId);
|
||||||
serverRequest.setRequestId(server.getRequestCounter().incrementAndGet());
|
serverRequest.setRequestId(server.getRequestCounter().incrementAndGet());
|
||||||
serverRequest.setStreamId(fullHttpRequest.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()));
|
serverRequest.setStreamId(fullHttpRequest.headers().getInt(HttpConversionUtil.ExtensionHeaderNames.STREAM_ID.text()));
|
||||||
|
|
|
@ -2,7 +2,6 @@ package org.xbib.netty.http.server.transport;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
import io.netty.buffer.ByteBufInputStream;
|
import io.netty.buffer.ByteBufInputStream;
|
||||||
import io.netty.channel.ChannelHandlerContext;
|
|
||||||
import io.netty.handler.codec.http.FullHttpRequest;
|
import io.netty.handler.codec.http.FullHttpRequest;
|
||||||
import io.netty.handler.codec.http.HttpHeaderValues;
|
import io.netty.handler.codec.http.HttpHeaderValues;
|
||||||
import io.netty.handler.codec.http.HttpHeaders;
|
import io.netty.handler.codec.http.HttpHeaders;
|
||||||
|
@ -13,7 +12,6 @@ import org.xbib.net.PercentDecoder;
|
||||||
import org.xbib.net.QueryParameters;
|
import org.xbib.net.QueryParameters;
|
||||||
import org.xbib.net.URL;
|
import org.xbib.net.URL;
|
||||||
import org.xbib.netty.http.common.HttpParameters;
|
import org.xbib.netty.http.common.HttpParameters;
|
||||||
import org.xbib.netty.http.server.Server;
|
|
||||||
import org.xbib.netty.http.server.api.ServerRequest;
|
import org.xbib.netty.http.server.api.ServerRequest;
|
||||||
|
|
||||||
import javax.net.ssl.SSLSession;
|
import javax.net.ssl.SSLSession;
|
||||||
|
@ -40,14 +38,16 @@ public class HttpServerRequest implements ServerRequest {
|
||||||
|
|
||||||
private final FullHttpRequest httpRequest;
|
private final FullHttpRequest httpRequest;
|
||||||
|
|
||||||
private final ChannelHandlerContext ctx;
|
private final InetSocketAddress localAddress;
|
||||||
|
|
||||||
|
private final InetSocketAddress remoteAddress;
|
||||||
|
|
||||||
|
private final Map<String, String> pathParameters;
|
||||||
|
|
||||||
private List<String> context;
|
private List<String> context;
|
||||||
|
|
||||||
private String contextPath;
|
private String contextPath;
|
||||||
|
|
||||||
private Map<String, String> pathParameters;
|
|
||||||
|
|
||||||
private HttpParameters parameters;
|
private HttpParameters parameters;
|
||||||
|
|
||||||
private URL url;
|
private URL url;
|
||||||
|
@ -60,10 +60,16 @@ public class HttpServerRequest implements ServerRequest {
|
||||||
|
|
||||||
private SSLSession sslSession;
|
private SSLSession sslSession;
|
||||||
|
|
||||||
HttpServerRequest(Server server, FullHttpRequest fullHttpRequest,
|
public HttpServerRequest(FullHttpRequest fullHttpRequest) {
|
||||||
ChannelHandlerContext ctx) {
|
this( fullHttpRequest ,null, null);
|
||||||
this.httpRequest = fullHttpRequest.retainedDuplicate();
|
}
|
||||||
this.ctx = ctx;
|
|
||||||
|
public HttpServerRequest(FullHttpRequest fullHttpRequest,
|
||||||
|
InetSocketAddress localAddress,
|
||||||
|
InetSocketAddress remoteAddress) {
|
||||||
|
this.httpRequest = fullHttpRequest != null ? fullHttpRequest.retainedDuplicate() : null;
|
||||||
|
this.localAddress = localAddress;
|
||||||
|
this.remoteAddress = remoteAddress;
|
||||||
this.pathParameters = new LinkedHashMap<>();
|
this.pathParameters = new LinkedHashMap<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -204,12 +210,12 @@ public class HttpServerRequest implements ServerRequest {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getLocalAddress() {
|
public InetSocketAddress getLocalAddress() {
|
||||||
return (InetSocketAddress) ctx.channel().localAddress();
|
return localAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public InetSocketAddress getRemoteAddress() {
|
public InetSocketAddress getRemoteAddress() {
|
||||||
return (InetSocketAddress) ctx.channel().remoteAddress();
|
return remoteAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -0,0 +1,75 @@
|
||||||
|
package org.xbib.netty.http.server.test;
|
||||||
|
|
||||||
|
import io.netty.handler.codec.http.DefaultFullHttpRequest;
|
||||||
|
import io.netty.handler.codec.http.HttpMethod;
|
||||||
|
import io.netty.handler.codec.http.HttpVersion;
|
||||||
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
|
import org.xbib.net.URL;
|
||||||
|
import org.xbib.netty.http.common.HttpAddress;
|
||||||
|
import org.xbib.netty.http.server.Domain;
|
||||||
|
import org.xbib.netty.http.server.Server;
|
||||||
|
import org.xbib.netty.http.server.api.ServerRequest;
|
||||||
|
import org.xbib.netty.http.server.endpoint.HttpEndpoint;
|
||||||
|
import org.xbib.netty.http.server.endpoint.HttpEndpointResolver;
|
||||||
|
import org.xbib.netty.http.server.transport.HttpServerRequest;
|
||||||
|
|
||||||
|
@ExtendWith(NettyHttpTestExtension.class)
|
||||||
|
public class ContextURLTest {
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void testServerPublishURL() throws Exception {
|
||||||
|
HttpAddress httpAddress = HttpAddress.http1("localhost", 8008);
|
||||||
|
|
||||||
|
HttpEndpointResolver endpointResolver1 = HttpEndpointResolver.builder()
|
||||||
|
.addEndpoint(HttpEndpoint.builder().setPrefix("/one").setPath("/**").build())
|
||||||
|
.setDispatcher((endpoint, serverRequest, serverResponse) -> {})
|
||||||
|
.build();
|
||||||
|
HttpEndpointResolver endpointResolver2 = HttpEndpointResolver.builder()
|
||||||
|
.addEndpoint(HttpEndpoint.builder().setPrefix("/two").setPath("/**").build())
|
||||||
|
.setDispatcher((endpoint, serverRequest, serverResponse) -> {})
|
||||||
|
.build();
|
||||||
|
HttpEndpointResolver endpointResolver3 = HttpEndpointResolver.builder()
|
||||||
|
.addEndpoint(HttpEndpoint.builder().setPrefix("/three").setPath("/**").build())
|
||||||
|
.setDispatcher((endpoint, serverRequest, serverResponse) -> {})
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Domain one = Domain.builder(httpAddress, "domain.one:8008")
|
||||||
|
.addEndpointResolver(endpointResolver1)
|
||||||
|
.build();
|
||||||
|
Domain two = Domain.builder(one)
|
||||||
|
.setServerName("domain.two:8008")
|
||||||
|
.addEndpointResolver(endpointResolver2)
|
||||||
|
.addEndpointResolver(endpointResolver3)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
Server server = Server.builder(one)
|
||||||
|
.addDomain(two)
|
||||||
|
.build();
|
||||||
|
|
||||||
|
URL url0 = server.getContextURL();
|
||||||
|
assertEquals("http://localhost:8008", url0.toString());
|
||||||
|
|
||||||
|
DefaultFullHttpRequest fullHttpRequest1 = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/one");
|
||||||
|
fullHttpRequest1.headers().add("host", "domain.one:8008");
|
||||||
|
ServerRequest serverRequest1 = new HttpServerRequest(fullHttpRequest1);
|
||||||
|
URL url1 = server.getContextURL(serverRequest1);
|
||||||
|
assertEquals("domain.one", url1.getHost());
|
||||||
|
assertEquals("/one", url1.getPath());
|
||||||
|
|
||||||
|
DefaultFullHttpRequest fullHttpRequest2 = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/two");
|
||||||
|
fullHttpRequest2.headers().add("host", "domain.two:8008");
|
||||||
|
ServerRequest serverRequest2 = new HttpServerRequest(fullHttpRequest2);
|
||||||
|
URL url2 = server.getContextURL(serverRequest2);
|
||||||
|
assertEquals("domain.two", url2.getHost());
|
||||||
|
assertEquals("/two", url2.getPath());
|
||||||
|
|
||||||
|
DefaultFullHttpRequest fullHttpRequest3 = new DefaultFullHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, "/three");
|
||||||
|
fullHttpRequest3.headers().add("host", "domain.two:8008");
|
||||||
|
ServerRequest serverRequest3 = new HttpServerRequest(fullHttpRequest3);
|
||||||
|
URL url3 = server.getContextURL(serverRequest3);
|
||||||
|
assertEquals("domain.two", url3.getHost());
|
||||||
|
assertEquals("/three", url3.getPath());
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package org.xbib.netty.http.server.test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.xbib.netty.http.client.Client;
|
import org.xbib.netty.http.client.Client;
|
||||||
import org.xbib.netty.http.client.api.Request;
|
import org.xbib.netty.http.client.api.Request;
|
||||||
import org.xbib.netty.http.common.HttpAddress;
|
import org.xbib.netty.http.common.HttpAddress;
|
||||||
|
@ -15,6 +16,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@Disabled
|
@Disabled
|
||||||
|
@ExtendWith(NettyHttpTestExtension.class)
|
||||||
class MultiDomainSecureServerTest {
|
class MultiDomainSecureServerTest {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(MultiDomainSecureServerTest.class.getName());
|
private static final Logger logger = Logger.getLogger(MultiDomainSecureServerTest.class.getName());
|
||||||
|
@ -52,7 +54,7 @@ class MultiDomainSecureServerTest {
|
||||||
.url("https://fl.hbz-nrw.de:8443")
|
.url("https://fl.hbz-nrw.de:8443")
|
||||||
.setResponseListener(resp -> {
|
.setResponseListener(resp -> {
|
||||||
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
||||||
logger.log(Level.INFO, "got response: " + response + " status=" + resp.getStatus());
|
logger.log(Level.INFO, "fl: got response: " + response + " status=" + resp.getStatus());
|
||||||
assertEquals("Hello fl.hbz-nrw.de", response);
|
assertEquals("Hello fl.hbz-nrw.de", response);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
@ -62,7 +64,7 @@ class MultiDomainSecureServerTest {
|
||||||
.url("https://zfl2.hbz-nrw.de:8443")
|
.url("https://zfl2.hbz-nrw.de:8443")
|
||||||
.setResponseListener(resp -> {
|
.setResponseListener(resp -> {
|
||||||
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
||||||
logger.log(Level.INFO, "got response: " + response + " status=" + resp.getStatus());
|
logger.log(Level.INFO, "zfl2: got response: " + response + " status=" + resp.getStatus());
|
||||||
assertEquals("Hello zfl2.hbz-nrw.de", response);
|
assertEquals("Hello zfl2.hbz-nrw.de", response);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -3,6 +3,7 @@ package org.xbib.netty.http.server.test;
|
||||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||||
import org.junit.jupiter.api.Disabled;
|
import org.junit.jupiter.api.Disabled;
|
||||||
import org.junit.jupiter.api.Test;
|
import org.junit.jupiter.api.Test;
|
||||||
|
import org.junit.jupiter.api.extension.ExtendWith;
|
||||||
import org.xbib.netty.http.client.Client;
|
import org.xbib.netty.http.client.Client;
|
||||||
import org.xbib.netty.http.client.api.Request;
|
import org.xbib.netty.http.client.api.Request;
|
||||||
import org.xbib.netty.http.common.HttpAddress;
|
import org.xbib.netty.http.common.HttpAddress;
|
||||||
|
@ -14,6 +15,7 @@ import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@Disabled
|
@Disabled
|
||||||
|
@ExtendWith(NettyHttpTestExtension.class)
|
||||||
class MultiDomainServerTest {
|
class MultiDomainServerTest {
|
||||||
|
|
||||||
private static final Logger logger = Logger.getLogger(MultiDomainServerTest.class.getName());
|
private static final Logger logger = Logger.getLogger(MultiDomainServerTest.class.getName());
|
||||||
|
@ -39,7 +41,7 @@ class MultiDomainServerTest {
|
||||||
.url("http://fl.hbz-nrw.de:8008")
|
.url("http://fl.hbz-nrw.de:8008")
|
||||||
.setResponseListener(resp -> {
|
.setResponseListener(resp -> {
|
||||||
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
||||||
logger.log(Level.INFO, "got response: " + response + " status=" + resp.getStatus());
|
logger.log(Level.INFO, "fl: got response: " + response + " status=" + resp.getStatus());
|
||||||
assertEquals("Hello fl.hbz-nrw.de", response);
|
assertEquals("Hello fl.hbz-nrw.de", response);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
@ -48,7 +50,7 @@ class MultiDomainServerTest {
|
||||||
.url("http://zfl2.hbz-nrw.de:8008")
|
.url("http://zfl2.hbz-nrw.de:8008")
|
||||||
.setResponseListener(resp -> {
|
.setResponseListener(resp -> {
|
||||||
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
String response = resp.getBodyAsString(StandardCharsets.UTF_8);
|
||||||
logger.log(Level.INFO, "got response: " + response + " status=" + resp.getStatus());
|
logger.log(Level.INFO, "zfl2: got response: " + response + " status=" + resp.getStatus());
|
||||||
assertEquals("Hello zfl2.hbz-nrw.de", response);
|
assertEquals("Hello zfl2.hbz-nrw.de", response);
|
||||||
})
|
})
|
||||||
.build();
|
.build();
|
||||||
|
|
Loading…
Reference in a new issue