You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@asterixdb.apache.org by al...@apache.org on 2021/10/27 06:03:33 UTC

[asterixdb] branch master updated: [ASTERIXDB-2976][API] Infra to ignore query parameters on POST/DELETE/PUT requests

This is an automated email from the ASF dual-hosted git repository.

alsuliman pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/asterixdb.git


The following commit(s) were added to refs/heads/master by this push:
     new a4e2dba  [ASTERIXDB-2976][API] Infra to ignore query parameters on POST/DELETE/PUT requests
a4e2dba is described below

commit a4e2dbaa3254e64355d6348417805d31831f7a63
Author: Ali Alsuliman <al...@gmail.com>
AuthorDate: Mon Oct 25 16:22:25 2021 -0700

    [ASTERIXDB-2976][API] Infra to ignore query parameters on POST/DELETE/PUT requests
    
    - user model changes: no
    - storage format changes: no
    - interface changes: yes
    
    Change-Id: Ib084b583bae914ae5bde5c7a70e0b8e5699407de
    Reviewed-on: https://asterix-gerrit.ics.uci.edu/c/asterixdb/+/13664
    Integration-Tests: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Tested-by: Jenkins <je...@fulliautomatix.ics.uci.edu>
    Reviewed-by: Ali Alsuliman <al...@gmail.com>
    Reviewed-by: Murtadha Hubail <mh...@apache.org>
---
 .../asterix/api/http/server/BasicAuthServlet.java  |   5 +
 .../test/common/CancellationTestExecutor.java      |  22 +----
 .../common/RebalanceCancellationTestExecutor.java  |  16 +--
 .../apache/asterix/test/common/TestExecutor.java   | 107 +++++++++++----------
 .../java/org/apache/hyracks/http/api/IServlet.java |   7 ++
 .../hyracks/http/server/AbstractServlet.java       |   4 +
 .../apache/hyracks/http/server/BaseRequest.java    |   7 +-
 .../hyracks/http/server/FormUrlEncodedRequest.java |   9 +-
 .../hyracks/http/server/HttpServerHandler.java     |   7 +-
 .../apache/hyracks/http/server/utils/HttpUtil.java |  11 ++-
 10 files changed, 98 insertions(+), 97 deletions(-)

diff --git a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/BasicAuthServlet.java b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/BasicAuthServlet.java
index 9dc971a..061ceb9 100644
--- a/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/BasicAuthServlet.java
+++ b/asterixdb/asterix-app/src/main/java/org/apache/asterix/api/http/server/BasicAuthServlet.java
@@ -168,4 +168,9 @@ public class BasicAuthServlet implements IServlet {
     private static String generateRandomString(int size) {
         return RandomStringUtils.randomAlphanumeric(size);
     }
+
+    @Override
+    public boolean ignoresQueryParameters(HttpMethod method) {
+        return delegate.ignoresQueryParameters(method);
+    }
 }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
index db7ca7d..766a9d4 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/CancellationTestExecutor.java
@@ -19,10 +19,11 @@
 
 package org.apache.asterix.test.common;
 
+import static org.apache.asterix.api.http.server.QueryServiceRequestParameters.Parameter.CLIENT_ID;
+
 import java.io.InputStream;
 import java.net.URI;
 import java.nio.charset.Charset;
-import java.nio.charset.StandardCharsets;
 import java.util.BitSet;
 import java.util.Iterator;
 import java.util.List;
@@ -40,8 +41,6 @@ import org.apache.asterix.testframework.xml.ParameterTypeEnum;
 import org.apache.asterix.testframework.xml.TestCase;
 import org.apache.commons.lang3.mutable.MutableInt;
 import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
 import org.apache.hyracks.api.util.ExceptionUtils;
 import org.junit.Assert;
 
@@ -55,8 +54,8 @@ public class CancellationTestExecutor extends TestExecutor {
             Predicate<Integer> responseCodeValidator, boolean cancellable) throws Exception {
         cancellable = cancellable && !containsClientContextID(str);
         String clientContextId = UUID.randomUUID().toString();
-        final List<TestCase.CompilationUnit.Parameter> newParams = cancellable
-                ? upsertParam(params, "client_context_id", ParameterTypeEnum.STRING, clientContextId) : params;
+        final List<TestCase.CompilationUnit.Parameter> newParams =
+                cancellable ? upsertParam(params, CLIENT_ID.str(), ParameterTypeEnum.STRING, clientContextId) : params;
         Callable<InputStream> query = () -> {
             try {
                 return CancellationTestExecutor.super.executeQueryService(str, fmt, uri,
@@ -89,21 +88,10 @@ public class CancellationTestExecutor extends TestExecutor {
 
     // Cancels a submitted query through the cancellation REST API.
     private int cancelQuery(URI uri, List<TestCase.CompilationUnit.Parameter> params) throws Exception {
-        HttpUriRequest method = constructDeleteMethodUrl(uri, params);
-        HttpResponse response = executeHttpRequest(method);
+        HttpResponse response = executeHttpRequest(constructDeleteMethod(uri, params));
         return response.getStatusLine().getStatusCode();
     }
 
-    // Constructs a HTTP DELETE request.
-    private HttpUriRequest constructDeleteMethodUrl(URI uri, List<TestCase.CompilationUnit.Parameter> otherParams) {
-        RequestBuilder builder = RequestBuilder.delete(uri);
-        for (TestCase.CompilationUnit.Parameter param : otherParams) {
-            builder.addParameter(param.getName(), param.getValue());
-        }
-        builder.setCharset(StandardCharsets.UTF_8);
-        return builder.build();
-    }
-
     @Override
     protected boolean isUnExpected(Exception e, List<String> expectedErrors, int numOfErrors, MutableInt queryCount,
             boolean expectedSourceLoc) {
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/RebalanceCancellationTestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/RebalanceCancellationTestExecutor.java
index d35bfb7..758ba6f 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/RebalanceCancellationTestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/RebalanceCancellationTestExecutor.java
@@ -21,7 +21,6 @@ package org.apache.asterix.test.common;
 
 import java.io.File;
 import java.net.URI;
-import java.nio.charset.StandardCharsets;
 import java.util.Collections;
 import java.util.List;
 import java.util.Map;
@@ -35,8 +34,6 @@ import org.apache.asterix.testframework.xml.ComparisonEnum;
 import org.apache.asterix.testframework.xml.TestCase;
 import org.apache.commons.lang3.mutable.MutableInt;
 import org.apache.http.HttpResponse;
-import org.apache.http.client.methods.HttpUriRequest;
-import org.apache.http.client.methods.RequestBuilder;
 import org.apache.hyracks.api.util.ExceptionUtils;
 import org.apache.logging.log4j.Level;
 import org.junit.Assert;
@@ -102,18 +99,7 @@ public class RebalanceCancellationTestExecutor extends TestExecutor {
 
     // Cancels a submitted query through the cancellation REST API.
     private int cancelQuery(URI uri, List<TestCase.CompilationUnit.Parameter> params) throws Exception {
-        HttpUriRequest method = constructDeleteMethodUrl(uri, params);
-        HttpResponse response = executeHttpRequest(method);
+        HttpResponse response = executeHttpRequest(constructDeleteMethod(uri, params));
         return response.getStatusLine().getStatusCode();
     }
-
-    // Constructs a HTTP DELETE request.
-    private HttpUriRequest constructDeleteMethodUrl(URI uri, List<TestCase.CompilationUnit.Parameter> otherParams) {
-        RequestBuilder builder = RequestBuilder.delete(uri);
-        for (TestCase.CompilationUnit.Parameter param : otherParams) {
-            builder.addParameter(param.getName(), param.getValue());
-        }
-        builder.setCharset(StandardCharsets.UTF_8);
-        return builder.build();
-    }
 }
diff --git a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
index 95b77cc..7dc42b2 100644
--- a/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
+++ b/asterixdb/asterix-app/src/test/java/org/apache/asterix/test/common/TestExecutor.java
@@ -128,6 +128,7 @@ import org.apache.commons.io.IOUtils;
 import org.apache.commons.io.output.ByteArrayOutputStream;
 import org.apache.commons.lang3.StringUtils;
 import org.apache.commons.lang3.mutable.MutableInt;
+import org.apache.http.Consts;
 import org.apache.http.HttpResponse;
 import org.apache.http.HttpStatus;
 import org.apache.http.NameValuePair;
@@ -136,6 +137,7 @@ import org.apache.http.auth.UsernamePasswordCredentials;
 import org.apache.http.client.AuthCache;
 import org.apache.http.client.CredentialsProvider;
 import org.apache.http.client.HttpClient;
+import org.apache.http.client.entity.UrlEncodedFormEntity;
 import org.apache.http.client.methods.HttpGet;
 import org.apache.http.client.methods.HttpUriRequest;
 import org.apache.http.client.methods.RequestBuilder;
@@ -152,6 +154,7 @@ import org.apache.http.impl.client.BasicCredentialsProvider;
 import org.apache.http.impl.client.CloseableHttpClient;
 import org.apache.http.impl.client.HttpClients;
 import org.apache.http.impl.client.StandardHttpRequestRetryHandler;
+import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.protocol.HttpContext;
 import org.apache.http.util.EntityUtils;
 import org.apache.hyracks.algebricks.common.utils.Pair;
@@ -172,6 +175,8 @@ import com.fasterxml.jackson.databind.ObjectWriter;
 import com.fasterxml.jackson.databind.node.ObjectNode;
 import com.fasterxml.jackson.databind.util.RawValue;
 
+import io.netty.handler.codec.http.HttpMethod;
+
 public class TestExecutor {
 
     /*
@@ -929,20 +934,6 @@ public class TestExecutor {
         return result;
     }
 
-    private HttpUriRequest constructHttpMethod(String statement, URI uri, String stmtParam, boolean postStmtAsParam,
-            List<Parameter> otherParams) {
-        String stmtParamName = (postStmtAsParam ? stmtParam : null);
-        return constructPostMethodUrl(statement, uri, stmtParamName, otherParams);
-    }
-
-    private HttpUriRequest constructGetMethod(URI endpoint, List<Parameter> params) {
-        RequestBuilder builder = RequestBuilder.get(endpoint);
-        for (Parameter param : params) {
-            builder.addParameter(param.getName(), param.getValue());
-        }
-        return builder.build();
-    }
-
     private boolean isMultipart(Parameter p) {
         return p != null && (ParameterTypeEnum.MULTIPART_TEXT == p.getType()
                 || ParameterTypeEnum.MULTIPART_BINARY == p.getType());
@@ -966,16 +957,30 @@ public class TestExecutor {
                         || p.getType() == ParameterTypeEnum.MULTIPART_TEXT)
                                 ? Optional.of(MultipartEntityBuilder.create().setMode(HttpMultipartMode.STRICT))
                                 : Optional.empty();
+        List<NameValuePair> parameters = new ArrayList<>();
         for (Parameter param : params) {
             if (isMultipart(param)) {
                 addMultipart(mPartBuilder.get(), param);
             } else {
-                builder.addParameter(param.getName(), param.getValue());
+                parameters.add(new BasicNameValuePair(param.getName(), param.getValue()));
             }
         }
         builder.setCharset(UTF_8);
         mPartBuilder.ifPresent(mpb -> builder.setEntity(mpb.build()));
-        body.ifPresent(s -> builder.setEntity(new StringEntity(s, contentType)));
+        if (body.isPresent()) {
+            builder.addParameters(parameters.toArray(new NameValuePair[0]));
+            builder.setEntity(new StringEntity(body.get(), contentType));
+        } else if (mPartBuilder.isPresent()) {
+            builder.addParameters(parameters.toArray(new NameValuePair[0]));
+            builder.setEntity(mPartBuilder.get().build());
+        } else {
+            boolean formParams = HttpUtil.ignoreQueryParameters(HttpMethod.valueOf(method));
+            if (formParams) {
+                builder.setEntity(new UrlEncodedFormEntity(parameters, Consts.UTF_8));
+            } else {
+                builder.addParameters(parameters.toArray(new NameValuePair[0]));
+            }
+        }
         return builder.build();
     }
 
@@ -994,6 +999,27 @@ public class TestExecutor {
         return method;
     }
 
+    public static HttpUriRequest constructGetMethod(URI endpoint, List<Parameter> params) {
+        RequestBuilder builder = RequestBuilder.get(endpoint);
+        for (Parameter param : params) {
+            builder.addParameter(param.getName(), param.getValue());
+        }
+        return builder.build();
+    }
+
+    public static HttpUriRequest constructDeleteMethod(URI uri, List<Parameter> params) {
+        List<NameValuePair> form = new ArrayList<>();
+        for (Parameter param : params) {
+            form.add(new BasicNameValuePair(param.getName(), param.getValue()));
+        }
+        return constructDeleteRequest(uri, form);
+    }
+
+    public static HttpUriRequest constructDeleteRequest(URI uri, List<NameValuePair> params) {
+        RequestBuilder builder = RequestBuilder.delete(uri);
+        return builder.setEntity(new UrlEncodedFormEntity(params, Consts.UTF_8)).setCharset(UTF_8).build();
+    }
+
     private HttpUriRequest constructPostMethod(URI uri, List<Parameter> params) {
         RequestBuilder builder = RequestBuilder.post(uri);
         for (Parameter param : params) {
@@ -1065,12 +1091,6 @@ public class TestExecutor {
                 TEXT_PLAIN_UTF8);
     }
 
-    public InputStream executeJSON(OutputFormat fmt, String method, URI uri, Predicate<Integer> responseCodeValidator)
-            throws Exception {
-        return executeJSON(fmt, method, uri, Collections.emptyList(), responseCodeValidator, Optional.empty(),
-                TEXT_PLAIN_UTF8);
-    }
-
     private InputStream executeJSON(OutputFormat fmt, String method, URI uri, List<Parameter> params,
             Predicate<Integer> responseCodeValidator, Optional<String> body, ContentType contentType) throws Exception {
         HttpUriRequest request = buildRequest(method, uri, fmt, params, body, contentType);
@@ -1491,25 +1511,24 @@ public class TestExecutor {
         final String mimeReqType = extractHttpRequestType(statement);
         final String saveResponseVar = getResultVariable(statement);
         ContentType contentType = mimeReqType != null ? ContentType.create(mimeReqType, UTF_8) : TEXT_PLAIN_UTF8;
-        if (!body.isPresent()) {
+        if (body.isEmpty()) {
             body = getBodyFromReference(statement, variableCtx);
         }
         final Pair<String, String> credentials = extractCredentials(statement);
         InputStream resultStream;
+        URI uri;
         if ("http".equals(extension)) {
-            if (credentials != null) {
-                resultStream = executeHttp(reqType, variablesReplaced, fmt, params, statusCodePredicate, body,
-                        contentType, credentials);
-            } else {
-                resultStream =
-                        executeHttp(reqType, variablesReplaced, fmt, params, statusCodePredicate, body, contentType);
-            }
+            uri = createEndpointURI(variablesReplaced);
         } else if ("uri".equals(extension)) {
-            resultStream = executeURI(reqType, URI.create(variablesReplaced), fmt, params, statusCodePredicate, body,
-                    contentType);
+            uri = URI.create(variablesReplaced);
         } else {
             throw new IllegalArgumentException("Unexpected format for method " + reqType + ": " + extension);
         }
+        if (credentials != null) {
+            resultStream = executeURI(reqType, uri, fmt, params, statusCodePredicate, body, contentType, credentials);
+        } else {
+            resultStream = executeURI(reqType, uri, fmt, params, statusCodePredicate, body, contentType);
+        }
         if (extracResult) {
             resultStream = ResultExtractor.extract(resultStream, UTF_8).getResult();
         } else if (extractStatus) {
@@ -1530,8 +1549,8 @@ public class TestExecutor {
                     LOGGER.info("Diagnostic output: {}", IOUtils.toString(resultStream, UTF_8));
                 } else {
                     LOGGER.info("Unexpected output: {}", IOUtils.toString(resultStream, UTF_8));
-                    Assert.fail("no result file for " + testFile.toString() + "; queryCount: " + queryCount
-                            + ", filectxs.size: " + numResultFiles);
+                    Assert.fail("no result file for " + testFile + "; queryCount: " + queryCount + ", filectxs.size: "
+                            + numResultFiles);
                 }
             } else {
                 writeOutputToFile(actualResultFile, resultStream);
@@ -1988,9 +2007,8 @@ public class TestExecutor {
     }
 
     public static Pair<String, String> extractCredentials(String statement) {
-        List<Parameter> params = new ArrayList<>();
         final Matcher m = HTTP_AUTH_PATTERN.matcher(statement);
-        while (m.find()) {
+        if (m.find()) {
             String username = m.group("username");
             String password = m.group("password");
             return new Pair<>(username, password);
@@ -2041,23 +2059,6 @@ public class TestExecutor {
         }
     }
 
-    protected InputStream executeHttp(String ctxType, String endpoint, OutputFormat fmt, List<Parameter> params,
-            Predicate<Integer> statusCodePredicate, Optional<String> body, ContentType contentType) throws Exception {
-        URI uri = createEndpointURI(endpoint);
-        return executeURI(ctxType, uri, fmt, params, statusCodePredicate, body, contentType);
-    }
-
-    private InputStream executeHttp(String ctxType, String endpoint, OutputFormat fmt, List<Parameter> params,
-            Predicate<Integer> statusCodePredicate, Optional<String> body, ContentType contentType,
-            Pair<String, String> credentials) throws Exception {
-        URI uri = createEndpointURI(endpoint);
-        return executeURI(ctxType, uri, fmt, params, statusCodePredicate, body, contentType, credentials);
-    }
-
-    private InputStream executeURI(String ctxType, URI uri, OutputFormat fmt, List<Parameter> params) throws Exception {
-        return executeJSON(fmt, ctxType.toUpperCase(), uri, params);
-    }
-
     private InputStream executeURI(String ctxType, URI uri, OutputFormat fmt, List<Parameter> params,
             Predicate<Integer> responseCodeValidator, Optional<String> body, ContentType contentType) throws Exception {
         return executeJSON(fmt, ctxType.toUpperCase(), uri, params, responseCodeValidator, body, contentType);
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServlet.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServlet.java
index 515b95c..f3e099d 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServlet.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/api/IServlet.java
@@ -23,6 +23,8 @@ import java.util.concurrent.ConcurrentMap;
 
 import org.apache.hyracks.http.server.HttpServer;
 
+import io.netty.handler.codec.http.HttpMethod;
+
 /**
  * Represents a component that handles IServlet requests
  */
@@ -62,4 +64,9 @@ public interface IServlet {
      */
     default void init() throws IOException {
     }
+
+    /**
+     * @return {@code true} if the servlet ignores query parameters.
+     */
+    boolean ignoresQueryParameters(HttpMethod method);
 }
diff --git a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
index ed567f5..ff23ac2 100644
--- a/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
+++ b/hyracks-fullstack/hyracks/hyracks-http/src/main/java/org/apache/hyracks/http/server/AbstractServlet.java
@@ -205,4 +205,8 @@ public abstract class AbstractServlet implements IServlet {
         return this.getClass().getSimpleName() + Arrays.toString(paths);
     }
 
+    @Override
+    public boolean ignoresQueryParameters(HttpMethod method) {
+        return false;
+    }
 }
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 d4f57ea..c3c7dbc 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
@@ -43,9 +43,10 @@ public class BaseRequest implements IServletRequest {
     protected final HttpScheme scheme;
     protected final InetSocketAddress localAddress;
 
-    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme) {
-        QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
-        Map<? extends CharSequence, List<String>> param = decoder.parameters();
+    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme,
+            boolean ignoreQueryParameters) {
+        Map<? extends CharSequence, List<String>> param =
+                ignoreQueryParameters ? Collections.emptyMap() : new QueryStringDecoder(request.uri()).parameters();
         InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
         InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress();
         return new BaseRequest(request, localAddress, remoteAddress, param, 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 de6ed72..fa7ef66 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
@@ -36,13 +36,16 @@ import io.netty.handler.codec.http.QueryStringDecoder;
 
 public class FormUrlEncodedRequest extends BaseRequest implements IServletRequest {
 
-    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme) {
+    public static IServletRequest create(ChannelHandlerContext ctx, FullHttpRequest request, HttpScheme scheme,
+            boolean ignoreQueryParameters) {
         Charset charset = HttpUtil.getRequestCharset(request);
         Map<String, List<String>> parameters = new LinkedHashMap<>();
         URLEncodedUtils.parse(request.content().toString(charset), charset).forEach(
                 pair -> parameters.computeIfAbsent(pair.getName(), a -> new ArrayList<>()).add(pair.getValue()));
-        new QueryStringDecoder(request.uri()).parameters()
-                .forEach((name, value) -> parameters.computeIfAbsent(name, a -> new ArrayList<>()).addAll(value));
+        if (!ignoreQueryParameters) {
+            new QueryStringDecoder(request.uri()).parameters()
+                    .forEach((name, value) -> parameters.computeIfAbsent(name, a -> new ArrayList<>()).addAll(value));
+        }
         InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
         InetSocketAddress localAddress = (InetSocketAddress) ctx.channel().localAddress();
         return new FormUrlEncodedRequest(request, localAddress, remoteAddress, parameters, scheme);
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 a7ace7a..b5adf2f 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
@@ -142,7 +142,8 @@ public class HttpServerHandler<T extends HttpServer> extends SimpleChannelInboun
         IServletRequest servletRequest;
         try {
             HttpScheme scheme = HttpUtil.getScheme(server, request);
-            servletRequest = createServletRequest(ctx, request, scheme);
+            boolean ignoreParam = servlet.ignoresQueryParameters(request.method());
+            servletRequest = createServletRequest(ctx, request, scheme, ignoreParam);
         } catch (IllegalArgumentException e) {
             LOGGER.log(Level.WARN, "Failure Decoding Request", e);
             respond(ctx, request, HttpResponseStatus.BAD_REQUEST);
@@ -171,8 +172,8 @@ public class HttpServerHandler<T extends HttpServer> extends SimpleChannelInboun
     }
 
     protected IServletRequest createServletRequest(ChannelHandlerContext ctx, FullHttpRequest request,
-            HttpScheme scheme) {
-        return HttpUtil.toServletRequest(ctx, request, scheme);
+            HttpScheme scheme, boolean ignoreQueryParameters) {
+        return HttpUtil.toServletRequest(ctx, request, scheme, ignoreQueryParameters);
     }
 
     @Override
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 1d5df5c..3bd4033 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
@@ -71,10 +71,15 @@ public class HttpUtil {
     }
 
     public static IServletRequest toServletRequest(ChannelHandlerContext ctx, FullHttpRequest request,
-            HttpScheme scheme) {
+            HttpScheme scheme, boolean ignoreQueryParameters) {
         return ContentType.APPLICATION_X_WWW_FORM_URLENCODED.equals(getContentTypeOnly(request))
-                && !HttpMethod.GET.equals(request.method()) ? FormUrlEncodedRequest.create(ctx, request, scheme)
-                        : BaseRequest.create(ctx, request, scheme);
+                && !HttpMethod.GET.equals(request.method())
+                        ? FormUrlEncodedRequest.create(ctx, request, scheme, ignoreQueryParameters)
+                        : BaseRequest.create(ctx, request, scheme, ignoreQueryParameters);
+    }
+
+    public static boolean ignoreQueryParameters(HttpMethod method) {
+        return HttpMethod.POST.equals(method) || HttpMethod.DELETE.equals(method) || HttpMethod.PUT.equals(method);
     }
 
     public static String getContentTypeOnly(IServletRequest request) {