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 <mblow@apache.org>
|