Unverified Commit 04eeb4ff authored by Zelda Hessler's avatar Zelda Hessler Committed by GitHub
Browse files

update: simplify and fix a latent issue with bytestream's streaming impl (#1461)

update: print helpful panic message for users on 32bit systems that try to stream large bodies
update: CHANGELOG.next.toml
parent 898dc706
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -17,6 +17,15 @@ references = ["aws-sdk-rust#547", "smithy-rs#1458"]
meta = { "breaking" = false, "tada" = false, "bug" = true }
author = "rcoh"

[[smithy-rs]]
message = """
Fix a potential bug with `ByteStream`'s implementation of `futures_core::stream::Stream` and add helpful error messages
for users on 32-bit systems that try to stream HTTP bodies larger than 4.29Gb.
"""
references = ["smithy-rs#1460"]
meta = { "breaking" = false, "tada" = false, "bug" = false }
author = "Velfi"

[[aws-sdk-rust]]
message = "Add `Debug` implementation to several types in `aws-config`"
references = ["smithy-rs#1421"]
+16 −15
Original line number Diff line number Diff line
@@ -546,31 +546,32 @@ impl Inner<SdkBody> {
    }
}

const SIZE_HINT_32_BIT_PANIC_MESSAGE: &str = r#"
You're running a 32-bit system and this stream's length is too large to be represented with a usize.
Please limit stream length to less than 4.294Gb or run this program on a 64-bit computer architecture.
"#;

impl<B> futures_core::stream::Stream for Inner<B>
where
    B: http_body::Body,
    B: http_body::Body<Data = Bytes>,
{
    type Item = Result<Bytes, B::Error>;

    fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
        match self.project().body.poll_data(cx) {
            Poll::Ready(Some(Ok(mut data))) => {
                let len = data.chunk().len();
                let bytes = data.copy_to_bytes(len);
                Poll::Ready(Some(Ok(bytes)))
            }
            Poll::Ready(None) => Poll::Ready(None),
            Poll::Ready(Some(Err(e))) => Poll::Ready(Some(Err(e))),
            Poll::Pending => Poll::Pending,
        }
        self.project().body.poll_data(cx)
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let size_hint = http_body::Body::size_hint(&self.body);
        (
            size_hint.lower() as usize,
            size_hint.upper().map(|u| u as usize),
        )
        let lower = size_hint.lower().try_into();
        let upper = size_hint.upper().map(|u| u.try_into()).transpose();

        match (lower, upper) {
            (Ok(lower), Ok(upper)) => (lower, upper),
            (Err(_), _) | (_, Err(_)) => {
                panic!("{}", SIZE_HINT_32_BIT_PANIC_MESSAGE)
            }
        }
    }
}