Search code examples
javahttp-proxy

How to get form data from POST request in Java


How to I extract form data from a POST request eg. $ curl -X POST -d asdf=blah http://localhost:8000/proxy/http://httpbin.org/post - and I need to extract asdf=blah.

The way I am currently doing it relies heavily on the data I have read being in a certain format (I am assuming the form data is always on the last line). Is there a better (and/or simpler) way to get the data which does not depend on the format of the data being read ?

(Note: the proxy deals with both GET and POST requests)

Here is code I have written :

public class ProxyThread3 extends Thread {
private Socket clientSocket = null;

private OutputStream clientOutputStream;


private static final int BUFFER_SIZE = 32768;

public ProxyThread3(Socket socket) {
    super("ProxyThread");
    this.clientSocket = socket;

}


public void run() {
    try {

        clientOutputStream = clientSocket.getOutputStream();

        // Read request
        InputStream clientInputStream = clientSocket.getInputStream();

        byte[] b = new byte[8196];
        int len = clientInputStream.read(b);

        String urlToCall = "";


        if (len > 0) {

            String userData = new String(b, 0, len);

            String[] userDataArray = userData.split("\n");

            //Parse first line to get URL
            String firstLine = userDataArray[0];
            for (int i = 0; i < firstLine.length(); i++) {

                if (firstLine.substring(i).startsWith("http://")) {

                    urlToCall = firstLine.substring(i).split(" ")[0];
                    break;
                }

            }


            //get request type
            String requestType = firstLine.split(" ")[0];

            String userAgentHeader = "";


            //get USER-AGENT Header and Accept Header
            for (String data : userDataArray) {

                if (data.startsWith("User-Agent")) {

                    userAgentHeader = data.split(":")[1].trim();
                    break;

                }

            }


            switch (requestType) {

                case "GET": {

                    sendGetRequest(urlToCall, userAgentHeader);
                    break;
                }

                case "POST": {


                    String postParams = null;

                    //Get Form Data
                    if (!userDataArray[userDataArray.length - 1].isEmpty()) {

                        postParams = userDataArray[userDataArray.length - 1];

                    }

                    sendPostRequest(urlToCall, userAgentHeader, postParams);
                    break;
                }


            }

        } else {
            clientInputStream.close();
        }

    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            clientSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}


private void sendPostRequest(String urlToCall, String userAgentHeader,  String postParams) throws IOException {


    URL urlToWriteAndReadFrom = new URL(urlToCall);

    HttpURLConnection httpURLConnection = (HttpURLConnection) urlToWriteAndReadFrom.openConnection();

    httpURLConnection.setRequestMethod("POST");

    // set User-Agent header
    httpURLConnection.setRequestProperty("User-Agent", userAgentHeader);


    httpURLConnection.setDoOutput(true);

    OutputStream urlOutputStream = httpURLConnection.getOutputStream();

    if (postParams != null) {
        urlOutputStream.write(postParams.getBytes());
        urlOutputStream.flush();

    }


    urlOutputStream.close();

    int responseCode = httpURLConnection.getResponseCode();


    if (responseCode == HttpURLConnection.HTTP_OK) { // success


        InputStream dataReader = httpURLConnection.getInputStream();


        //begin send response to client
        byte inputInBytes[] = new byte[BUFFER_SIZE];

        assert dataReader != null;

        int index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);

        while (index != -1) {
            clientOutputStream.write(inputInBytes, 0, index);
            index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
        }
        clientOutputStream.flush();


    }


}

private void sendGetRequest(String urlToCall, String userAgentHeader) throws IOException {


    URL urlToReadFrom = new URL(urlToCall);
    HttpURLConnection httpURLConnection = (HttpURLConnection) urlToReadFrom.openConnection();

    // set True since reading and getting input
    httpURLConnection.setDoInput(true);
    httpURLConnection.setRequestMethod("GET");

    // set User-Agent header
    httpURLConnection.setRequestProperty("User-Agent", userAgentHeader);

    int responseCode = httpURLConnection.getResponseCode();

    if (responseCode == HttpURLConnection.HTTP_OK) { // success


        InputStream dataReader = httpURLConnection.getInputStream();


        //begin send response to client
        byte inputInBytes[] = new byte[BUFFER_SIZE];

        assert dataReader != null;

        int index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);

        while (index != -1) {
            clientOutputStream.write(inputInBytes, 0, index);
            index = dataReader.read(inputInBytes, 0, BUFFER_SIZE);
        }
        clientOutputStream.flush();


    }


}

}

PS. I am new to all of this so if there are any errors in my code, please do point them out


Solution

  • Here is a full example on how to create a Java HTTP server that handles POST and GET requests.

    https://www.codeproject.com/Tips/1040097/Create-a-Simple-Web-Server-in-Java-HTTP-Server

    That being shared, this is quite primitive, I'd recommend using any third party library or light-weight Java server like Grizzly or Jetty if not a server like Apache Tomcat utilizing J2EE Servlets which are made for this purpose.