def read_stream(self, stream_id, size=None):
        """
        Read data from the given stream.

        By default (`size=None`), this returns all data left in current HTTP/2
        frame. In other words, default behavior is to receive frame by frame.

        If size is given a number above zero, method will try to return as much
        bytes as possible up to the given size, block until enough bytes are
        ready or stream is remotely closed.

        If below zero, it will read until the stream is remotely closed and
        return everything at hand.

        `size=0` is a special case that does nothing but returns `b''`. The
        same result `b''` is also returned under other conditions if there is
        no more data on the stream to receive, even under `size=None` and peer
        sends an empty frame - you can use `b''` to safely identify the end of
        the given stream.

        Flow control frames will be automatically sent while reading clears the
        buffer, allowing more data to come in.

        :param stream_id: Stream to read
        :param size: Expected size to read, `-1` for all, default frame.
        :return: Bytes read or empty if there is no more to expect.
        """
        rv = []
        try:
            with (yield from self._get_stream(stream_id).rlock):
                if size is None:
                    rv.append((
                        yield from self._get_stream(stream_id).read_frame()))
                    self._flow_control(stream_id)
                elif size < 0:
                    while True:
                        rv.extend((
                            yield from self._get_stream(stream_id).read_all()))
                        self._flow_control(stream_id)
                else:
                    while size > 0:
                        bufs, count = yield from self._get_stream(
                            stream_id).read(size)
                        rv.extend(bufs)
                        size -= count
                        self._flow_control(stream_id)
        except StreamClosedError:
            pass
        except _StreamEndedException as e:
            try:
                self._flow_control(stream_id)
            except StreamClosedError:
                pass
            rv.extend(e.bufs)
        return b''.join(rv)
Read data from the given stream.

        By default (`size=None`), this returns all data left in current HTTP/2
        frame. In other words, default behavior is to receive frame by frame.

        If size is given a number above zero, method will try to return as much
        bytes as possible up to the given size, block until enough bytes are
        ready or stream is remotely closed.

        If below zero, it will read until the stream is remotely closed and
        return everything at hand.

        `size=0` is a special case that does nothing but returns `b''`. The
        same result `b''` is also returned under other conditions if there is
        no more data on the stream to receive, even under `size=None` and peer
        sends an empty frame - you can use `b''` to safely identify the end of
        the given stream.

        Flow control frames will be automatically sent while reading clears the
        buffer, allowing more data to come in.

        :param stream_id: Stream to read
        :param size: Expected size to read, `-1` for all, default frame.
        :return: Bytes read or empty if there is no more to expect.