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))) => {
buf.put_slice(dat.borrow());
Poll::Ready(Ok(()))
}
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?
alice
June 25, 2021, 5:15pm
#3
Your solution is incorrect because:
If the provided buf
is shorter than the data
you get, then you are throwing away data.
If the data
chunk is empty, then you are incorrectly reporting EOF.
You can use StreamReader
to perform this conversion.
2 Likes
Had some logic at an upper level that handled case 1 and didn't get to the actual testing for case 2 . But it's always better to use standard stuff.
Thank you very much!
system
closed
September 24, 2021, 7:50am
#5
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.