hyperium / h2

HTTP 2.0 client & server implementation for Rust.
MIT License
1.34k stars 266 forks source link

Unable to send response. #681

Closed nurmohammed840 closed 1 year ago

nurmohammed840 commented 1 year ago

I am trying to send large payload (409600+ bytes)

For some reason I was unable to send payload, I think there is something wrong with h2 crate ?

Here is my code:

pub struct Sender {
    pub inner: h2::SendStream<Bytes>,
}

impl Sender {
    #[inline]
    pub async fn write(&mut self, data: impl Into<Bytes>) -> Result<()> {
        let mut bytes: Bytes = data.into();
        while !bytes.is_empty() {
            let len = bytes.len();
            self.inner.reserve_capacity(len);
            match poll_fn(|cx| self.inner.poll_capacity(cx)).await {
                None => return Err(h2::Error::from(h2::Reason::CANCEL)),
                Some(nbytes) => {
                    let data = bytes.split_to(nbytes?.min(len));
                    self.inner.send_data(data, false)?;
                }
            }
        }
        Ok(())
    }

    #[inline]
    pub fn end(mut self) -> Result<()> {
        self.inner.send_data(Bytes::new(), true)
    }
}

Here is the full example

On first iteration poll_capacity return Ready(Ok(409600)), But poll_capacity doesn't resolve on second iteration,

Using wireshark, I notice that server didn't response with any application data at all...

seanmonstar commented 1 year ago

You need to be polling the connection actively. That is what sends the actual frames.

If you use hyper, it will help take care of these things for you.

nurmohammed840 commented 1 year ago

I think doc should include this information.

Thanks!

seanmonstar commented 1 year ago

The docs do mention it:

The Connection instance is used to manage connection state. The caller is required to call either Connection::accept or Connection::poll_close in order to advance the connection state. Simply operating on SendStream or RecvStream will have no effect unless the connection state is advanced.