From 04eeb4ff13563ec098401d5253565f94958730c0 Mon Sep 17 00:00:00 2001 From: Zelda Hessler Date: Wed, 15 Jun 2022 15:18:20 -0500 Subject: [PATCH] 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 --- CHANGELOG.next.toml | 9 ++++++ .../aws-smithy-http/src/byte_stream.rs | 31 ++++++++++--------- 2 files changed, 25 insertions(+), 15 deletions(-) diff --git a/CHANGELOG.next.toml b/CHANGELOG.next.toml index 79ce9f47c1..05fa4cd30f 100644 --- a/CHANGELOG.next.toml +++ b/CHANGELOG.next.toml @@ -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"] diff --git a/rust-runtime/aws-smithy-http/src/byte_stream.rs b/rust-runtime/aws-smithy-http/src/byte_stream.rs index a8c18d28ed..e9b3c0ccc9 100644 --- a/rust-runtime/aws-smithy-http/src/byte_stream.rs +++ b/rust-runtime/aws-smithy-http/src/byte_stream.rs @@ -546,31 +546,32 @@ impl Inner { } } +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 futures_core::stream::Stream for Inner where - B: http_body::Body, + B: http_body::Body, { type Item = Result; fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll> { - 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) { 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) + } + } } }