Michael Blow has uploaded a new change for review.
https://asterix-gerrit.ics.uci.edu/1911
Change subject: WIP: config null handling, http request processing
......................................................................
WIP: config null handling, http request processing
- handle null config values when marshall/unmarshalling
- support non-post x-www-form-urlencoded directly
- don't assume POSTs are x-www-form-urlencoded
Change-Id: I670b815a5276d870f7d538d1ce9d8bef2d0fcf4f
---
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java
M
asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
M
hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOption.java
M
hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOptionType.java
M hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/pom.xml
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
M
hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/OptionTypes.java
M
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServletRequest.java
M
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/BaseRequest.java
A
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java
D
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/PostRequest.java
M
hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/utils/HttpUtil.java
14 files changed, 235 insertions(+), 110 deletions(-)
git pull ssh://asterix-gerrit.ics.uci.edu:29418/asterixdb
refs/changes/11/1911/1
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
index 42e23ba..901aff8 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryResultApiServlet.java
@@ -41,7 +41,7 @@
public class QueryResultApiServlet extends AbstractQueryApiServlet {
private static final Logger LOGGER =
Logger.getLogger(QueryResultApiServlet.class.getName());
- public QueryResultApiServlet(ConcurrentMap<String, Object> ctx, String[]
paths, IApplicationContext appCtx) {
+ public QueryResultApiServlet(ConcurrentMap<String, Object> ctx,
IApplicationContext appCtx, String... paths) {
super(appCtx, ctx, paths);
}
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
index 9ee064e..1cec616 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryServiceServlet.java
@@ -62,8 +62,6 @@
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
-
-import io.netty.handler.codec.http.HttpHeaderNames;
import io.netty.handler.codec.http.HttpResponseStatus;
public class QueryServiceServlet extends AbstractQueryApiServlet {
@@ -317,9 +315,7 @@
}
private RequestParameters getRequestParameters(IServletRequest request)
throws IOException {
- final String contentTypeParam =
request.getHttpRequest().headers().get(HttpHeaderNames.CONTENT_TYPE);
- int sep = contentTypeParam.indexOf(';');
- final String contentType = sep < 0 ? contentTypeParam.trim() :
contentTypeParam.substring(0, sep).trim();
+ final String contentType = HttpUtil.getContentTypeOnly(request);
RequestParameters param = new RequestParameters();
param.host = host(request);
param.path = servletPath(request);
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java
index 71dddc0..cec65f7 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/QueryStatusApiServlet.java
@@ -41,7 +41,7 @@
public class QueryStatusApiServlet extends AbstractQueryApiServlet {
private static final Logger LOGGER =
Logger.getLogger(QueryStatusApiServlet.class.getName());
- public QueryStatusApiServlet(ConcurrentMap<String, Object> ctx, String[]
paths, IApplicationContext appCtx) {
+ public QueryStatusApiServlet(ConcurrentMap<String, Object> ctx,
IApplicationContext appCtx, String... paths) {
super(appCtx, ctx, paths);
}
diff --git
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
index 3627974..e8636c8 100644
---
a/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
+++
b/asterixdb/asterix-app/src/main/java/org/apache/asterix/hyracks/bootstrap/CCApplication.java
@@ -287,9 +287,9 @@
case Servlets.RUNNING_REQUESTS:
return new QueryCancellationServlet(ctx, paths);
case Servlets.QUERY_STATUS:
- return new QueryStatusApiServlet(ctx, paths, appCtx);
+ return new QueryStatusApiServlet(ctx, appCtx, paths);
case Servlets.QUERY_RESULT:
- return new QueryResultApiServlet(ctx, paths, appCtx);
+ return new QueryResultApiServlet(ctx, appCtx, paths);
case Servlets.QUERY_SERVICE:
return new QueryServiceServlet(ctx, paths, appCtx, SQLPP,
ccExtensionManager.getCompilationProvider(SQLPP),
getStatementExecutorFactory(),
diff --git
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOption.java
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOption.java
index 834d73c..b8e7635 100644
---
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOption.java
+++
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOption.java
@@ -20,6 +20,9 @@
import java.util.function.Function;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.commons.lang3.text.WordUtils;
+
public interface IOption {
String name();
@@ -64,6 +67,10 @@
return name().toLowerCase().replace("_", ".");
}
+ default String json() {
+ return StringUtils.remove(WordUtils.capitalize("z" +
name().toLowerCase(), '_').substring(1), '_');
+ }
+
default String toIniString() {
return "[" + section().sectionName() + "] " + ini();
}
diff --git
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOptionType.java
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOptionType.java
index 1bd6097..d2a254f 100644
---
a/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOptionType.java
+++
b/hyracks-fullstack/hyracks/hyracks-api/src/main/java/org/apache/hyracks/api/config/IOptionType.java
@@ -18,6 +18,8 @@
*/
package org.apache.hyracks.api.config;
+import com.fasterxml.jackson.databind.node.ObjectNode;
+
public interface IOptionType<T> {
/**
* @throws IllegalArgumentException when the supplied string cannot be
interpreted
@@ -34,6 +36,11 @@
}
/**
+ * @return the value in a format suitable for serialized JSON
+ */
+ void serializeJSONField(String fieldName, Object value, ObjectNode node);
+
+ /**
* @return the value in a format suitable for serialized ini file
*/
default String serializeToIni(Object value) {
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/pom.xml
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/pom.xml
index 5120047..80ef088 100644
--- a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/pom.xml
+++ b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/pom.xml
@@ -75,5 +75,9 @@
<groupId>org.apache.commons</groupId>
<artifactId>commons-collections4</artifactId>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-lang3</artifactId>
+ </dependency>
</dependencies>
</project>
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
index fcaee6d..a595301 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/ConfigManager.java
@@ -425,7 +425,7 @@
}
public List<String> getNodeNames() {
- return Collections.unmodifiableList(new
ArrayList(nodeSpecificMap.keySet()));
+ return Collections.unmodifiableList(new
ArrayList<>(nodeSpecificMap.keySet()));
}
public IApplicationConfig getNodeEffectiveConfig(String nodeId) {
diff --git
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/OptionTypes.java
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/OptionTypes.java
index 02b9325..1e92a7a 100644
---
a/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/OptionTypes.java
+++
b/hyracks-fullstack/hyracks/hyracks-control/hyracks-control-common/src/main/java/org/apache/hyracks/control/common/config/OptionTypes.java
@@ -21,14 +21,20 @@
import java.net.MalformedURLException;
import java.util.logging.Level;
+import org.apache.commons.lang3.StringUtils;
import org.apache.hyracks.api.config.IOptionType;
import org.apache.hyracks.util.StorageUtil;
+
+import com.fasterxml.jackson.databind.node.ObjectNode;
public class OptionTypes {
public static final IOptionType<Integer> INTEGER_BYTE_UNIT = new
IOptionType<Integer>() {
@Override
public Integer parse(String s) {
+ if (s == null) {
+ return null;
+ }
long result1 = StorageUtil.getByteValue(s);
if (result1 > Integer.MAX_VALUE || result1 < Integer.MIN_VALUE) {
throw new IllegalArgumentException(
@@ -46,12 +52,17 @@
public String serializeToHumanReadable(Object value) {
return value + " (" + StorageUtil.toHumanReadableSize((int)value)
+ ")";
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (int)value);
+ }
};
public static final IOptionType<Long> LONG_BYTE_UNIT = new
IOptionType<Long>() {
@Override
public Long parse(String s) {
- return StorageUtil.getByteValue(s);
+ return s == null ? null : StorageUtil.getByteValue(s);
}
@Override
@@ -62,6 +73,11 @@
@Override
public String serializeToHumanReadable(Object value) {
return value + " (" + StorageUtil.toHumanReadableSize((long)value)
+ ")";
+ }
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (long)value);
}
};
@@ -75,6 +91,11 @@
public Class<Integer> targetType() {
return Integer.class;
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (int)value);
+ }
};
public static final IOptionType<Double> DOUBLE = new IOptionType<Double>()
{
@@ -86,6 +107,11 @@
@Override
public Class<Double> targetType() {
return Double.class;
+ }
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (double)value);
}
};
@@ -99,6 +125,11 @@
public Class<String> targetType() {
return String.class;
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (String)value);
+ }
};
public static final IOptionType<Long> LONG = new IOptionType<Long>() {
@@ -110,6 +141,11 @@
@Override
public Class<Long> targetType() {
return Long.class;
+ }
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (long)value);
}
};
@@ -123,12 +159,17 @@
public Class<Boolean> targetType() {
return Boolean.class;
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, (boolean)value);
+ }
};
public static final IOptionType<Level> LEVEL = new IOptionType<Level>() {
@Override
public Level parse(String s) {
- return Level.parse(s);
+ return s == null ? null : Level.parse(s);
}
@Override
@@ -137,20 +178,25 @@
}
@Override
- public Object serializeToJSON(Object value) {
- return ((Level)value).getName();
+ public String serializeToJSON(Object value) {
+ return value == null ? null : ((Level)value).getName();
}
@Override
public String serializeToIni(Object value) {
return ((Level)value).getName();
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, serializeToJSON(value));
+ }
};
public static final IOptionType<String []> STRING_ARRAY = new
IOptionType<String []>() {
@Override
public String [] parse(String s) {
- return s.split("\\s*,\\s*");
+ return s == null ? null : s.split("\\s*,\\s*");
}
@Override
@@ -162,13 +208,18 @@
public String serializeToIni(Object value) {
return String.join(",", (String [])value);
}
+
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, value == null ? null :
StringUtils.join((String [])value, ','));
+ }
};
public static final IOptionType<java.net.URL> URL = new
IOptionType<java.net.URL>() {
@Override
public java.net.URL parse(String s) {
try {
- return new java.net.URL(s);
+ return s == null ? null : new java.net.URL(s);
} catch (MalformedURLException e) {
throw new IllegalArgumentException(e);
}
@@ -178,8 +229,12 @@
public Class<java.net.URL> targetType() {
return java.net.URL.class;
}
- };
+ @Override
+ public void serializeJSONField(String fieldName, Object value,
ObjectNode node) {
+ node.put(fieldName, value == null ? null : String.valueOf(value));
+ }
+ };
private OptionTypes() {
}
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 610c3d1..587cbe3 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
@@ -18,6 +18,9 @@
*/
package org.apache.hyracks.http.api;
+import java.util.Map;
+import java.util.Set;
+
import io.netty.handler.codec.http.FullHttpRequest;
/**
@@ -38,6 +41,20 @@
String getParameter(CharSequence name);
/**
+ * Get the names of any request parameters
+ *
+ * @return the list of parameter names
+ */
+ Set<String> getParameterNames();
+
+ /**
+ * Get the all request parameters
+ *
+ * @return the parameters
+ */
+ Map<String, String> getParameters();
+
+ /**
* Get a request header
*
* @param name
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 5b354af..0c633cf 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
@@ -19,8 +19,11 @@
package org.apache.hyracks.http.server;
import java.io.IOException;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import java.util.Set;
import org.apache.hyracks.http.api.IServletRequest;
import org.apache.hyracks.http.server.utils.HttpUtil;
@@ -54,6 +57,21 @@
}
@Override
+ public Set<String> getParameterNames() {
+ return Collections.unmodifiableSet(parameters.keySet());
+ }
+
+ @Override
+ public Map<String, String> getParameters() {
+ HashMap<String, String> paramMap = new HashMap<>();
+ for (String name : parameters.keySet()) {
+ paramMap.put(name, HttpUtil.getParameter(parameters, name));
+
+ }
+ return Collections.unmodifiableMap(paramMap);
+ }
+
+ @Override
public String getHeader(CharSequence name) {
return request.headers().get(name);
}
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
new file mode 100644
index 0000000..743a2c4
--- /dev/null
+++
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/FormUrlEncodedRequest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.hyracks.http.server;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.hyracks.http.api.IServletRequest;
+import org.apache.hyracks.http.server.utils.HttpUtil;
+
+import io.netty.handler.codec.http.FullHttpRequest;
+import io.netty.handler.codec.http.QueryStringDecoder;
+import io.netty.handler.codec.http.multipart.Attribute;
+import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
+import io.netty.handler.codec.http.multipart.InterfaceHttpData;
+import io.netty.handler.codec.http.multipart.MixedAttribute;
+
+public class FormUrlEncodedRequest extends BaseRequest implements
IServletRequest {
+
+ private final List<String> names;
+ private final List<String> values;
+
+ public static IServletRequest create(FullHttpRequest request) throws
IOException {
+ List<String> names = new ArrayList<>();
+ List<String> values = new ArrayList<>();
+ HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
+ try {
+ List<InterfaceHttpData> bodyHttpDatas = decoder.getBodyHttpDatas();
+ for (InterfaceHttpData data : bodyHttpDatas) {
+ if
(data.getHttpDataType().equals(InterfaceHttpData.HttpDataType.Attribute)) {
+ Attribute attr = (MixedAttribute) data;
+ names.add(data.getName());
+ values.add(attr.getValue());
+ }
+ }
+ } finally {
+ decoder.destroy();
+ }
+ return new FormUrlEncodedRequest(request, new
QueryStringDecoder(request.uri()).parameters(), names, values);
+ }
+
+ protected FormUrlEncodedRequest(FullHttpRequest request, Map<String,
List<String>> parameters, List<String> names,
+ List<String> values) {
+ super(request, parameters);
+ this.names = names;
+ this.values = values;
+ }
+
+ @Override
+ public String getParameter(CharSequence name) {
+ for (int i = 0; i < names.size(); i++) {
+ if (name.equals(names.get(i))) {
+ return values.get(i);
+ }
+ }
+ return HttpUtil.getParameter(parameters, name);
+ }
+
+ @Override
+ public Set<String> getParameterNames() {
+ HashSet<String> paramNames = new HashSet<>();
+ paramNames.addAll(parameters.keySet());
+ paramNames.addAll(names);
+ return Collections.unmodifiableSet(paramNames);
+ }
+
+ @Override
+ public Map<String, String> getParameters() {
+ HashMap<String, String> paramMap = new HashMap<>();
+ paramMap.putAll(super.getParameters());
+ for (int i = 0; i < names.size(); i++) {
+ paramMap.put(names.get(i), values.get(i));
+ }
+
+ return Collections.unmodifiableMap(paramMap);
+ }
+}
diff --git
a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/PostRequest.java
b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/PostRequest.java
deleted file mode 100644
index 1dcb088..0000000
---
a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/PostRequest.java
+++ /dev/null
@@ -1,89 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.hyracks.http.server;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.logging.Level;
-import java.util.logging.Logger;
-
-import org.apache.hyracks.http.api.IServletRequest;
-import org.apache.hyracks.http.server.utils.HttpUtil;
-
-import io.netty.handler.codec.http.FullHttpRequest;
-import io.netty.handler.codec.http.QueryStringDecoder;
-import io.netty.handler.codec.http.multipart.Attribute;
-import io.netty.handler.codec.http.multipart.HttpPostRequestDecoder;
-import io.netty.handler.codec.http.multipart.InterfaceHttpData;
-import io.netty.handler.codec.http.multipart.MixedAttribute;
-
-public class PostRequest extends BaseRequest implements IServletRequest {
-
- private static final Logger LOGGER =
Logger.getLogger(PostRequest.class.getName());
-
- private final List<String> names;
- private final List<String> values;
-
- public static IServletRequest create(FullHttpRequest request) throws
IOException {
- List<String> names = new ArrayList<>();
- List<String> values = new ArrayList<>();
- HttpPostRequestDecoder decoder = null;
- try {
- decoder = new HttpPostRequestDecoder(request);
- } catch (Exception e) {
- //ignore. this means that the body of the POST request does not
have key value pairs
- LOGGER.log(Level.WARNING, "Failed to decode a post message. Fix
the API not to have queries as POST body",
- e);
- }
- if (decoder != null) {
- try {
- List<InterfaceHttpData> bodyHttpDatas =
decoder.getBodyHttpDatas();
- for (InterfaceHttpData data : bodyHttpDatas) {
- if
(data.getHttpDataType().equals(InterfaceHttpData.HttpDataType.Attribute)) {
- Attribute attr = (MixedAttribute) data;
- names.add(data.getName());
- values.add(attr.getValue());
- }
- }
- } finally {
- decoder.destroy();
- }
- }
- return new PostRequest(request, new
QueryStringDecoder(request.uri()).parameters(), names, values);
- }
-
- protected PostRequest(FullHttpRequest request, Map<String, List<String>>
parameters, List<String> names,
- List<String> values) {
- super(request, parameters);
- this.names = names;
- this.values = values;
- }
-
- @Override
- public String getParameter(CharSequence name) {
- for (int i = 0; i < names.size(); i++) {
- if (name.equals(names.get(i))) {
- return values.get(i);
- }
- }
- return HttpUtil.getParameter(parameters, name);
- }
-}
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 c11deef..2babc73 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
@@ -26,11 +26,11 @@
import org.apache.hyracks.http.api.IServletRequest;
import org.apache.hyracks.http.api.IServletResponse;
import org.apache.hyracks.http.server.BaseRequest;
-import org.apache.hyracks.http.server.PostRequest;
+import org.apache.hyracks.http.server.FormUrlEncodedRequest;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpHeaderNames;
-import io.netty.handler.codec.http.HttpMethod;
+import io.netty.handler.codec.http.HttpRequest;
public class HttpUtil {
@@ -47,6 +47,7 @@
public static class ContentType {
public static final String APPLICATION_ADM = "application/x-adm";
public static final String APPLICATION_JSON = "application/json";
+ public static final String APPLICATION_X_WWW_FORM_URLENCODED =
"application/x-www-form-urlencoded";
public static final String CSV = "text/csv";
public static final String IMG_PNG = "image/png";
public static final String TEXT_HTML = "text/html";
@@ -57,7 +58,7 @@
}
public static String getParameter(Map<String, List<String>> parameters,
CharSequence name) {
- List<String> parameter = parameters.get(name);
+ List<String> parameter = parameters.get(String.valueOf(name));
if (parameter == null) {
return null;
} else if (parameter.size() == 1) {
@@ -72,7 +73,17 @@
}
public static IServletRequest toServletRequest(FullHttpRequest request)
throws IOException {
- return request.method() == HttpMethod.POST ?
PostRequest.create(request) : BaseRequest.create(request);
+ return
ContentType.APPLICATION_X_WWW_FORM_URLENCODED.equals(getContentTypeOnly(request))
+ ? FormUrlEncodedRequest.create(request) :
BaseRequest.create(request);
+ }
+
+ public static String getContentTypeOnly(IServletRequest request) {
+ return getContentTypeOnly(request.getHttpRequest());
+ }
+
+ public static String getContentTypeOnly(HttpRequest request) {
+ String contentType =
request.headers().get(HttpHeaderNames.CONTENT_TYPE);
+ return contentType == null ? null : contentType.split(";")[0];
}
public static String getRequestBody(IServletRequest request) {
--
To view, visit https://asterix-gerrit.ics.uci.edu/1911
To unsubscribe, visit https://asterix-gerrit.ics.uci.edu/settings
Gerrit-MessageType: newchange
Gerrit-Change-Id: I670b815a5276d870f7d538d1ce9d8bef2d0fcf4f
Gerrit-PatchSet: 1
Gerrit-Project: asterixdb
Gerrit-Branch: master
Gerrit-Owner: Michael Blow <[email protected]>