// Path: commons/src/main/java/org/nesty/commons/constant/http/HttpConstants.java
// public class HttpConstants {
// 
//     public static final String HEADER_X_FORWARDED_FOR = "X-Forwarded-For";
//     public static final String HEADER_CONTENT_LENGTH = "Content-Length";
//     public static final String HEADER_CONTENT_TYPE = "Content-Type";
//     public static final String HEADER_CONNECTION = "Connection";
// 
//     public static final String HEADER_SERVER = "Server";
//     public static final String HEADER_REQUEST_ID = "Request-Id";
//     public static final String HEADER_CONNECTION_KEEPALIVE = "keep-alive";
//     public static final String HEADER_CONNECTION_CLOSE = "close";
//     public static final String HEADER_CONTENT_TYPE_TEXT = "application/text";
//     public static final String HEADER_CONTENT_TYPE_JSON = "application/json";
// }
// 
// Path: commons/src/main/java/org/nesty/commons/constant/http/RequestMethod.java
// public enum RequestMethod {
//     GET, POST, PUT, DELETE, UNKOWN
// }
// 
// Path: core/src/main/java/org/nesty/core/server/utils/HttpUtils.java
// public class HttpUtils {
// 
//     public static RequestMethod convertHttpMethodFromNetty(FullHttpRequest request) {
//         try {
//             return RequestMethod.valueOf(request.getMethod().name().toUpperCase());
//         } catch (IllegalArgumentException | NullPointerException e) {
//             return RequestMethod.UNKOWN;
//         }
//     }
// 
//     public static String truncateUrl(String url) {
//         if (url.contains("?"))
//             url = url.substring(0, url.indexOf("?"));
//         return url;
//     }
// }


import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.util.CharsetUtil;
import org.nesty.commons.constant.http.HttpConstants;
import org.nesty.commons.constant.http.RequestMethod;
import org.nesty.core.server.utils.HttpUtils;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
        QueryStringDecoder decoder = new QueryStringDecoder(request.getUri(), Charset.forName("UTF-8"));
        for (Map.Entry<String, List<String>> item : decoder.parameters().entrySet())
            params.put(item.getKey(), item.getValue().get(0));

        // query string and body
        if (visitHttpMethod() != RequestMethod.GET) {
            // from content body key-value
            QueryStringDecoder kvDecoder = new QueryStringDecoder(visitHttpBody(), Charset.forName("UTF-8"), false);
            for (Map.Entry<String, List<String>> item : kvDecoder.parameters().entrySet())
                params.put(item.getKey(), item.getValue().get(0));
        }

        return params;
    }

    @Override
    public Map<String, String> visitHttpHeaders() {
        Map<String, String> headers = new HashMap<>(32);
        for (Map.Entry<String, String> entry : request.headers())
            headers.put(entry.getKey(), entry.getValue());
        return headers;
    }

    @Override
    public String visitURI() {
        return request.getUri();
    }

    @Override
    public String[] visitTerms() {
// Path: commons/src/main/java/org/nesty/commons/constant/http/HttpConstants.java
// public class HttpConstants {
// 
//     public static final String HEADER_X_FORWARDED_FOR = "X-Forwarded-For";
//     public static final String HEADER_CONTENT_LENGTH = "Content-Length";
//     public static final String HEADER_CONTENT_TYPE = "Content-Type";
//     public static final String HEADER_CONNECTION = "Connection";
// 
//     public static final String HEADER_SERVER = "Server";
//     public static final String HEADER_REQUEST_ID = "Request-Id";
//     public static final String HEADER_CONNECTION_KEEPALIVE = "keep-alive";
//     public static final String HEADER_CONNECTION_CLOSE = "close";
//     public static final String HEADER_CONTENT_TYPE_TEXT = "application/text";
//     public static final String HEADER_CONTENT_TYPE_JSON = "application/json";
// }
// 
// Path: commons/src/main/java/org/nesty/commons/constant/http/RequestMethod.java
// public enum RequestMethod {
//     GET, POST, PUT, DELETE, UNKOWN
// }
// 
// Path: core/src/main/java/org/nesty/core/server/utils/HttpUtils.java
// public class HttpUtils {
// 
//     public static RequestMethod convertHttpMethodFromNetty(FullHttpRequest request) {
//         try {
//             return RequestMethod.valueOf(request.getMethod().name().toUpperCase());
//         } catch (IllegalArgumentException | NullPointerException e) {
//             return RequestMethod.UNKOWN;
//         }
//     }
// 
//     public static String truncateUrl(String url) {
//         if (url.contains("?"))
//             url = url.substring(0, url.indexOf("?"));
//         return url;
//     }
// }


// Path: core/src/main/java/org/nesty/core/server/rest/request/NettyHttpRequestVisitor.java
import com.google.common.base.Splitter;
import com.google.common.collect.FluentIterable;
import io.netty.channel.Channel;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpVersion;
import io.netty.handler.codec.http.QueryStringDecoder;
import io.netty.util.CharsetUtil;
import org.nesty.commons.constant.http.HttpConstants;
import org.nesty.commons.constant.http.RequestMethod;
import org.nesty.core.server.utils.HttpUtils;
import java.net.InetSocketAddress;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

        QueryStringDecoder decoder = new QueryStringDecoder(request.getUri(), Charset.forName("UTF-8"));
        for (Map.Entry<String, List<String>> item : decoder.parameters().entrySet())
            params.put(item.getKey(), item.getValue().get(0));

        // query string and body
        if (visitHttpMethod() != RequestMethod.GET) {
            // from content body key-value
            QueryStringDecoder kvDecoder = new QueryStringDecoder(visitHttpBody(), Charset.forName("UTF-8"), false);
            for (Map.Entry<String, List<String>> item : kvDecoder.parameters().entrySet())
                params.put(item.getKey(), item.getValue().get(0));
        }

        return params;
    }

    @Override
    public Map<String, String> visitHttpHeaders() {
        Map<String, String> headers = new HashMap<>(32);
        for (Map.Entry<String, String> entry : request.headers())
            headers.put(entry.getKey(), entry.getValue());
        return headers;
    }

    @Override
    public String visitURI() {
        return request.getUri();
    }

    @Override
    public String[] visitTerms() {
        String termsUrl = HttpUtils.truncateUrl(request.getUri());