node.jshttpstreamcontent-lengthtransfer-encoding

[http]How to identify end of stream when content-length is not specified?


First let me show my code.

http=require("http");
fs=require("fs");
var server=http.createServer(function(req,res){
    var readStream=fs.createReadStream("1.jpg");
    readStream.on("data",function(data){
        res.write(data);
    });
    readStream.on("end",function(data){
        res.write("this string seems not to be sent","utf8");
        res.end("end","utf8");
    });
});

server.listen(3000);

I created a readStream of picture 1.jpg and then sent data stream. After the "end" event was fired, I sent a string "this string seems not to be sent". I didn't specify a content-length in headers.

On the client side, I actually got 1.jpg correctly. But I didn't receive the string. I guess there must be something that marks the end of stream. If so, what the mark is? how it works?

I know that assigning transfer-encoding with "chunked" is a way to send data whose length is uncertain, but my safari shows the response headers are:

Connection keep-alive
Transfer-Encoding Identity


Solution

  • On the client side, I actually got 1.jpg correctly. But I didn't receive the string.

    In fact, the string is sent. To confirm this:

    $ echo '(Contents of a JPEG file.)' >1.jpg
    
    $ curl -i http://localhost:3000/
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2015 08:01:48 GMT
    Connection: keep-alive
    Transfer-Encoding: chunked
    
    (Contents of a JPEG file.)
    this string seems not to be sentend
    

    Your browser (or image viewer) understands the format of a JPEG, so it ignores the extra string at the end. However, it is sent.

    I guess there must be something that marks the end of stream.

    Yes. The data is delimited by chunked transfer encoding markers. curl doesn't show them by default, but they're present. To see them in the response:

    $ curl -i --raw http://localhost:3000/
    HTTP/1.1 200 OK
    Date: Sat, 23 May 2015 08:23:02 GMT
    Connection: keep-alive
    Transfer-Encoding: chunked
    
    1b
    (Contents of a JPEG file.)
    
    20
    this string seems not to be sent
    3
    end
    0