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

xpressj.server.RequestImpl Maven / Gradle / Ivy

/*
 * Copyright 2014 - Alexey Kamenskiy
 *
 * Licensed 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 xpressj.server;

import java.io.*;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by akamensky on 8/2/14.
 */
public class RequestImpl implements Request {

    private String method;
    private String URI;
    private String protocol;
    private Map headers;
    private Map cookies;
    private Map queryParams;

    private boolean hasBody;
    private boolean isMultipart;

    private String requestString;
    private byte[] requestBytes;

    private ResponseImpl response;

    public RequestImpl(InputStream in) {
        this.headers = new HashMap<>();
        this.cookies = new HashMap<>();
        this.queryParams = new HashMap<>();

        //Read and parse request
        ByteArrayOutputStream buffer = new ByteArrayOutputStream();
        BufferedReader reader = new BufferedReader(new InputStreamReader(in));

        //parse headers
        //unconditional as headers must be present
        this.parseHeaders(reader, buffer);

        //parse body
        //conditional depending on appropriate headers
        if (this.hasBody && !this.isMultipart) {
            this.parseBody(reader, buffer);
        } else if (this.hasBody && this.isMultipart){
            this.parseMultipart(reader, buffer);
        }

        //Write raw presentation of request as bytes
        //and request content as string
        //TODO:don't need content request as string I guess
        try {
            buffer.flush();
        } catch (Exception e) {
            e.printStackTrace();
        }
        this.requestBytes = buffer.toByteArray();
        this.requestString = new String(this.requestBytes);
    }

    public void setResponse(ResponseImpl response) {
        this.response = response;
        response.send(this.requestString);
    }

    private void parseHeaders(BufferedReader reader, ByteArrayOutputStream buffer){
        String inputLine;
        try {
            while ((inputLine = reader.readLine()) != null) {
                buffer.write((inputLine+"\r\n").getBytes());
                if (this.method == null) {
                    inputLine = inputLine.trim();
                    String[] parts = inputLine.split(" ");
                    if (parts.length < 3) {
                        throw new RuntimeException("Malformed request");
                    } else {
                        this.method = parts[0].toUpperCase();
                        this.URI = parts[1];
                        this.protocol = parts[2];
                    }
                } else if (!inputLine.isEmpty()) {
                    String[] parts = inputLine.split(": ");
                    this.headers.put(parts[0], parts[1]);
                    //Parse cookies
                    if (parts[0].equals("Cookie")) {
                        this.parseCookie(parts[1]);
                    }
                } else {
                    //detect request body
                    if (this.headers.containsKey("Content-Length") && Integer.parseInt(this.headers.get("Content-Length")) > 0) {
                        this.hasBody = true;
                    }
                    //detect if request is multipart
                    if (this.headers.containsKey("Content-Type") && this.headers.get("Content-Type").startsWith("multipart/form-data") && this.headers.get("Content-Type").contains("boundary=")) {
                        this.isMultipart = true;
                    }
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private void parseBody(BufferedReader reader, ByteArrayOutputStream buffer) {
        //read body
        String body = "";
        try {
            char[] cbuf = new char[Integer.parseInt(this.headers.get("Content-Length"))];
            reader.read(cbuf, 0, Integer.parseInt(this.headers.get("Content-Length")));
            body = new String(cbuf);
            buffer.write(body.getBytes());
        } catch (Exception e) {
            e.printStackTrace();
        }
        //parse body
        if (body.length() > 0) {
            //get pairs name=value
            String[] pairs = body.split("&");
            for (String pair : pairs) {
                String[] vals = pair.split("=");
                //Body is malformed
                if (vals.length != 2) {
                    throw new RuntimeException("malformed request");
                }
                try {
                    this.addQueryParam(vals[0], URLDecoder.decode(vals[1], "UTF-8"));
                } catch (UnsupportedEncodingException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    private void parseMultipart(BufferedReader reader, ByteArrayOutputStream buffer){
        //TODO: handle malformed requests!!!
        //find boundary
        String boundary = this.headers.get("Content-Type").substring(this.headers.get("Content-Type").indexOf("boundary=") + "boundary=".length());

        //start parsing
        String inputLine;
        ArrayList multiparts = new ArrayList<>();
        Multipart multipart = new Multipart();
        try {
            while ((inputLine = reader.readLine()) != null) {
                buffer.write((inputLine + "\r\n").getBytes());
                if (inputLine.equals("--"+boundary)) {
                    //new part started
                    if (!multipart.lines.isEmpty()) {
                        multiparts.add(multipart);
                    }
                    multipart = new Multipart();
                } else if (inputLine.equals("--"+boundary+"--")) {
                    //all of them ended
                    if (!multipart.lines.isEmpty()) {
                        multiparts.add(multipart);
                    }
                    break;
                } else {
                    //Add line to multipart object
                    multipart.lines.add(inputLine);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        //parse parts
        //TODO: parse parts
    }

    private void parseCookie(String cookieString) {
        //TODO:implement parsing cookies
    }

    private void addQueryParam(String name, String value) {
        if (this.queryParams.containsKey(name) && this.queryParams.get(name) instanceof String) {
            String[] arr = new String[2];
            arr[0] = (String)this.queryParams.get(name);
            arr[1] = value;
            this.queryParams.put(name, arr);
        } else if (this.queryParams.containsKey(name) && this.queryParams.get(name) instanceof String[]) {
            String[] old_arr = (String[])this.queryParams.get(name);
            String[] arr = new String[old_arr.length + 1];
            for (int i = 0; i < old_arr.length; i++) {
                arr[i] = old_arr[i];
            }
            arr[arr.length - 1] = value;
            this.queryParams.put(name, arr);
        } else {
            this.queryParams.put(name, value);
        }
    }

    public String getUri() {
        return null;
    }

    public String getHttpMethod() {
        return null;
    }

    public void addParam(String key, String value) {

    }

    public HashMap getParams() {
        return null;
    }

    public String getParam(String key) {
        return null;
    }

    public void clearParams() {

    }

    public int getParamsCount() {
        return 0;
    }

    public int getQueryParamsCount() {
        return 0;
    }

    public String[] getQueryParam(String key) {
        return new String[0];
    }

    public Map getQueryParams() {
        return null;
    }

    public String[] getQueryParamsNames() {
        return new String[0];
    }

    public Map getCookies() {
        return null;
    }

    public Cookie getCookie(String name) {
        return null;
    }

    public String getHeader(String name) {
        return null;
    }

    public Collection getHeaderNames() {
        return null;
    }

    public Map getHeaders() {
        return null;
    }

    public File getFile(String name) {
        return null;
    }

    public Map getFiles() {
        return null;
    }

    public Session getSession() {
        return null;
    }

    public void renewSession() {

    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy