You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by mb...@apache.org on 2019/10/07 16:29:23 UTC

[asterixdb] 02/04: [NO ISSUE][API] Add ability to identify secure servlet requests

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 <mb...@apache.org>
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 <je...@fulliautomatix.ics.uci.edu>
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Till Westmann <ti...@apache.org>
---
 .../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) {