Clay O'Neil
Clay O'Neil

Reputation: 37

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

Upvotes: 1

Views: 1310

Answers (2)

Stephen C
Stephen C

Reputation: 718866

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.

Upvotes: 3

Casey Murray
Casey Murray

Reputation: 1582

Use !=0 instead of !=null in your while loop:

while((line = buffer.readLine()).length() !=0) {

output:

port 8332 reading: POST / HTTP/1.1content-type: application/x-www-form-urlencodedContent-Length: 18Host: localhost:8332Connection: Keep-AliveUser-Agent: Apache-HttpClient/4.5.3 (Java/1.8.0_171)Accept-Encoding: gzip,deflateorg.apache.http.NoHttpResponseException: localhost:8332 failed to respond

Upvotes: -1

Related Questions