Read Hyper body into buffer or transform to tokio::AsyncRead

I am trying to pass the Http body input from Hyper to another worker thread that wants to read it into an owned buffer.

To do this I pass messages on a tokio::mpsc that implement tokio::AsyncRead.

The problem is I can't seem to access the raw content in a Hyper request without making an additional copy.

Any ideas how I could do this?

Alternatively, is there is any way to directly convert the body to a tokio::AsynRead object?

After some more digging I think my initial approach was OK.

Here is the code snippet

impl AsyncRead for HttpRequest {
    fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut ReadBuf<'_>) -> Poll<std::io::Result<()>> {
        match Body::poll_data(Pin::new(&mut self.body), cx) {
            Poll::Ready(None) => Poll::Ready(Ok(())),
            Poll::Pending => Poll::Pending,
            Poll::Ready(Some(Ok(data))) => {
            Poll::Ready(Some(Err(e))) => {
                Poll::Ready(Err(std::io::Error::new(ErrorKind::Other, e)))

HttpRequest is the actual message passed on the mpsc and self.body is of type hyper::Body.

The reason why I now think this is correct is because the Data for Body in the HttpBody is of type Bytes which looks like a zero copy rc slice of the network buffer.

Is my assumption true?

Your solution is incorrect because:

  1. If the provided buf is shorter than the data you get, then you are throwing away data.
  2. If the data chunk is empty, then you are incorrectly reporting EOF.

You can use StreamReader to perform this conversion.


Had some logic at an upper level that handled case 1 and didn't get to the actual testing for case 2 :see_no_evil:. But it's always better to use standard stuff.

Thank you very much!

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.