Repository: actix/actix-web
File: actix-http/src/h1/dispatcher.rs (Rust)

Code before:
        match actix_codec::poll_read_buf(Pin::new(io), cx, buf) {
            Poll::Pending => {
                return if read_some { Ok(Some(false)) } else { Ok(None) };
            }
            Poll::Ready(Ok(n)) => {
                if n == 0 {
                    return Ok(Some(true));
                } else {
                    // If buf is full return but do not disconnect since
                    // there is more reading to be done
                    if buf.len() >= HW_BUFFER_SIZE {
                        return Ok(Some(false));
                    }

                    read_some = true;
                }
            }
            Poll::Ready(Err(err)) => {
                return if err.kind() == io::ErrorKind::WouldBlock {
                    if read_some {
                        Ok(Some(false))
                    } else {
                        Ok(None)
                    }
                } else if err.kind() == io::ErrorKind::ConnectionReset && read_some {
                    Ok(Some(true))
                } else {
                    Err(err)
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::str;

    use actix_service::fn_service;
    use futures_util::future::{lazy, ready};

    use super::*;
    use crate::test::TestBuffer;
    use crate::{error::Error, KeepAlive};
    use crate::{
        h1::{ExpectHandler, UpgradeHandler},
        test::TestSeqBuffer,
    };

    fn find_slice(haystack: &[u8], needle: &[u8], from: usize) -> Option<usize> {
        haystack[from..]

Review comment (suggestion):
Shouldn't this return/signal an `Error` instead?  This should ideally somehow turn into a "413 Entity Too Large error" sent to remote.

Code after:
{
    let mut read_some = false;

    loop {
        // reserve capacity for buffer
        let remaining = buf.capacity() - buf.len();
        if remaining < LW_BUFFER_SIZE {
            buf.reserve(HW_BUFFER_SIZE - remaining);
        }

        match actix_codec::poll_read_buf(Pin::new(io), cx, buf) {
            Poll::Pending => {
                return if read_some { Ok(Some(false)) } else { Ok(None) };
            }
            Poll::Ready(Ok(n)) => {
                if n == 0 {
                    return Ok(Some(true));
                } else {
                    // If buf is full return but do not disconnect since
                    // there is more reading to be done
                    if buf.len() >= super::decoder::MAX_BUFFER_SIZE {
                        // at this point it's not known io is still scheduled to
                        // be waked up. so force wake up dispatcher just in case.
                        // TODO: figure out the overhead.
                        cx.waker().wake_by_ref();
                        return Ok(Some(false));
                    }

                    read_some = true;
                }
            }
            Poll::Ready(Err(err)) => {
                return if err.kind() == io::ErrorKind::WouldBlock {
                    if read_some {
                        Ok(Some(false))
                    } else {
                        Ok(None)
                    }
                } else if err.kind() == io::ErrorKind::ConnectionReset && read_some {
                    Ok(Some(true))
                } else {
                    Err(err)
                }
            }
        }
    }
}

#[cfg(test)]
mod tests {
    use std::str;