use `stream.read(buffer) == 0` to get eof