This is an automated email from the ASF dual-hosted git repository. mblow pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/asterixdb.git
commit 9796799b8e8c6ac6b7b02c71ae2870e8fc4ff3c9 Author: Michael Blow <[email protected]> AuthorDate: Fri Oct 4 17:05:22 2019 -0400 [NO ISSUE][API] Add ability to identify secure servlet requests Change-Id: Ia693e29a47b513a63fdce80383da90ba165c28d6 Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/3603 Tested-by: Jenkins <[email protected]> Integration-Tests: Jenkins <[email protected]> Reviewed-by: Till Westmann <[email protected]> --- .../apache/asterix/api/http/server/ClusterApiServlet.java | 3 ++- .../java/org/apache/hyracks/http/api/IServletRequest.java | 6 ++++++ .../java/org/apache/hyracks/http/server/BaseRequest.java | 15 +++++++++++---- .../apache/hyracks/http/server/FormUrlEncodedRequest.java | 9 +++++---- .../java/org/apache/hyracks/http/server/HttpServer.java | 5 +++++ .../org/apache/hyracks/http/server/HttpServerHandler.java | 8 +++++++- .../org/apache/hyracks/http/server/utils/HttpUtil.java | 9 ++++++--- 7 files changed, 42 insertions(+), 13 deletions(-) diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java index ce30637..bdc1bd7 100644 --- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java +++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/ClusterApiServlet.java @@ -145,7 +145,8 @@ public class ClusterApiServlet extends AbstractServlet { } protected String resolveClusterUrl(IServletRequest request, String pathToNode) { - final StringBuilder requestURL = new StringBuilder("http://"); + final StringBuilder requestURL = new StringBuilder(request.getScheme().name()); + requestURL.append("://"); requestURL.append(request.getHeader(HttpHeaderNames.HOST)); requestURL.append(request.getHttpRequest().uri()); if (requestURL.charAt(requestURL.length() - 1) != '/') { diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java index 7dae0b5..8af9f23 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java @@ -23,6 +23,7 @@ import java.util.Map; import java.util.Set; import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpScheme; /** * An Http Request instance @@ -81,4 +82,9 @@ public interface IServletRequest { * @return the remote address */ InetSocketAddress getRemoteAddress(); + + /** + * Indicates which scheme the client used making this request + */ + HttpScheme getScheme(); } diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java index d681d81..69f7c5f 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java @@ -18,7 +18,6 @@ */ package org.apache.hyracks.http.server; -import java.io.IOException; import java.net.InetSocketAddress; import java.util.Collections; import java.util.HashMap; @@ -31,25 +30,28 @@ import org.apache.hyracks.http.server.utils.HttpUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpScheme; import io.netty.handler.codec.http.QueryStringDecoder; public class BaseRequest implements IServletRequest { protected final FullHttpRequest request; protected final Map<String, List<String>> parameters; protected final InetSocketAddress remoteAddress; + protected final HttpScheme scheme; - public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request) throws IOException { + public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme) { QueryStringDecoder decoder = new QueryStringDecoder(request.uri()); Map<String, List<String>> param = decoder.parameters(); InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - return new BaseRequest(request, remoteAddress, param); + return new BaseRequest(request, remoteAddress, param, scheme); } protected BaseRequest(FullHttpRequest request, InetSocketAddress remoteAddress, - Map<String, List<String>> parameters) { + Map<String, List<String>> parameters, HttpScheme scheme) { this.request = request; this.remoteAddress = remoteAddress; this.parameters = parameters; + this.scheme = scheme; } @Override @@ -86,4 +88,9 @@ public class BaseRequest implements IServletRequest { public InetSocketAddress getRemoteAddress() { return remoteAddress; } + + @Override + public HttpScheme getScheme() { + return scheme; + } } diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java index 81cd04e..0e57d8d 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java @@ -31,11 +31,12 @@ import org.apache.hyracks.http.server.utils.HttpUtil; import io.netty.channel.ChannelHandlerContext; import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpScheme; import io.netty.handler.codec.http.QueryStringDecoder; public class FormUrlEncodedRequest extends BaseRequest implements IServletRequest { - public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request) { + public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme) { Charset charset = HttpUtil.getRequestCharset(request); Map<String, List<String>> parameters = new LinkedHashMap<>(); URLEncodedUtils.parse(request.content().toString(charset), charset).forEach( @@ -43,11 +44,11 @@ public class FormUrlEncodedRequest extends BaseRequest implements IServletReques new QueryStringDecoder(request.uri()).parameters() .forEach((name, value) -> parameters.computeIfAbsent(name, a -> new ArrayList<>()).addAll(value)); InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress(); - return new FormUrlEncodedRequest(request, remoteAddress, parameters); + return new FormUrlEncodedRequest(request, remoteAddress, parameters, scheme); } private FormUrlEncodedRequest(FullHttpRequest request, InetSocketAddress remoteAddress, - Map<String, List<String>> parameters) { - super(request, remoteAddress, parameters); + Map<String, List<String>> parameters, HttpScheme scheme) { + super(request, remoteAddress, parameters, scheme); } } diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServer.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServer.java index d9902da..2a7b47e 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServer.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServer.java @@ -48,6 +48,7 @@ import io.netty.channel.WriteBufferWaterMark; import io.netty.channel.socket.SocketChannel; import io.netty.channel.socket.nio.NioServerSocketChannel; import io.netty.handler.codec.http.FullHttpRequest; +import io.netty.handler.codec.http.HttpScheme; import io.netty.handler.logging.LogLevel; import io.netty.handler.logging.LoggingHandler; @@ -404,6 +405,10 @@ public class HttpServer { return closedHandler; } + public HttpScheme getScheme() { + return HttpScheme.HTTP; + } + @Override public String toString() { return "{\"class\":\"" + getClass().getSimpleName() + "\",\"address\":" + address + ",\"state\":\"" + getState() diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java index fe6a431..4882572 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/HttpServerHandler.java @@ -18,6 +18,8 @@ */ package org.apache.hyracks.http.server; +import static org.apache.hyracks.http.server.utils.HttpUtil.X_FORWARDED_PROTO; + import java.io.IOException; import java.util.concurrent.Future; import java.util.concurrent.RejectedExecutionException; @@ -42,6 +44,7 @@ import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpRequest; import io.netty.handler.codec.http.HttpResponseStatus; +import io.netty.handler.codec.http.HttpScheme; public class HttpServerHandler<T extends HttpServer> extends SimpleChannelInboundHandler<Object> implements ChannelFutureListener { @@ -130,7 +133,10 @@ public class HttpServerHandler<T extends HttpServer> extends SimpleChannelInboun private void submit(ChannelHandlerContext ctx, IServlet servlet, FullHttpRequest request) throws IOException { IServletRequest servletRequest; try { - servletRequest = HttpUtil.toServletRequest(ctx, request); + HttpScheme scheme = + server.getScheme() == HttpScheme.HTTPS || "https".equals(request.headers().get(X_FORWARDED_PROTO)) + ? HttpScheme.HTTPS : HttpScheme.HTTP; + servletRequest = HttpUtil.toServletRequest(ctx, request, scheme); } catch (IllegalArgumentException e) { LOGGER.log(Level.WARN, "Failure Decoding Request", e); respond(ctx, request, HttpResponseStatus.BAD_REQUEST); diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java index 34ca2c4..0f857bd 100644 --- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java +++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java @@ -44,6 +44,7 @@ import io.netty.handler.codec.http.FullHttpRequest; import io.netty.handler.codec.http.HttpHeaderNames; import io.netty.handler.codec.http.HttpHeaderValues; import io.netty.handler.codec.http.HttpRequest; +import io.netty.handler.codec.http.HttpScheme; import io.netty.util.AsciiString; public class HttpUtil { @@ -51,6 +52,8 @@ public class HttpUtil { private static final Pattern PARENT_DIR = Pattern.compile("/[^./]+/\\.\\./"); private static final Charset DEFAULT_RESPONSE_CHARSET = StandardCharsets.UTF_8; + public static final AsciiString X_FORWARDED_PROTO = AsciiString.cached("x-forwarded-proto"); + private HttpUtil() { } @@ -80,10 +83,10 @@ public class HttpUtil { return parameter == null ? null : String.join(",", parameter); } - public static IServletRequest toServletRequest(ChannelHandlerContext ctx, FullHttpRequest request) - throws IOException { + public static IServletRequest toServletRequest(ChannelHandlerContext ctx, FullHttpRequest request, + HttpScheme scheme) { return ContentType.APPLICATION_X_WWW_FORM_URLENCODED.equals(getContentTypeOnly(request)) - ? FormUrlEncodedRequest.create(ctx, request) : BaseRequest.create(ctx, request); + ? FormUrlEncodedRequest.create(ctx, request, scheme) : BaseRequest.create(ctx, request, scheme); } public static String getContentTypeOnly(IServletRequest request) {
