Read complete HTTP request-header

2019-09-20 05:48发布

问题:

I'm currently creating a little webserver (for testing purposes) and I have a problem reading the HTTP request-header (coming from the browser, chromium in my case).

First, I simply tried something like this:

BufferedReader in = new BufferedReader(
  new InputStreamReader(client_socket.getInputStream(), "UTF-8")
);
StringBuilder builder = new StringBuilder();
while (in.ready()){
    builder.append(in.readLine());
}
return builder.toString();

This worked fine for the first request. However, after the first request was done, the ready()-method only returned false (i closed the client_socket as well as all readers/writers).

After a little searching I stumbled across this older question: Read/convert an InputStream to a String

I tried the first four solutions (two with Apache Commons, the one with the Scanner and the one with the do-while loop). All of them blocked for ever and the browser gave me a "Website not reachable"-error.

I'd like to do this on my own (without using any library's or embedded servers), that's why I even try.

I'm a little lost right now, how would you go about this?

回答1:

You are reading from the socket until there is no more data to read. That is wrong. You need to keep reading until you encounter a 0-length line, then process the received headers to determine if there is more data to read (look for Content-Length: ... and Transfer-Encoding: chunked headers), eg:

StringBuilder builder = new StringBuilder(); 
String line;
do
{
    line = in.readLine(); 
    if (line == "") break;
    builder.append(line);
}
while (true);
// use builder as needed...
// read message body data if headers say there
// is a body to read, per RFC 2616 Section 4.4...

Read RFC 2616 Section 4 for more details. Not only does this facilitate proper request reading, but doing so also allows you to support HTTP keep-alives correctly (for sending multiple requests on a single connection).



回答2:

The solution suggested above by Remy Lebeau is wrong, as it was shown in a test of mine. This alternative is fail-safe:

StringBuilder builder = new StringBuilder(); 
String line;
do
{
    line = in.readLine(); 
    if (line.equals("")) break;
    builder.append(line);
}
while (true);

Refer to: How do I compare strings in Java?