Search code examples
javaserverclientbufferedreader

BufferedReader is not reading body of request


I am trying to read the data from an HttpPost, but when I read the data from BufferedReader I only get the header info. Please see the code below.

Here is the server

try {
        ServerSocket server = new ServerSocket(8332);
        System.out.println("Listening for connection on port 8332 ....");
        while (true) {
            try (Socket socket = server.accept()) {
                BufferedReader buffer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                String request = "";
                String line;
                while ((line = buffer.readLine()) != null) {
                    System.out.println(line);
                    request += line;
                }

                System.out.print("port 8332 reading: " + request);

            } catch (IOException e) {
                System.out.print(e.getMessage());
            }
        }
    } catch (IOException e){
        System.out.print(e.getMessage());
    }

Here is the Client

    HttpClient client = HttpClientBuilder.create().build();
    HttpPost post = new HttpPost("http://localhost:8332");

    try {
        StringEntity params =new StringEntity("details={\"name\":\"myname\",\"age\":\"20\"} ");
        post.addHeader("content-type", "application/x-www-form-urlencoded");
        post.setEntity(params);

        client.execute(post);
    } catch (IOException e){
        System.out.println(e);
    }

When I run this program I just get the following output

Listening for connection on port 8332 ....
POST / HTTP/1.1
content-type: application/x-www-form-urlencoded
Content-Length: 37
Host: localhost:8332
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.5.6 (Java/1.8.0_131)
Accept-Encoding: gzip,deflate

Upon debugging it seems like the program is not exiting this while loop

while ((line = buffer.readLine()) != null) {
                System.out.println(line);
                request += line;
            }

But I can't figure out why. Please help I have been stuck all day.

Thanks in advance


Solution

  • But I can't figure out why.

    The only way that your server will get a null from buffer.readLine() is if the client closes its socket output stream.

    The problem is that the client side is trying to keep the connection alive ... which means that it won't close its socket output stream. That means that the server needs to respect the "content-length" header; i.e. count the number of bytes read rather than looking for an end-of-stream.

    Fundamentally, your server side is not implementing the HTTP 1.1 specification correctly.

    What to do?

    Well my advice is to not try to implement HTTP starting from sockets. Use and existing framework ... or the Apache HttpComponents library.

    But if you insist on doing it this way1, read the HTTP specification thoroughly before you start trying to implement it. And consult the spec whenever you run into problems with your implementation to check that you are doing the right thing.


    1 - Definition: Masochism - the enjoyment of an activity that appears to be painful or tedious.