All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.devops4j.embedded.servlet.EmbeddedHttpServletRequest Maven / Gradle / Ivy

package com.devops4j.embedded.servlet;


import com.devops4j.embedded.httpserver.Headers;
import com.devops4j.embedded.httpserver.HttpExchange;
import com.devops4j.embedded.httpserver.HttpServer;
import com.devops4j.io.buffer.ByteBuf;

import javax.servlet.*;
import javax.servlet.http.*;
import java.io.*;
import java.net.URLDecoder;
import java.security.Principal;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;

/**
 * Created by devops4j on 2018/1/20.
 */
public class EmbeddedHttpServletRequest implements HttpServletRequest {

    // ---------------------------------------------------------------------
    // ServletRequest properties
    // ---------------------------------------------------------------------

    private final Map attributes = new LinkedHashMap();

    private String characterEncoding;

    private String contentType;

    private final Map parameters = new LinkedHashMap();

    private String protocol = "http";

    private String scheme = "http";

    private String serverName = "localhost";

    private int serverPort = 80;

    private String remoteAddr = "127.0.0.1";

    private String remoteHost = "localhost";

    /**
     * List of locales in descending order
     */
    private final List locales = new LinkedList();

    private boolean secure = false;

    private int remotePort = 80;

    private String localName = "localhost";

    private String localAddr = "127.0.0.1";

    private int localPort = 80;

    private boolean asyncStarted = false;

    private boolean asyncSupported = false;

    private DispatcherType dispatcherType = DispatcherType.REQUEST;

    private String authType;

    private Cookie[] cookies;

    private final Map> headers = new ConcurrentHashMap();

    private String method;

    private String pathInfo;

    private String contextPath = "";

    private String queryString = "";

    private String remoteUser;

    private final Set userRoles = new HashSet();

    private Principal userPrincipal;

    private String requestedSessionId;

    private String requestURI;

    private String servletPath = "";

    private HttpSession session;

    private boolean requestedSessionIdValid = true;

    private boolean requestedSessionIdFromCookie = true;

    private boolean requestedSessionIdFromURL = false;

    EmbeddedServletInputStream inputStream;

    ByteBuf byteBuf;

    public EmbeddedHttpServletRequest(HttpExchange exchange) {
        this.scheme = exchange.getHttpContext().getServer() instanceof HttpServer ? "http" : "https";
        this.requestURI = exchange.getRequestURI().getRawPath();
        this.queryString = exchange.getRequestURI().getQuery();
        this.queryString = this.queryString == null ? "" : this.queryString;
        this.contextPath = exchange.getRequestURI().getPath();
        this.method = exchange.getRequestMethod();
        this.byteBuf = ByteBuf.allocate(1024).autoExpand(true);
        Headers headers_ = exchange.getRequestHeaders();
        for (String name : headers_.keySet()) {
            this.headers.put(name, new ArrayList(headers_.get(name)));
        }
        InputStream is = exchange.getRequestBody();
        try {
            byte[] data = new byte[1024];
            int byteWriteLen = 0;
            while ((byteWriteLen = is.read(data)) > 0) {
                byte[] data0 = new byte[Math.min(1024, byteWriteLen)];
                System.arraycopy(data, 0, data0, 0, byteWriteLen);
                this.byteBuf.put(data0);
            }
        } catch (IOException e) {

        }
        this.inputStream = new EmbeddedServletInputStream(this.byteBuf);
        if (this.method.equals("POST")) {
            try {
                this.queryString = URLDecoder.decode(this.byteBuf.asString("UTF-8"), "UTF-8");
            } catch (UnsupportedEncodingException e) {
                System.err.println("request chart encoding is unsupported!");
                throw new RuntimeException(e);
            }
            this.byteBuf.resetRead();
        }
        this.queryString = this.queryString == null ? "" : this.queryString;
        if (!this.queryString.isEmpty()) {
            String[] temps = this.queryString.split("&");
            for (String temp : temps) {
                String name = temp;
                String value = null;
                int idx = temp.indexOf("=");
                if (idx > -1) {
                    name = temp.substring(0, idx);
                    value = temp.substring(idx + 1);
                }
                setParameter(name, value);
            }
        }
    }


    // -------------------------s--------------------------------------------
    // Lifecycle methods
    // ---------------------------------------------------------------------

    @Override
    public ServletContext getServletContext() {
        return null;
    }

    public boolean isActive() {
        return true;
    }

    public void close() {
    }


    // ---------------------------------------------------------------------
    // ServletRequest interface
    // ---------------------------------------------------------------------

    @Override
    public Object getAttribute(String name) {
        return this.attributes.get(name);
    }

    @Override
    public Enumeration getAttributeNames() {
        return Collections.enumeration(new LinkedHashSet(this.attributes.keySet()));
    }

    @Override
    public String getCharacterEncoding() {
        return this.characterEncoding;
    }

    @Override
    public void setCharacterEncoding(String characterEncoding) {
        this.characterEncoding = characterEncoding;
    }

    @Override
    public int getContentLength() {
        return inputStream.getByteBuf().capacity();
    }

    public long getContentLengthLong() {
        return getContentLength();
    }

    public void setContentType(String contentType) {
        this.contentType = contentType;
    }

    @Override
    public String getContentType() {
        return this.contentType;
    }

    @Override
    public ServletInputStream getInputStream() {
        return this.inputStream;
    }

    public void setParameter(String name, String value) {
        setParameter(name, new String[]{value});
    }

    public void setParameter(String name, String... values) {
        this.parameters.put(name, values);
    }

    public void setParameters(Map params) {
        for (String key : params.keySet()) {
            Object value = params.get(key);
            if (value instanceof String) {
                setParameter(key, (String) value);
            } else if (value instanceof String[]) {
                setParameter(key, (String[]) value);
            } else {
                throw new IllegalArgumentException(
                        "Parameter map value must be single value " + " or array of type [" + String.class.getName() + "]");
            }
        }
    }

    public void addParameter(String name, String value) {
        addParameter(name, new String[]{value});
    }

    public void addParameter(String name, String... values) {
        String[] oldArr = this.parameters.get(name);
        if (oldArr != null) {
            String[] newArr = new String[oldArr.length + values.length];
            System.arraycopy(oldArr, 0, newArr, 0, oldArr.length);
            System.arraycopy(values, 0, newArr, oldArr.length, values.length);
            this.parameters.put(name, newArr);
        } else {
            this.parameters.put(name, values);
        }
    }

    public void addParameters(Map params) {
        for (String key : params.keySet()) {
            Object value = params.get(key);
            if (value instanceof String) {
                addParameter(key, (String) value);
            } else if (value instanceof String[]) {
                addParameter(key, (String[]) value);
            } else {
                throw new IllegalArgumentException("Parameter map value must be single value " +
                        " or array of type [" + String.class.getName() + "]");
            }
        }
    }


    public void removeParameter(String name) {
        this.parameters.remove(name);
    }

    public void removeAllParameters() {
        this.parameters.clear();
    }

    @Override
    public String getParameter(String name) {
        String[] arr = (name != null ? this.parameters.get(name) : null);
        return (arr != null && arr.length > 0 ? arr[0] : null);
    }

    @Override
    public Enumeration getParameterNames() {
        return Collections.enumeration(this.parameters.keySet());
    }

    @Override
    public String[] getParameterValues(String name) {
        return (name != null ? this.parameters.get(name) : null);
    }

    @Override
    public Map getParameterMap() {
        return Collections.unmodifiableMap(this.parameters);
    }

    public void setProtocol(String protocol) {
        this.protocol = protocol;
    }

    @Override
    public String getProtocol() {
        return this.protocol;
    }

    public void setScheme(String scheme) {
        this.scheme = scheme;
    }

    @Override
    public String getScheme() {
        return this.scheme;
    }

    public void setServerName(String serverName) {
        this.serverName = serverName;
    }

    @Override
    public String getServerName() {
        String host = getHeader("Host");
        if (host != null) {
            host = host.trim();
            if (host.startsWith("[")) {
                host = host.substring(1, host.indexOf(']'));
            } else if (host.contains(":")) {
                host = host.substring(0, host.indexOf(':'));
            }
            return host;
        }

        // else
        return this.serverName;
    }

    @Override
    public int getServerPort() {
        String host = getHeader("Host");
        if (host != null) {
            host = host.trim();
            int idx;
            if (host.startsWith("[")) {
                idx = host.indexOf(':', host.indexOf(']'));
            } else {
                idx = host.indexOf(':');
            }
            if (idx != -1) {
                return Integer.parseInt(host.substring(idx + 1));
            }
        }

        // else
        return this.serverPort;
    }

    @Override
    public BufferedReader getReader() throws UnsupportedEncodingException {
        InputStream sourceStream = new ByteArrayInputStream(this.inputStream.getByteBuf().getBytes(this.inputStream.getByteBuf().readableLength()));
        Reader sourceReader = (this.characterEncoding != null) ?
                new InputStreamReader(sourceStream, this.characterEncoding) :
                new InputStreamReader(sourceStream);
        return new BufferedReader(sourceReader);
    }

    public void setRemoteAddr(String remoteAddr) {
        this.remoteAddr = remoteAddr;
    }

    @Override
    public String getRemoteAddr() {
        return this.remoteAddr;
    }

    public void setRemoteHost(String remoteHost) {
        this.remoteHost = remoteHost;
    }

    @Override
    public String getRemoteHost() {
        return this.remoteHost;
    }

    @Override
    public void setAttribute(String name, Object value) {
        if (value != null) {
            this.attributes.put(name, value);
        } else {
            this.attributes.remove(name);
        }
    }

    @Override
    public void removeAttribute(String name) {
        this.attributes.remove(name);
    }

    public void clearAttributes() {
        this.attributes.clear();
    }

    public void addPreferredLocale(Locale locale) {
        this.locales.add(0, locale);
    }


    public void setPreferredLocales(List locales) {
        this.locales.clear();
        this.locales.addAll(locales);
    }

    @Override
    public Locale getLocale() {
        return this.locales.get(0);
    }

    @Override
    public Enumeration getLocales() {
        return Collections.enumeration(this.locales);
    }

    public void setSecure(boolean secure) {
        this.secure = secure;
    }

    @Override
    public boolean isSecure() {
        return (this.secure || "https".equalsIgnoreCase(this.scheme));
    }

    @Override
    public RequestDispatcher getRequestDispatcher(String path) {
        return null;
    }

    @Override
    @Deprecated
    public String getRealPath(String path) {
        return requestURI;
    }

    public void setRemotePort(int remotePort) {
        this.remotePort = remotePort;
    }

    @Override
    public int getRemotePort() {
        return this.remotePort;
    }

    public void setLocalName(String localName) {
        this.localName = localName;
    }

    @Override
    public String getLocalName() {
        return this.localName;
    }

    public void setLocalAddr(String localAddr) {
        this.localAddr = localAddr;
    }

    @Override
    public String getLocalAddr() {
        return this.localAddr;
    }

    public void setLocalPort(int localPort) {
        this.localPort = localPort;
    }

    @Override
    public int getLocalPort() {
        return this.localPort;
    }

    @Override
    public AsyncContext startAsync() {
        return startAsync(this, null);
    }

    @Override
    public AsyncContext startAsync(ServletRequest request, ServletResponse response) {
        if (!this.asyncSupported) {
            throw new IllegalStateException("Async not supported");
        }
        this.asyncStarted = true;
        return null;
    }

    public void setAsyncStarted(boolean asyncStarted) {
        this.asyncStarted = asyncStarted;
    }

    @Override
    public boolean isAsyncStarted() {
        return this.asyncStarted;
    }

    public void setAsyncSupported(boolean asyncSupported) {
        this.asyncSupported = asyncSupported;
    }

    @Override
    public boolean isAsyncSupported() {
        return this.asyncSupported;
    }

    @Override
    public AsyncContext getAsyncContext() {
        return null;
    }

    public void setDispatcherType(DispatcherType dispatcherType) {
        this.dispatcherType = dispatcherType;
    }

    @Override
    public DispatcherType getDispatcherType() {
        return this.dispatcherType;
    }


    // ---------------------------------------------------------------------
    // HttpServletRequest interface
    // ---------------------------------------------------------------------

    public void setAuthType(String authType) {
        this.authType = authType;
    }

    @Override
    public int hashCode() {
        return super.hashCode();
    }

    @Override
    public String getAuthType() {
        return this.authType;
    }

    @Override
    public Cookie[] getCookies() {
        return this.cookies;
    }

    public void addHeader(String name, Object value) {
        if ("Content-Type".equalsIgnoreCase(name) && !this.headers.containsKey("Content-Type")) {
            setContentType(value.toString());
        } else {
            doAddHeaderValue(name, value);
        }
    }

    private void doAddHeaderValue(String name, Object value) {
        List header0 = this.headers.get(name);
        if (header0 == null) {
            header0 = new ArrayList();
            this.headers.put(name, header0);
        }
        header0.add(value.toString());
    }

    @Override
    public long getDateHeader(String name) {
        return -1L;
    }

    @Override
    public String getHeader(String name) {
        List header_ = this.headers.get(name);
        if (header_ != null && !header_.isEmpty()) {
            return header_.get(0) == null ? null : header_.get(0).toString();
        } else {
            return null;
        }
    }

    @Override
    public Enumeration getHeaders(String name) {
        List header_ = this.headers.get(name);
        List header_1 = new ArrayList();
        for (Object value : header_) {
            header_1.add(value == null ? null : value.toString());
        }
        return Collections.enumeration(header_1);
    }

    @Override
    public Enumeration getHeaderNames() {
        return Collections.enumeration(this.headers.keySet());
    }

    @Override
    public int getIntHeader(String name) {
        String value = getHeader(name);
        try {
            return Integer.parseInt(value);
        } catch (Exception e) {
            return -1;
        }
    }

    public void setMethod(String method) {
        this.method = method;
    }

    @Override
    public String getMethod() {
        return this.method;
    }

    public void setPathInfo(String pathInfo) {
        this.pathInfo = pathInfo;
    }

    @Override
    public String getPathInfo() {
        return this.pathInfo;
    }

    @Override
    public String getPathTranslated() {
        return (this.pathInfo != null ? getRealPath(this.pathInfo) : null);
    }

    @Override
    public String getContextPath() {
        return this.contextPath;
    }

    public void setQueryString(String queryString) {
        this.queryString = queryString;
    }

    @Override
    public String getQueryString() {
        return this.queryString;
    }

    public void setRemoteUser(String remoteUser) {
        this.remoteUser = remoteUser;
    }

    @Override
    public String getRemoteUser() {
        return this.remoteUser;
    }

    public void addUserRole(String role) {
        this.userRoles.add(role);
    }

    @Override
    public boolean isUserInRole(String role) {
        return false;
    }

    public void setUserPrincipal(Principal userPrincipal) {
        this.userPrincipal = userPrincipal;
    }

    @Override
    public Principal getUserPrincipal() {
        return this.userPrincipal;
    }

    public void setRequestedSessionId(String requestedSessionId) {
        this.requestedSessionId = requestedSessionId;
    }

    @Override
    public String getRequestedSessionId() {
        return this.requestedSessionId;
    }

    public void setRequestURI(String requestURI) {
        this.requestURI = requestURI;
    }

    @Override
    public String getRequestURI() {
        return this.requestURI;
    }

    @Override
    public StringBuffer getRequestURL() {
        StringBuffer url = new StringBuffer(this.scheme).append("://").append(this.serverName);
        if (this.serverPort > 0 && (("http".equalsIgnoreCase(this.scheme) && this.serverPort != 80) ||
                ("https".equalsIgnoreCase(this.scheme) && this.serverPort != 443))) {
            url.append(':').append(this.serverPort);
        }
        String uri = getRequestURI();
        if (uri != null && !uri.isEmpty()) {
            url.append(getRequestURI());
        }
        return url;
    }

    public void setServletPath(String servletPath) {
        this.servletPath = servletPath;
    }

    @Override
    public String getServletPath() {
        return this.servletPath;
    }

    public void setSession(HttpSession session) {
        this.session = session;
    }

    @Override
    public HttpSession getSession(boolean create) {
        return this.session;
    }

    @Override
    public HttpSession getSession() {
        return getSession(true);
    }

    public String changeSessionId() {
        return this.session.getId();
    }

    public void setRequestedSessionIdValid(boolean requestedSessionIdValid) {
        this.requestedSessionIdValid = requestedSessionIdValid;
    }

    @Override
    public boolean isRequestedSessionIdValid() {
        return this.requestedSessionIdValid;
    }

    public void setRequestedSessionIdFromCookie(boolean requestedSessionIdFromCookie) {
        this.requestedSessionIdFromCookie = requestedSessionIdFromCookie;
    }

    @Override
    public boolean isRequestedSessionIdFromCookie() {
        return this.requestedSessionIdFromCookie;
    }

    public void setRequestedSessionIdFromURL(boolean requestedSessionIdFromURL) {
        this.requestedSessionIdFromURL = requestedSessionIdFromURL;
    }

    @Override
    public boolean isRequestedSessionIdFromURL() {
        return this.requestedSessionIdFromURL;
    }

    @Override
    @Deprecated
    public boolean isRequestedSessionIdFromUrl() {
        return isRequestedSessionIdFromURL();
    }

    @Override
    public boolean authenticate(HttpServletResponse response) throws IOException, ServletException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void login(String username, String password) throws ServletException {
        throw new UnsupportedOperationException();
    }

    @Override
    public void logout() throws ServletException {
        this.userPrincipal = null;
        this.remoteUser = null;
        this.authType = null;
    }


    @Override
    public Part getPart(String name) throws IOException, IllegalStateException, ServletException {
        return null;
    }

    @Override
    public  T upgrade(Class handlerClass) throws IOException, ServletException {
        return null;
    }

    @Override
    public Collection getParts() throws IOException, IllegalStateException, ServletException {
        List result = new LinkedList();
        return result;
    }

}