Flerex
Flerex

Reputation: 354

HTTP Server not sending the last character in an Output Stream

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?

Upvotes: 0

Views: 144

Answers (1)

ram
ram

Reputation: 1169

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
);

Upvotes: 3

Related Questions