0

I am doing an exercise out of a book, creating a very primitive web server in Java using nothing but a Socket. I believe I have everything working, except that when I point my browser to localhost:8080 I see the header included in the response. The response in my browser looks like this:

HTTP/1.1 200 Ok
content-type: text/plain; charset=UTF-16
content-length: 50
date: Sat, 22 Feb 2014 01:21:50 GMT
Success!! You connected.

My code to generate the response looks like this:

private static final String HTTP_VALID = "HTTP/1.1";
private static final String METHOD_GET = "GET";
private static final String ENCODING = "UTF-16";
private static final String CONTENT_TYPE = "Content-Type: text/plain; charset=" + ENCODING;
private static final String CONTENT_LENGTH = "Content-Length: ";
private static final String DATE = "Date: ";

private void issueResponse(String dir, boolean success) throws IOException
{
    try (BufferedWriter buf = new BufferedWriter
            (new OutputStreamWriter(clientSocket.getOutputStream(), ENCODING)))
    {
        String statusCode = null;
        String statusResponse = null;
        String message = null;

        if (success)
        {
            statusCode = "200";
            statusResponse = "Ok";
            message = "Success!! You connected.";
        }
        else
        {
            statusCode = "404";
            statusResponse = "Not Found";
            message = "Failure, resource not found.";
        }

        long cLength = message.getBytes(ENCODING).length;
        int l = message.length();
        String now = generateDate();

        buf.write(HTTP_VALID + " " + statusCode + " " + statusResponse);
        buf.write(System.lineSeparator());
        buf.write(CONTENT_TYPE);
        buf.write(System.lineSeparator());
        buf.write(CONTENT_LENGTH + cLength);
        buf.write(System.lineSeparator());
        buf.write(DATE + now);
        buf.write(System.lineSeparator());
        buf.write(System.lineSeparator());
        buf.write(message);
        buf.flush();
    }
}

Should I be seeing the header in the browser like that, or did I do something wrong?

Update: Here is results of telnet session, it appears there is a garbage character before the header, what can be causing this?

Steve@Steve-PC ~
$ telnet localhost 8080
Trying 127.0.0.1...
Connected to localhost.
Escape character is '^]'.
GET / HTTP/1.1

▒HTTP/1.1 200 Ok
Content-Type: text/plain; charset=UTF-16
Content-Length: 50
Date: Sat, 22 Feb 2014 01:37:56 GMT

Success!! You connected.Connection closed by foreign host.

Update - changed encoding to UTF-8 and no garbage character, what gives?

Steve M
  • 9,296
  • 11
  • 49
  • 98
  • It seems that the header was already consumed by the browser. You could try `telnet localhost 8080` and then sending `GET HTTP/1.0` followed by two carriage returns, and you will have a server response printed where you can check that. After the second newline, no more headers are allowed. – helderdarocha Feb 22 '14 at 01:28

1 Answers1

1

Your text is not being sent as a header. It is being sent after a header generated by the server. You can check that by connecting to the server through a console (you can also use any client that exposes the headers).

Headers have a mandatory newline indicating it is finished.

If it worked correctly, this should be the output if you connect to the server port through a console client (note the new line):

HTTP/1.1 200 Ok
Content-Type: text/plain; charset=UTF-16
Content-Length: 50
Date: Sat, 22 Feb 2014 01:21:50 GMT

Success!! You connected.
helderdarocha
  • 23,209
  • 4
  • 50
  • 65
  • It appears I have a garbage character before the header (see update) why might I be getting this? – Steve M Feb 22 '14 at 01:43
  • I changed the encoding to UTF-8 and it works (header consumed by browser correctly and looks good in telnet)? What gives? – Steve M Feb 22 '14 at 01:45
  • I wasn't aware that you were using UTF-16. Decoding of UTF-16 is not trivial and the rules are different than UTF-8. If you really want to use UTF-16, you should add BOM (byte-order) mark at the beginning of the encoded data. – helderdarocha Feb 22 '14 at 02:02