Note that this function will potentially block after each read operation to
see if the end has already been reached - this may take as long until either
new data has arrived or until the connection was closed.
The stream will also guarantee that the inner stream is not used after it
has been determined to be empty. It can thus be safely deleted once the
callback is invoked.