0

I'm trying to build a HTTP Server using sockets but I came with a weird problem. Everything seems to work fine but when I use my browser to get an html file or a txt file I don't get the last character.

For example, I have a pretty standard testing .html file. This file ends exactly after </html> so the browser gets the whole file but ending with </html.

As of images, they appear to be corrupted but I supposed that it is something related to the previous problem.

The code is the following:

printWriter.println(
        this.getStatusLineFromStatusCode(statusCode) + CRLF
        + "Date: " + currentTime + CRLF
        + "Server: Definitely not Apache" + CRLF
        + ( (statusCode == 200) ?
                "Last-Modified: " + lastModified + CRLF : "" )
        + "Content-Length: " + dir.length() + CRLF
        + "Content-Type: " + fileType + CRLF + CRLF
    );

if(request.get("requestMethod").equals("GET")
        && dir.exists() && dir.isFile()) {
    FileInputStream in = null;

    try {
        System.out.println(dir.getPath());
        in = new FileInputStream(dir.getPath());
        int c;
        while((c = in.read()) != -1) {
            outputStream.write(c); // Here is the write operation
        }


    } catch(Exception e) {
        System.out.println(e);
    }  finally {
        if(in != null) {
            in.close();
        }
    }
}

printWriter.close();

I commented the part where the write happens. It's really weird because if I use a FileOutputStream to copy at the same time the file to somewhere else in my disk, the file is copied correctly.

Does anybody know why is this happening?

Flerex
  • 324
  • 2
  • 12

1 Answers1

3

The problem is, you are printing CRLF + CRLF, but also printing with println, which adds another new line. This extra new line is considered to be the part of the content, and since the content length header is predefined, the last character of the actual content is discarded.

Shortly, use print rather than println in the following part:

printWriter.println(
    this.getStatusLineFromStatusCode(statusCode) + CRLF
    + "Date: " + currentTime + CRLF
    + "Server: Definitely not Apache" + CRLF
    + ( (statusCode == 200) ?
            "Last-Modified: " + lastModified + CRLF : "" )
    + "Content-Length: " + dir.length() + CRLF
    + "Content-Type: " + fileType + CRLF + CRLF
);
ram
  • 1,099
  • 1
  • 7
  • 22
  • Wow. Nice catch! I would never see that. If I remove the last `+ CRLF` everything works but if I change `println` to `print` I get the HTML code as text and afterwards, also as text, the HTTP Request. http://i.imgur.com/aKbAyLF.png Why is this? – Flerex Feb 20 '17 at 19:24
  • After print, flush the writer. Although it is created with autoflush enabled, it may be flushing only after new lines, i.e. println calls. – ram Feb 20 '17 at 19:25
  • If you prefer to remove additional CRLF instead, you might have problems if the server is linux, since the println will ad only LF, not CRLF. So prefer to use print with double CRLF. – ram Feb 20 '17 at 19:28
  • Yes, you were right. This is all new to me. Thank you very much! – Flerex Feb 20 '17 at 19:28